Skip to content

Commit b11e59e

Browse files
ewiandaaignas
andcommitted
Update CHANGELOG.md
Co-authored-by: Ignas Anikevicius <240938+aignas@users.noreply.github.com>
1 parent f148ca6 commit b11e59e

File tree

4 files changed

+40
-42
lines changed

4 files changed

+40
-42
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ Unreleased changes template.
8181

8282
{#v0-0-0-fixed}
8383
### Fixed
84-
* (pypi) Platform specific markers are now correctly handled when using `requirments_by_platform`
85-
in pip.parse Fixed in [#2766](https://github.com/bazel-contrib/rules_python/pull/2766).
84+
* (pypi) Platform specific extras are now correctly handled when using
85+
universal lock files with environment markers. Fixes [#2690](https://github.com/bazel-contrib/rules_python/pull/2690).
8686
* (runfiles) ({obj}`--bootstrap_impl=script`) Follow symlinks when searching for runfiles.
8787
* (toolchains) Do not try to run `chmod` when downloading non-windows hermetic toolchain
8888
repositories on Windows. Fixes

python/private/pypi/parse_requirements.bzl

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,9 @@ load("//python/private:normalize_name.bzl", "normalize_name")
3030
load("//python/private:repo_utils.bzl", "repo_utils")
3131
load(":index_sources.bzl", "index_sources")
3232
load(":parse_requirements_txt.bzl", "parse_requirements_txt")
33-
load(":pep508_req.bzl", "requirement")
33+
load(":pep508_requirement.bzl", "requirement")
3434
load(":whl_target_platforms.bzl", "select_whls")
3535

36-
def _extract_version(entry):
37-
"""Extract the version part from the requirement string.
38-
39-
40-
Args:
41-
entry: {type}`str` The requirement string.
42-
"""
43-
version_start = entry.find("==")
44-
if version_start != -1:
45-
# Extract everything after '==' until the next space or end of the string
46-
version, _, _ = entry[version_start + 2:].partition(" ")
47-
return version
48-
return None
49-
5036
def parse_requirements(
5137
ctx,
5238
*,
@@ -113,19 +99,19 @@ def parse_requirements(
11399
# are returned as just the base package name. e.g., `foo[bar]` results
114100
# in an entry like `("foo", "foo[bar] == 1.0 ...")`.
115101
# Lines with different markers are not condidered duplicates.
116-
requirements_dict = {
117-
(normalize_name(entry[0]), _extract_version(entry[1]), requirement(entry[1]).marker): entry
118-
for entry in sorted(
119-
parse_result.requirements,
120-
# Get the longest match and fallback to original WORKSPACE sorting,
121-
# which should get us the entry with most extras.
122-
#
123-
# FIXME @aignas 2024-05-13: The correct behaviour might be to get an
124-
# entry with all aggregated extras, but it is unclear if we
125-
# should do this now.
126-
key = lambda x: (len(x[1].partition("==")[0]), x),
127-
)
128-
}.values()
102+
requirements_dict = {}
103+
for entry in sorted(
104+
parse_result.requirements,
105+
# Get the longest match and fallback to original WORKSPACE sorting,
106+
# which should get us the entry with most extras.
107+
#
108+
# FIXME @aignas 2024-05-13: The correct behaviour might be to get an
109+
# entry with all aggregated extras, but it is unclear if we
110+
# should do this now.
111+
key = lambda x: (len(x[1].partition("==")[0]), x),
112+
):
113+
req = requirement(entry[1])
114+
requirements_dict[(req.name, req.version, req.marker)] = entry
129115

130116
tokenized_options = []
131117
for opt in parse_result.options:
@@ -134,7 +120,7 @@ def parse_requirements(
134120

135121
pip_args = tokenized_options + extra_pip_args
136122
for plat in plats:
137-
requirements[plat] = requirements_dict
123+
requirements[plat] = requirements_dict.values()
138124
options[plat] = pip_args
139125

140126
requirements_by_platform = {}

python/private/pypi/pep508_requirement.bzl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ def requirement(spec):
3030
"""
3131
spec = spec.strip()
3232
requires, _, maybe_hashes = spec.partition(";")
33+
34+
version_start = requires.find("==")
35+
version = None
36+
if version_start != -1:
37+
# Extract everything after '==' until the next space or end of the string
38+
version, _, _ = requires[version_start + 2:].partition(" ")
39+
40+
# Remove any trailing characters from the version string
41+
version = version.strip(" ")
42+
3343
marker, _, _ = maybe_hashes.partition("--hash")
3444
requires, _, extras_unparsed = requires.partition("[")
3545
extras_unparsed, _, _ = extras_unparsed.partition("]")
@@ -42,4 +52,5 @@ def requirement(spec):
4252
name = normalize_name(name).replace("_", "-"),
4353
marker = marker.strip(" "),
4454
extras = extras,
55+
version = version,
4556
)

tests/pypi/pep508/requirement_tests.bzl

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,21 @@ _tests = []
2020

2121
def _test_requirement_line_parsing(env):
2222
want = {
23-
" name1[ foo ] ": ("name1", ["foo"]),
24-
"Name[foo]": ("name", ["foo"]),
25-
"name [fred,bar] @ http://foo.com ; python_version=='2.7'": ("name", ["fred", "bar"]),
26-
"name; (os_name=='a' or os_name=='b') and os_name=='c'": ("name", [""]),
27-
"name@http://foo.com": ("name", [""]),
28-
"name[ Foo123 ]": ("name", ["Foo123"]),
29-
"name[extra]@http://foo.com": ("name", ["extra"]),
30-
"name[foo]": ("name", ["foo"]),
31-
"name[quux, strange];python_version<'2.7' and platform_version=='2'": ("name", ["quux", "strange"]),
32-
"name_foo[bar]": ("name-foo", ["bar"]),
23+
" name1[ foo ] ": ("name1", ["foo"], None, ""),
24+
"Name[foo]": ("name", ["foo"], None, ""),
25+
"name [fred,bar] @ http://foo.com ; python_version=='2.7'": ("name", ["fred", "bar"], None, "python_version=='2.7'"),
26+
"name; (os_name=='a' or os_name=='b') and os_name=='c'": ("name", [""], None, "(os_name=='a' or os_name=='b') and os_name=='c'"),
27+
"name@http://foo.com": ("name", [""], None, ""),
28+
"name[ Foo123 ]": ("name", ["Foo123"], None, ""),
29+
"name[extra]@http://foo.com": ("name", ["extra"], None, ""),
30+
"name[foo]": ("name", ["foo"], None, ""),
31+
"name[quux, strange];python_version<'2.7' and platform_version=='2'": ("name", ["quux", "strange"], None, "python_version<'2.7' and platform_version=='2'"),
32+
"name_foo[bar]": ("name-foo", ["bar"], None, ""),
33+
"name_foo[bar]==0.25": ("name-foo", ["bar"], "0.25", ""),
3334
}
3435

3536
got = {
36-
i: (parsed.name, parsed.extras)
37+
i: (parsed.name, parsed.extras, parsed.version, parsed.marker)
3738
for i, parsed in {case: requirement(case) for case in want}.items()
3839
}
3940
env.expect.that_dict(got).contains_exactly(want)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy