-
-
Notifications
You must be signed in to change notification settings - Fork 30.7k
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
pkgutil.walk_packages returns extra modules #58992
Comments
|
pkgutil.walk_packages(paths) seems to return incorrect results when the name of a subpackage of a path in paths matches the name of a package in the standard library. It both excludes modules it should include, and includes modules it should exclude. Here is an example:
>>> from pkgutil import walk_packages
>>> for info in walk_packages(['temp']):
... print(info[1], info[0].path)
...
foo temp
logging temp
logging.config /opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/logging
logging.handlers /opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/logging
>>> Observe that logging.bar is absent from the list, and logging.config and logging.handlers are included. |
|
I confirm this behavior in 2.7 and 3.2 versions. In my 3.3.0a3+ it actually outputs nothing. foo temp |
|
So the lack of output in 3.3 is not surprising as walk_packages() won't work with the new import implementation as it relies on a non-standard method on loaders that import does not provide. |
|
For the record, this issue is still present after Nick's pkgutil changes documented in bpo-15343 (not that I expected it to be resolved since this issue is a bit different). |
|
Right, this is a separate bug in pkgutil. Specifically, when it goes to import a package in order to check it for submodules, it invokes the global import system via __import__() rather than constraining the import to the path argument supplied to walk_packages. This means that it will only find it if the path being walked is already on sys.path. In the case of your example, it isn't (it's on a subdirectory). The reason my new tests didn't pick this up is that they're built on the test_runpy infrastructure, and one of the steps in that infrastructure is to add the new package path to sys.path so it can be imported. This isn't an easy one to fix - you basically need something along the lines of a PEP-406 style import engine API in order to do the import without having potentially adverse effects on the state in the sys module. |
|
At the very least, the pkgutil docs need to state clearly that walk_packages only works properly with sys.path entries, and the constraint feature may not descend into packages correctly if an entry is shadowed by a sys.modules entry or an entry earlier on sys.meta_path or sys.path. |
|
I just realised this is going to behave strangely with namespace packages as well: the __import__ step will pick up *every* portion of the namespace package, not just those defined in the identified subset of sys.path. |
By adverse, do you just mean side effects? If so, since the documentation doesn't explicitly say so, is there any reason for the user to think there shouldn't be side effects? For example, I tried this in Python 2.7: >>> import os, sys, pkgutil, unittest
>>> len(sys.modules)
86
>>> g = pkgutil.walk_packages([os.path.dirname(unittest.__file__)])
>>> len(sys.modules)
86
>>> for i in g:
... pass
...
>>> len(sys.modules)
95Or maybe this isn't what you mean. If not, can you provide an example? |
|
I just ran into this bug myself with namespace packages (in Python 2.7). When you have multiple packages (ns.a, ns.b) under a namespace package (ns), and constrain the paths in walk_packages so it should only pick up ns.a, it will pick up ns.b as well. Any hope for a fix or workaround? |
|
Note that this is reference from bpo-15358. |
|
Any hope to add the warning in pkgutil docs about this problem? For example: |

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.

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: