Hello community, here is the log from the commit of package python-requirements-detector for openSUSE:Factory checked in at 2020-08-04 20:22:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-requirements-detector (Old) and /work/SRC/openSUSE:Factory/.python-requirements-detector.new.3592 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-requirements-detector" Tue Aug 4 20:22:24 2020 rev:9 rq:824190 version:0.7 Changes: -------- --- /work/SRC/openSUSE:Factory/python-requirements-detector/python-requirements-detector.changes 2020-06-03 20:36:26.073908340 +0200 +++ /work/SRC/openSUSE:Factory/.python-requirements-detector.new.3592/python-requirements-detector.changes 2020-08-04 20:22:36.317003067 +0200 @@ -1,0 +2,7 @@ +Mon Aug 3 10:06:26 UTC 2020 - Marketa Calabkova <mcalabk...@suse.com> + +- Update to version 0.7 + * support Python 3.8 + * code refactorings and cleanups + +------------------------------------------------------------------- Old: ---- 0.6.tar.gz New: ---- 0.7.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-requirements-detector.spec ++++++ --- /var/tmp/diff_new_pack.I0gprP/_old 2020-08-04 20:22:37.001003155 +0200 +++ /var/tmp/diff_new_pack.I0gprP/_new 2020-08-04 20:22:37.001003155 +0200 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define oldpython python Name: python-requirements-detector -Version: 0.6 +Version: 0.7 Release: 0 Summary: Python tool to find and list requirements of a Python project License: MIT @@ -30,12 +30,12 @@ BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros -Requires: python-astroid >= 1.0.0 +Requires: python-astroid >= 1.4 Requires(post): update-alternatives Requires(postun): update-alternatives BuildArch: noarch # SECTION test requirements -BuildRequires: %{python_module astroid} +BuildRequires: %{python_module astroid >= 1.4} BuildRequires: %{python_module pytest} # /SECTION %ifpython3 ++++++ 0.6.tar.gz -> 0.7.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requirements-detector-0.6/.travis.yml new/requirements-detector-0.7/.travis.yml --- old/requirements-detector-0.6/.travis.yml 2018-07-22 10:24:34.000000000 +0200 +++ new/requirements-detector-0.7/.travis.yml 2020-05-29 11:13:53.000000000 +0200 @@ -1,12 +1,12 @@ sudo: false language: python python: - - "2.6" - "2.7" - "3.4" - "3.5" - "3.6" - - "3.7-dev" + - "3.7" + - "3.8" install: - "pip install nose coverage coveralls" - "pip install --editable ." diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requirements-detector-0.6/README.md new/requirements-detector-0.7/README.md --- old/requirements-detector-0.6/README.md 2018-07-22 10:24:34.000000000 +0200 +++ new/requirements-detector-0.7/README.md 2020-05-29 11:13:53.000000000 +0200 @@ -47,3 +47,12 @@ >>> find_requirements(os.getcwd()) [DetectedRequirement:Django==1.5.2, DetectedRequirement:South>=0.8, ...] ``` + + +If you know the relevant file or directory, you can use `from_requirements_txt`, `from_setup_py` or `from_requirements_dir` directly. + +``` +>>> from requirements_detector import from_requirements_txt +>>> from_requirements_txt("/path/to/requirements.txt") +[DetectedRequirement:Django==1.5.2, DetectedRequirement:South>=0.8, ...] +``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requirements-detector-0.6/requirements_detector/__compat__.py new/requirements-detector-0.7/requirements_detector/__compat__.py --- old/requirements-detector-0.6/requirements_detector/__compat__.py 2018-07-22 10:24:34.000000000 +0200 +++ new/requirements-detector-0.7/requirements_detector/__compat__.py 2020-05-29 11:13:53.000000000 +0200 @@ -3,14 +3,12 @@ # translated to new. try: - from astroid import Call + from astroid import Call except ImportError: - from astroid import CallFunc as Call + from astroid import CallFunc as Call try: - from astroid import AssignName + from astroid import AssignName except ImportError: - from astroid import AssName as AssignName - - + from astroid import AssName as AssignName diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requirements-detector-0.6/requirements_detector/__init__.py new/requirements-detector-0.7/requirements_detector/__init__.py --- old/requirements-detector-0.6/requirements_detector/__init__.py 2018-07-22 10:24:34.000000000 +0200 +++ new/requirements-detector-0.7/requirements_detector/__init__.py 2020-05-29 11:13:53.000000000 +0200 @@ -1 +1,6 @@ -from requirements_detector.detect import find_requirements \ No newline at end of file +from requirements_detector.detect import ( + find_requirements, + from_requirements_txt, + from_requirements_dir, + from_setup_py, +) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requirements-detector-0.6/requirements_detector/detect.py new/requirements-detector-0.7/requirements_detector/detect.py --- old/requirements-detector-0.6/requirements_detector/detect.py 2018-07-22 10:24:34.000000000 +0200 +++ new/requirements-detector-0.7/requirements_detector/detect.py 2020-05-29 11:13:53.000000000 +0200 @@ -7,24 +7,31 @@ from requirements_detector.requirement import DetectedRequirement -__all__ = ['find_requirements', - 'RequirementsNotFound', - 'CouldNotParseRequirements'] +__all__ = [ + "find_requirements", + "from_requirements_txt", + "from_requirements_dir", + "from_setup_py", + "RequirementsNotFound", + "CouldNotParseRequirements", +] # PEP263, see http://legacy.python.org/dev/peps/pep-0263/ -_ENCODING_REGEXP = re.compile(r'coding[:=]\s*([-\w.]+)') +_ENCODING_REGEXP = re.compile(r"coding[:=]\s*([-\w.]+)") _PY3K = sys.version_info >= (3, 0) _PIP_OPTIONS = ( - '-i', '--index-url', - '--extra-index-url', - '--no-index', - '-f', '--find-links', - '-r' + "-i", + "--index-url", + "--extra-index-url", + "--no-index", + "-f", + "--find-links", + "-r", ) @@ -46,12 +53,12 @@ with open(filepath) as f: if _PY3K: return f.read() - + contents = f.readlines() result = [] encoding_lines = contents[0:2] - encoding = 'utf-8' + encoding = "utf-8" for line in encoding_lines: match = _ENCODING_REGEXP.search(line) if match is None: @@ -60,7 +67,7 @@ encoding = match.group(1) result += [line.rstrip() for line in contents[2:]] - result = '\n'.join(result) + result = "\n".join(result) return result.decode(encoding) @@ -83,7 +90,7 @@ """ requirements = [] - setup_py = os.path.join(path, 'setup.py') + setup_py = os.path.join(path, "setup.py") if os.path.exists(setup_py) and os.path.isfile(setup_py): try: requirements = from_setup_py(setup_py) @@ -92,7 +99,7 @@ except CouldNotParseRequirements: pass - for reqfile_name in ('requirements.txt', 'requirements.pip'): + for reqfile_name in ("requirements.txt", "requirements.pip"): reqfile_path = os.path.join(path, reqfile_name) if os.path.exists(reqfile_path) and os.path.isfile(reqfile_path): try: @@ -100,7 +107,7 @@ except CouldNotParseRequirements as e: pass - requirements_dir = os.path.join(path, 'requirements') + requirements_dir = os.path.join(path, "requirements") if os.path.exists(requirements_dir) and os.path.isdir(requirements_dir): from_dir = from_requirements_dir(requirements_dir) if from_dir is not None: @@ -119,7 +126,6 @@ class SetupWalker(object): - def __init__(self, ast): self._ast = ast self._setup_call = None @@ -133,7 +139,7 @@ # test to see if this is a call to setup() if isinstance(node, Call): for child_node in node.get_children(): - if isinstance(child_node, Name) and child_node.name == 'setup': + if isinstance(child_node, Name) and child_node.name == "setup": # TODO: what if this isn't actually the distutils setup? self._setup_call = node @@ -165,7 +171,7 @@ # do we want to try to handle positional arguments? continue - if child_node.arg not in ('install_requires', 'requires'): + if child_node.arg not in ("install_requires", "requires"): continue if isinstance(child_node.value, (List, Tuple)): @@ -225,10 +231,10 @@ requirements = [] with open(requirements_file) as f: for req in f.readlines(): - if req.strip() == '': + if req.strip() == "": # empty line continue - if req.strip().startswith('#'): + if req.strip().startswith("#"): # this is a comment continue if req.strip().split()[0] in _PIP_OPTIONS: @@ -248,7 +254,7 @@ filepath = os.path.join(path, entry) if not os.path.isfile(filepath): continue - if entry.endswith('.txt') or entry.endswith('.pip'): + if entry.endswith(".txt") or entry.endswith(".pip"): # TODO: deal with duplicates requirements += from_requirements_txt(filepath) @@ -262,10 +268,10 @@ filepath = os.path.join(path, entry) if not os.path.isfile(filepath): continue - m = re.match(r'^(\w*)req(uirement)?s(\w*)\.txt$', entry) + m = re.match(r"^(\w*)req(uirement)?s(\w*)\.txt$", entry) if m is None: continue - if m.group(1).startswith('test') or m.group(3).endswith('test'): + if m.group(1).startswith("test") or m.group(3).endswith("test"): continue requirements += from_requirements_txt(filepath) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requirements-detector-0.6/requirements_detector/formatters.py new/requirements-detector-0.7/requirements_detector/formatters.py --- old/requirements-detector-0.6/requirements_detector/formatters.py 2018-07-22 10:24:34.000000000 +0200 +++ new/requirements-detector-0.7/requirements_detector/formatters.py 2020-05-29 11:13:53.000000000 +0200 @@ -1,13 +1,10 @@ - import sys def requirements_file(requirements_list): for requirement in requirements_list: sys.stdout.write(requirement.pip_format()) - sys.stdout.write('\n') + sys.stdout.write("\n") -FORMATTERS = { - 'requirements_file': requirements_file -} +FORMATTERS = {"requirements_file": requirements_file} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requirements-detector-0.6/requirements_detector/requirement.py new/requirements-detector-0.7/requirements_detector/requirement.py --- old/requirements-detector-0.6/requirements_detector/requirement.py 2018-07-22 10:24:34.000000000 +0200 +++ new/requirements-detector-0.7/requirements_detector/requirement.py 2020-05-29 11:13:53.000000000 +0200 @@ -21,7 +21,7 @@ def _is_filepath(req): # this is (probably) a file - return os.path.sep in req or req.startswith('.') + return os.path.sep in req or req.startswith(".") def _parse_egg_name(url_fragment): @@ -31,12 +31,12 @@ >>> _parse_egg_name('something_spurious') None """ - if '=' not in url_fragment: + if "=" not in url_fragment: return None parts = urlparse.parse_qs(url_fragment) - if 'egg' not in parts: + if "egg" not in parts: return None - return parts['egg'][0] # taking the first value mimics pip's behaviour + return parts["egg"][0] # taking the first value mimics pip's behaviour def _strip_fragment(urlparts): @@ -46,13 +46,12 @@ urlparts.path, urlparts.params, urlparts.query, - None + None, ) return urlparse.urlunparse(new_urlparts) class DetectedRequirement(object): - def __init__(self, name=None, url=None, requirement=None, location_defined=None): if requirement is not None: self.name = requirement.key @@ -67,12 +66,14 @@ self.location_defined = location_defined def _format_specs(self): - return ','.join(['%s%s' % (comp, version) for comp, version in self.version_specs]) + return ",".join( + ["%s%s" % (comp, version) for comp, version in self.version_specs] + ) def pip_format(self): if self.url: if self.name: - return '%s#egg=%s' % (self.url, self.name) + return "%s#egg=%s" % (self.url, self.name) return self.url if self.name: if self.version_specs: @@ -80,22 +81,28 @@ return self.name def __str__(self): - rep = self.name or 'Unknown' + rep = self.name or "Unknown" if self.version_specs: - specs = ','.join(['%s%s' % (comp, version) for comp, version in self.version_specs]) - rep = '%s%s' % (rep, specs) + specs = ",".join( + ["%s%s" % (comp, version) for comp, version in self.version_specs] + ) + rep = "%s%s" % (rep, specs) if self.url: - rep = '%s (%s)' % (rep, self.url) + rep = "%s (%s)" % (rep, self.url) return rep def __hash__(self): return hash(str(self.name) + str(self.url) + str(self.version_specs)) def __repr__(self): - return 'DetectedRequirement:%s' % str(self) + return "DetectedRequirement:%s" % str(self) def __eq__(self, other): - return self.name == other.name and self.url == other.url and self.version_specs == other.version_specs + return ( + self.name == other.name + and self.url == other.url + and self.version_specs == other.version_specs + ) def __gt__(self, other): return (self.name or "") > (other.name or "") @@ -113,22 +120,28 @@ # 7) (-e|--editable) <vcs_url>#egg=<dependency_name> line = line.strip() + # We need to match whitespace + # because url based requirements specify + # egg_name after a '#' + comment_pos = re.search(r"\s#", line) + if comment_pos: + line = line[: comment_pos.start()] + # strip the editable flag - line = re.sub('^(-e|--editable) ', '', line) + line = re.sub("^(-e|--editable) ", "", line) url = urlparse.urlparse(line) # if it is a VCS URL, then we want to strip off the protocol as urlparse # might not handle it correctly vcs_scheme = None - if '+' in url.scheme or url.scheme in ('git',): - if url.scheme == 'git': - vcs_scheme = 'git+git' + if "+" in url.scheme or url.scheme in ("git",): + if url.scheme == "git": + vcs_scheme = "git+git" else: vcs_scheme = url.scheme - url = urlparse.urlparse(re.sub(r'^%s://' % re.escape(url.scheme), '', line)) + url = urlparse.urlparse(re.sub(r"^%s://" % re.escape(url.scheme), "", line)) - if vcs_scheme is None and url.scheme == '' and not _is_filepath(line): + if vcs_scheme is None and url.scheme == "" and not _is_filepath(line): # if we are here, it is a simple dependency try: req = Requirement.parse(line) @@ -136,13 +149,17 @@ # this happens if the line is invalid return None else: - return DetectedRequirement(requirement=req, location_defined=location_defined) + return DetectedRequirement( + requirement=req, location_defined=location_defined + ) # otherwise, this is some kind of URL name = _parse_egg_name(url.fragment) url = _strip_fragment(url) if vcs_scheme: - url = '%s://%s' % (vcs_scheme, url) + url = "%s://%s" % (vcs_scheme, url) - return DetectedRequirement(name=name, url=url, location_defined=location_defined) + return DetectedRequirement( + name=name, url=url, location_defined=location_defined + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requirements-detector-0.6/requirements_detector/run.py new/requirements-detector-0.7/requirements_detector/run.py --- old/requirements-detector-0.6/requirements_detector/run.py 2018-07-22 10:24:34.000000000 +0200 +++ new/requirements-detector-0.7/requirements_detector/run.py 2020-05-29 11:13:53.000000000 +0200 @@ -27,10 +27,10 @@ except RequirementsNotFound: _die("Unable to find requirements at %s" % path) - format_name = 'requirements_file' # TODO: other output formats such as JSON + format_name = "requirements_file" # TODO: other output formats such as JSON FORMATTERS[format_name](requirements) sys.exit(0) -if __name__ == '__main__': +if __name__ == "__main__": run() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requirements-detector-0.6/setup.py new/requirements-detector-0.7/setup.py --- old/requirements-detector-0.6/setup.py 2018-07-22 10:24:34.000000000 +0200 +++ new/requirements-detector-0.7/setup.py 2020-05-29 11:13:53.000000000 +0200 @@ -4,7 +4,7 @@ import sys -_version = "0.6" +_version = "0.7" _packages = find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]) _short_description = "Python tool to find and list requirements of a Python project" @@ -15,12 +15,12 @@ 'Intended Audience :: Developers', 'Operating System :: Unix', 'Topic :: Software Development :: Quality Assurance', - 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', 'License :: OSI Approved :: MIT License', ] @@ -30,6 +30,11 @@ _install_requires = [ 'astroid>=1.0,<1.3.0', ] +elif sys.version_info < (3, 0): + # astroid 2.x is Python 3 only + _install_requires = [ + 'astroid>=1.4,<2.0', + ] else: _install_requires = [ 'astroid>=1.4', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requirements-detector-0.6/tests/test_parsing.py new/requirements-detector-0.7/tests/test_parsing.py --- old/requirements-detector-0.6/tests/test_parsing.py 2018-07-22 10:24:34.000000000 +0200 +++ new/requirements-detector-0.7/tests/test_parsing.py 2020-05-29 11:13:53.000000000 +0200 @@ -25,6 +25,7 @@ self._test('Django', 'django') self._test('celery', 'celery') + def test_requirement_with_versions(self): self._test('Django==1.5.2', 'django', [('==', '1.5.2')]) self._test('South>0.8', 'south', [('>', '0.8')]) @@ -53,6 +54,24 @@ self._test('--editable git+ssh://g...@github.com/something/somelib.git#egg=somelib', name='somelib', url='git+ssh://g...@github.com/something/somelib.git') + def test_comments(self): + self._test('celery == 0.1 # comment', 'celery', [('==', '0.1')]) + self._test('celery == 0.1\t# comment', 'celery', [('==', '0.1')]) + self._test( + "somelib == 0.15 # pinned to 0.15 (https://github.com/owner/repo/issues/111)", + "somelib", + [("==", "0.15")] + ) + self._test( + 'http://example.com/somelib.tar.gz # comment', + url='http://example.com/somelib.tar.gz' + ) + self._test( + 'http://example.com/somelib.tar.gz#egg=somelib # url comment http://foo.com/bar', + name='somelib', + url='http://example.com/somelib.tar.gz' + ) + class TestEggFragmentParsing(TestCase): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/requirements-detector-0.6/tox.ini new/requirements-detector-0.7/tox.ini --- old/requirements-detector-0.6/tox.ini 2018-07-22 10:24:34.000000000 +0200 +++ new/requirements-detector-0.7/tox.ini 2020-05-29 11:13:53.000000000 +0200 @@ -1,5 +1,5 @@ [tox] -envlist = py26,py27,py33,py34,py35 +envlist = py27,py33,py34,py35,py36,py37,py38 [testenv] deps=nose