Get the correct version when passed multiple paths

This emulates more closely the behavior of an actual import statement by:
1. traversing `sys.path` in reverse so we keep the first module found.
2. checking if there is actually a module at `path / i_item` to avoid false positives.
I've checked both behaviors in concrete cases and they both match the python
interpreter now, when previously they didn't.

An example where both 1. and 2. are necessary is when `sys.path` is
'/usr/lib:/usr/local/lib/pythonX.Y/site-packages/:/usr/lib/pythonX.Y/site-packages/'
and different versions of the package are installed in the last two paths.
Notice how `os.walk` will traverse '/lib/pythonX.Y/site-packages/' for the first path
('/usr/lib'), despite the fact that there's nothing to import from there, and that
traversing the paths in direct order would result in the last path overwriting the
version from the middle path, which comes first in import order.
This commit is contained in:
Alexandre Hannud Abdo 2021-04-26 20:34:54 -03:00 committed by GitHub
parent cb4add28ef
commit 5d02bed770
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -209,7 +209,7 @@ def get_imports_info(
def get_locally_installed_packages(encoding=None):
packages = {}
ignore = ["tests", "_tests", "egg", "EGG", "info"]
for path in sys.path:
for path in reversed(sys.path):
for root, dirs, files in os.walk(path):
for item in files:
if "top_level" in item:
@ -223,7 +223,11 @@ def get_locally_installed_packages(encoding=None):
continue
for i_item in package_import:
if ((i_item not in ignore) and
(package[0] not in ignore)):
(package[0] not in ignore) and
(
os.path.isdir(os.path.join(path, i_item)) or
os.path.isfile(os.path.join(path, i_item + '.py'))
)):
version = None
if len(package) > 1:
version = package[1].replace(