-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
pyclbr.readmodule() and pyclbr.readmodule_ex() don't support namespace packages #70756
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
Comments
While working on the issue bpo-26295 which converts the test module to a package, I noticed that pyclbr doesn't work with packages: test_pyclbr fails when test becomes a package. Attached patch fixes pyclbr._readmodule():
I don't know importlib well enough to say if my usage of importlib spec is correct. |
Hmm. These two should be equivalent: if spec.loader.is_package(fullmodule):
dict['__path__'] = [os.path.dirname(fname)]
if spec.submodule_search_locations is not None:
dict['__path__'] = spec.submodule_search_locations Do you mean that "python -m pyclbr XXX" doesn't work for packages? I'm guessing you mean something else because I was able to run it successfully for both "os" (sort of a package) and "importlib". Also, I noticed that if I run pyclbr on the "test" package or "test.regrtest" I get back no output, not an error. I'd expect to get output though. Perhaps that's related? If you are getting an error, what is the traceback you are getting? Note that pyclbr fails with the following if you try to run it on a file or module that doesn't exist: AttributeError: 'NoneType' object has no attribute 'loader' |
The problem is that spec.loader is None when test is a package. It's easy to reproduce the issue: $ rm -f Lib/test/__init__.py Lib/test/__pycache__/__init__.cpython-36.pyc
$ ./python -m test -v -m test_decorators test_pyclbr
.. ====================================================================== Traceback (most recent call last):
...
File "/home/haypo/prog/python/default/Lib/pyclbr.py", line 145, in _readmodule
fname = spec.loader.get_filename(fullmodule)
AttributeError: 'NoneType' object has no attribute 'get_filename' |
Ah, you're talking about deleting Lib/test/init.py. Doing so makes it a namespace package. The loader we use for namespace packages [1] does not have a get_filename() method. So the problem to solve is supporting namespace packages in Lib/pyclbr.py. Regarding your patch, it's okay, but not the best option. Using spec.submodule_search_locations like you are isn't ideal, but works. However, you should be able to leave the is_package() call alone. TBH, the better option is to use importlib.util.module_from_spec() instead, since it does the right thing for you, like setting __path__. FWIW, I get the same as you by deleting those files and running the following: ./python Lib/pyclbr.py Lib/test [1] https://hg.python.org/cpython/file/default/Lib/importlib/_bootstrap_external.py#l991 |
I don't really care how the issue is fixed. As I wrote, I don't know well the importlib module. Feel free to propose a better patch :-) My main concern is to fix test_pyclbr when test becomes a namespace. |
Also, beside namespace packages, custom loaders may run into a similar problem with get_filename() and probably other code in there. It looks like the pyclbr module assumes that modules will be either builtin or loaded through SourceFileLoader. For example, you get a similar failure for frozen modules: ./python Lib/pyclbr.py _frozen_importlib |
Oh, and spec.loader for namespace package is set to None. |
Well, your patch is correct even if not ideal. :) Landing it as a short-term solution is fine. Just keep this issue open so we can address the problem more completely later. |
New changeset 700ae1bfc453 by Victor Stinner in branch '3.5': |
Ok, done. Sorry, I didn't write an unit test. I only tested manually by removing Lib/test/init.py.
If it's a different problem, I prefer to open a new issue. But it's up to you. Can you please rephrase the title to put your expectations there? I understood that you also want to support frozen module? |
Yeah, I've opened bpo-26584 to keep the matters separate. We can address a more comprehensive cleanup there. |
And thanks for addressing this here. :) |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: