Skip to content

Commit a07cd97

Browse files
committed
Merge branch 'master' of github.com:r1chardj0n3s/pip-check-reqs
2 parents 95b281c + 0d23ba6 commit a07cd97

File tree

7 files changed

+61
-16
lines changed

7 files changed

+61
-16
lines changed

pip_check_reqs/common.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
import os
66
import re
77

8+
from packaging.utils import canonicalize_name
9+
from pip.download import PipSession
10+
from pip.req import parse_requirements
11+
812
log = logging.getLogger(__name__)
913

1014

@@ -117,6 +121,18 @@ def find_imported_modules(options):
117121
return vis.finalise()
118122

119123

124+
def find_required_modules(options):
125+
explicit = set()
126+
for requirement in parse_requirements('requirements.txt',
127+
session=PipSession()):
128+
if options.ignore_reqs(requirement):
129+
log.debug('ignoring requirement: %s', requirement.name)
130+
else:
131+
log.debug('found requirement: %s', requirement.name)
132+
explicit.add(canonicalize_name(requirement.name))
133+
return explicit
134+
135+
120136
def is_package_file(path):
121137
'''Determines whether the path points to a Python package sentinel
122138
file - the __init__.py or its compiled variants.

pip_check_reqs/find_extra_reqs.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
import os
55
import sys
66

7+
from packaging.utils import canonicalize_name
78
from pip.commands.show import search_packages_info
8-
from pip.download import PipSession
9-
from pip.req import parse_requirements
10-
from pip.utils import get_installed_distributions, normalize_name
9+
from pip.utils import get_installed_distributions
1110

1211
from pip_check_reqs import common
1312

@@ -25,7 +24,7 @@ def find_extra_reqs(options):
2524
for package in search_packages_info(all_pkgs):
2625
log.debug('installed package: %s (at %s)', package['name'],
2726
package['location'])
28-
for f in package['files'] or []:
27+
for f in package.get('files', []) or []:
2928
path = os.path.realpath(os.path.join(package['location'], f))
3029
installed_files[path] = package['name']
3130
package_path = common.is_package_file(path)
@@ -40,7 +39,7 @@ def find_extra_reqs(options):
4039
for modname, info in used_modules.items():
4140
# probably standard library if it's not in the files list
4241
if info.filename in installed_files:
43-
used_name = normalize_name(installed_files[info.filename])
42+
used_name = canonicalize_name(installed_files[info.filename])
4443
log.debug('used module: %s (from package %s)', modname,
4544
installed_files[info.filename])
4645
used[used_name].append(info)
@@ -50,11 +49,7 @@ def find_extra_reqs(options):
5049
modname, info.filename)
5150

5251
# 4. compare with requirements.txt
53-
explicit = set()
54-
for requirement in parse_requirements('requirements.txt',
55-
session=PipSession()):
56-
log.debug('found requirement: %s', requirement.name)
57-
explicit.add(normalize_name(requirement.name))
52+
explicit = common.find_required_modules(options)
5853

5954
return [name for name in explicit if name not in used]
6055

@@ -70,6 +65,9 @@ def main():
7065
parser.add_option("-m", "--ignore-module", dest="ignore_mods",
7166
action="append", default=[],
7267
help="used module names (globs are ok) to ignore")
68+
parser.add_option("-r", "--ignore-requirement", dest="ignore_reqs",
69+
action="append", default=[],
70+
help="reqs in requirements.txt to ignore")
7371
parser.add_option("-v", "--verbose", dest="verbose",
7472
action="store_true", default=False, help="be more verbose")
7573
parser.add_option("-d", "--debug", dest="debug",
@@ -88,6 +86,7 @@ def main():
8886

8987
options.ignore_files = common.ignorer(options.ignore_files)
9088
options.ignore_mods = common.ignorer(options.ignore_mods)
89+
options.ignore_reqs = common.ignorer(options.ignore_reqs)
9190

9291
options.paths = args
9392

pip_check_reqs/find_missing_reqs.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
import os
55
import sys
66

7+
from packaging.utils import canonicalize_name
78
from pip.commands.show import search_packages_info
89
from pip.download import PipSession
910
from pip.req import parse_requirements
10-
from pip.utils import get_installed_distributions, normalize_name
11+
from pip.utils import get_installed_distributions
1112

1213
from pip_check_reqs import common
1314

@@ -25,7 +26,7 @@ def find_missing_reqs(options):
2526
for package in search_packages_info(all_pkgs):
2627
log.debug('installed package: %s (at %s)', package['name'],
2728
package['location'])
28-
for file in package['files'] or []:
29+
for file in package.get('files', []) or []:
2930
path = os.path.realpath(os.path.join(package['location'], file))
3031
installed_files[path] = package['name']
3132
package_path = common.is_package_file(path)
@@ -40,7 +41,7 @@ def find_missing_reqs(options):
4041
for modname, info in used_modules.items():
4142
# probably standard library if it's not in the files list
4243
if info.filename in installed_files:
43-
used_name = normalize_name(installed_files[info.filename])
44+
used_name = canonicalize_name(installed_files[info.filename])
4445
log.debug('used module: %s (from package %s)', modname,
4546
installed_files[info.filename])
4647
used[used_name].append(info)
@@ -54,7 +55,7 @@ def find_missing_reqs(options):
5455
for requirement in parse_requirements('requirements.txt',
5556
session=PipSession()):
5657
log.debug('found requirement: %s', requirement.name)
57-
explicit.add(normalize_name(requirement.name))
58+
explicit.add(canonicalize_name(requirement.name))
5859

5960
return [(name, used[name]) for name in used
6061
if name not in explicit]

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
pip>=6.0
2+
packaging

setup.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,8 @@
3838
'pip-extra-reqs=pip_check_reqs.find_extra_reqs:main',
3939
],
4040
},
41+
install_requires=[
42+
'packaging',
43+
'pip',
44+
],
4145
)

tests/test_common.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import absolute_import
22

33
import ast
4+
import collections
45
import logging
56
import os.path
67
import sys
@@ -159,3 +160,20 @@ def test_ignorer(monkeypatch, ignore_cfg, candidate, result):
159160
monkeypatch.setattr(os.path, 'relpath', lambda s: s.lstrip('/'))
160161
ignorer = common.ignorer(ignore_cfg)
161162
assert ignorer(candidate) == result
163+
164+
165+
def test_find_required_modules(monkeypatch):
166+
class options:
167+
@staticmethod
168+
def ignore_reqs(req):
169+
if req.name == 'barfoo':
170+
return True
171+
return False
172+
173+
FakeReq = collections.namedtuple('FakeReq', ['name'])
174+
requirements = [FakeReq('foobar'), FakeReq('barfoo')]
175+
monkeypatch.setattr(common, 'parse_requirements',
176+
pretend.call_recorder(lambda a, session=None: requirements))
177+
178+
reqs = common.find_required_modules(options)
179+
assert reqs == set(['foobar'])

tests/test_find_extra_reqs.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class options:
2121
version = False
2222
ignore_files = []
2323
ignore_mods = []
24+
ignore_reqs = []
2425
options = options()
2526
args = ['ham.py']
2627

@@ -64,10 +65,14 @@ def test_find_extra_reqs(monkeypatch):
6465

6566
FakeReq = collections.namedtuple('FakeReq', ['name'])
6667
requirements = [FakeReq('foobar')]
67-
monkeypatch.setattr(find_extra_reqs, 'parse_requirements',
68+
monkeypatch.setattr(common, 'parse_requirements',
6869
pretend.call_recorder(lambda a, session=None: requirements))
6970

70-
result = find_extra_reqs.find_extra_reqs(None)
71+
class options:
72+
ignore_reqs = lambda x, y: False
73+
options = options()
74+
75+
result = find_extra_reqs.find_extra_reqs(options)
7176
assert result == ['foobar']
7277

7378

@@ -117,6 +122,7 @@ class options:
117122
version = False
118123
ignore_files = []
119124
ignore_mods = []
125+
ignore_reqs = []
120126
options = options()
121127

122128
class FakeOptParse:

0 commit comments

Comments
 (0)