Skip to content

Commit dee6690

Browse files
committed
Renames, moves, docstrings, comments
1 parent 0862d40 commit dee6690

File tree

5 files changed

+36
-30
lines changed

5 files changed

+36
-30
lines changed

src/pip/_internal/req/constructors.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
InstallRequirement.
99
"""
1010

11-
import functools
1211
import logging
1312
import os
1413
import re
@@ -27,6 +26,7 @@
2726
from pip._internal.req.req_install import InstallRequirement
2827
from pip._internal.utils.filetypes import is_archive_file
2928
from pip._internal.utils.misc import is_installable_dir
29+
from pip._internal.utils.packaging import get_requirement
3030
from pip._internal.utils.urls import path_to_url
3131
from pip._internal.vcs import is_url, vcs
3232

@@ -40,11 +40,6 @@
4040
operators = Specifier._operators.keys()
4141

4242

43-
@functools.lru_cache(maxsize=None)
44-
def get_or_create_requirement(req_string: str) -> Requirement:
45-
return Requirement(req_string)
46-
47-
4843
def _strip_extras(path: str) -> Tuple[str, Optional[str]]:
4944
m = re.match(r"^(.+)(\[[^\]]+\])$", path)
5045
extras = None
@@ -60,7 +55,7 @@ def _strip_extras(path: str) -> Tuple[str, Optional[str]]:
6055
def convert_extras(extras: Optional[str]) -> Set[str]:
6156
if not extras:
6257
return set()
63-
return get_or_create_requirement("placeholder" + extras.lower()).extras
58+
return get_requirement("placeholder" + extras.lower()).extras
6459

6560

6661
def parse_editable(editable_req: str) -> Tuple[Optional[str], str, Set[str]]:
@@ -89,7 +84,7 @@ def parse_editable(editable_req: str) -> Tuple[Optional[str], str, Set[str]]:
8984
return (
9085
package_name,
9186
url_no_extras,
92-
get_or_create_requirement("placeholder" + extras.lower()).extras,
87+
get_requirement("placeholder" + extras.lower()).extras,
9388
)
9489
else:
9590
return package_name, url_no_extras, set()
@@ -315,7 +310,7 @@ def with_source(text: str) -> str:
315310

316311
def _parse_req_string(req_as_string: str) -> Requirement:
317312
try:
318-
req = get_or_create_requirement(req_as_string)
313+
req = get_requirement(req_as_string)
319314
except InvalidRequirement:
320315
if os.path.sep in req_as_string:
321316
add_msg = "It looks like a path."
@@ -392,7 +387,7 @@ def install_req_from_req_string(
392387
user_supplied: bool = False,
393388
) -> InstallRequirement:
394389
try:
395-
req = get_or_create_requirement(req_string)
390+
req = get_requirement(req_string)
396391
except InvalidRequirement:
397392
raise InstallationError(f"Invalid requirement: '{req_string}'")
398393

src/pip/_internal/resolution/resolvelib/factory.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,15 @@
3737
from pip._internal.models.link import Link
3838
from pip._internal.models.wheel import Wheel
3939
from pip._internal.operations.prepare import RequirementPreparer
40-
from pip._internal.req.constructors import (
41-
get_or_create_requirement,
42-
install_req_from_link_and_ireq,
43-
)
40+
from pip._internal.req.constructors import install_req_from_link_and_ireq
4441
from pip._internal.req.req_install import (
4542
InstallRequirement,
4643
check_invalid_constraint_type,
4744
)
4845
from pip._internal.resolution.base import InstallRequirementProvider
4946
from pip._internal.utils.compatibility_tags import get_supported
5047
from pip._internal.utils.hashes import Hashes
48+
from pip._internal.utils.packaging import get_requirement
5149
from pip._internal.utils.virtualenv import running_under_virtualenv
5250

5351
from .base import Candidate, CandidateVersion, Constraint, Requirement
@@ -367,7 +365,7 @@ def find_candidates(
367365
# If the current identifier contains extras, add explicit candidates
368366
# from entries from extra-less identifier.
369367
with contextlib.suppress(InvalidRequirement):
370-
parsed_requirement = get_or_create_requirement(identifier)
368+
parsed_requirement = get_requirement(identifier)
371369
explicit_candidates.update(
372370
self._iter_explicit_candidates_from_base(
373371
requirements.get(parsed_requirement.name, ()),

src/pip/_internal/utils/packaging.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import functools
12
import logging
23
from email.message import Message
34
from email.parser import FeedParser
45
from typing import Optional, Tuple
56

67
from pip._vendor import pkg_resources
78
from pip._vendor.packaging import specifiers, version
9+
from pip._vendor.packaging.requirements import Requirement
810
from pip._vendor.pkg_resources import Distribution
911

1012
from pip._internal.exceptions import NoneMetadataError
@@ -69,3 +71,14 @@ def get_installer(dist: Distribution) -> str:
6971
if line.strip():
7072
return line.strip()
7173
return ""
74+
75+
76+
@functools.lru_cache(maxsize=None)
77+
def get_requirement(req_string: str) -> Requirement:
78+
"""Construct a packaging.Requirement object with caching"""
79+
# Parsing requirement strings is expensive, and is also expected to happen
80+
# with a low diversity of different arguments (at least relative the number
81+
# constructed). This method adds a cache to requirement object creation to
82+
# minimize repeated parsing of the same string to construct equivalent
83+
# Requirement objects.
84+
return Requirement(req_string)

tests/unit/test_packaging.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
import pytest
44
from pip._vendor.packaging import specifiers
5+
from pip._vendor.packaging.requirements import Requirement
56

6-
from pip._internal.utils.packaging import check_requires_python
7+
from pip._internal.utils.packaging import check_requires_python, get_requirement
78

89

910
@pytest.mark.parametrize(
@@ -27,3 +28,16 @@ def test_check_requires_python__invalid() -> None:
2728
"""
2829
with pytest.raises(specifiers.InvalidSpecifier):
2930
check_requires_python("invalid", (3, 6, 5))
31+
32+
33+
def test_get_or_create_caching() -> None:
34+
"""test caching of get_or_create requirement"""
35+
teststr = "affinegap==1.10"
36+
from_helper = get_requirement(teststr)
37+
freshly_made = Requirement(teststr)
38+
# Requirement doesn't have an equality operator (yet) so test
39+
# equality of attribute for list of attributes
40+
for iattr in ["name", "url", "extras", "specifier", "marker"]:
41+
assert getattr(from_helper, iattr) == getattr(freshly_made, iattr)
42+
assert not (get_requirement(teststr) is Requirement(teststr))
43+
assert get_requirement(teststr) is get_requirement(teststr)

tests/unit/test_req.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
from pip._internal.req.constructors import (
2929
_get_url_from_path,
3030
_looks_like_path,
31-
get_or_create_requirement,
3231
install_req_from_editable,
3332
install_req_from_line,
3433
install_req_from_parsed_requirement,
@@ -659,19 +658,6 @@ def test_parse_editable_local_extras(
659658
)
660659

661660

662-
def test_get_or_create_caching() -> None:
663-
"""test caching of get_or_create requirement"""
664-
teststr = "affinegap==1.10"
665-
from_helper = get_or_create_requirement(teststr)
666-
freshly_made = Requirement(teststr)
667-
# Requirement doesn't have an equality operator (yet) so test
668-
# equality of attribute for list of attributes
669-
for iattr in ["name", "url", "extras", "specifier", "marker"]:
670-
assert getattr(from_helper, iattr) == getattr(freshly_made, iattr)
671-
assert not (get_or_create_requirement(teststr) is Requirement(teststr))
672-
assert get_or_create_requirement(teststr) is get_or_create_requirement(teststr)
673-
674-
675661
def test_exclusive_environment_markers() -> None:
676662
"""Make sure RequirementSet accepts several excluding env markers"""
677663
eq36 = install_req_from_line("Django>=1.6.10,<1.7 ; python_version == '3.6'")

0 commit comments

Comments
 (0)