-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Top-level module of namespace package incorrectly raises NotATopLevelModule
#141
Comments
Thanks for raising the issue. 😄 You're right, currently Grimp only treats packages as namespace packages - it explicitly checks that it's a package rather than a module. An even simpler example is to try to build the graph on an empty standalone Python file. This has always failed by design, but arguably that file could be seen as being in a namespace package of its parent. I suspect that adjusting this behaviour would require a rethink of Grimp's machinery, which is fundamentally oriented around the idea of the root item being a package with a directory, but it might not be too bad. Still, is it worth the effort? Interested to hear more about your use case - I would have thought that this requirement is quite niche, but perhaps I'm wrong. Also, is it the kind of thing you'd be interested in contributing a fix for? |
I didn't understand this comment. In my example, the namespace package is It is my understanding that namespace package can consist of packages and single-file modules. For example, in this discussion, the namespace package It is a pretty common pattern for a module to start out life as a single My particular use case is imposing some organization on my company's Python codebase, which is a single namespace package (the company name) split by topic and dependency into different portions. There are a lot of single-file modules. I started with your import-linter, which led me to Grimp. I am interested in working on this feature. |
You're right, I was thinking that
And what's the motivation for making that top level package a namespace package, rather than just adding an |
@seddonym Great module, found it from Talk Python To Me. I'm trying to use it on Apache Airflow (of which I'm a member of the core dev team) and our use of explicit namespace packages seems to confuse things. If I put a [importlinter]
root_packages=
airflow
airflow.providers
exclude_type_checking_imports = True And run it in verbose node (inside the uv managed venv,
However, if I hack packagefinder.py to Now, I'm about 30mins in to looking at grimp/import-linter so I don't understand much about it, but is that check even needed? If it is in some cases could we add a config option to turn it off? Will turning it off cause any other problems down the line? |
And if I don't put |
Hi Ash, Thanks for reaching out. You should just be able to include I checked out the latest airflow code, pip installed grimp into a virtual env, and then ran the repl from >>> import grimp
>>> graph = grimp.build_graph("airflow")
>>> len(graph.modules)
1094
>>> "airflow.providers" in graph.modules
True Could you say a bit more about what you're expecting to see instead, or does this resolve things for you? |
Ahhhh, the difference is where it's run from. Even though This is run from the root.
Curious. |
I think it's because I don't think this is a bug - it's just following the standard Python import resolution rules, do you agree? |
So with namespace packages that isn't true:
However due to $reasons (various tooling, IDE support etc) we've currently got to use the old-school explicit namespace packages mechanism https://github.com/apache/airflow/blob/ee07d6339a3b1a1b4451c20f5109ab51dcd13ebe/airflow/__init__.py#L23-L26 In ruff for example we've worked around this by being explicit about what is a namespace package https://github.com/apache/airflow/blob/ee07d6339a3b1a1b4451c20f5109ab51dcd13ebe/pyproject.toml#L214 |
Oh interesting, ok. So it sounds like Grimp doesn't support pgutil-style namespace packages (TIL!). I think this could do with its own issue, so I've created one here. Happy to consider a pull request. |
I have a namespace package
top
with the following files:top/a.py
does not import anything.top/b/__init__.py
containsimport top.a
.When building the graph, Grimp reports that
top.a
is not top level.top.b
works fine.Here's the traceback. Note that the exception class is raised, not an instance. Is this intentional?
I'm using v3.2 of grimp, Python 3.11.5.
The text was updated successfully, but these errors were encountered: