Skip to content

Commit 2e167ba

Browse files
author
Rebecca Graber
authored
feat: advertise constraints in setup.py (#150)
1 parent c8ac5b0 commit 2e167ba

File tree

2 files changed

+57
-10
lines changed

2 files changed

+57
-10
lines changed

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
include *.rst LICENSE.txt AUTHORS
22
include requirements/base.in
3+
include requirements/constraints.txt

setup.py

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#!/usr/bin/env python
22

3-
from setuptools import setup, find_packages
3+
import os
4+
import re
5+
6+
from setuptools import find_packages, setup
47

58
from auth_backends import __version__
69

@@ -11,24 +14,67 @@
1114
def load_requirements(*requirements_paths):
1215
"""
1316
Load all requirements from the specified requirements files.
17+
18+
Requirements will include any constraints from files specified
19+
with -c in the requirements files.
1420
Returns a list of requirement strings.
1521
"""
16-
requirements = set()
22+
# Modified from original SEMGREP update to allow package name with '[]' in it
23+
24+
requirements = {}
25+
constraint_files = set()
26+
27+
# groups "my-package-name<=x.y.z,..." into ("my-package-name", "<=x.y.z,...")
28+
requirement_line_regex = re.compile(r"([a-zA-Z0-9-_.\[\]]+)([<>=][^#\s]+)?")
29+
30+
def add_version_constraint_or_raise(current_line, current_requirements, add_if_not_present):
31+
regex_match = requirement_line_regex.match(current_line)
32+
if regex_match:
33+
package = regex_match.group(1)
34+
version_constraints = regex_match.group(2)
35+
existing_version_constraints = current_requirements.get(package, None)
36+
# it's fine to add constraints to an unconstrained package, but raise an error if there are already
37+
# constraints in place
38+
if existing_version_constraints and existing_version_constraints != version_constraints:
39+
raise BaseException(f'Multiple constraint definitions found for {package}:'
40+
f' "{existing_version_constraints}" and "{version_constraints}".'
41+
f'Combine constraints into one location with {package}'
42+
f'{existing_version_constraints},{version_constraints}.')
43+
if add_if_not_present or package in current_requirements:
44+
current_requirements[package] = version_constraints
45+
46+
# process .in files and store the path to any constraint files that are pulled in
1747
for path in requirements_paths:
1848
with open(path) as reqs:
19-
requirements.update(
20-
line.split('#')[0].strip() for line in reqs
21-
if is_requirement(line.strip())
22-
)
23-
return list(requirements)
49+
for line in reqs:
50+
if is_requirement(line):
51+
add_version_constraint_or_raise(line, requirements, True)
52+
if line and line.startswith('-c') and not line.startswith('-c http'):
53+
constraint_files.add(os.path.dirname(path) + '/' + line.split('#')[0].replace('-c', '').strip())
54+
55+
# process constraint files and add any new constraints found to existing requirements
56+
for constraint_file in constraint_files:
57+
with open(constraint_file) as reader:
58+
for line in reader:
59+
if is_requirement(line):
60+
add_version_constraint_or_raise(line, requirements, False)
61+
62+
# process back into list of pkg><=constraints strings
63+
constrained_requirements = [f'{pkg}{version or ""}' for (pkg, version) in sorted(requirements.items())]
64+
return constrained_requirements
2465

2566

2667
def is_requirement(line):
2768
"""
28-
Return True if the requirement line is a package requirement;
29-
that is, it is not blank, a comment, a URL, or an included file.
69+
Return True if the requirement line is a package requirement.
70+
71+
Returns:
72+
bool: True if the line is not blank, a comment,
73+
a URL, or an included file
3074
"""
31-
return line and not line.startswith(('-r', '#', '-e', 'git+', '-c'))
75+
# UPDATED VIA SEMGREP - if you need to remove/modify this method remove this line and add a comment specifying why
76+
77+
return line and line.strip() and not line.startswith(('-r', '#', '-e', 'git+', '-c'))
3278

3379

3480
setup(

0 commit comments

Comments
 (0)