Skip to content

Commit c14b5ab

Browse files
fix: updated setup.py using script. (#436)
1 parent 08bf52e commit c14b5ab

File tree

1 file changed

+82
-9
lines changed

1 file changed

+82
-9
lines changed

setup.py

Lines changed: 82 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import glob
2+
import os
23
import os.path
34
import re
45
import sys
@@ -26,24 +27,96 @@ def get_version(*file_paths):
2627
def load_requirements(*requirements_paths):
2728
"""
2829
Load all requirements from the specified requirements files.
30+
31+
Requirements will include any constraints from files specified
32+
with -c in the requirements files.
2933
Returns a list of requirement strings.
3034
"""
31-
requirements = set()
35+
# UPDATED VIA SEMGREP - if you need to remove/modify this method remove this line and add a comment specifying why.
36+
37+
# e.g. {"django": "Django", "confluent-kafka": "confluent_kafka[avro]"}
38+
by_canonical_name = {}
39+
40+
def check_name_consistent(package):
41+
"""
42+
Raise exception if package is named different ways.
43+
44+
This ensures that packages are named consistently so we can match
45+
constraints to packages. It also ensures that if we require a package
46+
with extras we don't constrain it without mentioning the extras (since
47+
that too would interfere with matching constraints.)
48+
"""
49+
canonical = package.lower().replace('_', '-').split('[')[0]
50+
seen_spelling = by_canonical_name.get(canonical)
51+
if seen_spelling is None:
52+
by_canonical_name[canonical] = package
53+
elif seen_spelling != package:
54+
raise Exception(
55+
f'Encountered both "{seen_spelling}" and "{package}" in requirements '
56+
'and constraints files; please use just one or the other.'
57+
)
58+
59+
requirements = {}
60+
constraint_files = set()
61+
62+
# groups "pkg<=x.y.z,..." into ("pkg", "<=x.y.z,...")
63+
re_package_name_base_chars = r"a-zA-Z0-9\-_." # chars allowed in base package name
64+
# Two groups: name[maybe,extras], and optionally a constraint
65+
requirement_line_regex = re.compile(
66+
r"([%s]+(?:\[[%s,\s]+\])?)([<>=][^#\s]+)?"
67+
% (re_package_name_base_chars, re_package_name_base_chars)
68+
)
69+
70+
def add_version_constraint_or_raise(current_line, current_requirements, add_if_not_present):
71+
regex_match = requirement_line_regex.match(current_line)
72+
if regex_match:
73+
package = regex_match.group(1)
74+
version_constraints = regex_match.group(2)
75+
check_name_consistent(package)
76+
existing_version_constraints = current_requirements.get(package, None)
77+
# It's fine to add constraints to an unconstrained package,
78+
# but raise an error if there are already constraints in place.
79+
if existing_version_constraints and existing_version_constraints != version_constraints:
80+
raise BaseException(f'Multiple constraint definitions found for {package}:'
81+
f' "{existing_version_constraints}" and "{version_constraints}".'
82+
f'Combine constraints into one location with {package}'
83+
f'{existing_version_constraints},{version_constraints}.')
84+
if add_if_not_present or package in current_requirements:
85+
current_requirements[package] = version_constraints
86+
87+
# Read requirements from .in files and store the path to any
88+
# constraint files that are pulled in.
3289
for path in requirements_paths:
3390
with open(path) as reqs:
34-
requirements.update(
35-
line.split('#')[0].strip() for line in reqs
36-
if is_requirement(line.strip())
37-
)
38-
return list(requirements)
91+
for line in reqs:
92+
if is_requirement(line):
93+
add_version_constraint_or_raise(line, requirements, True)
94+
if line and line.startswith('-c') and not line.startswith('-c http'):
95+
constraint_files.add(os.path.dirname(path) + '/' + line.split('#')[0].replace('-c', '').strip())
96+
97+
# process constraint files: add constraints to existing requirements
98+
for constraint_file in constraint_files:
99+
with open(constraint_file) as reader:
100+
for line in reader:
101+
if is_requirement(line):
102+
add_version_constraint_or_raise(line, requirements, False)
103+
104+
# process back into list of pkg><=constraints strings
105+
constrained_requirements = [f'{pkg}{version or ""}' for (pkg, version) in sorted(requirements.items())]
106+
return constrained_requirements
39107

40108

41109
def is_requirement(line):
42110
"""
43-
Return True if the requirement line is a package requirement;
44-
that is, it is not blank, a comment, a URL, or an included file.
111+
Return True if the requirement line is a package requirement.
112+
113+
Returns:
114+
bool: True if the line is not blank, a comment,
115+
a URL, or an included file
45116
"""
46-
return line and not line.startswith(('-r', '#', '-e', 'git+', '-c'))
117+
# UPDATED VIA SEMGREP - if you need to remove/modify this method remove this line and add a comment specifying why
118+
119+
return line and line.strip() and not line.startswith(('-r', '#', '-e', 'git+', '-c'))
47120

48121

49122
VERSION = get_version('edx_repo_tools', '__init__.py')

0 commit comments

Comments
 (0)