-
Notifications
You must be signed in to change notification settings - Fork 22
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
feat: Support multiple extras in requirements constraint advertisement #379
Changes from 2 commits
554dbc7
75c2538
b5c4888
27da069
41eaa6a
22be77a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -36,17 +36,43 @@ def load_requirements(*requirements_paths): | |||||
with -c in the requirements files. | ||||||
Returns a list of requirement strings. | ||||||
""" | ||||||
by_canonical_name = {} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A comment here with an example entry would be helpful. It took me a minute to figure out how it was being used. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, maybe something like this: # e.g. {"django": "Django", "openedx-events": "openedx_events"} |
||||||
|
||||||
def check_name_consistent(package): | ||||||
""" | ||||||
Raise exception if package is spelled different ways. | ||||||
|
||||||
This ensures that packages are spelled consistently so we can match | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not really spelling.
Suggested change
|
||||||
constraints to packages. It also ensures that if we require a package | ||||||
with extras we don't constrain it without mentioning the extras (since | ||||||
that too would interfere with matching constraints.) | ||||||
""" | ||||||
canonical = package.lower().replace('_', '-').split('[')[0] | ||||||
seen_spelling = by_canonical_name.get(canonical) | ||||||
if seen_spelling is None: | ||||||
by_canonical_name[canonical] = package | ||||||
elif seen_spelling != package: | ||||||
raise Exception( | ||||||
f'Encountered both "{seen_spelling}" and "{package}" in requirements ' | ||||||
'and constraints files; please use just one or the other.' | ||||||
) | ||||||
|
||||||
requirements = {} | ||||||
constraint_files = set() | ||||||
|
||||||
# groups "pkg<=x.y.z,..." into ("pkg", "<=x.y.z,...") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we update the comment to include how the regex treats [] ? it's a pretty hard regex to read There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How would you feel about using verbose mode? Not something I think I've ever used before, but I agree that this regex is... pretty dense. requirement_line_regex = re.compile(
r"""
(
# The base name of the package
[%s]+
# Optionally, an extras section, as in `some-package[extra-one, extra-two]`
(?:
\[[%s,\s]+\]
)?
)
# Optionally, a version constraint like `>=3.0`
(
[<>=][^#\s]+
)?
"""
% (re_package_name_base_chars, re_package_name_base_chars),
re.VERBOSE
) Or even using a raw format-string, which is apparently a thing you can do? And maybe adding some spaces inside some of the more confusing character classes: requirement_line_regex = re.compile(
fr"""
(
# The base name of the package
[ {re_package_name_base_chars} ]+
# Optionally, an extras section, as in `some-package[extra-one, extra-two]`
(?:
\[ [{re_package_name_base_chars},\s]+ \]
)?
)
# Optionally, a version constraint like `>=3.0`
(
[<>=][^#\s]+
)?
""",
re.VERBOSE
) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (I've pushed up a far simpler option. Verbose mode is cool but... probably overkill here.) |
||||||
requirement_line_regex = re.compile(r"([a-zA-Z0-9-_.\[\]]+)([<>=][^#\s]+)?") | ||||||
re_package_name_base_chars = r"a-zA-Z0-9\-_." # chars allowed in base package name | ||||||
requirement_line_regex = re.compile( | ||||||
r"([%s]+(?:\[[%s,\s]+\])?)([<>=][^#\s]+)?" | ||||||
% (re_package_name_base_chars, re_package_name_base_chars) | ||||||
) | ||||||
|
||||||
def add_version_constraint_or_raise(current_line, current_requirements, add_if_not_present): | ||||||
regex_match = requirement_line_regex.match(current_line) | ||||||
if regex_match: | ||||||
package = regex_match.group(1) | ||||||
version_constraints = regex_match.group(2) | ||||||
check_name_consistent(package) | ||||||
existing_version_constraints = current_requirements.get(package, None) | ||||||
# It's fine to add constraints to an unconstrained package, | ||||||
# but raise an error if there are already constraints in place. | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.