File tree 6 files changed +54
-2
lines changed 6 files changed +54
-2
lines changed Original file line number Diff line number Diff line change @@ -573,6 +573,9 @@ and use any packages found there. This is disabled via the same
573
573
of that is not part of the pip API. As of 7.0, pip makes a subdirectory for
574
574
each sdist that wheels are built from and places the resulting wheels inside.
575
575
576
+ As of version 20.0, pip also caches wheels it built from Git requirements
577
+ when such requirements reference an immutable commit hash.
578
+
576
579
Pip attempts to choose the best wheels from those built in preference to
577
580
building a new wheel. Note that this means when a package has both optional
578
581
C extensions and builds ``py `` tagged wheels when the C extension can't be built
Original file line number Diff line number Diff line change
1
+ Cache wheels built from Git requirements that are considered immutable,
2
+ because they point to a commit hash.
Original file line number Diff line number Diff line change 12
12
from pip ._vendor .six .moves .urllib import request as urllib_request
13
13
14
14
from pip ._internal .exceptions import BadCommand
15
- from pip ._internal .utils .misc import display_path
15
+ from pip ._internal .utils .misc import display_path , hide_url
16
16
from pip ._internal .utils .subprocess import make_command
17
17
from pip ._internal .utils .temp_dir import TempDirectory
18
18
from pip ._internal .utils .typing import MYPY_CHECK_RUNNING
@@ -59,6 +59,13 @@ class Git(VersionControl):
59
59
def get_base_rev_args (rev ):
60
60
return [rev ]
61
61
62
+ def is_immutable_rev_checkout (self , url , dest ):
63
+ # type: (str, str) -> bool
64
+ _ , rev_options = self .get_url_rev_options (hide_url (url ))
65
+ if not rev_options .rev :
66
+ return False
67
+ return self .is_commit_id_equal (dest , rev_options .rev )
68
+
62
69
def get_git_version (self ):
63
70
VERSION_PFX = 'git version '
64
71
version = self .run_command (['version' ], show_stdout = False )
Original file line number Diff line number Diff line change @@ -329,6 +329,20 @@ def get_base_rev_args(rev):
329
329
"""
330
330
raise NotImplementedError
331
331
332
+ def is_immutable_rev_checkout (self , url , dest ):
333
+ # type: (str, str) -> bool
334
+ """
335
+ Return true if the commit hash checked out at dest matches
336
+ the revision in url.
337
+
338
+ Always return False, if the VCS does not support immutable commit
339
+ hashes.
340
+
341
+ This method does not check if there are local uncommitted changes
342
+ in dest after checkout, as pip currently has no use case for that.
343
+ """
344
+ return False
345
+
332
346
@classmethod
333
347
def make_rev_options (cls , rev = None , extra_args = None ):
334
348
# type: (Optional[str], Optional[CommandArgs]) -> RevOptions
Original file line number Diff line number Diff line change 52
52
from pip ._internal .utils .ui import open_spinner
53
53
from pip ._internal .utils .unpacking import unpack_file
54
54
from pip ._internal .utils .urls import path_to_url
55
+ from pip ._internal .vcs import vcs
55
56
56
57
if MYPY_CHECK_RUNNING :
57
58
from typing import (
@@ -838,7 +839,15 @@ def should_cache(
838
839
return False
839
840
840
841
if req .link and req .link .is_vcs :
841
- # VCS checkout. Build wheel just for this run.
842
+ # VCS checkout. Build wheel just for this run
843
+ # unless it points to an immutable commit hash in which
844
+ # case it can be cached.
845
+ assert not req .editable
846
+ assert req .source_dir
847
+ vcs_backend = vcs .get_backend_for_scheme (req .link .scheme )
848
+ assert vcs_backend
849
+ if vcs_backend .is_immutable_rev_checkout (req .link .url , req .source_dir ):
850
+ return True
842
851
return False
843
852
844
853
link = req .link
Original file line number Diff line number Diff line change @@ -221,3 +221,20 @@ def test_is_commit_id_equal(script):
221
221
assert not Git .is_commit_id_equal (version_pkg_path , 'abc123' )
222
222
# Also check passing a None value.
223
223
assert not Git .is_commit_id_equal (version_pkg_path , None )
224
+
225
+
226
+ def test_is_immutable_rev_checkout (script ):
227
+ version_pkg_path = _create_test_package (script )
228
+ commit = script .run (
229
+ 'git' , 'rev-parse' , 'HEAD' ,
230
+ cwd = version_pkg_path
231
+ ).stdout .strip ()
232
+ assert Git ().is_immutable_rev_checkout (
233
+ "git+https://g.c/o/r@" + commit , version_pkg_path
234
+ )
235
+ assert not Git ().is_immutable_rev_checkout (
236
+ "git+https://g.c/o/r" , version_pkg_path
237
+ )
238
+ assert not Git ().is_immutable_rev_checkout (
239
+ "git+https://g.c/o/r@master" , version_pkg_path
240
+ )
You can’t perform that action at this time.
0 commit comments