import-linter icon indicating copy to clipboard operation
import-linter copied to clipboard

Limit imports only to symbols in __init__.py

Open hgrecco opened this issue 3 years ago • 3 comments

Awesome package. I was about to build something until I found this! Congrats

I have a something that looks like this

- __init__.py
- a.py
- b.py
- c.py
- inner
  - __init__.py
  - inner1
    - __init__.py 
    - a1.py
    - b1.py
    - c1.py
  - inner2
    - __init__.py
    - a2.py
    - b2.py
    - c2py

and I am trying to restrict imports from inner1 and inner2 only to those imported in their respective __init__.py How can I achieve this?

hgrecco avatar Apr 30 '22 02:04 hgrecco

Thanks for raising the issue!

I'm not totally clear on what you are trying to restrict, could you give an example?

seddonym avatar May 04 '22 13:05 seddonym

As python doesn't have public/private modifiers, I want to use a linter to promote a certain type of organization. Defining a subpackage as any folder that has an __init__.py inside, I would like a contract that states that modules in a subpackage can only import:

  • from modules in the same subpackage
  • from the __init__.py of child subpackges.

In the example above:

  • __init__.py, a, b, c should only import from each other and from inner/__init__.py
  • inner/__init__.py should only import from inner/inner1/__init__.py and inner/inner2/__init__.py
  • inner/inner1/__init__.py should be able to import from each other inner/inner2/__init__.py (as if it was inner/inner1__init__.py and inner/inner2__init__.py)

There should also be a way to exclude certain source and target files/folders from the rule (for example, from the testsuite I want to be able to import everything and maybe there is a compat module in the root that should be accesible to all.

hgrecco avatar May 04 '22 13:05 hgrecco

Interesting! I think there is a lot of mileage in the idea of private modules - in fact we use a (slightly different) convention at work where modules prefixed with an underscore are deemed 'private', and can only be imported by their parent __init__.py file. At some point I plan to make a built in contract type for this.

I think the best way forward with your requirements is to create a custom contract. Let me know if anything in the documentation isn't clear.

seddonym avatar May 04 '22 14:05 seddonym

I'm going to close this in favour of these issues:

  • https://github.com/seddonym/import-linter/issues/159
  • https://github.com/seddonym/import-linter/issues/158

seddonym avatar Feb 03 '23 15:02 seddonym

Thanks! , I will take a look!

hgrecco avatar Feb 03 '23 17:02 hgrecco