Skip to content
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

bpo-42856: Add --with-wheel-pkg-dir=PATH configure option #24210

Merged
merged 1 commit into from Jan 20, 2021

Conversation

@vstinner
Copy link
Member

@vstinner vstinner commented Jan 13, 2021

Add --with-wheel-pkg-dir=PATH option to the ./configure script. If
specified, the ensurepip module looks for setuptools and pip wheel
packages in this directory: if both are present, these wheel packages
are used instead of ensurepip bundled wheel packages.

Some Linux distribution packaging policies recommand against bundling
dependencies. For example, Fedora installs wheel packages in the
/usr/share/python-wheels/ directory and don't install the
ensurepip._bundled package.

ensurepip: Remove unused runpy import.

https://bugs.python.org/issue42856

@vstinner
Copy link
Member Author

@vstinner vstinner commented Jan 13, 2021

This PR is my second attempt which is way less than intrusive.

Changes since my first attempt PR #24154:

  • Only use the wheel package directory if setuptools and pip wheel packages are found there. Otherwise, use existing code.
  • Revert most changes to leave most of existing code unchanged: common case when --with-wheel-pkg-dir is not used.
  • Don't attempt to compare version numbers anymore. Only use sort(filename) for the case which should not happen: whne the wheel package directory contains multiple files for pip or setuptools. It prevents to have to bother with complex versions numbers like 20.3b1 (pip-20.3b1-py2.py3-none-any.whl filename).
@vstinner
Copy link
Member Author

@vstinner vstinner commented Jan 13, 2021

I created a PR on the Fedora python3.10 package to test the integration of my patch:
https://src.fedoraproject.org/rpms/python3.10/pull-request/22

@vstinner
Copy link
Member Author

@vstinner vstinner commented Jan 14, 2021

@xavfernandez @pradyunsg @pablogsal @kkonopko @hroncok @nanjekyejoannah: Hi, does anyone of you want to review this PR? See https://bugs.python.org/issue42856 for the rationale. (I looked at who modified Lib/ensurepip/ last months.)

@vstinner
Copy link
Member Author

@vstinner vstinner commented Jan 14, 2021

I fixed test_ensurepip when ensurepip._bundled is missing (on Fedora).

@vstinner vstinner force-pushed the vstinner:ensurepip_dir2 branch from 8a97d1e to 70e6f44 Jan 14, 2021
Copy link
Contributor

@xavfernandez xavfernandez left a comment

I did not review the non-python files.

The python part seems ok but now feels somewhat complicated.

I wonder if we should not drop _SETUPTOOLS_VERSION, _PIP_VERSION & _PROJECTS variables in favor of using importlib.resources.files on ensurepip._bundled to automatically discover the bundled versions (similarly to what is now done with _WHEEL_PKG_DIR).

This would ease the next pip/setuptools versions bump: all that would be necessary would be to replace the wheels in Lib/ensurepip/_bundled/ without specifying the expected versions.

def test_version(self):
# Test version()
with tempfile.TemporaryDirectory() as tmpdir:
self.touch(tmpdir, "pip-1.2.3b1-py2.py3-none-any.whl")

This comment has been minimized.

@xavfernandez

xavfernandez Jan 14, 2021
Contributor

Any reason for not using pathlib ?

Suggested change
self.touch(tmpdir, "pip-1.2.3b1-py2.py3-none-any.whl")
pathlib.Path(tmpdir, "pip-1.2.3b1-py2.py3-none-any.whl").touch()

This comment has been minimized.

@vstinner

vstinner Jan 14, 2021
Author Member

I prefer to avoid testing pathlib in test_ensurepip :-) I like low-level code :-D

@vstinner
Copy link
Member Author

@vstinner vstinner commented Jan 14, 2021

@xavfernandez:

I wonder if we should not drop _SETUPTOOLS_VERSION, _PIP_VERSION & _PROJECTS variables in favor of using importlib.resources.files on ensurepip._bundled to automatically discover the bundled versions (similarly to what is now done with _WHEEL_PKG_DIR).

Sure, that's doable, but can it be done in a following PR? I tried to reduce changes in my PR to focus on the new feature (and reduce any risk of regression).

My first PR attempt scanned ensurepip/_bundled/ to discover the version and Python tag of bundled setuptools and pip. It reused the os.listdir() code, but importlib.resources.files sounds like a better idea for bundled wheel packages.

@xavfernandez
Copy link
Contributor

@xavfernandez xavfernandez commented Jan 14, 2021

but can it be done in a following PR ?

certainly :)

@vstinner
Copy link
Member Author

@vstinner vstinner commented Jan 20, 2021

I tested manually 3 cases using test_ensurepip.

I added logs to see which packages are used with log.patch file:

diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py
index 8b000f93db..292b47002a 100644
--- a/Lib/ensurepip/__init__.py
+++ b/Lib/ensurepip/__init__.py
@@ -162,10 +162,12 @@ def _bootstrap(*, root=None, upgrade=False, user=False,
                 from ensurepip import _bundled
                 wheel_name = package.wheel_name
                 whl = resources.read_binary(_bundled, wheel_name)
+                print("WHEEL: read_binary")
             else:
                 with open(package.filename, "rb") as fp:
                     whl = fp.read()
                 wheel_name = os.path.basename(package.filename)
+                print("WHEEL: copy file", package.filename)
 
             filename = os.path.join(tmpdir, wheel_name)
             with open(filename, "wb") as fp:

Case 1: only bundled

git clean -fdx
git checkout .
git apply ~/log.patch
./configure --with-pydebug CFLAGS="-O0" && make && ./python -m test -v test_ensurepip

=> OK: BUNDLED is used, test_ensurepip pass

Case 2: only wheel dir

git clean -fdx
git checkout .
git apply ~/log.patch
rm -rf Lib/ensurepip/_bundled/
./configure --with-pydebug CFLAGS="-O0" --with-wheel-pkg-dir=/usr/share/python-wheels && make && ./python -m test -v test_ensurepip

=> OK: WHEEL DIR is used, test_ensurepip pass

Case 3: both, wheel dir + bundled

git clean -fdx
git checkout .
git apply ~/log.patch
./configure --with-pydebug CFLAGS="-O0" --with-wheel-pkg-dir=/usr/share/python-wheels && make && ./python -m test -v test_ensurepip

=> OK: WHEEL DIR is used, test_ensurepip pass

Copy link
Contributor

@hroncok hroncok left a comment

(I haven't check the configure changes, because I don't understand autotools.)

Lib/ensurepip/__init__.py Outdated Show resolved Hide resolved
Lib/ensurepip/__init__.py Outdated Show resolved Hide resolved
Lib/ensurepip/__init__.py Outdated Show resolved Hide resolved
packages = dir_packages
_PACKAGES = packages
return packages
_PACKAGES = None

This comment has been minimized.

@hroncok

hroncok Jan 20, 2021
Contributor

Why not move this to other constants?

This comment has been minimized.

@vstinner

vstinner Jan 20, 2021
Author Member

It's not a constant but a cache for _get_packages(). I prefer to keep it close to the function definition.

This comment has been minimized.

@hroncok

hroncok Jan 20, 2021
Contributor

Your call. The missing empty line looks weird thou.

)
with open(os.path.join(tmpdir, wheel_name), "wb") as fp:
for name, package in _get_packages().items():
if package.wheel_name:

This comment has been minimized.

@hroncok

hroncok Jan 20, 2021
Contributor

This is confusing. What about:

Suggested change
if package.wheel_name:
# bundled wheels have names:
if package.wheel_name:

This comment has been minimized.

@vstinner

vstinner Jan 20, 2021
Author Member

I added comments inside, is it better?

This comment has been minimized.

@hroncok

hroncok Jan 20, 2021
Contributor

Yes.

Lib/ensurepip/__init__.py Outdated Show resolved Hide resolved
Lib/ensurepip/__init__.py Outdated Show resolved Hide resolved
Lib/test/test_ensurepip.py Show resolved Hide resolved
Copy link
Contributor

@hroncok hroncok left a comment

Awesome, thanks!

Add --with-wheel-pkg-dir=PATH option to the ./configure script. If
specified, the ensurepip module looks for setuptools and pip wheel
packages in this directory: if both are present, these wheel packages
are used instead of ensurepip bundled wheel packages.

Some Linux distribution packaging policies recommend against bundling
dependencies. For example, Fedora installs wheel packages in the
/usr/share/python-wheels/ directory and don't install the
ensurepip._bundled package.

ensurepip: Remove unused runpy import.
@vstinner vstinner force-pushed the vstinner:ensurepip_dir2 branch from 37f4bac to ee03e54 Jan 20, 2021
@vstinner
Copy link
Member Author

@vstinner vstinner commented Jan 20, 2021

Oops, there is spelling mistake: recommand => recommend. I updated my PR :-)

@vstinner vstinner merged commit 75e59a9 into python:master Jan 20, 2021
11 checks passed
11 checks passed
Docs
Details
Check for source changes
Details
Check if generated files are up to date
Details
Windows (x86)
Details
Windows (x64)
Details
macOS
Details
Ubuntu
Details
Azure Pipelines PR #20210120.37 succeeded
Details
Travis CI - Pull Request Build Passed
Details
bedevere/issue-number Issue number 42856 found
Details
bedevere/news News entry found in Misc/NEWS.d
@vstinner vstinner deleted the vstinner:ensurepip_dir2 branch Jan 20, 2021
@vstinner
Copy link
Member Author

@vstinner vstinner commented Jan 20, 2021

Thanks for the reviews @xavfernandez and @hroncok! It's now merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

5 participants