this post was submitted on 21 Nov 2023
8 points (100.0% liked)

Python

6331 readers
301 users here now

Welcome to the Python community on the programming.dev Lemmy instance!

πŸ“… Events

PastNovember 2023

October 2023

July 2023

August 2023

September 2023

🐍 Python project:
πŸ’“ Python Community:
✨ Python Ecosystem:
🌌 Fediverse
Communities
Projects
Feeds

founded 1 year ago
MODERATORS
 

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?

you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] -1 points 11 months ago (1 children)

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

[–] [email protected] 1 points 11 months ago (2 children)

That's not correct. __all__ is not a whitelist. It is only the list used for

from module import *

If you have a module with submodules foo, bar and baz and __all__ = ["foo", "bar"] it will not prevent you from importing baz manually. It just won't do it automatically.

[–] [email protected] 0 points 11 months ago* (last edited 11 months ago) (1 children)

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 ;)

[–] [email protected] 0 points 11 months ago* (last edited 11 months ago) (1 children)

Bullshit!

module/__init__.py:

__all__ = ["foo", "bar"]

module/foo.py:

def foo():
    print("foo")

module/bar.py:

def bar():
    print("bar")

module/baz.py:

def baz():
    print("baz")

main.py:

from module import *
from module import baz

if __name__ == "__main__":
    print("main")
    foo.foo()
    bar.bar()
    baz.baz()

Output:

$ python main.py 
main
foo
bar
baz

No errors, warnings or anything.

[–] [email protected] 0 points 11 months ago (1 children)

You're running python without linters? Interesting approach.

[–] [email protected] 1 points 11 months ago

You can't expect the user to have one.

[–] [email protected] -1 points 11 months ago (1 children)

@Chais from module import \* should almost never be used anyway, so...

[–] [email protected] 2 points 11 months ago* (last edited 11 months ago)

Renders correctly for me
Screenshot_20231121-134426_Trebuchet_1