Skip to content

Commit

Permalink
Ensure all pip._vendor.* modules are mapped to debundled corresponden…
Browse files Browse the repository at this point in the history
…ces (#6113)

With the original `vendored()` implementation and such an initialization sequence:

```
vendored("packaging")
vendored("packaging.version")
```

In `sys.modules`, `pip._vendor.packaging` is correctly connected to the debundled `packaging`, while `pip._vendor.packaging.version` is not, as the latter is `__import__`ed from the existing `pip._vendor.packaging` module. That results in the same issue as #5429 - `pip._vendor.packaging.version.Version` and `packaging.version.Version` cannot be compared.

This patch attempts to fix this issue by skipping `__import__` from the vendored name. This is safe because `vendored()` is called only when `DEBUNDLED = True`, and vendored libraries are already deleted as per [debundling instructions](https://github.com/pypa/pip/blob/master/src/pip/_vendor/README.rst#debundling).
  • Loading branch information
Chih-Hsuan Yen authored and pradyunsg committed Mar 15, 2019
1 parent 7f6edbd commit 8ef3283
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 17 deletions.
Empty file.
3 changes: 3 additions & 0 deletions src/pip/_vendor/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,6 @@ extra work on your end in order to solve the problems described above.
6. *(optional)* Update the ``pip_version_check`` logic to use the
appropriate logic for determining the latest available version of pip and
prompt the user with the correct upgrade message.

Note that partial debundling is **NOT** supported. You need to prepare wheels
for all dependencies for successful debundling.
31 changes: 14 additions & 17 deletions src/pip/_vendor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,21 @@ def vendored(modulename):
vendored_name = "{0}.{1}".format(__name__, modulename)

try:
__import__(vendored_name, globals(), locals(), level=0)
__import__(modulename, globals(), locals(), level=0)
except ImportError:
try:
__import__(modulename, globals(), locals(), level=0)
except ImportError:
# We can just silently allow import failures to pass here. If we
# got to this point it means that ``import pip._vendor.whatever``
# failed and so did ``import whatever``. Since we're importing this
# upfront in an attempt to alias imports, not erroring here will
# just mean we get a regular import error whenever pip *actually*
# tries to import one of these modules to use it, which actually
# gives us a better error message than we would have otherwise
# gotten.
pass
else:
sys.modules[vendored_name] = sys.modules[modulename]
base, head = vendored_name.rsplit(".", 1)
setattr(sys.modules[base], head, sys.modules[modulename])
# We can just silently allow import failures to pass here. If we
# got to this point it means that ``import pip._vendor.whatever``
# failed and so did ``import whatever``. Since we're importing this
# upfront in an attempt to alias imports, not erroring here will
# just mean we get a regular import error whenever pip *actually*
# tries to import one of these modules to use it, which actually
# gives us a better error message than we would have otherwise
# gotten.
pass
else:
sys.modules[vendored_name] = sys.modules[modulename]
base, head = vendored_name.rsplit(".", 1)
setattr(sys.modules[base], head, sys.modules[modulename])


# If we're operating in a debundled setup, then we want to go ahead and trigger
Expand Down

0 comments on commit 8ef3283

Please sign in to comment.