Let's say I have the following structure:
my_module/
__init__.py
utilities.py
and __init__.py contains
from .utilities import SomeUtilityFunction
Is there a way to prevent or alert developers when they do
from my_module.utilities import SomeUtilityFunction
instead of
from my_module import SomeUtilityFunction
The problem arose when a few modules started using a function that was imported inside a module in which it wasn't used, while also being available on the module's __init__.py, so after linting the file and removing the unused import my tests started failing.
any other advice for situations like this?
13 Comments
Chais@sh.itjust.works · 2 pts · 2y
You could guard it.
__init__.py:utilities.py:Take this with a grain of salt, as I'm typing this on my phone and haven't actually tried it.
Alternatively there's the
import-guardpackage on PyPI. No idea if it's any good, though. Just something a quick search brought up.Edit:
Ok, I tried my suggestion and it doesn't work.
sebsch@discuss.tchncs.de · 1 pts · 2y
This approach seems quite overkomplex. Instead of having these errors on runtime, stuff like this should sit in linter rules of any kind.
Chais@sh.itjust.works · 1 pts · 2y
It's only useful during development there.
benc@mastodon.hawaga.org.uk · 0 pts · 2y
@fixmycode mypy type checking can report this error in your code:
iox3.py:3: error: Module "iox2" does not explicitly export attribute "y" [attr-defined]
which I think is roughly the problem you are encountering: an attribute in an imported module that wasn't explicitly defined in that module, but instead came from somewhere else.
fixmycode@feddit.cl · 1 pts · 2y
I think this is the more sensitive approach, I'll take a look at putting mypy in my pipeline
sebsch@discuss.tchncs.de · -1 pts · 2y
I am normally define the interface to models while defining
__all__.Defined in the
__init__it allows to define a whitelist what can be Imported from the outside.https://docs.python.org/3/tutorial/modules.html#importing-from-a-package
Chais@sh.itjust.works · 1 pts · 2y
That's not correct.
__all__is not a whitelist. It is only the list used forIf you have a module with submodules
foo,barandbazand__all__ = ["foo", "bar"]it will not prevent you from importingbazmanually. It just won't do it automatically.sebsch@discuss.tchncs.de · 0 pts · 2y
It works exactly like one. You get a warning if you try to import something not defined in it. The docs are just very confusing here ;)
Chais@sh.itjust.works · 0 pts · 2y
Bullshit!
module/__init__.py:module/foo.py:module/bar.py:module/baz.py:main.py:Output:
No errors, warnings or anything.
sebsch@discuss.tchncs.de · 0 pts · 2y
You're running python without linters? Interesting approach.
Chais@sh.itjust.works · 1 pts · 2y
You can't expect the user to have one.
twoframesperminute@mastodon.social · -1 pts · 2y
@Chais
from module import \*should almost never be used anyway, so...Chais@sh.itjust.works · 2 pts · 2y
Renders correctly for me
