diff --git a/requirements.txt b/requirements.txt index 8629a8f134a..fca8a4965e7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ click==6.7 colorama==0.4.4 commoncode==21.1.21 debian-inspector==0.9.10 -dparse2==0.5.0.4 +dparse==0.5.1 extractcode==21.2.24 extractcode-7z==16.5.210223 extractcode-libarchive==3.5.1.210223 @@ -40,7 +40,7 @@ patch==1.16 pdfminer.six==20181108 pefile==2019.4.18 pip==20.3.3 -pkginfo==1.5.0.1 +pkginfo==1.7.0 pluggy==0.12.0 plugincode==21.1.21 ply==3.9 diff --git a/setup.cfg b/setup.cfg index 90f8fed32d8..b2ed8ce94d2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -61,7 +61,7 @@ install_requires = colorama >= 0.3.9 commoncode >= 21.1.21 debian-inspector >= 0.9.10 - dparse2 + dparse >= 0.5.1 fasteners fingerprints >= 0.6.0 ftfy < 5.0.0 diff --git a/src/packagedcode/pypi.py b/src/packagedcode/pypi.py index ff2e358b42c..87746e447e9 100644 --- a/src/packagedcode/pypi.py +++ b/src/packagedcode/pypi.py @@ -8,6 +8,7 @@ # import ast +import email import io import json import logging @@ -17,14 +18,12 @@ import attr import dparse -from dparse import filetypes from pkginfo import BDist from pkginfo import Develop from pkginfo import SDist from pkginfo import UnpackedSDist from pkginfo import Wheel from packageurl import PackageURL -import saneyaml from commoncode import filetype from commoncode import fileutils @@ -32,11 +31,10 @@ from packagedcode.utils import build_description from packagedcode.utils import combine_expressions - """ Detect and collect Python packages information. - """ +# TODO: add support for poetry and setup.cfg TRACE = False @@ -60,9 +58,10 @@ def logger_debug(*args): @attr.s() class PythonPackage(models.Package): metafiles = ( - 'metadata.json', '*setup.py', + '*setup.cfg', 'PKG-INFO', + 'METADATA', '*.whl', '*.egg', '*requirements*.txt', @@ -73,8 +72,8 @@ class PythonPackage(models.Package): default_type = 'pypi' default_primary_language = 'Python' default_web_baseurl = 'https://pypi.org' - default_download_baseurl = 'https://pypi.io/packages/source' - default_api_baseurl = 'http://pypi.python.org/pypi' + default_download_baseurl = 'https://pypi.org/packages/source' + default_api_baseurl = 'https://pypi.org/pypi' @classmethod def recognize(cls, location): @@ -84,197 +83,208 @@ def compute_normalized_license(self): return compute_normalized_license(self.declared_license) def repository_homepage_url(self, baseurl=default_web_baseurl): - if not self.name: - return - return '{}/project/{}'.format(baseurl, self.name) + if self.name: + return f'{baseurl}/project/{baseurl}' def repository_download_url(self, baseurl=default_download_baseurl): - if not self.name or not self.version: - return - return '{baseurl}/{name[0]}/{name}/{name}-{version}.tar.gz'.format(baseurl=baseurl, name=self.name, version=self.version) + if self.name and self.version: + name = self.name + name1 = name[0] + return f'{baseurl}/{name1}/{name}/{name}-{self.version}.tar.gz' def api_data_url(self, baseurl=default_api_baseurl): - if not self.name: - return - if not self.version: - return '{}/{}/json'.format(baseurl, self.name) - return '{}/{}/{}/json'.format(baseurl, self.name, self.version) + if self.name: + if self.version: + return f'{baseurl}/{self.name}/{self.version}/json' + else: + return f'{baseurl}/{self.name}/json' def parse(location): """ - Return a Package built from parsing a file or directory at 'location' + Return a Package built from parsing a file or directory at 'location'. """ + # FIXME: there are more cases such as setup.py and more if filetype.is_dir(location): - package = parse_unpackaged_source(location) + package = None + if location.endswith('.dist-info'): + package = parse_wheel(location) + else: + package = parse_unpacked_sdist(location) + if package: - parse_dependencies(location, package) - return package - else: - file_name = fileutils.file_name(location) - parsers = { - 'setup.py': parse_setup_py, - 'requirements.txt': parse_requirements_txt, - 'requirements.in': parse_requirements_txt, - 'Pipfile.lock': parse_pipfile_lock, - 'metadata.json': parse_metadata, - 'PKG-INFO': parse_unpackaged_source, - '.whl': parse_wheel, - '.egg': parse_egg_binary, - '.tar.gz': parse_source_distribution, - '.zip': parse_source_distribution, - } - for name, parser in parsers.items(): - if file_name.endswith(name): - package = parser(location) - if package: - parent_directory = fileutils.parent_directory(location) - parse_dependencies(parent_directory, package) - return package - - -def parse_unpackaged_source(location): - """ - Passing it the path to the unpacked package, or by passing it the setup.py at the top level. - """ - unpackaged_dist = None + package.dependencies.extend(get_dependencies(location)) + return package + + # not a dir + file_name = fileutils.file_name(location) + + # FIXME these are not the same as the PythonPackage definitions + parsers = { + 'setup.py': parse_setup_py, + 'requirements.txt': parse_requirements_txt, + 'requirements.in': parse_requirements_txt, + 'Pipfile.lock': parse_pipfile_lock, + 'PKG-INFO': parse_unpacked_sdist, + 'METADATA': parse_metadata, + '.whl': parse_wheel, + '.egg': parse_egg_binary, + '.tar.gz': parse_source_distribution, + '.zip': parse_source_distribution, + } + + for name, parser in parsers.items(): + if not file_name.endswith(name): + continue + + package = parser(location) + if not package: + continue + + parent_directory = fileutils.parent_directory(location) + package.dependencies.extend(get_dependencies(parent_directory)) + return package + + +def parse_unpacked_sdist(location): + """ + Return a PytthonPackage from a unpacked/extracted sdist source distribution + archive, including --develop installations. + """ + unpacked_sdist = None + try: - unpackaged_dist = UnpackedSDist(location) + unpacked_sdist = UnpackedSDist(location) except ValueError: try: - unpackaged_dist = Develop(location) + unpacked_sdist = Develop(location) except ValueError: pass - return parse_with_pkginfo(unpackaged_dist) + if unpacked_sdist: + return parse_with_pkginfo(unpacked_sdist) + return parse_metadata(location) -def parse_with_pkginfo(pkginfo): - if pkginfo and pkginfo.name: - description = pkginfo.description - if not description: - description = pkginfo.summary - common_data = dict( - name=pkginfo.name, - version=pkginfo.version, - description=description, - download_url=pkginfo.download_url, - homepage_url=pkginfo.home_page, - ) - package = PythonPackage(**common_data) - declared_license = {} - if pkginfo.license: - # TODO: We should make the declared license as it is, this should be updated in scancode to parse a pure string - declared_license['license'] = pkginfo.license - if pkginfo.classifiers: - license_classifiers = [] - other_classifiers = [] - for classifier in pkginfo.classifiers: - if classifier.startswith('License'): - license_classifiers.append(classifier) - else: - other_classifiers.append(classifier) - declared_license['classifiers'] = license_classifiers - package.keywords = other_classifiers - if declared_license: - package.declared_license = declared_license - if pkginfo.author_email: - parties = [] - parties.append(models.Party( - type=models.party_person, name=pkginfo.author, role='author', email=pkginfo.author_email)) - package.parties = parties - return package +def parse_wheel(location): + """ + Passing wheel file location which is generated via setup.py bdist_wheel. + """ + return parse_with_pkginfo(Wheel(location)) -def parse_dependencies(location, package): + +def parse_egg_binary(location): """ - Loop all resources from the passing folder location, get the dependencies from the resources and set it to the passing package object. + Passing wheel file location which is generated via setup.py bdist, including + legacy eggs. """ - for resource_location in os.listdir(location): - dependencies = parse_with_dparse(resource_location) - if dependencies: - package.dependencies = dependencies + return parse_with_pkginfo(BDist(location)) -dependency_type_by_extensions = { - ('.txt', '.in'): 'requirements.txt', - ('Pipfile.lock'): 'Pipfile.lock', -} +def parse_source_distribution(location): + """ + SDist objects are created from a filesystem path to the corresponding + archive. Such as Zip or .tar.gz files + """ + return parse_with_pkginfo(SDist(location)) -def get_dependency_type(file_name, dependency_type_by_extensions=dependency_type_by_extensions): +def parse_setup_py(location): """ - Return the type of a dependency as a string or None given a `file_name` string. + Return a PythonPackage built from setup.py data. """ - for extensions, dependency_type in dependency_type_by_extensions.items(): - if file_name.endswith(extensions): - return dependency_type + if not location or not location.endswith('setup.py'): + return + setup_args = get_setup_py_args(location) -def parse_with_dparse(location): - is_dir = filetype.is_dir(location) - if is_dir: + # FIXME: it may be legit to have a name-less package? + package_name = setup_args.get('name') + if not package_name: return - file_name = fileutils.file_name(location) - dependency_type = get_dependency_type(file_name) + parties = get_parties(setup_args) + description = get_description(setup_args) + declared_license = get_declared_license(setup_args) + keywords = get_keywords(setup_args) + # FIXME: handle other_urls + urls, other_urls = get_urls(setup_args) + + detected_version = setup_args.get('version') + if not detected_version: + # search for possible dunder versions here and elsewhere + detected_version = detect_version_attribute(location) + + return PythonPackage( + name=package_name, + version=detected_version, + description=description, + parties=parties, + declared_license=declared_license, + keywords=keywords, + **urls, + ) + - if dependency_type not in (filetypes.requirements_txt, - filetypes.conda_yml, - filetypes.tox_ini, - filetypes.pipfile, - filetypes.pipfile_lock): +def parse_with_pkginfo(pkginfo, location=None): + """ + Return a PythonPackage built from a pkginfo Distribution object, either an + UnpackedSDist or a Develop object. + """ + if not pkginfo or not pkginfo.name: return - with open(location) as f: - content = f.read() + # FIXME: handle other_urls + urls, other_urls = get_urls(pkginfo) + return PythonPackage( + name=pkginfo.name, + version=pkginfo.version, + description=get_description(pkginfo, location=location), + declared_license=get_declared_license(pkginfo), + keywords=get_keywords(pkginfo), + parties=get_parties(pkginfo), + **urls, + ) - df = dparse.parse(content, file_type=dependency_type) - df_dependencies = df.dependencies - if not df_dependencies: +def parse_metadata(location): + """ + Return a PythonPackage from a a 'PKG-INFO' or 'METADATA' file at 'location' + or None. + """ + if not location or not location.endswith(('PKG-INFO', 'METADATA',)): return - package_dependencies = [] - for df_dependency in df_dependencies: - specs = list(df_dependency.specs._specs) - is_resolved = False - requirement = None - purl = PackageURL( - type='pypi', - name=df_dependency.name - ).to_string() - if specs: - requirement = str(df_dependency.specs) - for spec in specs: - operator = spec.operator - version = spec.version - if any(operator == element for element in ('==', '===')): - is_resolved = True - purl = PackageURL( - type='pypi', - name=df_dependency.name, - version=version - ).to_string() - package_dependencies.append( - models.DependentPackage( - purl=purl, - scope='dependencies', - is_runtime=True, - is_optional=False, - is_resolved=is_resolved, - requirement=requirement - ) - ) + with io.open(location, encoding='utf-8') as loc: + infos = email.message_from_string(loc.read()) - return package_dependencies + # TODO: may we should not bail out here? + if not infos.get('Name'): + return + + parties = get_parties(infos) + # FIXME: handle other_urls + urls, other_urls = get_urls(infos) + + package = PythonPackage( + name=get_attribute(infos, 'Name'), + version=get_attribute(infos, 'Version'), + description=get_description(infos, location), + declared_license=get_declared_license(infos), + keywords=get_keywords(infos), + parties=parties, + **urls, + ) + return package def parse_requirements_txt(location): """ - Return a PythonPackage built from a Python requirements.txt files at location. + Return a PythonPackage built from a Python requirements.txt files at + location. """ - package_dependencies = parse_with_dparse(location) - return PythonPackage(dependencies=package_dependencies) + dependent_packages = parse_with_dparse(location) + return PythonPackage(dependencies=dependent_packages) def parse_pipfile_lock(location): @@ -292,20 +302,268 @@ def parse_pipfile_lock(location): if name == 'hash': sha256 = meta.get('sha256') - package_dependencies = parse_with_dparse(location) - return PythonPackage( - sha256=sha256, - dependencies=package_dependencies + dependent_packages = parse_with_dparse(location) + return PythonPackage(sha256=sha256, dependencies=dependent_packages) + + +def get_attribute(metainfo, name, multiple=False): + """ + Return the value for the attribute ``name`` in the ``metainfo`` mapping, + pkginfo object or email object. Treat the value as a list of multiple values + if ``multiple`` is True. Return None or an empty list (if multiple is True) + if no value is found or the attribute ``name`` does not exist. + Ignore case (but returns the value for the original case if present. + """ + + # note: the approach for this function is to be used with the various + # metainfo objects and dictionsaries we use that can be a + # pkginfo.Distribution, an email.message.EmailMessage or a dict. + + # Because of that, the key can be obtained as a plain named attribute, + # either as-is or lowercased (and with dash replaced by dunder) or we + # can use a get on dicts of emails. + + def attr_getter(_aname, default): + _aname = _aname.replace('-', '_') + return ( + getattr(metainfo, _aname, default) + or getattr(metainfo, _aname.lower(), default) + ) + + def item_getter(_iname, getter, default): + getter = getattr(metainfo, getter, None) + if getter: + return getter(_iname, default) or getter(_iname.lower(), default) + return default + + if multiple: + return ( + attr_getter(name, []) + or item_getter(name, 'get_all', []) + or item_getter(name, 'get', []) + or [] + ) + else: + return ( + attr_getter(name, None) + or item_getter(name, 'get', None) + or None + ) + + +def get_description(metainfo, location=None): + """ + Return a list of keywords found in a ``metainfo`` object or mapping. + """ + description = None + # newer metadata versions use the payload for the description + if hasattr(metainfo, 'get_payload'): + description = metainfo.get_payload() + if not description: + # legacymetadata versions use the Description for the description + description = get_attribute(metainfo, 'Description') + if not description and location: + # older metadata versions can use a DESCRIPTION.rst file + description = get_legacy_description( + fileutils.parent_directory(location)) + + summary = get_attribute(metainfo, 'Summary') + return build_description(summary, description) + + +def get_legacy_description(location): + """ + Return the text of a legacy DESCRIPTION.rst. + """ + location = os.path.join(location, 'DESCRIPTION.rst') + if os.path.exists(location): + with open(location) as i: + return i.read() + + +def get_declared_license(metainfo): + """ + Return a mapping of declared license information found in a ``metainfo`` + object or mapping. + """ + declared_license = {} + # TODO: We should make the declared license as it is, this should be + # updated in scancode to parse a pure string + lic = get_attribute(metainfo, 'License') + if lic and not lic =='UNKNOWN': + declared_license['license'] = lic + + license_classifiers, _ = get_classifiers(metainfo) + if license_classifiers: + declared_license['classifiers'] = license_classifiers + return declared_license + + +def get_classifiers(metainfo): + """ + Return a two tuple of (license_classifiers, other_classifiers) found in a + ``metainfo`` object or mapping. + """ + + classifiers = ( + get_attribute(metainfo, 'Classifier', multiple=True) + or get_attribute(metainfo, 'Classifiers', multiple=True) ) + if not classifiers: + return [], [] + license_classifiers = [] + other_classifiers = [] + for classifier in classifiers: + if classifier.startswith('License'): + license_classifiers.append(classifier) + else: + other_classifiers.append(classifier) + return license_classifiers, other_classifiers -def parse_setup_py(location): + +def get_keywords(metainfo): """ - Return a PythonPackage built from setup.py data. + Return a list of keywords found in a ``metainfo`` object or mapping. """ - if not location or not location.endswith('setup.py'): + keywords = [] + kws = get_attribute(metainfo, 'Keywords') or [] + if kws: + if isinstance(kws, str): + kws = kws.split(',') + elif isinstance(kws, (list, tuple)): + pass + else: + kws = [repr(kws)] + kws = [k.strip() for k in kws if k and k.strip()] + keywords.extend(kws) + + # we are calling this again and ignoring licenses + _, other_classifiers = get_classifiers(metainfo) + keywords.extend(other_classifiers) + return keywords + + +def get_parties(metainfo): + """ + Return a list of parties found in a ``metainfo`` object or mapping. + """ + parties = [] + author = get_attribute(metainfo, 'Author') + author_email = get_attribute(metainfo, 'Author-email') + if author or author_email: + parties.append(models.Party( + type=models.party_person, + name=author or None, + role='author', + email=author_email or None, + )) + return parties + + +def get_dependencies(location): + """ + Return a list of DependentPackage found in dependency manifests (aka. lock + files) in the ``location`` directory or an empty list. + """ + dependencies = [] + for name in os.listdir(location): + loc = os.path.join(location, name) + dependencies = parse_with_dparse(loc) or [] + dependencies.extend(dependencies) + return dependencies + + +def get_dparse_dependency_type(file_name): + """ + Return the type of a dependency as a string or None given a `file_name` + string. + """ + # this is kludgy but the upstream data structure and API needs this + filetype_by_name_end = { + ('.txt', '.in'): dparse.filetypes.requirements_txt, + 'Pipfile.lock': dparse.filetypes.pipfile_lock, + 'Pipfile': dparse.filetypes.pipfile, + 'conda.yml': dparse.filetypes.conda_yml, + 'setup.cfg': dparse.filetypes.setup_cfg, + 'tox.ini': dparse.filetypes.tox_ini, + } + for extensions, dependency_type in filetype_by_name_end.items(): + if file_name.endswith(extensions): + return dependency_type + + +def parse_with_dparse(location): + """ + Return a list of DependentPackage built from a dparse-supported dependency + manifest such as requirements.txt, Conda manifest or Pipfile.lock files , or + return an empty list. + """ + is_dir = filetype.is_dir(location) + if is_dir: return + file_name = fileutils.file_name(location) + + dependency_type = get_dparse_dependency_type(file_name) + if not dependency_type: + return + + with open(location) as f: + content = f.read() + + dep_file = dparse.parse(content, file_type=dependency_type) + if not dep_file: + return [] + + dependent_packages = [] + + for dependency in dep_file.dependencies: + requirement = dependency.name + is_resolved = False + purl = PackageURL(type='pypi', name=dependency.name) + + # note: dparse.dependencies.Dependency.specs comes from + # packaging.requirements.Requirement.specifier + # which in turn is a packaging.specifiers.SpecifierSet objects + # and a SpecifierSet._specs is a set of either: + # packaging.specifiers.Specifier or packaging.specifiers.LegacySpecifier + # and each of these have a .operator and .version property + + # a packaging.specifiers.SpecifierSet + specifiers_set = dependency.specs + # a list of packaging.specifiers.Specifier + specifiers = specifiers_set._specs + + if specifiers: + # SpecifierSet stringifies to comma-separated sorted Specifiers + requirement = str(specifiers_set) + # are we pinned e.g. resolved? + if len(specifiers) == 1: + specifier = list(specifiers)[0] + if specifier.operator in ('==', '==='): + is_resolved = True + purl = purl._replace(version=specifier.version) + + dependent_packages.append( + models.DependentPackage( + purl=purl.to_string(), + # are we always this scope? what if we have requirements-dev.txt? + scope='dependencies', + is_runtime=True, + is_optional=False, + is_resolved=is_resolved, + requirement=requirement + ) + ) + + return dependent_packages + + +def get_setup_py_args(location): + """ + Return a mapping of arguments passed to a setup.py setup() function. + """ with open(location) as inp: setup_text = inp.read() @@ -316,89 +574,140 @@ def parse_setup_py(location): for statement in tree.body: # We only care about function calls or assignments to functions named # `setup` or `main` - if (isinstance(statement, (ast.Expr, ast.Call, ast.Assign)) + if not (isinstance(statement, (ast.Expr, ast.Call, ast.Assign)) and isinstance(statement.value, ast.Call) and isinstance(statement.value.func, ast.Name) # we also look for main as sometimes this is used instead of setup() and statement.value.func.id in ('setup', 'main') ): + continue - # Process the arguments to the setup function - for kw in getattr(statement.value, 'keywords', []): - arg_name = kw.arg - - if isinstance(kw.value, ast.Str): - setup_args[arg_name] = kw.value.s - - elif isinstance(kw.value, (ast.List, ast.Tuple, ast.Set,)): - # We collect the elements of a list if the element - # and tag function calls - value = [ - elt.s for elt in kw.value.elts - if not isinstance(elt, ast.Call) - ] - setup_args[arg_name] = value - - # TODO: what if isinstance(kw.value, ast.Dict) - # or an expression like a call to version=get_version or version__version__ - - package_name = setup_args.get('name') - if not package_name: - return + # Process the arguments to the setup function + for kw in getattr(statement.value, 'keywords', []): + arg_name = kw.arg + + if isinstance(kw.value, ast.Str): + setup_args[arg_name] = kw.value.s + + elif isinstance(kw.value, (ast.List, ast.Tuple, ast.Set,)): + # We collect the elements of a list if the element + # and tag function calls + value = [ + elt.s for elt in kw.value.elts + if not isinstance(elt, ast.Call) + ] + setup_args[arg_name] = value + + # TODO: what if isinstance(kw.value, ast.Dict) + # or an expression like a call to version=get_version or version__version__ + + return setup_args + + +def get_urls(metainfo): + """ + Return a mapping of Package URLs and a mapping of other URLs collected from + metainfo. + """ + # Misc URLs to possibly track + # Project-URL: Release notes + # Project-URL: Release Notes + # Project-URL: Changelog + # Project-URL: Changes + # + # Project-URL: Further Documentation + # Project-URL: Packaging tutorial + # Project-URL: Docs + # Project-URL: Docs: RTD + # Project-URL: Documentation + # Project-URL: Documentation (dev) + # Project-URL: Wiki + # + # Project-URL: Chat + # Project-URL: Chat: Gitter + # Project-URL: Mailing lists + # Project-URL: Twitter + # + # Project-URL: Travis CI + # Project-URL: Coverage: codecov + # Project-URL: CI + # Project-URL: CI: Azure Pipelines + # Project-URL: CI: Shippable + # + # Project-URL: Tidelift + # Project-URL: Code of Conduct + # Project-URL: Donate + # Project-URL: Funding + # Project-URL: Ko-fi + # Project-URL: Twine documentation + # Project-URL: Twine source + # Project-URL: Say Thanks! + + urls = {} + other_urls = {} + + def add_url(_url, _utype=None, _attribute=None): + """ + Add ``_url`` to ``urls`` as _``_attribute`` or to ``other_urls`` as + ``_utype`` if already defined or no ``_attribute`` is provided. + """ + if _url: + if _attribute and _attribute not in urls: + urls[_attribute] = _url + elif _utype: + other_urls[_utype] = _url + + # get first as this is the most common one + homepage_url = ( + get_attribute(metainfo, 'Home-page') + or get_attribute(metainfo, 'url') + or get_attribute(metainfo, 'home') + ) + add_url(homepage_url, _attribute='homepage_url') - description = build_description( - setup_args.get('summary', ''), - setup_args.get('description', ''), + project_urls = ( + get_attribute(metainfo, 'Project-URL', multiple=True) + or get_attribute(metainfo, 'project_urls') + or [] ) - parties = [] - author = setup_args.get('author') - author_email = setup_args.get('author_email') - homepage_url = setup_args.get('url') - if author: - parties.append( - models.Party( - type=models.party_person, - name=author, - email=author_email, - role='author', - url=homepage_url - ) - ) - elif author_email: - parties.append( - models.Party( - type=models.party_person, - email=author_email, - role='author', - url=homepage_url - ) - ) + for url in project_urls: + utype, _, uvalue = url.partition(',') + uvalue = uvalue.strip() + utype = utype.strip() + utypel = utype.lower() + if utypel in ( + 'tracker', + 'bug reports', + 'github: issues', + 'bug tracker', + 'issues', + 'issue tracker', + ): + add_url(url, _utype=utype, _attribute='bug_tracking_url') - declared_license = {} - license_setuptext = setup_args.get('license') - declared_license['license'] = license_setuptext + elif utypel in ( + 'source', + 'source code', + 'code', + ): + add_url(url, _utype=utype, _attribute='code_view_url') - classifiers = setup_args.get('classifiers', []) - license_classifiers = [c for c in classifiers if c.startswith('License')] - declared_license['classifiers'] = license_classifiers + elif utypel in ('github: repo', 'repository'): + add_url(url, _utype=utype, _attribute='vcs_url') - other_classifiers = [c for c in classifiers if not c.startswith('License')] + elif utypel in ('website', 'homepage', 'home',): + add_url(url, _utype=utype, _attribute='homepage_url') - detected_version = setup_args.get('version') - if not detected_version: - # search for possible dunder versions here and elsewhere - detected_version = detect_version_attribute(location) + else: + add_url(url, _utype=utype) - return PythonPackage( - name=package_name, - version=detected_version, - description=description or None, - homepage_url=setup_args.get('url') or None, - parties=parties, - declared_license=declared_license, - keywords=other_classifiers, - ) + # FIXME: this may not be the actual correct package download URL, so for now + # we incorrectly set this as the vcs_url + download_url = get_attribute(metainfo, 'Download-URL') + add_url(download_url, _utype='Download-URL', _attribute='vcs_url') + + return urls, other_urls def find_pattern(location, pattern): @@ -465,7 +774,8 @@ def find_setup_py_dunder_version(location): """ pattern = re.compile(r"^\s*version\s*=\s*(.*__version__)", re.MULTILINE) match = find_pattern(location, pattern) - if TRACE: logger_debug('find_setup_py_dunder_version:', 'location:', location, 'match:', match) + if TRACE: + logger_debug('find_setup_py_dunder_version:', 'location:', location, 'match:', match) return match @@ -482,6 +792,7 @@ def detect_version_attribute(setup_location): logger_debug(' detect_dunder_version:', 'setup_location:', setup_location) logger_debug(' setup_version_arg:', repr(setup_version_arg),) logger_debug(' setup_py__version:', repr(setup_py__version),) + if setup_version_arg == '__version__' and setup_py__version: version = setup_py__version or None if TRACE: logger_debug(' detect_dunder_version: A:', version) @@ -534,7 +845,10 @@ def detect_version_attribute(setup_location): if has_src: candidate_locs.append(['src', seg + '.py']) - candidate_locs = [os.path.join(setup_py_dir, *cand_loc_segs) for cand_loc_segs in candidate_locs] + candidate_locs = [ + os.path.join(setup_py_dir, *cand_loc_segs) + for cand_loc_segs in candidate_locs + ] for fl in get_module_scripts( location=setup_py_dir, @@ -563,17 +877,27 @@ def detect_version_attribute(setup_location): def detect_version_in_locations(candidate_locs, detector=find_plain_version): """ - Return the first version found in a location from `candidate_locs` using the - `detector` callable. Or None. + Return the first version found in a location from the `candidate_locs` list + using the `detector` callable. Return None if no version is found. """ for loc in candidate_locs: - if os.path.exists(loc): - if TRACE: logger_debug('detect_version_in_locations:', 'loc:', loc) - # here the file exists try to get a dunder version - version = detector(loc) - if TRACE: logger_debug('detect_version_in_locations:', 'detector', detector, 'version:', version) - if version: - return version + if not os.path.exists(loc): + continue + + if TRACE: logger_debug('detect_version_in_locations:', 'loc:', loc) + + # here the file exists try to get a dunder version + version = detector(loc) + + if TRACE: + logger_debug( + 'detect_version_in_locations:', + 'detector', detector, + 'version:', version, + ) + + if version: + return version def get_module_scripts(location, max_depth=1, interesting_names=()): @@ -597,148 +921,10 @@ def get_module_scripts(location, max_depth=1, interesting_names=()): current_depth -= 1 -# FIXME: use proper library for parsing these -def parse_metadata(location): - """ - Return a Package object from the Python wheel 'metadata.json' file - at 'location' or None. Check if the parent directory of 'location' - contains both a 'METADATA' and a 'DESCRIPTION.rst' file to ensure - this is a proper metadata.json file. - """ - if not location or not location.endswith('metadata.json'): - if TRACE: logger_debug('parse_metadata: not metadata.json:', location) - return - parent_dir = fileutils.parent_directory(location) - # FIXME: is the absence of these two files a show stopper? - paths = [os.path.join(parent_dir, n) for n in ('METADATA', 'DESCRIPTION.rst')] - if not all(os.path.exists(p) for p in paths): - if TRACE: logger_debug('parse_metadata: not extra paths', paths) - return - - with open(location, 'rb') as infs: - infos = json.load(infs) - - extensions = infos.get('extensions') - if TRACE: logger_debug('parse_metadata: extensions:', extensions) - details = extensions and extensions.get('python.details') - urls = details and details.get('project_urls') - homepage_url = urls and urls.get('Home') - - parties = [] - if TRACE: logger_debug('parse_metadata: contacts:', details.get('contacts')) - contacts = details and details.get('contacts') or [] - for contact in contacts: - if TRACE: logger_debug('parse_metadata: contact:', contact) - name = contact and contact.get('name') - if not name: - if TRACE: logger_debug('parse_metadata: no name:', contact) - continue - parties.append(models.Party(type=models.party_person, name=name, role='contact')) - - description = build_description( - infos.get('summary'), - infos.get('description') - ) - - classifiers = infos.get('classifiers') - license_classifiers = [] - other_classifiers = [] - if classifiers: - for classifier in classifiers: - if classifier.startswith('License'): - license_classifiers.append(classifier) - else: - other_classifiers.append(classifier) - - declared_license = {} - lic = infos.get('license') - if lic: - declared_license['license'] = lic - if license_classifiers: - declared_license['classifiers'] = license_classifiers - - package = PythonPackage( - name=infos.get('name'), - version=infos.get('version'), - description=description or None, - declared_license=declared_license or None, - homepage_url=homepage_url or None, - parties=parties, - keywords=other_classifiers, - ) - return package - - -def parse_pkg_info(location): - """ - Return a PythonPackage from a a 'PKG-INFO' file at 'location' or None. - """ - if not location: - return - - if not location.endswith('PKG-INFO'): - return - - with io.open(location, encoding='utf-8') as loc: - infos = saneyaml.load(loc.read()) - - logger.error(logger) - if not infos.get('Name'): - return - - parties = [] - author = infos.get('Author') - if author: - parties.append(models.Party(type=models.party_person, name=author, role='')) - - package = PythonPackage( - name=infos.get('Name'), - version=infos.get('Version'), - description=infos.get('Summary') or infos.get('Description'), - homepage_url=infos.get('Home-page') or None, - # FIXME: this is NOT correct as classifiers can be used for this too - declared_license=infos.get('License') or None, - # FIXME: what about email? - # FIXME: what about maintainers? - parties=parties, - ) - return package - - -def parse_wheel(location): - """ - Passing wheel file location which is generated via setup.py bdist_wheel. - """ - wheel = Wheel(location) - return parse_with_pkginfo(wheel) - - -def parse_egg_binary(location): - """ - Passing wheel file location which is generated via setup.py bdist_wheel. - """ - binary_dist = BDist(location) - return parse_with_pkginfo(binary_dist) - - -def parse_source_distribution(location): - """ - SDist objects are created from a filesystem path to the corresponding archive. Such as Zip or .tar.gz files - """ - sdist = SDist(location) - if sdist: - common_data = dict( - name=sdist.name, - version=sdist.version, - ) - package = PythonPackage(**common_data) - return package - - def compute_normalized_license(declared_license): """ - Return a normalized license expression string detected from a mapping or list of - declared license items. + Return a normalized license expression string detected from a mapping or + list of declared license items. """ if not declared_license: return diff --git a/tests/packagedcode/data/pypi/3to2/expected.json b/tests/packagedcode/data/pypi/3to2/expected.json deleted file mode 100644 index ffd3754a1c9..00000000000 --- a/tests/packagedcode/data/pypi/3to2/expected.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "type": "pypi", - "namespace": null, - "name": "3to2", - "version": "1.1.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Refactors valid 3.x syntax into valid 2.x syntax, if a syntactical conversion is possible\nDownload\n========\nRelease for 2.7 and 3.x (last version I tested was 3.4.3): https://pypi.python.org/pypi/3to2\nAbstract\n========\nlib3to2 is a set of fixers that are intended to backport code written for\nPython version 3.x into Python version 2.x. The final target 2.x version is\nthe latest version of the 2.7 branch, as that is the last release in the Python\n2.x branch. Some attempts have been made, however, to make code compatible as\nmuch as possible with versions of Python back to 2.5, and bug reports are still\nwelcome for Python features only present in 2.6+ that are not addressed by\nlib3to2.\nThis project came about as a Google Summer of Code (TM) project in 2009.\nStatus\n======\nBecause of the nature of the subject matter, 3to2 is not perfect, so check all\noutput manually. 3to2 does the bulk of the work, but there is code that simply\ncannot be converted into a Python 2 equivalent for one reason or another.\n3to2 will either produce working Python 2 code or warn about why it did not.\nAny other behavior is a bug and should be reported.\nlib3to2's fixers are somewhat well-tested individually, but there is no testing\nthat is done on interactions between multiple fixers, so most of the bugs in\nthe future will likely be found there.\nIntention\n=========\nlib3to2 is intended to be a tool in the process of developing code that is\nbackwards-compatible between Python 3 and Python 2. It is not intended to be a\ncomplete solution for directly backporting Python 3 code, though it can often\nbe used for this purpose without issue. Sufficiently large packages should be\ndeveloped with lib3to2 used throughout the process to avoid backwards-\nincompatible code from becoming too embedded.\nThere are some features of Python 3 that have no equivalent in Python 2, and\nthough lib3to2 tries to fix as many of these as it can, some features are\nbeyond its grasp. This is especially true of features not readily detectable\nby their syntax alone and extremely subtle features, so make sure that code\nusing lib3to2 is thoroughly tested.\nRepository\n==========\nlib3to2 resides at http://bitbucket.org/amentajo/lib3to2, where the bug tracker\ncan be found at http://bitbucket.org/amentajo/lib3to2/issues\nUsage\n=====\nRun \"./3to2\"to convert stdin (\"-\"), files or directories given as\narguments. By default, the tool outputs a unified diff-formatted patch on\nstandard output and a \"what was changed\"summary on standard error, but the\n\"-w\"option can be given to write back converted files, creating\n\".bak\"-named backup files.\nIf you are root, you can also install with \"./setup.py build\"and\n\"./setup.py install\"(\"make install\"does this for you).\nThis branch of 3to2 must be run with Python 3.\nTo install locally (used for running tests as a non-privileged user), the\nscripts assume you are using python3.1. Modify accordingly if you are not.\nRelationship with lib2to3\n=========================\nSome of the fixers for lib3to2 are directly copy-pasted from their 2to3\nequivalent, with the element of PATTERN and the corresponding transformation\nswitched places. Most fixers written for this program with a corresponding\n2to3 fixer started from a clone of the 2to3 fixer, then modifying that fixer to\nwork in reverse. I do not claim original authorship of these fixers, but I do\nclaim that they will work for 3to2, independent of how they work for 2to3.\nIn addition, this program depends on lib2to3 to implement fixers, test cases,\nrefactoring, and grammar. Some portions of lib2to3 were modified to be more\ngeneric to support lib3to2's calls.\nYou should use the latest version of lib2to3 from the Python sandbox rather\nthan the version (if any) that comes with Python. As a convenience,\n\"two2three\"from the Python Package Index is a recent enough version of lib2to3\nrenamed to avoid conflicts. To use this package, replace all usage of\n\"lib2to3\"with \"two2three\"within the 3to2 source files after installing\n\"two2three\"from the PyPI. Depending on the developer's mood, a version of\n3to2 may be provided with this change already made.", - "release_date": null, - "parties": [ - { - "type": "person", - "role": "author", - "name": "Joe Amenta", - "email": "airbreather@linux.com", - "url": null - } - ], - "keywords": [], - "homepage_url": "http://www.startcodon.com/wordpress/?cat=8", - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": "", - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": "apache-2.0", - "declared_license": { - "license": [], - "classifiers": [ - "License :: OSI Approved :: Apache Software License" - ] - }, - "notice_text": null, - "root_path": null, - "dependencies": [], - "contains_source_code": null, - "source_packages": [], - "purl": "pkg:pypi/3to2@1.1.1", - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": null -} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/3to2/input.json b/tests/packagedcode/data/pypi/3to2/input.json deleted file mode 100644 index 110a1c82dbb..00000000000 --- a/tests/packagedcode/data/pypi/3to2/input.json +++ /dev/null @@ -1 +0,0 @@ -{"info": {"maintainer": null, "docs_url": null, "requires_python": null, "maintainer_email": null, "cheesecake_code_kwalitee_id": null, "keywords": null, "package_url": "http://pypi.python.org/pypi/3to2", "author": "Joe Amenta", "author_email": "airbreather@linux.com", "download_url": "UNKNOWN", "platform": "", "version": "1.1.1", "cheesecake_documentation_id": null, "_pypi_hidden": false, "description": "Download\n========\nRelease for 2.7 and 3.x (last version I tested was 3.4.3): https://pypi.python.org/pypi/3to2\nAbstract\n========\nlib3to2 is a set of fixers that are intended to backport code written for\nPython version 3.x into Python version 2.x. The final target 2.x version is\nthe latest version of the 2.7 branch, as that is the last release in the Python\n2.x branch. Some attempts have been made, however, to make code compatible as\nmuch as possible with versions of Python back to 2.5, and bug reports are still\nwelcome for Python features only present in 2.6+ that are not addressed by\nlib3to2.\nThis project came about as a Google Summer of Code (TM) project in 2009.\nStatus\n======\nBecause of the nature of the subject matter, 3to2 is not perfect, so check all\noutput manually. 3to2 does the bulk of the work, but there is code that simply\ncannot be converted into a Python 2 equivalent for one reason or another.\n3to2 will either produce working Python 2 code or warn about why it did not.\nAny other behavior is a bug and should be reported.\nlib3to2's fixers are somewhat well-tested individually, but there is no testing\nthat is done on interactions between multiple fixers, so most of the bugs in\nthe future will likely be found there.\nIntention\n=========\nlib3to2 is intended to be a tool in the process of developing code that is\nbackwards-compatible between Python 3 and Python 2. It is not intended to be a\ncomplete solution for directly backporting Python 3 code, though it can often\nbe used for this purpose without issue. Sufficiently large packages should be\ndeveloped with lib3to2 used throughout the process to avoid backwards-\nincompatible code from becoming too embedded.\nThere are some features of Python 3 that have no equivalent in Python 2, and\nthough lib3to2 tries to fix as many of these as it can, some features are\nbeyond its grasp. This is especially true of features not readily detectable\nby their syntax alone and extremely subtle features, so make sure that code\nusing lib3to2 is thoroughly tested.\nRepository\n==========\nlib3to2 resides at http://bitbucket.org/amentajo/lib3to2, where the bug tracker\ncan be found at http://bitbucket.org/amentajo/lib3to2/issues\nUsage\n=====\nRun \"./3to2\"to convert stdin (\"-\"), files or directories given as\narguments. By default, the tool outputs a unified diff-formatted patch on\nstandard output and a \"what was changed\"summary on standard error, but the\n\"-w\"option can be given to write back converted files, creating\n\".bak\"-named backup files.\nIf you are root, you can also install with \"./setup.py build\"and\n\"./setup.py install\"(\"make install\"does this for you).\nThis branch of 3to2 must be run with Python 3.\nTo install locally (used for running tests as a non-privileged user), the\nscripts assume you are using python3.1. Modify accordingly if you are not.\nRelationship with lib2to3\n=========================\nSome of the fixers for lib3to2 are directly copy-pasted from their 2to3\nequivalent, with the element of PATTERN and the corresponding transformation\nswitched places. Most fixers written for this program with a corresponding\n2to3 fixer started from a clone of the 2to3 fixer, then modifying that fixer to\nwork in reverse. I do not claim original authorship of these fixers, but I do\nclaim that they will work for 3to2, independent of how they work for 2to3.\nIn addition, this program depends on lib2to3 to implement fixers, test cases,\nrefactoring, and grammar. Some portions of lib2to3 were modified to be more\ngeneric to support lib3to2's calls.\nYou should use the latest version of lib2to3 from the Python sandbox rather\nthan the version (if any) that comes with Python. As a convenience,\n\"two2three\"from the Python Package Index is a recent enough version of lib2to3\nrenamed to avoid conflicts. To use this package, replace all usage of\n\"lib2to3\"with \"two2three\"within the 3to2 source files after installing\n\"two2three\"from the PyPI. Depending on the developer's mood, a version of\n3to2 may be provided with this change already made.", "release_url": "http://pypi.python.org/pypi/3to2/1.1.1", "downloads": {"last_month": 6, "last_week": 1, "last_day": 0}, "_pypi_ordering": 7, "classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Topic :: Software Development :: Code Generators", "Topic :: Software Development :: Libraries :: Python Modules"], "name": "3to2", "bugtrack_url": "", "license": "UNKNOWN", "summary": "Refactors valid 3.x syntax into valid 2.x syntax, if a syntactical conversion is possible", "home_page": "http://www.startcodon.com/wordpress/?cat=8", "cheesecake_installability_id": null}, "urls": [{"has_sig": false, "upload_time": "2015-04-16T00:52:21", "comment_text": "", "python_version": "source", "url": "https://pypi.python.org/packages/8f/ab/58a363eca982c40e9ee5a7ca439e8ffc5243dde2ae660ba1ffdd4868026b/3to2-1.1.1.zip", "md5_digest": "cbeed28e350dbdaef86111ace3052824", "downloads": 432241, "filename": "3to2-1.1.1.zip", "packagetype": "sdist", "path": "8f/ab/58a363eca982c40e9ee5a7ca439e8ffc5243dde2ae660ba1ffdd4868026b/3to2-1.1.1.zip", "size": 78779}], "releases": {"1.1.1": [{"has_sig": false, "upload_time": "2015-04-16T00:52:21", "comment_text": "", "python_version": "source", "url": "https://pypi.python.org/packages/8f/ab/58a363eca982c40e9ee5a7ca439e8ffc5243dde2ae660ba1ffdd4868026b/3to2-1.1.1.zip", "md5_digest": "cbeed28e350dbdaef86111ace3052824", "downloads": 432241, "filename": "3to2-1.1.1.zip", "packagetype": "sdist", "path": "8f/ab/58a363eca982c40e9ee5a7ca439e8ffc5243dde2ae660ba1ffdd4868026b/3to2-1.1.1.zip", "size": 78779}], "1.0": [{"has_sig": false, "upload_time": "2010-10-24T08:47:19", "comment_text": "", "python_version": "source", "url": "https://pypi.python.org/packages/02/92/85277af0707b62ff5330569b0bb657cf24527cb115cd9dd2b83e90cc4c98/3to2-1.0.tar.gz", "md5_digest": "41550d29aec107347f708d1550f889e0", "downloads": 41078, "filename": "3to2-1.0.tar.gz", "packagetype": "sdist", "path": "02/92/85277af0707b62ff5330569b0bb657cf24527cb115cd9dd2b83e90cc4c98/3to2-1.0.tar.gz", "size": 46028}], "1.1": [{"has_sig": false, "upload_time": "2015-04-14T00:27:02", "comment_text": "", "python_version": "source", "url": "https://pypi.python.org/packages/db/cd/5e2b6894cf324b2fab30d0d664930af415a4744a4214e53c2136eed48f3d/3to2-1.1.zip", "md5_digest": "566313a7c23d47c019c4bfa744a4d4b6", "downloads": 1678, "filename": "3to2-1.1.zip", "packagetype": "sdist", "path": "db/cd/5e2b6894cf324b2fab30d0d664930af415a4744a4214e53c2136eed48f3d/3to2-1.1.zip", "size": 78453}], "0.1": [{"has_sig": false, "upload_time": "2010-06-15T19:57:20", "comment_text": "", "python_version": "source", "url": "https://pypi.python.org/packages/3a/7b/c33a0596f5eb2db032f40868788b27c2874d9c75c3fd97d390639b73a68b/3to2-0.1.tar.gz", "md5_digest": "5b3d846dba708aa550e5ebcdd49d3d8e", "downloads": 5510, "filename": "3to2-0.1.tar.gz", "packagetype": "sdist", "path": "3a/7b/c33a0596f5eb2db032f40868788b27c2874d9c75c3fd97d390639b73a68b/3to2-0.1.tar.gz", "size": 41346}], "0.1a1": [], "0.1a3": [{"has_sig": false, "upload_time": "2010-02-03T17:43:06", "comment_text": "", "python_version": "source", "url": "https://pypi.python.org/packages/7f/d6/c46b1a64d25d02d16ccb63244006e242474639c1a7b802e1c50e3587ad97/3to2-0.1a3.tar.gz", "md5_digest": "51d6dcb4909aaa4a42b8f4f41d3d2945", "downloads": 5433, "filename": "3to2-0.1a3.tar.gz", "packagetype": "sdist", "path": "7f/d6/c46b1a64d25d02d16ccb63244006e242474639c1a7b802e1c50e3587ad97/3to2-0.1a3.tar.gz", "size": 34083}], "0.1a2": [{"has_sig": false, "upload_time": "2009-09-17T14:45:27", "comment_text": "", "python_version": "source", "url": "https://pypi.python.org/packages/a7/ac/22860a64f687c0dd3e19a07141c1206ad71a5083ff5f477e8c961a21e979/3to2-0.1a2.tar.gz", "md5_digest": "585b292e24e44ca8ce721294d8736270", "downloads": 5541, "filename": "3to2-0.1a2.tar.gz", "packagetype": "sdist", "path": "a7/ac/22860a64f687c0dd3e19a07141c1206ad71a5083ff5f477e8c961a21e979/3to2-0.1a2.tar.gz", "size": 30217}], "0.1b1": [{"has_sig": false, "upload_time": "2010-06-08T22:34:18", "comment_text": "", "python_version": "source", "url": "https://pypi.python.org/packages/c2/f4/77d8771cc1335492c489747632cd8da99f61a96ef3acee5834ad6879e166/3to2-0.1b1.tar.gz", "md5_digest": "efb055e801b65b1becdaf3baf4525664", "downloads": 5428, "filename": "3to2-0.1b1.tar.gz", "packagetype": "sdist", "path": "c2/f4/77d8771cc1335492c489747632cd8da99f61a96ef3acee5834ad6879e166/3to2-0.1b1.tar.gz", "size": 36982}]}} diff --git a/tests/packagedcode/data/pypi/develop/scancode_toolkit.egg-info-expected-parse.json b/tests/packagedcode/data/pypi/develop/scancode_toolkit.egg-info-expected-parse.json new file mode 100644 index 00000000000..90b4883f59f --- /dev/null +++ b/tests/packagedcode/data/pypi/develop/scancode_toolkit.egg-info-expected-parse.json @@ -0,0 +1,930 @@ +{ + "type": "pypi", + "namespace": null, + "name": "scancode-toolkit", + "version": "21.3.31", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "ScanCode is a tool to scan code for license, copyright, package and their documented dependencies and other interesting facts.\n================\nScanCode toolkit\n================\n\nA typical software project often reuses hundreds of third-party packages.\nLicense and origin information is not always easy to find and not normalized:\nScanCode discovers and normalizes this data for you.\n\nRead more about ScanCode here: `scancode-toolkit.readthedocs.io `_.\n\nWhy use ScanCode?\n=================\n\n- As a **standalone command-line tool**, ScanCode is **easy to install**, run,\n and embed in your CI/CD processing pipeline.\n It runs on **Windows, macOS, and Linux**.\n\n- ScanCode is **used by several projects and organizations** such as\n the `Eclipse Foundation `_,\n `OpenEmbedded.org `_,\n the `FSFE `_,\n the `FSF `_,\n `OSS Review Toolkit `_, \n `ClearlyDefined.io `_,\n `RedHat Fabric8 analytics `_,\n and many more.\n\n- ScanCode detects licenses, copyrights, package manifests, direct\n dependencies, and more both in **source code** and **binary** files.\n\n- ScanCode provides the **most accurate license detection engine** and does a\n full comparison (also known as diff or red line comparison) between a database\n of license texts and your code instead of relying only on approximate regex\n patterns or probabilistic search, edit distance or machine learning.\n\n- Written in Python, ScanCode is **easy to extend with plugins** to contribute\n new and improved scanners, data summarization, package manifest parsers, and\n new outputs.\n\n- You can save your scan results as **JSON, HTML, CSV or SPDX**. And you can use the\n companion `ScanCode workbench GUI app `_\n to review and display scan results, statistics and graphics.\n\n- You can also organize and run ScanCode server-side with the\n companion `ScanCode.io web app `_\n to organize and store multiple scan projects including scripting scanning piplines.\n\n\n- ScanCode is **actively maintained**, has a **growing users and contributors\n community**.\n\n- ScanCode is heavily **tested** with an automated test suite of over **20,000 tests**.\n\n- ScanCode has an extensive and growing documentation.\n\nSee our `roadmap `_\nfor upcoming features.\n\n\nBuild and tests status\n======================\n\n+-------+--------------+-----------------+--------------+\n|Branch | **Coverage** | **Linux/macOS** | **Windows** |\n+=======+==============+=================+==============+\n|Master | |master-cov| | |master-posix| | |master-win| |\n+-------+--------------+-----------------+--------------+\n|Develop| |devel-cov| | |devel-posix| | |devel-win| |\n+-------+--------------+-----------------+--------------+\n\nDocumentation Build\n-------------------\n\n+--------+--------------+\n|Version | **RTD Build**|\n+========+==============+\n| Latest | |docs-rtd| |\n+--------+--------------+\n\n\nDocumentation\n=============\n\nThe ScanCode documentation is hosted at `scancode-toolkit.readthedocs.io `_.\n\nIf you are new to Scancode, start `here `_.\n\nOther Important Documentation Pages:\n\n- A `synopsis `_ \n of ScanCode command line options.\n\n- Tutorials on:\n\n - `How to run a scan `_\n - `How to visualize scan results `_\n\n- An exhaustive list of `all available options `_\n\n- Documentation on `Contributing to Code Development `_\n\n- Documentation on `Plugin Architecture `_\n\n- `FAQ `_\n\nSee also https://aboutcode.org for related companion projects and tools.\n\n\nInstallation\n============\n\nBefore installing ScanCode make sure that you have installed the prerequisites\nproperly. This means installing Python (Python 3.6+ is required).\nSee `prerequisites `_\nfor detailed information on the support platforms and Python versions.\n\nThere are a few common ways to `install ScanCode `_.\n\n- `*Recommended* installation as an application: Download a release archive, extract and run.\n `_\n\n- `Development installation from source code using a git clone\n `_\n\n- `Development installation as a library with \"pip install scancode-toolkit\"\n `_\n\n- `Run in a Docker container with a git clone and \"docker run\"\n `_\n\n\nQuick Start\n===========\n\nNote the `commands variation `_\nacross installation methods and platforms.\n\nYou can run an example scan printed on screen as JSON::\n\n ./scancode -clip --json-pp - samples\n\nFollow the `How to Run a Scan `_\ntutorial to perform a basic scan on the ``samples`` directory distributed by\ndefault with Scancode.\n\nSee more command examples::\n\n ./scancode --examples\n\nSee `How to select what will be detected in a scan\n`_\nand `How to specify the output format `_\nfor more information.\n\nYou can also refer to the `command line options synopsis\n`_\nand an exhaustive list of `all available command line options\n`_.\n\n\nArchive extraction\n==================\n\nBy default ScanCode does not extract files from tarballs, zip files, and\nother archives as part of the scan. The archives that exist in a codebase\nmust be extracted before running a scan: `extractcode` is a bundled utility\nbehaving as a mostly-universal archive extractor. For example, this command will\nrecursively extract the mytar.tar.bz2 tarball in the mytar.tar.bz2-extract\ndirectory::\n\n ./extractcode mytar.tar.bz2\n\nSee `all extractcode options `_\nand `how to extract archives `_ for details.\n\n\nSupport\n=======\n\nIf you have a problem, a suggestion or found a bug, please enter a ticket at:\nhttps://github.com/nexB/scancode-toolkit/issues\n\nFor discussions and chats, we have:\n\n* an official Gitter channel for `web-based chats\n `_.\n Gitter is also accessible via an `IRC bridge `_.\n There are other AboutCode project-specific channels available there too.\n\n* an official `#aboutcode` IRC channel on freenode (server chat.freenode.net).\n This channel receives build and commit notifications and can be noisy.\n You can use your favorite IRC client or use the `web chat \n `_.\n\n\nSource code and downloads\n=========================\n\n* https://github.com/nexB/scancode-toolkit/releases\n* https://github.com/nexB/scancode-toolkit.git\n* https://pypi.org/project/scancode-toolkit/\n* https://github.com/nexB/scancode-thirdparty-src.git\n\n\nLicense\n=======\n\n* Apache-2.0 as the overall license\n* CC-BY-4.0 for reference datasets (initially was in the Public Domain).\n* Multiple other secondary permissive or copyleft licenses (LGPL, MIT,\n BSD, GPL 2/3, etc.) for third-party components.\n\n\nSee the NOTICE file and the .ABOUT files that document the origin and license of\nthe third-party code used in ScanCode for more details.\n\n\n.. |master-cov| image:: https://codecov.io/gh/nexB/scancode-toolkit/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/nexB/scancode-toolkit/branch/master\n :alt: Master branch test coverage (Linux)\n.. |devel-cov| image:: https://codecov.io/gh/nexB/scancode-toolkit/branch/develop/graph/badge.svg\n :target: https://codecov.io/gh/nexB/scancode-toolkit/branch/develop\n :alt: Develop branch test coverage (Linux)\n\n.. |master-posix| image:: https://api.travis-ci.org/nexB/scancode-toolkit.png?branch=master\n :target: https://travis-ci.org/nexB/scancode-toolkit\n :alt: Linux Master branch tests status\n.. |devel-posix| image:: https://api.travis-ci.org/nexB/scancode-toolkit.png?branch=develop\n :target: https://travis-ci.org/nexB/scancode-toolkit\n :alt: Linux Develop branch tests status\n\n.. |master-win| image:: https://ci.appveyor.com/api/projects/status/4webymu0l2ip8utr/branch/master?png=true\n :target: https://ci.appveyor.com/project/nexB/scancode-toolkit\n :alt: Windows Master branch tests status\n.. |devel-win| image:: https://ci.appveyor.com/api/projects/status/4webymu0l2ip8utr/branch/develop?png=true\n :target: https://ci.appveyor.com/project/nexB/scancode-toolkit\n :alt: Windows Develop branch tests status\n\n.. |docs-rtd| image:: https://readthedocs.org/projects/scancode-toolkit/badge/?version=latest\n :target: https://scancode-toolkit.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "ScanCode", + "email": "info@aboutcode.org", + "url": null + } + ], + "keywords": [ + "open source", + "scan", + "license", + "package", + "dependency", + "copyright", + "filetype", + "author", + "extract", + "licensing", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Programming Language :: Python", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Topic :: Utilities" + ], + "homepage_url": "https://github.com/nexB/scancode-toolkit", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": "apache-2.0 AND cc-by-4.0 AND other-permissive AND other-copyleft", + "declared_license": { + "license": "Apache-2.0 AND CC-BY-4.0 AND LicenseRef-scancode-other-permissive AND LicenseRef-scancode-other-copyleft" + }, + "notice_text": null, + "root_path": null, + "dependencies": [ + { + "purl": "pkg:pypi/attrs", + "requirement": "!=20.1.0,>=18.1", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/beautifulsoup4", + "requirement": "<5.0.0,>=4.0.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/bitarray", + "requirement": "<1.0.0,>=0.8.1", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/boolean.py", + "requirement": "<4.0,>=3.5", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/chardet", + "requirement": ">=3.0.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/click", + "requirement": "!=7.0,>=6.7", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/colorama", + "requirement": ">=0.3.9", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/commoncode", + "requirement": ">=21.1.21", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/debian-inspector", + "requirement": ">=0.9.10", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/dparse", + "requirement": ">=0.5.1", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/fasteners", + "requirement": "fasteners", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/fingerprints", + "requirement": ">=0.6.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/ftfy", + "requirement": "<5.0.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/gemfileparser", + "requirement": ">=0.7.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/html5lib", + "requirement": "html5lib", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/intbitset", + "requirement": "<3.0,>=2.3.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/jaraco.functools", + "requirement": "jaraco.functools", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/javaproperties", + "requirement": ">=0.5", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/jinja2", + "requirement": "<3.0.0,>=2.7.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/jsonstreams", + "requirement": ">=0.5.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/license-expression", + "requirement": ">=0.99", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/lxml", + "requirement": "<5.0.0,>=4.0.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/markupsafe", + "requirement": ">=0.23", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/nltk", + "requirement": "!=3.6,<4.0,>=3.2", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/packageurl-python", + "requirement": ">=0.7.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pdfminer.six", + "requirement": ">=20170720", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pefile", + "requirement": ">=2018.8.8", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pkginfo", + "requirement": ">=1.5.0.1", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pluggy", + "requirement": "<1.0,>=0.4.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/plugincode", + "requirement": ">=21.1.21", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/publicsuffix2", + "requirement": "publicsuffix2", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pyahocorasick", + "requirement": "<1.5,>=1.4", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pycryptodome", + "requirement": ">=3.4", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pygments", + "requirement": "pygments", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pymaven-patch", + "requirement": ">=0.2.8", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/requests", + "requirement": "<3.0.0,>=2.7.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/saneyaml", + "requirement": ">=0.5.2", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/spdx-tools", + "requirement": ">=0.6.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/text-unidecode", + "requirement": "<2.0,>=1.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/toml", + "requirement": ">=0.10.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/urlpy", + "requirement": "urlpy", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/xmltodict", + "requirement": ">=0.11.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/extractcode", + "requirement": ">=21.2.24", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/typecode", + "requirement": ">=21.2.24", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/typing", + "requirement": "<3.7,>=3.6", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pytest", + "requirement": "pytest", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pytest-cov", + "requirement": "pytest-cov", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pytest-xdist", + "requirement": "pytest-xdist", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pytest-rerunfailures", + "requirement": "pytest-rerunfailures", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/aboutcode-toolkit", + "requirement": ">=6.0.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/bump2version", + "requirement": "bump2version", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/codecov", + "requirement": "codecov", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/coverage", + "requirement": "coverage", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/rpm-inspector-rpm", + "requirement": ">=4.16.1.3", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/attrs", + "requirement": "!=20.1.0,>=18.1", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/beautifulsoup4", + "requirement": "<5.0.0,>=4.0.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/bitarray", + "requirement": "<1.0.0,>=0.8.1", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/boolean.py", + "requirement": "<4.0,>=3.5", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/chardet", + "requirement": ">=3.0.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/click", + "requirement": "!=7.0,>=6.7", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/colorama", + "requirement": ">=0.3.9", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/commoncode", + "requirement": ">=21.1.21", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/debian-inspector", + "requirement": ">=0.9.10", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/dparse", + "requirement": ">=0.5.1", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/fasteners", + "requirement": "fasteners", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/fingerprints", + "requirement": ">=0.6.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/ftfy", + "requirement": "<5.0.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/gemfileparser", + "requirement": ">=0.7.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/html5lib", + "requirement": "html5lib", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/intbitset", + "requirement": "<3.0,>=2.3.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/jaraco.functools", + "requirement": "jaraco.functools", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/javaproperties", + "requirement": ">=0.5", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/jinja2", + "requirement": "<3.0.0,>=2.7.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/jsonstreams", + "requirement": ">=0.5.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/license-expression", + "requirement": ">=0.99", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/lxml", + "requirement": "<5.0.0,>=4.0.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/markupsafe", + "requirement": ">=0.23", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/nltk", + "requirement": "!=3.6,<4.0,>=3.2", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/packageurl-python", + "requirement": ">=0.7.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pdfminer.six", + "requirement": ">=20170720", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pefile", + "requirement": ">=2018.8.8", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pkginfo", + "requirement": ">=1.5.0.1", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pluggy", + "requirement": "<1.0,>=0.4.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/plugincode", + "requirement": ">=21.1.21", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/publicsuffix2", + "requirement": "publicsuffix2", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pyahocorasick", + "requirement": "<1.5,>=1.4", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pycryptodome", + "requirement": ">=3.4", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pygments", + "requirement": "pygments", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pymaven-patch", + "requirement": ">=0.2.8", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/requests", + "requirement": "<3.0.0,>=2.7.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/saneyaml", + "requirement": ">=0.5.2", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/spdx-tools", + "requirement": ">=0.6.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/text-unidecode", + "requirement": "<2.0,>=1.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/toml", + "requirement": ">=0.10.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/urlpy", + "requirement": "urlpy", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/xmltodict", + "requirement": ">=0.11.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/extractcode", + "requirement": ">=21.2.24", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/typecode", + "requirement": ">=21.2.24", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/typing", + "requirement": "<3.7,>=3.6", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pytest", + "requirement": "pytest", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pytest-cov", + "requirement": "pytest-cov", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pytest-xdist", + "requirement": "pytest-xdist", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/pytest-rerunfailures", + "requirement": "pytest-rerunfailures", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/aboutcode-toolkit", + "requirement": ">=6.0.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/bump2version", + "requirement": "bump2version", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/codecov", + "requirement": "codecov", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/coverage", + "requirement": "coverage", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + }, + { + "purl": "pkg:pypi/rpm-inspector-rpm", + "requirement": ">=4.16.1.3", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": false + } + ], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/scancode-toolkit@21.3.31", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/s/scancode-toolkit/scancode-toolkit-21.3.31.tar.gz", + "api_data_url": "https://pypi.org/pypi/scancode-toolkit/21.3.31/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/develop/scancode_toolkit.egg-info-expected-sdist.json b/tests/packagedcode/data/pypi/develop/scancode_toolkit.egg-info-expected-sdist.json new file mode 100644 index 00000000000..5b76442656c --- /dev/null +++ b/tests/packagedcode/data/pypi/develop/scancode_toolkit.egg-info-expected-sdist.json @@ -0,0 +1,65 @@ +{ + "type": "pypi", + "namespace": null, + "name": "scancode-toolkit", + "version": "21.3.31", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "ScanCode is a tool to scan code for license, copyright, package and their documented dependencies and other interesting facts.\n================\nScanCode toolkit\n================\n\nA typical software project often reuses hundreds of third-party packages.\nLicense and origin information is not always easy to find and not normalized:\nScanCode discovers and normalizes this data for you.\n\nRead more about ScanCode here: `scancode-toolkit.readthedocs.io `_.\n\nWhy use ScanCode?\n=================\n\n- As a **standalone command-line tool**, ScanCode is **easy to install**, run,\n and embed in your CI/CD processing pipeline.\n It runs on **Windows, macOS, and Linux**.\n\n- ScanCode is **used by several projects and organizations** such as\n the `Eclipse Foundation `_,\n `OpenEmbedded.org `_,\n the `FSFE `_,\n the `FSF `_,\n `OSS Review Toolkit `_, \n `ClearlyDefined.io `_,\n `RedHat Fabric8 analytics `_,\n and many more.\n\n- ScanCode detects licenses, copyrights, package manifests, direct\n dependencies, and more both in **source code** and **binary** files.\n\n- ScanCode provides the **most accurate license detection engine** and does a\n full comparison (also known as diff or red line comparison) between a database\n of license texts and your code instead of relying only on approximate regex\n patterns or probabilistic search, edit distance or machine learning.\n\n- Written in Python, ScanCode is **easy to extend with plugins** to contribute\n new and improved scanners, data summarization, package manifest parsers, and\n new outputs.\n\n- You can save your scan results as **JSON, HTML, CSV or SPDX**. And you can use the\n companion `ScanCode workbench GUI app `_\n to review and display scan results, statistics and graphics.\n\n- You can also organize and run ScanCode server-side with the\n companion `ScanCode.io web app `_\n to organize and store multiple scan projects including scripting scanning piplines.\n\n\n- ScanCode is **actively maintained**, has a **growing users and contributors\n community**.\n\n- ScanCode is heavily **tested** with an automated test suite of over **20,000 tests**.\n\n- ScanCode has an extensive and growing documentation.\n\nSee our `roadmap `_\nfor upcoming features.\n\n\nBuild and tests status\n======================\n\n+-------+--------------+-----------------+--------------+\n|Branch | **Coverage** | **Linux/macOS** | **Windows** |\n+=======+==============+=================+==============+\n|Master | |master-cov| | |master-posix| | |master-win| |\n+-------+--------------+-----------------+--------------+\n|Develop| |devel-cov| | |devel-posix| | |devel-win| |\n+-------+--------------+-----------------+--------------+\n\nDocumentation Build\n-------------------\n\n+--------+--------------+\n|Version | **RTD Build**|\n+========+==============+\n| Latest | |docs-rtd| |\n+--------+--------------+\n\n\nDocumentation\n=============\n\nThe ScanCode documentation is hosted at `scancode-toolkit.readthedocs.io `_.\n\nIf you are new to Scancode, start `here `_.\n\nOther Important Documentation Pages:\n\n- A `synopsis `_ \n of ScanCode command line options.\n\n- Tutorials on:\n\n - `How to run a scan `_\n - `How to visualize scan results `_\n\n- An exhaustive list of `all available options `_\n\n- Documentation on `Contributing to Code Development `_\n\n- Documentation on `Plugin Architecture `_\n\n- `FAQ `_\n\nSee also https://aboutcode.org for related companion projects and tools.\n\n\nInstallation\n============\n\nBefore installing ScanCode make sure that you have installed the prerequisites\nproperly. This means installing Python (Python 3.6+ is required).\nSee `prerequisites `_\nfor detailed information on the support platforms and Python versions.\n\nThere are a few common ways to `install ScanCode `_.\n\n- `*Recommended* installation as an application: Download a release archive, extract and run.\n `_\n\n- `Development installation from source code using a git clone\n `_\n\n- `Development installation as a library with \"pip install scancode-toolkit\"\n `_\n\n- `Run in a Docker container with a git clone and \"docker run\"\n `_\n\n\nQuick Start\n===========\n\nNote the `commands variation `_\nacross installation methods and platforms.\n\nYou can run an example scan printed on screen as JSON::\n\n ./scancode -clip --json-pp - samples\n\nFollow the `How to Run a Scan `_\ntutorial to perform a basic scan on the ``samples`` directory distributed by\ndefault with Scancode.\n\nSee more command examples::\n\n ./scancode --examples\n\nSee `How to select what will be detected in a scan\n`_\nand `How to specify the output format `_\nfor more information.\n\nYou can also refer to the `command line options synopsis\n`_\nand an exhaustive list of `all available command line options\n`_.\n\n\nArchive extraction\n==================\n\nBy default ScanCode does not extract files from tarballs, zip files, and\nother archives as part of the scan. The archives that exist in a codebase\nmust be extracted before running a scan: `extractcode` is a bundled utility\nbehaving as a mostly-universal archive extractor. For example, this command will\nrecursively extract the mytar.tar.bz2 tarball in the mytar.tar.bz2-extract\ndirectory::\n\n ./extractcode mytar.tar.bz2\n\nSee `all extractcode options `_\nand `how to extract archives `_ for details.\n\n\nSupport\n=======\n\nIf you have a problem, a suggestion or found a bug, please enter a ticket at:\nhttps://github.com/nexB/scancode-toolkit/issues\n\nFor discussions and chats, we have:\n\n* an official Gitter channel for `web-based chats\n `_.\n Gitter is also accessible via an `IRC bridge `_.\n There are other AboutCode project-specific channels available there too.\n\n* an official `#aboutcode` IRC channel on freenode (server chat.freenode.net).\n This channel receives build and commit notifications and can be noisy.\n You can use your favorite IRC client or use the `web chat \n `_.\n\n\nSource code and downloads\n=========================\n\n* https://github.com/nexB/scancode-toolkit/releases\n* https://github.com/nexB/scancode-toolkit.git\n* https://pypi.org/project/scancode-toolkit/\n* https://github.com/nexB/scancode-thirdparty-src.git\n\n\nLicense\n=======\n\n* Apache-2.0 as the overall license\n* CC-BY-4.0 for reference datasets (initially was in the Public Domain).\n* Multiple other secondary permissive or copyleft licenses (LGPL, MIT,\n BSD, GPL 2/3, etc.) for third-party components.\n\n\nSee the NOTICE file and the .ABOUT files that document the origin and license of\nthe third-party code used in ScanCode for more details.\n\n\n.. |master-cov| image:: https://codecov.io/gh/nexB/scancode-toolkit/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/nexB/scancode-toolkit/branch/master\n :alt: Master branch test coverage (Linux)\n.. |devel-cov| image:: https://codecov.io/gh/nexB/scancode-toolkit/branch/develop/graph/badge.svg\n :target: https://codecov.io/gh/nexB/scancode-toolkit/branch/develop\n :alt: Develop branch test coverage (Linux)\n\n.. |master-posix| image:: https://api.travis-ci.org/nexB/scancode-toolkit.png?branch=master\n :target: https://travis-ci.org/nexB/scancode-toolkit\n :alt: Linux Master branch tests status\n.. |devel-posix| image:: https://api.travis-ci.org/nexB/scancode-toolkit.png?branch=develop\n :target: https://travis-ci.org/nexB/scancode-toolkit\n :alt: Linux Develop branch tests status\n\n.. |master-win| image:: https://ci.appveyor.com/api/projects/status/4webymu0l2ip8utr/branch/master?png=true\n :target: https://ci.appveyor.com/project/nexB/scancode-toolkit\n :alt: Windows Master branch tests status\n.. |devel-win| image:: https://ci.appveyor.com/api/projects/status/4webymu0l2ip8utr/branch/develop?png=true\n :target: https://ci.appveyor.com/project/nexB/scancode-toolkit\n :alt: Windows Develop branch tests status\n\n.. |docs-rtd| image:: https://readthedocs.org/projects/scancode-toolkit/badge/?version=latest\n :target: https://scancode-toolkit.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "ScanCode", + "email": "info@aboutcode.org", + "url": null + } + ], + "keywords": [ + "open source", + "scan", + "license", + "package", + "dependency", + "copyright", + "filetype", + "author", + "extract", + "licensing", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Programming Language :: Python", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Topic :: Utilities" + ], + "homepage_url": "https://github.com/nexB/scancode-toolkit", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": "apache-2.0 AND cc-by-4.0 AND other-permissive AND other-copyleft", + "declared_license": { + "license": "Apache-2.0 AND CC-BY-4.0 AND LicenseRef-scancode-other-permissive AND LicenseRef-scancode-other-copyleft" + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/scancode-toolkit@21.3.31", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/s/scancode-toolkit/scancode-toolkit-21.3.31.tar.gz", + "api_data_url": "https://pypi.org/pypi/scancode-toolkit/21.3.31/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/dparse/requirements.txt-expected.json b/tests/packagedcode/data/pypi/dparse/requirements.txt-expected.json new file mode 100644 index 00000000000..a1fb4090ff2 --- /dev/null +++ b/tests/packagedcode/data/pypi/dparse/requirements.txt-expected.json @@ -0,0 +1,18 @@ +[ + { + "purl": "pkg:pypi/lxml@3.4.4", + "requirement": "==3.4.4", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": true + }, + { + "purl": "pkg:pypi/requests@2.7.0", + "requirement": "==2.7.0", + "scope": "dependencies", + "is_runtime": true, + "is_optional": false, + "is_resolved": true + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/METADATA b/tests/packagedcode/data/pypi/metadata/METADATA similarity index 100% rename from tests/packagedcode/data/pypi/METADATA rename to tests/packagedcode/data/pypi/metadata/METADATA diff --git a/tests/packagedcode/data/pypi/metadata/METADATA-expected.json b/tests/packagedcode/data/pypi/metadata/METADATA-expected.json new file mode 100644 index 00000000000..a51b64bb560 --- /dev/null +++ b/tests/packagedcode/data/pypi/metadata/METADATA-expected.json @@ -0,0 +1,54 @@ +{ + "type": "pypi", + "namespace": null, + "name": "six", + "version": "1.10.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Python 2 and 3 compatibility utilities\nSix is a Python 2 and 3 compatibility library. It provides utility functions\nfor smoothing over the differences between the Python versions with the goal of\nwriting Python code that is compatible on both Python versions. See the\ndocumentation for more information on what is provided.\n\nSix supports every Python version since 2.6. It is contained in only one Python\nfile, so it can be easily copied into your project. (The copyright and license\nnotice must be retained.)\n\nOnline documentation is at https://pythonhosted.org/six/.\n\nBugs can be reported to https://bitbucket.org/gutworth/six. The code can also\nbe found there.\n\nFor questions about six or porting in general, email the python-porting mailing\nlist: https://mail.python.org/mailman/listinfo/python-porting", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "Benjamin Peterson", + "email": "benjamin@python.org", + "url": null + } + ], + "keywords": [ + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 3", + "Intended Audience :: Developers", + "Topic :: Software Development :: Libraries", + "Topic :: Utilities" + ], + "homepage_url": "http://pypi.python.org/pypi/six/", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": "mit", + "declared_license": { + "license": "MIT", + "classifiers": [ + "License :: OSI Approved :: MIT License" + ] + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/six@1.10.0", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/s/six/six-1.10.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/six/1.10.0/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/metadata/PKG-INFO b/tests/packagedcode/data/pypi/metadata/PKG-INFO new file mode 100644 index 00000000000..9385b5993fa --- /dev/null +++ b/tests/packagedcode/data/pypi/metadata/PKG-INFO @@ -0,0 +1,83 @@ +Metadata-Version: 1.1 +Name: python-mimeparse +Version: 1.6.0 +Summary: A module provides basic functions for parsing mime-type names and matching them against a list of media-ranges. +Home-page: https://github.com/dbtsai/python-mimeparse +Author: DB Tsai +Author-email: dbtsai@dbtsai.com +License: UNKNOWN +Download-URL: https://github.com/dbtsai/python-mimeparse/tarball/1.6.0 +Description: Python-MimeParse + ================ + + .. image:: https://travis-ci.org/dbtsai/python-mimeparse.svg?branch=master + :target: https://travis-ci.org/dbtsai/python-mimeparse + + This module provides basic functions for handling mime-types. It can + handle matching mime-types against a list of media-ranges. See section + 5.3.2 of the HTTP 1.1 Semantics and Content specification [RFC 7231] for + a complete explanation: https://tools.ietf.org/html/rfc7231#section-5.3.2 + + Installation + ------------ + + Use **pip**: + + .. code-block:: sh + + $ pip install python-mimeparse + + It supports Python 2.7 - 3.5 and PyPy. + + Functions + --------- + + **parse_mime_type()** + + Parses a mime-type into its component parts. + + **parse_media_range()** + + Media-ranges are mime-types with wild-cards and a "q" quality parameter. + + **quality()** + + Determines the quality ("q") of a mime-type when compared against a list of + media-ranges. + + **quality_parsed()** + + Just like ``quality()`` except the second parameter must be pre-parsed. + + **best_match()** + + Choose the mime-type with the highest quality ("q") from a list of candidates. + + Testing + ------- + + Run the tests by typing: ``python mimeparse_test.py``. The tests require Python 2.6. + + To make sure that the package works in all the supported environments, you can + run **tox** tests: + + .. code-block:: sh + + $ pip install tox + $ tox + + The format of the JSON test data file is as follows: A top-level JSON object + which has a key for each of the functions to be tested. The value corresponding + to that key is a list of tests. Each test contains: the argument or arguments + to the function being tested, the expected results and an optional description. + +Keywords: mime-type +Platform: UNKNOWN +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: Software Development :: Libraries :: Python Modules diff --git a/tests/packagedcode/data/pypi/metadata/PKG-INFO-expected.json b/tests/packagedcode/data/pypi/metadata/PKG-INFO-expected.json new file mode 100644 index 00000000000..bf46cc02fdc --- /dev/null +++ b/tests/packagedcode/data/pypi/metadata/PKG-INFO-expected.json @@ -0,0 +1,56 @@ +{ + "type": "pypi", + "namespace": null, + "name": "python-mimeparse", + "version": "1.6.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "A module provides basic functions for parsing mime-type names and matching them against a list of media-ranges.\nPython-MimeParse\n ================\n \n .. image:: https://travis-ci.org/dbtsai/python-mimeparse.svg?branch=master\n :target: https://travis-ci.org/dbtsai/python-mimeparse\n \n This module provides basic functions for handling mime-types. It can\n handle matching mime-types against a list of media-ranges. See section\n 5.3.2 of the HTTP 1.1 Semantics and Content specification [RFC 7231] for\n a complete explanation: https://tools.ietf.org/html/rfc7231#section-5.3.2\n \n Installation\n ------------\n \n Use **pip**:\n \n .. code-block:: sh\n \n $ pip install python-mimeparse\n \n It supports Python 2.7 - 3.5 and PyPy.\n \n Functions\n ---------\n \n **parse_mime_type()**\n \n Parses a mime-type into its component parts.\n \n **parse_media_range()**\n \n Media-ranges are mime-types with wild-cards and a \"q\" quality parameter.\n \n **quality()**\n \n Determines the quality (\"q\") of a mime-type when compared against a list of\n media-ranges.\n \n **quality_parsed()**\n \n Just like ``quality()`` except the second parameter must be pre-parsed.\n \n **best_match()**\n \n Choose the mime-type with the highest quality (\"q\") from a list of candidates.\n \n Testing\n -------\n \n Run the tests by typing: ``python mimeparse_test.py``. The tests require Python 2.6.\n \n To make sure that the package works in all the supported environments, you can\n run **tox** tests:\n \n .. code-block:: sh\n \n $ pip install tox\n $ tox\n \n The format of the JSON test data file is as follows: A top-level JSON object\n which has a key for each of the functions to be tested. The value corresponding\n to that key is a list of tests. Each test contains: the argument or arguments\n to the function being tested, the expected results and an optional description.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "DB Tsai", + "email": "dbtsai@dbtsai.com", + "url": null + } + ], + "keywords": [ + "mime-type", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Operating System :: OS Independent", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Software Development :: Libraries :: Python Modules" + ], + "homepage_url": "https://github.com/dbtsai/python-mimeparse", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": "https://github.com/dbtsai/python-mimeparse/tarball/1.6.0", + "copyright": null, + "license_expression": "mit", + "declared_license": { + "classifiers": [ + "License :: OSI Approved :: MIT License" + ] + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/python-mimeparse@1.6.0", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/python-mimeparse/python-mimeparse-1.6.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/python-mimeparse/1.6.0/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/metadata/v10/PKG-INFO b/tests/packagedcode/data/pypi/metadata/v10/PKG-INFO new file mode 100644 index 00000000000..169fb375296 --- /dev/null +++ b/tests/packagedcode/data/pypi/metadata/v10/PKG-INFO @@ -0,0 +1,156 @@ +Metadata-Version: 1.0 +Name: prompt-toolkit +Version: 0.53.1 +Summary: Library for building powerful interactive command lines in Python +Home-page: https://github.com/jonathanslenders/python-prompt-toolkit +Author: Jonathan Slenders +Author-email: UNKNOWN +License: LICENSE.txt +Description: Python Prompt Toolkit + ===================== + + |Build Status| |PyPI| + + ``prompt_toolkit`` is a library for building powerful interactive command lines + in Python. + + Looking for ptpython, the Python REPL? + ************************************** + + Are you looking for ``ptpython``, the interactive Python Shell? We moved the + ``ptpython`` source code to a separate repository. This way we are sure not to + pollute the ``prompt_toolkit`` library with any ``ptpython``-specific stuff and + ``ptpython`` can be developed independently. You will now have to install it + through:: + + pip install ptpython + + `Go to ptpython... `_ + + .. image :: https://github.com/jonathanslenders/python-prompt-toolkit/raw/master/docs/images/ptpython.png + + prompt-toolkit features + *********************** + + ``prompt_toolkit`` could be a replacement for `GNU readline + `_, but it can be much + more than that. + + Some features: + + - Pure Python. + - Syntax highlighting of the input while typing. (For instance, with a Pygments lexer.) + - Multi-line input editing. + - Advanced code completion. + - Both Emacs and Vi key bindings. (Similar to readline.) + - Reverse and forward incremental search. + - Runs on all Python versions from 2.6 up to 3.4. + - Works well with Unicode double width characters. (Chinese input.) + - Selecting text for copy/paste. (Both Emacs and Vi style.) + - Mouse support for cursor positioning and scrolling. + - Auto suggestions. (Like `fish shell `_.) + - Multiple input buffers. + - No global state. + - Lightweight, the only dependencies are Pygments, six and wcwidth. + - Code written with love. + - Runs on Linux, OS X, OpenBSD and Windows systems. + + Feel free to create tickets for bugs and feature requests, and create pull + requests if you have nice patches that you would like to share with others. + + + About Windows support + ********************* + + ``prompt_toolkit`` is cross platform, and everything that you build on top + should run fine on both Unix and Windows systems. On Windows, it uses a + different event loop (``WaitForMultipleObjects`` instead of ``select``), and + another input and output system. (Win32 APIs instead of pseudo-terminals and + VT100.) + + It's worth noting that the implementation is a "best effort of what is + possible". Both Unix and Windows terminals have their limitations. But in + general, the Unix experience will still be a little better. + + For Windows, it's recommended to use either `cmder + `_ or `conemu `_. + + + Installation + ************ + + :: + + pip install prompt-toolkit + + + Getting started + *************** + + The most simple example of the library would look like this: + + .. code:: python + + from prompt_toolkit import prompt + + if __name__ == '__main__': + answer = prompt('Give me some input: ') + print('You said: %s' % answer) + + For more complex examples, have a look in the ``examples`` directory. All + examples are chosen to demonstrate only one thing. Also, don't be afraid to + look at the source code. The implementation of the ``prompt`` function could be + a good start. + + Note: For Python 2, you need to add ``from __future__ import unicode_literals`` + to the above example. All strings are expected to be unicode strings. + + + Projects using prompt-toolkit + ***************************** + + - `ptpython `_: Python REPL + - `ptpdb `_: Python debugger (pdb replacement) + - `pgcli `_: Postgres client. + - `mycli `_: MySql client. + - `pyvim `_: A Vim clone in pure Python + - `wharfee `_: A Docker command line. + - `xonsh `_: A Python-ish, BASHwards-compatible shell. + - `saws `_: A Supercharged AWS Command Line Interface. + + + (Want your own project to be listed here? Please create a GitHub issue.) + + + Philosophy + ********** + + The source code of ``prompt_toolkit`` should be readable, concise and + efficient. We prefer short functions focussing each on one task and for which + the input and output types are clearly specified. We mostly prefer composition + over inheritance, because inheritance can result in too much functionality in + the same object. We prefer immutable objects where possible (objects don't + change after initialisation). Reusability is important. We absolutely refrain + from having a changing global state, it should be possible to have multiple + independent instances of the same code in the same process. The architecture + should be layered: the lower levels operate on primitive operations and data + structures giving -- when correctly combined -- all the possible flexibility; + while at the higher level, there should be a simpler API, ready-to-use and + sufficient for most use cases. Thinking about algorithms and efficiency is + important, but avoid premature optimization. + + + Special thanks to + ***************** + + - `Pygments `_: Syntax highlighter. + - `wcwidth `_: Determine columns needed for a wide characters. + + .. |Build Status| image:: https://api.travis-ci.org/jonathanslenders/python-prompt-toolkit.svg?branch=master + :target: https://travis-ci.org/jonathanslenders/python-prompt-toolkit# + + .. |PyPI| image:: https://pypip.in/version/prompt-toolkit/badge.svg + :target: https://pypi.python.org/pypi/prompt-toolkit/ + :alt: Latest Version + +Platform: UNKNOWN diff --git a/tests/packagedcode/data/pypi/metadata/v10/PKG-INFO-expected.json b/tests/packagedcode/data/pypi/metadata/v10/PKG-INFO-expected.json new file mode 100644 index 00000000000..c5034455796 --- /dev/null +++ b/tests/packagedcode/data/pypi/metadata/v10/PKG-INFO-expected.json @@ -0,0 +1,45 @@ +{ + "type": "pypi", + "namespace": null, + "name": "prompt-toolkit", + "version": "0.53.1", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Library for building powerful interactive command lines in Python\nPython Prompt Toolkit\n =====================\n \n |Build Status| |PyPI|\n \n ``prompt_toolkit`` is a library for building powerful interactive command lines\n in Python.\n \n Looking for ptpython, the Python REPL?\n **************************************\n \n Are you looking for ``ptpython``, the interactive Python Shell? We moved the\n ``ptpython`` source code to a separate repository. This way we are sure not to\n pollute the ``prompt_toolkit`` library with any ``ptpython``-specific stuff and\n ``ptpython`` can be developed independently. You will now have to install it\n through::\n \n pip install ptpython\n \n `Go to ptpython... `_\n \n .. image :: https://github.com/jonathanslenders/python-prompt-toolkit/raw/master/docs/images/ptpython.png\n \n prompt-toolkit features\n ***********************\n \n ``prompt_toolkit`` could be a replacement for `GNU readline\n `_, but it can be much\n more than that.\n \n Some features:\n \n - Pure Python.\n - Syntax highlighting of the input while typing. (For instance, with a Pygments lexer.)\n - Multi-line input editing.\n - Advanced code completion.\n - Both Emacs and Vi key bindings. (Similar to readline.)\n - Reverse and forward incremental search.\n - Runs on all Python versions from 2.6 up to 3.4.\n - Works well with Unicode double width characters. (Chinese input.)\n - Selecting text for copy/paste. (Both Emacs and Vi style.)\n - Mouse support for cursor positioning and scrolling.\n - Auto suggestions. (Like `fish shell `_.)\n - Multiple input buffers.\n - No global state.\n - Lightweight, the only dependencies are Pygments, six and wcwidth.\n - Code written with love.\n - Runs on Linux, OS X, OpenBSD and Windows systems.\n \n Feel free to create tickets for bugs and feature requests, and create pull\n requests if you have nice patches that you would like to share with others.\n \n \n About Windows support\n *********************\n \n ``prompt_toolkit`` is cross platform, and everything that you build on top\n should run fine on both Unix and Windows systems. On Windows, it uses a\n different event loop (``WaitForMultipleObjects`` instead of ``select``), and\n another input and output system. (Win32 APIs instead of pseudo-terminals and\n VT100.)\n \n It's worth noting that the implementation is a \"best effort of what is\n possible\". Both Unix and Windows terminals have their limitations. But in\n general, the Unix experience will still be a little better.\n \n For Windows, it's recommended to use either `cmder\n `_ or `conemu `_.\n \n \n Installation\n ************\n \n ::\n \n pip install prompt-toolkit\n \n \n Getting started\n ***************\n \n The most simple example of the library would look like this:\n \n .. code:: python\n \n from prompt_toolkit import prompt\n \n if __name__ == '__main__':\n answer = prompt('Give me some input: ')\n print('You said: %s' % answer)\n \n For more complex examples, have a look in the ``examples`` directory. All\n examples are chosen to demonstrate only one thing. Also, don't be afraid to\n look at the source code. The implementation of the ``prompt`` function could be\n a good start.\n \n Note: For Python 2, you need to add ``from __future__ import unicode_literals``\n to the above example. All strings are expected to be unicode strings.\n \n \n Projects using prompt-toolkit\n *****************************\n \n - `ptpython `_: Python REPL\n - `ptpdb `_: Python debugger (pdb replacement)\n - `pgcli `_: Postgres client.\n - `mycli `_: MySql client.\n - `pyvim `_: A Vim clone in pure Python\n - `wharfee `_: A Docker command line.\n - `xonsh `_: A Python-ish, BASHwards-compatible shell.\n - `saws `_: A Supercharged AWS Command Line Interface.\n \n \n (Want your own project to be listed here? Please create a GitHub issue.)\n \n \n Philosophy\n **********\n \n The source code of ``prompt_toolkit`` should be readable, concise and\n efficient. We prefer short functions focussing each on one task and for which\n the input and output types are clearly specified. We mostly prefer composition\n over inheritance, because inheritance can result in too much functionality in\n the same object. We prefer immutable objects where possible (objects don't\n change after initialisation). Reusability is important. We absolutely refrain\n from having a changing global state, it should be possible to have multiple\n independent instances of the same code in the same process. The architecture\n should be layered: the lower levels operate on primitive operations and data\n structures giving -- when correctly combined -- all the possible flexibility;\n while at the higher level, there should be a simpler API, ready-to-use and\n sufficient for most use cases. Thinking about algorithms and efficiency is\n important, but avoid premature optimization.\n \n \n Special thanks to\n *****************\n \n - `Pygments `_: Syntax highlighter.\n - `wcwidth `_: Determine columns needed for a wide characters.\n \n .. |Build Status| image:: https://api.travis-ci.org/jonathanslenders/python-prompt-toolkit.svg?branch=master\n :target: https://travis-ci.org/jonathanslenders/python-prompt-toolkit#\n \n .. |PyPI| image:: https://pypip.in/version/prompt-toolkit/badge.svg\n :target: https://pypi.python.org/pypi/prompt-toolkit/\n :alt: Latest Version", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "Jonathan Slenders", + "email": "UNKNOWN", + "url": null + } + ], + "keywords": [], + "homepage_url": "https://github.com/jonathanslenders/python-prompt-toolkit", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": "unknown", + "declared_license": { + "license": "LICENSE.txt" + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/prompt-toolkit@0.53.1", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/prompt-toolkit/prompt-toolkit-0.53.1.tar.gz", + "api_data_url": "https://pypi.org/pypi/prompt-toolkit/0.53.1/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/metadata/v11/PKG-INFO b/tests/packagedcode/data/pypi/metadata/v11/PKG-INFO new file mode 100644 index 00000000000..9385b5993fa --- /dev/null +++ b/tests/packagedcode/data/pypi/metadata/v11/PKG-INFO @@ -0,0 +1,83 @@ +Metadata-Version: 1.1 +Name: python-mimeparse +Version: 1.6.0 +Summary: A module provides basic functions for parsing mime-type names and matching them against a list of media-ranges. +Home-page: https://github.com/dbtsai/python-mimeparse +Author: DB Tsai +Author-email: dbtsai@dbtsai.com +License: UNKNOWN +Download-URL: https://github.com/dbtsai/python-mimeparse/tarball/1.6.0 +Description: Python-MimeParse + ================ + + .. image:: https://travis-ci.org/dbtsai/python-mimeparse.svg?branch=master + :target: https://travis-ci.org/dbtsai/python-mimeparse + + This module provides basic functions for handling mime-types. It can + handle matching mime-types against a list of media-ranges. See section + 5.3.2 of the HTTP 1.1 Semantics and Content specification [RFC 7231] for + a complete explanation: https://tools.ietf.org/html/rfc7231#section-5.3.2 + + Installation + ------------ + + Use **pip**: + + .. code-block:: sh + + $ pip install python-mimeparse + + It supports Python 2.7 - 3.5 and PyPy. + + Functions + --------- + + **parse_mime_type()** + + Parses a mime-type into its component parts. + + **parse_media_range()** + + Media-ranges are mime-types with wild-cards and a "q" quality parameter. + + **quality()** + + Determines the quality ("q") of a mime-type when compared against a list of + media-ranges. + + **quality_parsed()** + + Just like ``quality()`` except the second parameter must be pre-parsed. + + **best_match()** + + Choose the mime-type with the highest quality ("q") from a list of candidates. + + Testing + ------- + + Run the tests by typing: ``python mimeparse_test.py``. The tests require Python 2.6. + + To make sure that the package works in all the supported environments, you can + run **tox** tests: + + .. code-block:: sh + + $ pip install tox + $ tox + + The format of the JSON test data file is as follows: A top-level JSON object + which has a key for each of the functions to be tested. The value corresponding + to that key is a list of tests. Each test contains: the argument or arguments + to the function being tested, the expected results and an optional description. + +Keywords: mime-type +Platform: UNKNOWN +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: Software Development :: Libraries :: Python Modules diff --git a/tests/packagedcode/data/pypi/metadata/v11/PKG-INFO-expected.json b/tests/packagedcode/data/pypi/metadata/v11/PKG-INFO-expected.json new file mode 100644 index 00000000000..bf46cc02fdc --- /dev/null +++ b/tests/packagedcode/data/pypi/metadata/v11/PKG-INFO-expected.json @@ -0,0 +1,56 @@ +{ + "type": "pypi", + "namespace": null, + "name": "python-mimeparse", + "version": "1.6.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "A module provides basic functions for parsing mime-type names and matching them against a list of media-ranges.\nPython-MimeParse\n ================\n \n .. image:: https://travis-ci.org/dbtsai/python-mimeparse.svg?branch=master\n :target: https://travis-ci.org/dbtsai/python-mimeparse\n \n This module provides basic functions for handling mime-types. It can\n handle matching mime-types against a list of media-ranges. See section\n 5.3.2 of the HTTP 1.1 Semantics and Content specification [RFC 7231] for\n a complete explanation: https://tools.ietf.org/html/rfc7231#section-5.3.2\n \n Installation\n ------------\n \n Use **pip**:\n \n .. code-block:: sh\n \n $ pip install python-mimeparse\n \n It supports Python 2.7 - 3.5 and PyPy.\n \n Functions\n ---------\n \n **parse_mime_type()**\n \n Parses a mime-type into its component parts.\n \n **parse_media_range()**\n \n Media-ranges are mime-types with wild-cards and a \"q\" quality parameter.\n \n **quality()**\n \n Determines the quality (\"q\") of a mime-type when compared against a list of\n media-ranges.\n \n **quality_parsed()**\n \n Just like ``quality()`` except the second parameter must be pre-parsed.\n \n **best_match()**\n \n Choose the mime-type with the highest quality (\"q\") from a list of candidates.\n \n Testing\n -------\n \n Run the tests by typing: ``python mimeparse_test.py``. The tests require Python 2.6.\n \n To make sure that the package works in all the supported environments, you can\n run **tox** tests:\n \n .. code-block:: sh\n \n $ pip install tox\n $ tox\n \n The format of the JSON test data file is as follows: A top-level JSON object\n which has a key for each of the functions to be tested. The value corresponding\n to that key is a list of tests. Each test contains: the argument or arguments\n to the function being tested, the expected results and an optional description.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "DB Tsai", + "email": "dbtsai@dbtsai.com", + "url": null + } + ], + "keywords": [ + "mime-type", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Operating System :: OS Independent", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Software Development :: Libraries :: Python Modules" + ], + "homepage_url": "https://github.com/dbtsai/python-mimeparse", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": "https://github.com/dbtsai/python-mimeparse/tarball/1.6.0", + "copyright": null, + "license_expression": "mit", + "declared_license": { + "classifiers": [ + "License :: OSI Approved :: MIT License" + ] + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/python-mimeparse@1.6.0", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/python-mimeparse/python-mimeparse-1.6.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/python-mimeparse/1.6.0/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/metadata/v12/PKG-INFO b/tests/packagedcode/data/pypi/metadata/v12/PKG-INFO new file mode 100644 index 00000000000..d8a6e65df11 --- /dev/null +++ b/tests/packagedcode/data/pypi/metadata/v12/PKG-INFO @@ -0,0 +1,38 @@ +Metadata-Version: 1.2 +Name: pyldap +Version: 2.4.45 +Summary: Python modules for implementing LDAP clients +Home-page: https://github.com/pyldap/pyldap/ +Author: pyldap project +License: Python style +Download-URL: https://pypi.python.org/pypi/pyldap/ +Description: pyldap: + pyldap is a fork of python-ldap, and provides an object-oriented API to access LDAP + directory servers from Python programs. Mainly it wraps the OpenLDAP 2.x libs for that purpose. + Additionally the package contains modules for other LDAP-related stuff + (e.g. processing LDIF, LDAPURLs, LDAPv3 schema, LDAPv3 extended operations + and controls, etc.). + +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: Operating System :: OS Independent +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX +Classifier: Programming Language :: C +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Topic :: Database +Classifier: Topic :: Internet +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP +Classifier: License :: OSI Approved :: Python Software Foundation License +Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.* diff --git a/tests/packagedcode/data/pypi/metadata/v12/PKG-INFO-expected.json b/tests/packagedcode/data/pypi/metadata/v12/PKG-INFO-expected.json new file mode 100644 index 00000000000..cf600ac74ac --- /dev/null +++ b/tests/packagedcode/data/pypi/metadata/v12/PKG-INFO-expected.json @@ -0,0 +1,69 @@ +{ + "type": "pypi", + "namespace": null, + "name": "pyldap", + "version": "2.4.45", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Python modules for implementing LDAP clients\npyldap:\n pyldap is a fork of python-ldap, and provides an object-oriented API to access LDAP\n directory servers from Python programs. Mainly it wraps the OpenLDAP 2.x libs for that purpose.\n Additionally the package contains modules for other LDAP-related stuff\n (e.g. processing LDIF, LDAPURLs, LDAPv3 schema, LDAPv3 extended operations\n and controls, etc.).", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "pyldap project", + "email": null, + "url": null + } + ], + "keywords": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "Operating System :: OS Independent", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Programming Language :: C", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Topic :: Database", + "Topic :: Internet", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP" + ], + "homepage_url": "https://github.com/pyldap/pyldap/", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": "https://pypi.python.org/pypi/pyldap/", + "copyright": null, + "license_expression": "unknown AND python", + "declared_license": { + "license": "Python style", + "classifiers": [ + "License :: OSI Approved :: Python Software Foundation License" + ] + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/pyldap@2.4.45", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/pyldap/pyldap-2.4.45.tar.gz", + "api_data_url": "https://pypi.org/pypi/pyldap/2.4.45/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/metadata/v20/PKG-INFO b/tests/packagedcode/data/pypi/metadata/v20/PKG-INFO new file mode 100644 index 00000000000..617020fb710 --- /dev/null +++ b/tests/packagedcode/data/pypi/metadata/v20/PKG-INFO @@ -0,0 +1,234 @@ +Metadata-Version: 2.0 +Name: pymongo +Version: 3.6.1 +Summary: Python driver for MongoDB +Home-page: http://github.com/mongodb/mongo-python-driver +Author: Bernie Hackett +Author-email: bernie@mongodb.com +License: Apache License, Version 2.0 +Keywords: mongo,mongodb,pymongo,gridfs,bson +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Database +Provides-Extra: gssapi +Requires-Dist: pykerberos; extra == 'gssapi' +Provides-Extra: srv +Requires-Dist: dnspython (>=1.8.0,<2.0.0); extra == 'srv' +Provides-Extra: tls +Requires-Dist: ipaddress; extra == 'tls' + +======= +PyMongo +======= +:Info: See `the mongo site `_ for more information. See `github `_ for the latest source. +:Author: Mike Dirolf +:Maintainer: Bernie Hackett + +About +===== + +The PyMongo distribution contains tools for interacting with MongoDB +database from Python. The ``bson`` package is an implementation of +the `BSON format `_ for Python. The ``pymongo`` +package is a native Python driver for MongoDB. The ``gridfs`` package +is a `gridfs +`_ +implementation on top of ``pymongo``. + +PyMongo supports MongoDB 2.6, 3.0, 3.2, 3.4, and 3.6. + +Support / Feedback +================== + +For issues with, questions about, or feedback for PyMongo, please look into +our `support channels `_. Please +do not email any of the PyMongo developers directly with issues or +questions - you're more likely to get an answer on the `mongodb-user +`_ list on Google Groups. + +Bugs / Feature Requests +======================= + +Think you’ve found a bug? Want to see a new feature in PyMongo? Please open a +case in our issue management tool, JIRA: + +- `Create an account and login `_. +- Navigate to `the PYTHON project `_. +- Click **Create Issue** - Please provide as much information as possible about the issue type and how to reproduce it. + +Bug reports in JIRA for all driver projects (i.e. PYTHON, CSHARP, JAVA) and the +Core Server (i.e. SERVER) project are **public**. + +How To Ask For Help +------------------- + +Please include all of the following information when opening an issue: + +- Detailed steps to reproduce the problem, including full traceback, if possible. +- The exact python version used, with patch level:: + + $ python -c "import sys; print(sys.version)" + +- The exact version of PyMongo used, with patch level:: + + $ python -c "import pymongo; print(pymongo.version); print(pymongo.has_c())" + +- The operating system and version (e.g. Windows 7, OSX 10.8, ...) +- Web framework or asynchronous network library used, if any, with version (e.g. + Django 1.7, mod_wsgi 4.3.0, gevent 1.0.1, Tornado 4.0.2, ...) + +Security Vulnerabilities +------------------------ + +If you’ve identified a security vulnerability in a driver or any other +MongoDB project, please report it according to the `instructions here +`_. + +Installation +============ + +PyMongo can be installed with `pip `_:: + + $ python -m pip install pymongo + +Or ``easy_install`` from +`setuptools `_:: + + $ python -m easy_install pymongo + +You can also download the project source and do:: + + $ python setup.py install + +Do **not** install the "bson" package from pypi. PyMongo comes with its own +bson package; doing "easy_install bson" installs a third-party package that +is incompatible with PyMongo. + +Dependencies +============ + +PyMongo supports CPython 2.6, 2.7, 3.4+, PyPy, and PyPy3. + +Optional dependencies: + +GSSAPI authentication requires `pykerberos +`_ on Unix or `WinKerberos +`_ on Windows. The correct +dependency can be installed automatically along with PyMongo:: + + $ python -m pip install pymongo[gssapi] + +Support for mongodb+srv:// URIs requires `dnspython +`_:: + + $ python -m pip install pymongo[srv] + +TLS / SSL support may require `ipaddress +`_ and `certifi +`_ or `wincertstore +`_ depending on the Python +version in use. The necessary dependencies can be installed along with +PyMongo:: + + $ python -m pip install pymongo[tls] + +You can install all dependencies automatically with the following +command:: + + $ python -m pip install pymongo[gssapi,srv,tls] + +Other optional packages: + +- `backports.pbkdf2 `_, + improves authentication performance with SCRAM-SHA-1, the default + authentication mechanism for MongoDB 3.0+. It especially improves + performance on Python versions older than 2.7.8. +- `monotonic `_ adds support for + a monotonic clock, which improves reliability in environments + where clock adjustments are frequent. Not needed in Python 3. + + +Additional dependencies are: + +- (to generate documentation) sphinx_ +- (to run the tests under Python 2.6) unittest2_ + +Examples +======== +Here's a basic example (for more see the *examples* section of the docs): + +.. code-block:: python + + >>> import pymongo + >>> client = pymongo.MongoClient("localhost", 27017) + >>> db = client.test + >>> db.name + u'test' + >>> db.my_collection + Collection(Database(MongoClient('localhost', 27017), u'test'), u'my_collection') + >>> db.my_collection.insert_one({"x": 10}).inserted_id + ObjectId('4aba15ebe23f6b53b0000000') + >>> db.my_collection.insert_one({"x": 8}).inserted_id + ObjectId('4aba160ee23f6b543e000000') + >>> db.my_collection.insert_one({"x": 11}).inserted_id + ObjectId('4aba160ee23f6b543e000002') + >>> db.my_collection.find_one() + {u'x': 10, u'_id': ObjectId('4aba15ebe23f6b53b0000000')} + >>> for item in db.my_collection.find(): + ... print(item["x"]) + ... + 10 + 8 + 11 + >>> db.my_collection.create_index("x") + u'x_1' + >>> for item in db.my_collection.find().sort("x", pymongo.ASCENDING): + ... print(item["x"]) + ... + 8 + 10 + 11 + >>> [item["x"] for item in db.my_collection.find().limit(2).skip(1)] + [8, 11] + +Documentation +============= + +You will need sphinx_ installed to generate the +documentation. Documentation can be generated by running **python +setup.py doc**. Generated documentation can be found in the +*doc/build/html/* directory. + +Testing +======= + +The easiest way to run the tests is to run **python setup.py test** in +the root of the distribution. Note that you will need unittest2_ to +run the tests under Python 2.6. + +To verify that PyMongo works with Gevent's monkey-patching:: + + $ python green_framework_test.py gevent + +Or with Eventlet's:: + + $ python green_framework_test.py eventlet + +.. _sphinx: http://sphinx.pocoo.org/ +.. _unittest2: https://pypi.python.org/pypi/unittest2 + + diff --git a/tests/packagedcode/data/pypi/metadata/v20/PKG-INFO-expected.json b/tests/packagedcode/data/pypi/metadata/v20/PKG-INFO-expected.json new file mode 100644 index 00000000000..7a4d26c40da --- /dev/null +++ b/tests/packagedcode/data/pypi/metadata/v20/PKG-INFO-expected.json @@ -0,0 +1,69 @@ +{ + "type": "pypi", + "namespace": null, + "name": "pymongo", + "version": "3.6.1", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Python driver for MongoDB \n=======\nPyMongo\n=======\n:Info: See `the mongo site `_ for more information. See `github `_ for the latest source.\n:Author: Mike Dirolf\n:Maintainer: Bernie Hackett \n\nAbout\n=====\n\nThe PyMongo distribution contains tools for interacting with MongoDB\ndatabase from Python. The ``bson`` package is an implementation of\nthe `BSON format `_ for Python. The ``pymongo``\npackage is a native Python driver for MongoDB. The ``gridfs`` package\nis a `gridfs\n`_\nimplementation on top of ``pymongo``.\n\nPyMongo supports MongoDB 2.6, 3.0, 3.2, 3.4, and 3.6.\n\nSupport / Feedback\n==================\n\nFor issues with, questions about, or feedback for PyMongo, please look into\nour `support channels `_. Please\ndo not email any of the PyMongo developers directly with issues or\nquestions - you're more likely to get an answer on the `mongodb-user\n`_ list on Google Groups.\n\nBugs / Feature Requests\n=======================\n\nThink you\u2019ve found a bug? Want to see a new feature in PyMongo? Please open a\ncase in our issue management tool, JIRA:\n\n- `Create an account and login `_.\n- Navigate to `the PYTHON project `_.\n- Click **Create Issue** - Please provide as much information as possible about the issue type and how to reproduce it.\n\nBug reports in JIRA for all driver projects (i.e. PYTHON, CSHARP, JAVA) and the\nCore Server (i.e. SERVER) project are **public**.\n\nHow To Ask For Help\n-------------------\n\nPlease include all of the following information when opening an issue:\n\n- Detailed steps to reproduce the problem, including full traceback, if possible.\n- The exact python version used, with patch level::\n\n $ python -c \"import sys; print(sys.version)\"\n\n- The exact version of PyMongo used, with patch level::\n\n $ python -c \"import pymongo; print(pymongo.version); print(pymongo.has_c())\"\n\n- The operating system and version (e.g. Windows 7, OSX 10.8, ...)\n- Web framework or asynchronous network library used, if any, with version (e.g.\n Django 1.7, mod_wsgi 4.3.0, gevent 1.0.1, Tornado 4.0.2, ...)\n\nSecurity Vulnerabilities\n------------------------\n\nIf you\u2019ve identified a security vulnerability in a driver or any other\nMongoDB project, please report it according to the `instructions here\n`_.\n\nInstallation\n============\n\nPyMongo can be installed with `pip `_::\n\n $ python -m pip install pymongo\n\nOr ``easy_install`` from\n`setuptools `_::\n\n $ python -m easy_install pymongo\n\nYou can also download the project source and do::\n\n $ python setup.py install\n\nDo **not** install the \"bson\" package from pypi. PyMongo comes with its own\nbson package; doing \"easy_install bson\" installs a third-party package that\nis incompatible with PyMongo.\n\nDependencies\n============\n\nPyMongo supports CPython 2.6, 2.7, 3.4+, PyPy, and PyPy3.\n\nOptional dependencies:\n\nGSSAPI authentication requires `pykerberos\n`_ on Unix or `WinKerberos\n`_ on Windows. The correct\ndependency can be installed automatically along with PyMongo::\n\n $ python -m pip install pymongo[gssapi]\n\nSupport for mongodb+srv:// URIs requires `dnspython\n`_::\n\n $ python -m pip install pymongo[srv]\n\nTLS / SSL support may require `ipaddress\n`_ and `certifi\n`_ or `wincertstore\n`_ depending on the Python\nversion in use. The necessary dependencies can be installed along with\nPyMongo::\n\n $ python -m pip install pymongo[tls]\n\nYou can install all dependencies automatically with the following\ncommand::\n\n $ python -m pip install pymongo[gssapi,srv,tls]\n\nOther optional packages:\n\n- `backports.pbkdf2 `_,\n improves authentication performance with SCRAM-SHA-1, the default\n authentication mechanism for MongoDB 3.0+. It especially improves\n performance on Python versions older than 2.7.8.\n- `monotonic `_ adds support for\n a monotonic clock, which improves reliability in environments\n where clock adjustments are frequent. Not needed in Python 3.\n\n\nAdditional dependencies are:\n\n- (to generate documentation) sphinx_\n- (to run the tests under Python 2.6) unittest2_\n\nExamples\n========\nHere's a basic example (for more see the *examples* section of the docs):\n\n.. code-block:: python\n\n >>> import pymongo\n >>> client = pymongo.MongoClient(\"localhost\", 27017)\n >>> db = client.test\n >>> db.name\n u'test'\n >>> db.my_collection\n Collection(Database(MongoClient('localhost', 27017), u'test'), u'my_collection')\n >>> db.my_collection.insert_one({\"x\": 10}).inserted_id\n ObjectId('4aba15ebe23f6b53b0000000')\n >>> db.my_collection.insert_one({\"x\": 8}).inserted_id\n ObjectId('4aba160ee23f6b543e000000')\n >>> db.my_collection.insert_one({\"x\": 11}).inserted_id\n ObjectId('4aba160ee23f6b543e000002')\n >>> db.my_collection.find_one()\n {u'x': 10, u'_id': ObjectId('4aba15ebe23f6b53b0000000')}\n >>> for item in db.my_collection.find():\n ... print(item[\"x\"])\n ...\n 10\n 8\n 11\n >>> db.my_collection.create_index(\"x\")\n u'x_1'\n >>> for item in db.my_collection.find().sort(\"x\", pymongo.ASCENDING):\n ... print(item[\"x\"])\n ...\n 8\n 10\n 11\n >>> [item[\"x\"] for item in db.my_collection.find().limit(2).skip(1)]\n [8, 11]\n\nDocumentation\n=============\n\nYou will need sphinx_ installed to generate the\ndocumentation. Documentation can be generated by running **python\nsetup.py doc**. Generated documentation can be found in the\n*doc/build/html/* directory.\n\nTesting\n=======\n\nThe easiest way to run the tests is to run **python setup.py test** in\nthe root of the distribution. Note that you will need unittest2_ to\nrun the tests under Python 2.6.\n\nTo verify that PyMongo works with Gevent's monkey-patching::\n\n $ python green_framework_test.py gevent\n\nOr with Eventlet's::\n\n $ python green_framework_test.py eventlet\n\n.. _sphinx: http://sphinx.pocoo.org/\n.. _unittest2: https://pypi.python.org/pypi/unittest2", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "Bernie Hackett", + "email": "bernie@mongodb.com", + "url": null + } + ], + "keywords": [ + "mongo", + "mongodb", + "pymongo", + "gridfs", + "bson", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.6", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Database" + ], + "homepage_url": "http://github.com/mongodb/mongo-python-driver", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": "apache-2.0", + "declared_license": { + "license": "Apache License, Version 2.0", + "classifiers": [ + "License :: OSI Approved :: Apache Software License" + ] + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/pymongo@3.6.1", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/pymongo/pymongo-3.6.1.tar.gz", + "api_data_url": "https://pypi.org/pypi/pymongo/3.6.1/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/metadata/v21/PKG-INFO b/tests/packagedcode/data/pypi/metadata/v21/PKG-INFO new file mode 100644 index 00000000000..0cb4350af8d --- /dev/null +++ b/tests/packagedcode/data/pypi/metadata/v21/PKG-INFO @@ -0,0 +1,73 @@ +Metadata-Version: 2.1 +Name: pbr +Version: 4.0.1 +Summary: Python Build Reasonableness +Home-page: https://docs.openstack.org/pbr/latest/ +Author: OpenStack +Author-email: openstack-dev@lists.openstack.org +License: UNKNOWN +Project-URL: Bug Tracker, https://bugs.launchpad.net/pbr/ +Project-URL: Documentation, https://docs.openstack.org/pbr/ +Project-URL: Source Code, https://git.openstack.org/cgit/openstack-dev/pbr/ +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Environment :: OpenStack +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Information Technology +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Description-Content-Type: text/x-rst; charset=UTF-8 + +Introduction +============ + +.. image:: https://img.shields.io/pypi/v/pbr.svg + :target: https://pypi.python.org/pypi/pbr/ + :alt: Latest Version + +.. image:: https://img.shields.io/pypi/dm/pbr.svg + :target: https://pypi.python.org/pypi/pbr/ + :alt: Downloads + +PBR is a library that injects some useful and sensible default behaviors +into your setuptools run. It started off life as the chunks of code that +were copied between all of the `OpenStack`_ projects. Around the time that +OpenStack hit 18 different projects each with at least 3 active branches, +it seemed like a good time to make that code into a proper reusable library. + +PBR is only mildly configurable. The basic idea is that there's a decent +way to run things and if you do, you should reap the rewards, because then +it's simple and repeatable. If you want to do things differently, cool! But +you've already got the power of Python at your fingertips, so you don't +really need PBR. + +PBR builds on top of the work that `d2to1`_ started to provide for declarative +configuration. `d2to1`_ is itself an implementation of the ideas behind +`distutils2`_. Although `distutils2`_ is now abandoned in favor of work towards +`PEP 426`_ and Metadata 2.0, declarative config is still a great idea and +specifically important in trying to distribute setup code as a library +when that library itself will alter how the setup is processed. As Metadata +2.0 and other modern Python packaging PEPs come out, PBR aims to support +them as quickly as possible. + +* License: Apache License, Version 2.0 +* Documentation: https://docs.openstack.org/pbr/latest/ +* Source: https://git.openstack.org/cgit/openstack-dev/pbr +* Bugs: https://bugs.launchpad.net/pbr +* Change Log: https://docs.openstack.org/pbr/latest/user/history.html + +.. _d2to1: https://pypi.python.org/pypi/d2to1 +.. _distutils2: https://pypi.python.org/pypi/Distutils2 +.. _PEP 426: http://legacy.python.org/dev/peps/pep-0426/ +.. _OpenStack: https://www.openstack.org/ + + + diff --git a/tests/packagedcode/data/pypi/metadata/v21/PKG-INFO-expected.json b/tests/packagedcode/data/pypi/metadata/v21/PKG-INFO-expected.json new file mode 100644 index 00000000000..158cb6ee1b0 --- /dev/null +++ b/tests/packagedcode/data/pypi/metadata/v21/PKG-INFO-expected.json @@ -0,0 +1,61 @@ +{ + "type": "pypi", + "namespace": null, + "name": "pbr", + "version": "4.0.1", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Python Build Reasonableness\nIntroduction\n============\n\n.. image:: https://img.shields.io/pypi/v/pbr.svg\n :target: https://pypi.python.org/pypi/pbr/\n :alt: Latest Version\n\n.. image:: https://img.shields.io/pypi/dm/pbr.svg\n :target: https://pypi.python.org/pypi/pbr/\n :alt: Downloads\n\nPBR is a library that injects some useful and sensible default behaviors\ninto your setuptools run. It started off life as the chunks of code that\nwere copied between all of the `OpenStack`_ projects. Around the time that\nOpenStack hit 18 different projects each with at least 3 active branches,\nit seemed like a good time to make that code into a proper reusable library.\n\nPBR is only mildly configurable. The basic idea is that there's a decent\nway to run things and if you do, you should reap the rewards, because then\nit's simple and repeatable. If you want to do things differently, cool! But\nyou've already got the power of Python at your fingertips, so you don't\nreally need PBR.\n\nPBR builds on top of the work that `d2to1`_ started to provide for declarative\nconfiguration. `d2to1`_ is itself an implementation of the ideas behind\n`distutils2`_. Although `distutils2`_ is now abandoned in favor of work towards\n`PEP 426`_ and Metadata 2.0, declarative config is still a great idea and\nspecifically important in trying to distribute setup code as a library\nwhen that library itself will alter how the setup is processed. As Metadata\n2.0 and other modern Python packaging PEPs come out, PBR aims to support\nthem as quickly as possible.\n\n* License: Apache License, Version 2.0\n* Documentation: https://docs.openstack.org/pbr/latest/\n* Source: https://git.openstack.org/cgit/openstack-dev/pbr\n* Bugs: https://bugs.launchpad.net/pbr\n* Change Log: https://docs.openstack.org/pbr/latest/user/history.html\n\n.. _d2to1: https://pypi.python.org/pypi/d2to1\n.. _distutils2: https://pypi.python.org/pypi/Distutils2\n.. _PEP 426: http://legacy.python.org/dev/peps/pep-0426/\n.. _OpenStack: https://www.openstack.org/", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "OpenStack", + "email": "openstack-dev@lists.openstack.org", + "url": null + } + ], + "keywords": [ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Environment :: OpenStack", + "Intended Audience :: Developers", + "Intended Audience :: Information Technology", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5" + ], + "homepage_url": "https://docs.openstack.org/pbr/latest/", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": "Bug Tracker, https://bugs.launchpad.net/pbr/", + "code_view_url": "Source Code, https://git.openstack.org/cgit/openstack-dev/pbr/", + "vcs_url": null, + "copyright": null, + "license_expression": "apache-2.0", + "declared_license": { + "classifiers": [ + "License :: OSI Approved :: Apache Software License" + ] + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/pbr@4.0.1", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/pbr/pbr-4.0.1.tar.gz", + "api_data_url": "https://pypi.org/pypi/pbr/4.0.1/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/package/DESCRIPTION.rst b/tests/packagedcode/data/pypi/package/DESCRIPTION.rst deleted file mode 100644 index 2e2607dc8c0..00000000000 --- a/tests/packagedcode/data/pypi/package/DESCRIPTION.rst +++ /dev/null @@ -1,18 +0,0 @@ -Six is a Python 2 and 3 compatibility library. It provides utility functions -for smoothing over the differences between the Python versions with the goal of -writing Python code that is compatible on both Python versions. See the -documentation for more information on what is provided. - -Six supports every Python version since 2.6. It is contained in only one Python -file, so it can be easily copied into your project. (The copyright and license -notice must be retained.) - -Online documentation is at https://pythonhosted.org/six/. - -Bugs can be reported to https://bitbucket.org/gutworth/six. The code can also -be found there. - -For questions about six or porting in general, email the python-porting mailing -list: https://mail.python.org/mailman/listinfo/python-porting - - diff --git a/tests/packagedcode/data/pypi/package/PKG-INFO b/tests/packagedcode/data/pypi/package/PKG-INFO deleted file mode 100644 index 0bf271985db..00000000000 --- a/tests/packagedcode/data/pypi/package/PKG-INFO +++ /dev/null @@ -1,10 +0,0 @@ -Metadata-Version: 1.0 -Name: TicketImport -Version: 0.7a -Summary: Import CSV and Excel files -Home-page: http://nexb.com -Author: Francois Granade -Author-email: fg@nexb.com -License: BSD -Description: UNKNOWN -Platform: UNKNOWN diff --git a/tests/packagedcode/data/pypi/package/metadata.json b/tests/packagedcode/data/pypi/package/metadata.json deleted file mode 100644 index dcfbdb299c1..00000000000 --- a/tests/packagedcode/data/pypi/package/metadata.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "generator": "bdist_wheel (0.26.0)", - "summary": "Python 2 and 3 compatibility utilities", - "classifiers": [ - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3", - "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities" - ], - "extensions": { - "python.details": { - "project_urls": { - "Home": "http://pypi.python.org/pypi/six/" - }, - "contacts": [ - { - "email": "benjamin@python.org", - "name": "Benjamin Peterson", - "role": "author" - } - ], - "document_names": { - "description": "DESCRIPTION.rst" - } - } - }, - "license": "MIT", - "metadata_version": "2.0", - "name": "six", - "version": "1.10.0" -} diff --git a/tests/packagedcode/data/pypi/pipfile.lock/sample1/output.expected.json b/tests/packagedcode/data/pypi/pipfile.lock/sample1/Pipfile.lock-expected.json similarity index 100% rename from tests/packagedcode/data/pypi/pipfile.lock/sample1/output.expected.json rename to tests/packagedcode/data/pypi/pipfile.lock/sample1/Pipfile.lock-expected.json diff --git a/tests/packagedcode/data/pypi/pipfile.lock/sample2/output.expected.json b/tests/packagedcode/data/pypi/pipfile.lock/sample2/Pipfile.lock-expected.json similarity index 100% rename from tests/packagedcode/data/pypi/pipfile.lock/sample2/output.expected.json rename to tests/packagedcode/data/pypi/pipfile.lock/sample2/Pipfile.lock-expected.json diff --git a/tests/packagedcode/data/pypi/pipfile.lock/sample3/output.expected.json b/tests/packagedcode/data/pypi/pipfile.lock/sample3/Pipfile.lock-expected.json similarity index 100% rename from tests/packagedcode/data/pypi/pipfile.lock/sample3/output.expected.json rename to tests/packagedcode/data/pypi/pipfile.lock/sample3/Pipfile.lock-expected.json diff --git a/tests/packagedcode/data/pypi/pipfile.lock/sample4/output.expected.json b/tests/packagedcode/data/pypi/pipfile.lock/sample4/Pipfile.lock-expected.json similarity index 100% rename from tests/packagedcode/data/pypi/pipfile.lock/sample4/output.expected.json rename to tests/packagedcode/data/pypi/pipfile.lock/sample4/Pipfile.lock-expected.json diff --git a/tests/packagedcode/data/pypi/pipfile.lock/sample5/output.expected.json b/tests/packagedcode/data/pypi/pipfile.lock/sample5/Pipfile.lock-expected.json similarity index 100% rename from tests/packagedcode/data/pypi/pipfile.lock/sample5/output.expected.json rename to tests/packagedcode/data/pypi/pipfile.lock/sample5/Pipfile.lock-expected.json diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample1/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/basic/output.expected.json similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample1/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/basic/output.expected.json diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample1/requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/basic/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample1/requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/basic/requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample17/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/comments_and_empties/output.expected.json similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample17/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/comments_and_empties/output.expected.json diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample17/requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/comments_and_empties/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample17/requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/comments_and_empties/requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample9/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/complex/output.expected.json similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample9/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/complex/output.expected.json diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample9/requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/complex/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample9/requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/complex/requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample6/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/dev/output.expected.json similarity index 97% rename from tests/packagedcode/data/pypi/requirements_txt/sample6/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/dev/output.expected.json index 2b98ed36c62..a65ec662340 100644 --- a/tests/packagedcode/data/pypi/requirements_txt/sample6/output.expected.json +++ b/tests/packagedcode/data/pypi/requirements_txt/dev/output.expected.json @@ -44,7 +44,7 @@ }, { "purl": "pkg:pypi/regex", - "requirement": null, + "requirement": "regex", "scope": "dependencies", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample3/requirements-dev.txt b/tests/packagedcode/data/pypi/requirements_txt/dev/requirements-dev.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample3/requirements-dev.txt rename to tests/packagedcode/data/pypi/requirements_txt/dev/requirements-dev.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample11/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/double_extras/output.expected.json similarity index 97% rename from tests/packagedcode/data/pypi/requirements_txt/sample11/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/double_extras/output.expected.json index 99e42e003a4..4da7f11a39d 100644 --- a/tests/packagedcode/data/pypi/requirements_txt/sample11/output.expected.json +++ b/tests/packagedcode/data/pypi/requirements_txt/double_extras/output.expected.json @@ -36,7 +36,7 @@ }, { "purl": "pkg:pypi/fizzy", - "requirement": null, + "requirement": "Fizzy", "scope": "dependencies", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample11/requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/double_extras/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample11/requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/double_extras/requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample14/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/editable/output.expected.json similarity index 96% rename from tests/packagedcode/data/pypi/requirements_txt/sample14/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/editable/output.expected.json index 98992efb56a..eaa89d96815 100644 --- a/tests/packagedcode/data/pypi/requirements_txt/sample14/output.expected.json +++ b/tests/packagedcode/data/pypi/requirements_txt/editable/output.expected.json @@ -25,7 +25,7 @@ "declared_license": null, "notice_text": null, "root_path": null, - "dependencies": null, + "dependencies": [], "contains_source_code": null, "source_packages": [], "purl": null, diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample10/requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/editable/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample10/requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/editable/requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample8/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/eol_comment/output.expected.json similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample8/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/eol_comment/output.expected.json diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample8/requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/eol_comment/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample8/requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/eol_comment/requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample10/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/local_paths_and_files/output.expected.json similarity index 96% rename from tests/packagedcode/data/pypi/requirements_txt/sample10/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/local_paths_and_files/output.expected.json index 98992efb56a..eaa89d96815 100644 --- a/tests/packagedcode/data/pypi/requirements_txt/sample10/output.expected.json +++ b/tests/packagedcode/data/pypi/requirements_txt/local_paths_and_files/output.expected.json @@ -25,7 +25,7 @@ "declared_license": null, "notice_text": null, "root_path": null, - "dependencies": null, + "dependencies": [], "contains_source_code": null, "source_packages": [], "purl": null, diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample14/requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/local_paths_and_files/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample14/requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/local_paths_and_files/requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample18/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/many_specs/output.expected.json similarity index 92% rename from tests/packagedcode/data/pypi/requirements_txt/sample18/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/many_specs/output.expected.json index fe0938dad3d..bc699561bb6 100644 --- a/tests/packagedcode/data/pypi/requirements_txt/sample18/output.expected.json +++ b/tests/packagedcode/data/pypi/requirements_txt/many_specs/output.expected.json @@ -27,12 +27,12 @@ "root_path": null, "dependencies": [ { - "purl": "pkg:pypi/pickything@2.4c1", + "purl": "pkg:pypi/pickything", "requirement": "!=1.9.6,<1.6,<2.0a0,==2.4c1,>1.9", "scope": "dependencies", "is_runtime": true, "is_optional": false, - "is_resolved": true + "is_resolved": false } ], "contains_source_code": null, diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample18/requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/many_specs/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample18/requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/many_specs/requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample16/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/mixed/output.expected.json similarity index 95% rename from tests/packagedcode/data/pypi/requirements_txt/sample16/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/mixed/output.expected.json index 15d9cd16e51..0388d74496c 100644 --- a/tests/packagedcode/data/pypi/requirements_txt/sample16/output.expected.json +++ b/tests/packagedcode/data/pypi/requirements_txt/mixed/output.expected.json @@ -36,7 +36,7 @@ }, { "purl": "pkg:pypi/numpy", - "requirement": null, + "requirement": "numpy", "scope": "dependencies", "is_runtime": true, "is_optional": false, @@ -44,7 +44,7 @@ }, { "purl": "pkg:pypi/docparser", - "requirement": null, + "requirement": "DocParser", "scope": "dependencies", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample16/requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/mixed/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample16/requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/mixed/requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample2/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/pinned/output.expected.json similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample2/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/pinned/output.expected.json diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample2/sample-requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/pinned/sample-requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample2/sample-requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/pinned/sample-requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample12/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/repeated/output.expected.json similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample12/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/repeated/output.expected.json diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample12/requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/repeated/requirements.txt similarity index 50% rename from tests/packagedcode/data/pypi/requirements_txt/sample12/requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/repeated/requirements.txt index d49b4140ae4..1d5b21b397a 100644 --- a/tests/packagedcode/data/pypi/requirements_txt/sample12/requirements.txt +++ b/tests/packagedcode/data/pypi/requirements_txt/repeated/requirements.txt @@ -1,2 +1,2 @@ -test>>1.2.0 +test==1.2.0 test=>1.2.0 diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample4/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/requirements_in/output.expected.json similarity index 94% rename from tests/packagedcode/data/pypi/requirements_txt/sample4/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/requirements_in/output.expected.json index ace4248299d..9d2a627ffc2 100644 --- a/tests/packagedcode/data/pypi/requirements_txt/sample4/output.expected.json +++ b/tests/packagedcode/data/pypi/requirements_txt/requirements_in/output.expected.json @@ -28,7 +28,7 @@ "dependencies": [ { "purl": "pkg:pypi/setuptools", - "requirement": null, + "requirement": "setuptools", "scope": "dependencies", "is_runtime": true, "is_optional": false, @@ -36,7 +36,7 @@ }, { "purl": "pkg:pypi/nose", - "requirement": null, + "requirement": "nose", "scope": "dependencies", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample4/requirements.in b/tests/packagedcode/data/pypi/requirements_txt/requirements_in/requirements.in similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample4/requirements.in rename to tests/packagedcode/data/pypi/requirements_txt/requirements_in/requirements.in diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample19/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/sample19/output.expected.json deleted file mode 100644 index 98992efb56a..00000000000 --- a/tests/packagedcode/data/pypi/requirements_txt/sample19/output.expected.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "type": "pypi", - "namespace": null, - "name": null, - "version": null, - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": null, - "release_date": null, - "parties": [], - "keywords": [], - "homepage_url": null, - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": null, - "notice_text": null, - "root_path": null, - "dependencies": null, - "contains_source_code": null, - "source_packages": [], - "purl": null, - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": null -} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample20/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/sample20/output.expected.json deleted file mode 100644 index 98992efb56a..00000000000 --- a/tests/packagedcode/data/pypi/requirements_txt/sample20/output.expected.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "type": "pypi", - "namespace": null, - "name": null, - "version": null, - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": null, - "release_date": null, - "parties": [], - "keywords": [], - "homepage_url": null, - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": null, - "notice_text": null, - "root_path": null, - "dependencies": null, - "contains_source_code": null, - "source_packages": [], - "purl": null, - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": null -} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample21/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/sample21/output.expected.json deleted file mode 100644 index 98992efb56a..00000000000 --- a/tests/packagedcode/data/pypi/requirements_txt/sample21/output.expected.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "type": "pypi", - "namespace": null, - "name": null, - "version": null, - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": null, - "release_date": null, - "parties": [], - "keywords": [], - "homepage_url": null, - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": null, - "notice_text": null, - "root_path": null, - "dependencies": null, - "contains_source_code": null, - "source_packages": [], - "purl": null, - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": null -} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample3/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/sample3/output.expected.json deleted file mode 100644 index 2b98ed36c62..00000000000 --- a/tests/packagedcode/data/pypi/requirements_txt/sample3/output.expected.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "type": "pypi", - "namespace": null, - "name": null, - "version": null, - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": null, - "release_date": null, - "parties": [], - "keywords": [], - "homepage_url": null, - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": null, - "notice_text": null, - "root_path": null, - "dependencies": [ - { - "purl": "pkg:pypi/prompt-toolkit", - "requirement": ">=1.0.14", - "scope": "dependencies", - "is_runtime": true, - "is_optional": false, - "is_resolved": false - }, - { - "purl": "pkg:pypi/pygments@2.2.0", - "requirement": "==2.2.0", - "scope": "dependencies", - "is_runtime": true, - "is_optional": false, - "is_resolved": true - }, - { - "purl": "pkg:pypi/regex", - "requirement": null, - "scope": "dependencies", - "is_runtime": true, - "is_optional": false, - "is_resolved": false - } - ], - "contains_source_code": null, - "source_packages": [], - "purl": null, - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": null -} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample5/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/sample5/output.expected.json deleted file mode 100644 index 2b98ed36c62..00000000000 --- a/tests/packagedcode/data/pypi/requirements_txt/sample5/output.expected.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "type": "pypi", - "namespace": null, - "name": null, - "version": null, - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": null, - "release_date": null, - "parties": [], - "keywords": [], - "homepage_url": null, - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": null, - "notice_text": null, - "root_path": null, - "dependencies": [ - { - "purl": "pkg:pypi/prompt-toolkit", - "requirement": ">=1.0.14", - "scope": "dependencies", - "is_runtime": true, - "is_optional": false, - "is_resolved": false - }, - { - "purl": "pkg:pypi/pygments@2.2.0", - "requirement": "==2.2.0", - "scope": "dependencies", - "is_runtime": true, - "is_optional": false, - "is_resolved": true - }, - { - "purl": "pkg:pypi/regex", - "requirement": null, - "scope": "dependencies", - "is_runtime": true, - "is_optional": false, - "is_resolved": false - } - ], - "contains_source_code": null, - "source_packages": [], - "purl": null, - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": null -} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample5/requirements-test.txt b/tests/packagedcode/data/pypi/requirements_txt/sample5/requirements-test.txt deleted file mode 100644 index 1b1a895d2c1..00000000000 --- a/tests/packagedcode/data/pypi/requirements_txt/sample5/requirements-test.txt +++ /dev/null @@ -1,3 +0,0 @@ -prompt_toolkit>=1.0.14 -Pygments==2.2.0 -regex diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample6/requirements-dev.in b/tests/packagedcode/data/pypi/requirements_txt/sample6/requirements-dev.in deleted file mode 100644 index 1b1a895d2c1..00000000000 --- a/tests/packagedcode/data/pypi/requirements_txt/sample6/requirements-dev.in +++ /dev/null @@ -1,3 +0,0 @@ -prompt_toolkit>=1.0.14 -Pygments==2.2.0 -regex diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample7/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/sample7/output.expected.json deleted file mode 100644 index a5a15d0c959..00000000000 --- a/tests/packagedcode/data/pypi/requirements_txt/sample7/output.expected.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "type": "pypi", - "namespace": null, - "name": null, - "version": null, - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": null, - "release_date": null, - "parties": [], - "keywords": [], - "homepage_url": null, - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": null, - "notice_text": null, - "root_path": null, - "dependencies": [ - { - "purl": "pkg:pypi/aiohttp@3.6.2", - "requirement": "==3.6.2", - "scope": "dependencies", - "is_runtime": true, - "is_optional": false, - "is_resolved": true - }, - { - "purl": "pkg:pypi/async-timeout@3.0.1", - "requirement": "==3.0.1", - "scope": "dependencies", - "is_runtime": true, - "is_optional": false, - "is_resolved": true - }, - { - "purl": "pkg:pypi/attrs@19.3.0", - "requirement": "==19.3.0", - "scope": "dependencies", - "is_runtime": true, - "is_optional": false, - "is_resolved": true - } - ], - "contains_source_code": null, - "source_packages": [], - "purl": null, - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": null -} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample7/requirements-test.in b/tests/packagedcode/data/pypi/requirements_txt/sample7/requirements-test.in deleted file mode 100644 index a02822196e7..00000000000 --- a/tests/packagedcode/data/pypi/requirements_txt/sample7/requirements-test.in +++ /dev/null @@ -1,3 +0,0 @@ -aiohttp==3.6.2 -async-timeout==3.0.1 -attrs==19.3.0 diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample15/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/urls_wth_checksums/output.expected.json similarity index 96% rename from tests/packagedcode/data/pypi/requirements_txt/sample15/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/urls_wth_checksums/output.expected.json index 98992efb56a..eaa89d96815 100644 --- a/tests/packagedcode/data/pypi/requirements_txt/sample15/output.expected.json +++ b/tests/packagedcode/data/pypi/requirements_txt/urls_wth_checksums/output.expected.json @@ -25,7 +25,7 @@ "declared_license": null, "notice_text": null, "root_path": null, - "dependencies": null, + "dependencies": [], "contains_source_code": null, "source_packages": [], "purl": null, diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample15/requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/urls_wth_checksums/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample15/requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/urls_wth_checksums/requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample13/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/vcs-git/output.expected.json similarity index 96% rename from tests/packagedcode/data/pypi/requirements_txt/sample13/output.expected.json rename to tests/packagedcode/data/pypi/requirements_txt/vcs-git/output.expected.json index 98992efb56a..eaa89d96815 100644 --- a/tests/packagedcode/data/pypi/requirements_txt/sample13/output.expected.json +++ b/tests/packagedcode/data/pypi/requirements_txt/vcs-git/output.expected.json @@ -25,7 +25,7 @@ "declared_license": null, "notice_text": null, "root_path": null, - "dependencies": null, + "dependencies": [], "contains_source_code": null, "source_packages": [], "purl": null, diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample21/vcs_git_requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/vcs-git/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample21/vcs_git_requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/vcs-git/requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/vcs_editable/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/vcs_editable/output.expected.json new file mode 100644 index 00000000000..eaa89d96815 --- /dev/null +++ b/tests/packagedcode/data/pypi/requirements_txt/vcs_editable/output.expected.json @@ -0,0 +1,35 @@ +{ + "type": "pypi", + "namespace": null, + "name": null, + "version": null, + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "release_date": null, + "parties": [], + "keywords": [], + "homepage_url": null, + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": null, + "declared_license": null, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": null, + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample19/requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/vcs_editable/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample19/requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/vcs_editable/requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/vcs_eggs/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/vcs_eggs/output.expected.json new file mode 100644 index 00000000000..eaa89d96815 --- /dev/null +++ b/tests/packagedcode/data/pypi/requirements_txt/vcs_eggs/output.expected.json @@ -0,0 +1,35 @@ +{ + "type": "pypi", + "namespace": null, + "name": null, + "version": null, + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "release_date": null, + "parties": [], + "keywords": [], + "homepage_url": null, + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": null, + "declared_license": null, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": null, + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample13/requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/vcs_eggs/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample13/requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/vcs_eggs/requirements.txt diff --git a/tests/packagedcode/data/pypi/requirements_txt/vcs_extras_require/output.expected.json b/tests/packagedcode/data/pypi/requirements_txt/vcs_extras_require/output.expected.json new file mode 100644 index 00000000000..eaa89d96815 --- /dev/null +++ b/tests/packagedcode/data/pypi/requirements_txt/vcs_extras_require/output.expected.json @@ -0,0 +1,35 @@ +{ + "type": "pypi", + "namespace": null, + "name": null, + "version": null, + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "release_date": null, + "parties": [], + "keywords": [], + "homepage_url": null, + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": null, + "declared_license": null, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": null, + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/requirements_txt/sample20/vcs_git_extras_require_requirements.txt b/tests/packagedcode/data/pypi/requirements_txt/vcs_extras_require/requirements.txt similarity index 100% rename from tests/packagedcode/data/pypi/requirements_txt/sample20/vcs_git_extras_require_requirements.txt rename to tests/packagedcode/data/pypi/requirements_txt/vcs_extras_require/requirements.txt diff --git a/tests/packagedcode/data/pypi/setup.py/arpy_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/arpy_setup.py-expected.json index 4ff1239b227..d106678c405 100644 --- a/tests/packagedcode/data/pypi/setup.py/arpy_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/arpy_setup.py-expected.json @@ -13,8 +13,8 @@ "type": "person", "role": "author", "name": "Stanis\u0142aw Pitucha", - "email": "viraptor@gmail.com", - "url": "http://bitbucket.org/viraptor/arpy" + "email": null, + "url": null } ], "keywords": [], @@ -31,8 +31,7 @@ "copyright": null, "license_expression": "bsd-simplified", "declared_license": { - "license": "Simplified BSD", - "classifiers": [] + "license": "Simplified BSD" }, "notice_text": null, "root_path": null, @@ -40,7 +39,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/arpy@0.1.1", - "repository_homepage_url": "https://pypi.org/project/arpy", - "repository_download_url": "https://pypi.io/packages/source/a/arpy/arpy-0.1.1.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/arpy/0.1.1/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/a/arpy/arpy-0.1.1.tar.gz", + "api_data_url": "https://pypi.org/pypi/arpy/0.1.1/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/boolean2_py_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/boolean2_py_setup.py-expected.json index 1e43a5983dd..e1f8de07ed1 100644 --- a/tests/packagedcode/data/pypi/setup.py/boolean2_py_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/boolean2_py_setup.py-expected.json @@ -13,11 +13,15 @@ "type": "person", "role": "author", "name": "Sebastian Kraemer", - "email": "basti.kr@gmail.com", - "url": "https://github.com/bastikr/boolean.py" + "email": null, + "url": null } ], "keywords": [ + "boolean expression", + "boolean algebra", + "logic", + "expression parser", "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Operating System :: OS Independent", @@ -53,7 +57,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/boolean.py@1.2", - "repository_homepage_url": "https://pypi.org/project/boolean.py", - "repository_download_url": "https://pypi.io/packages/source/b/boolean.py/boolean.py-1.2.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/boolean.py/1.2/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/b/boolean.py/boolean.py-1.2.tar.gz", + "api_data_url": "https://pypi.org/pypi/boolean.py/1.2/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/container_check_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/container_check_setup.py-expected.json index b792457b2e2..19cd5a33eef 100644 --- a/tests/packagedcode/data/pypi/setup.py/container_check_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/container_check_setup.py-expected.json @@ -13,11 +13,12 @@ "type": "person", "role": "author", "name": "Ian Main", - "email": "imain@redhat.com", - "url": "https://github.com/imain/container-check" + "email": null, + "url": null } ], "keywords": [ + "containers update rpm yum", "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Topic :: System :: Archiving :: Packaging", @@ -52,7 +53,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/container-check@1.0.6", - "repository_homepage_url": "https://pypi.org/project/container-check", - "repository_download_url": "https://pypi.io/packages/source/c/container-check/container-check-1.0.6.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/container-check/1.0.6/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/c/container-check/container-check-1.0.6.tar.gz", + "api_data_url": "https://pypi.org/pypi/container-check/1.0.6/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/fb303_py_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/fb303_py_setup.py-expected.json index d6e524d85dd..b369365b5c9 100644 --- a/tests/packagedcode/data/pypi/setup.py/fb303_py_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/fb303_py_setup.py-expected.json @@ -15,10 +15,8 @@ "name": [ "Thrift Developers" ], - "email": [ - "dev@thrift.apache.org" - ], - "url": "http://thrift.apache.org" + "email": null, + "url": null } ], "keywords": [ @@ -43,8 +41,7 @@ "copyright": null, "license_expression": "apache-2.0", "declared_license": { - "license": "Apache License 2.0", - "classifiers": [] + "license": "Apache License 2.0" }, "notice_text": null, "root_path": null, @@ -52,7 +49,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/thrift-fb303@0.10.0", - "repository_homepage_url": "https://pypi.org/project/thrift_fb303", - "repository_download_url": "https://pypi.io/packages/source/t/thrift_fb303/thrift_fb303-0.10.0.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/thrift_fb303/0.10.0/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/t/thrift_fb303/thrift_fb303-0.10.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/thrift_fb303/0.10.0/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/frell_src_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/frell_src_setup.py-expected.json index 12131a1e769..56ff874ca28 100644 --- a/tests/packagedcode/data/pypi/setup.py/frell_src_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/frell_src_setup.py-expected.json @@ -13,7 +13,7 @@ "type": "person", "role": "author", "name": "Brett Smith", - "email": "bc.smith@sas.com", + "email": null, "url": null } ], @@ -31,8 +31,7 @@ "copyright": null, "license_expression": "apache-2.0", "declared_license": { - "license": "Apache License 2.0", - "classifiers": [] + "license": "Apache License 2.0" }, "notice_text": null, "root_path": null, @@ -40,7 +39,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/%40name%40", - "repository_homepage_url": "https://pypi.org/project/@NAME@", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", "repository_download_url": null, - "api_data_url": "http://pypi.python.org/pypi/@NAME@/json" + "api_data_url": "https://pypi.org/pypi/@NAME@/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/gyp_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/gyp_setup.py-expected.json index 799860c7e88..5a758e008ab 100644 --- a/tests/packagedcode/data/pypi/setup.py/gyp_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/gyp_setup.py-expected.json @@ -13,8 +13,8 @@ "type": "person", "role": "author", "name": "Chromium Authors", - "email": "chromium-dev@googlegroups.com", - "url": "http://code.google.com/p/gyp" + "email": null, + "url": null } ], "keywords": [], @@ -30,17 +30,14 @@ "vcs_url": null, "copyright": null, "license_expression": null, - "declared_license": { - "license": null, - "classifiers": [] - }, + "declared_license": {}, "notice_text": null, "root_path": null, "dependencies": [], "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/gyp@0.1", - "repository_homepage_url": "https://pypi.org/project/gyp", - "repository_download_url": "https://pypi.io/packages/source/g/gyp/gyp-0.1.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/gyp/0.1/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/g/gyp/gyp-0.1.tar.gz", + "api_data_url": "https://pypi.org/pypi/gyp/0.1/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/interlap_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/interlap_setup.py-expected.json index 0587785592e..bab7a2f8082 100644 --- a/tests/packagedcode/data/pypi/setup.py/interlap_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/interlap_setup.py-expected.json @@ -13,8 +13,8 @@ "type": "person", "role": "author", "name": "Brent S Pedersen", - "email": "bpederse@gmail.com", - "url": "http://brentp.github.io/interlap" + "email": null, + "url": null } ], "keywords": [ @@ -53,7 +53,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/interlap", - "repository_homepage_url": "https://pypi.org/project/interlap", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", "repository_download_url": null, - "api_data_url": "http://pypi.python.org/pypi/interlap/json" + "api_data_url": "https://pypi.org/pypi/interlap/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/mb_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/mb_setup.py-expected.json index c806e017aa2..e0a7743e534 100644 --- a/tests/packagedcode/data/pypi/setup.py/mb_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/mb_setup.py-expected.json @@ -13,8 +13,8 @@ "type": "person", "role": "author", "name": "MirrorBrain project", - "email": "info@mirrorbrain.org", - "url": "http://mirrorbrain.org/" + "email": null, + "url": null } ], "keywords": [], @@ -31,8 +31,7 @@ "copyright": null, "license_expression": "gpl-2.0", "declared_license": { - "license": "GPLv2", - "classifiers": [] + "license": "GPLv2" }, "notice_text": null, "root_path": null, @@ -40,7 +39,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/mb@2.19.0", - "repository_homepage_url": "https://pypi.org/project/mb", - "repository_download_url": "https://pypi.io/packages/source/m/mb/mb-2.19.0.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/mb/2.19.0/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/m/mb/mb-2.19.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/mb/2.19.0/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/ntfs_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/ntfs_setup.py-expected.json index 4be74784b2c..9f7db97fbba 100644 --- a/tests/packagedcode/data/pypi/setup.py/ntfs_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/ntfs_setup.py-expected.json @@ -13,11 +13,12 @@ "type": "person", "role": "author", "name": "Siddharth Agarwal", - "email": "sid.bugzilla@gmail.com", - "url": "https://github.com/sid0/ntfs" + "email": null, + "url": null } ], "keywords": [ + "windows ntfs hardlink junction", "Intended Audience :: Developers", "Topic :: Software Development :: Libraries :: Python Modules", "Programming Language :: Python :: 2.5", @@ -49,7 +50,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/ntfsutils", - "repository_homepage_url": "https://pypi.org/project/ntfsutils", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", "repository_download_url": null, - "api_data_url": "http://pypi.python.org/pypi/ntfsutils/json" + "api_data_url": "https://pypi.org/pypi/ntfsutils/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/nvchecker_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/nvchecker_setup.py-expected.json index c40fb28f0cf..4493e6997a2 100644 --- a/tests/packagedcode/data/pypi/setup.py/nvchecker_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/nvchecker_setup.py-expected.json @@ -13,11 +13,12 @@ "type": "person", "role": "author", "name": "lilydjwg", - "email": "lilydjwg@gmail.com", - "url": "https://github.com/lilydjwg/nvchecker" + "email": null, + "url": null } ], "keywords": [ + "new version build check", "Development Status :: 4 - Beta", "Environment :: Console", "Intended Audience :: Developers", @@ -59,7 +60,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/nvchecker", - "repository_homepage_url": "https://pypi.org/project/nvchecker", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", "repository_download_url": null, - "api_data_url": "http://pypi.python.org/pypi/nvchecker/json" + "api_data_url": "https://pypi.org/pypi/nvchecker/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/oi_agents_common_code_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/oi_agents_common_code_setup.py-expected.json index a6e36b38364..bbe84b8124d 100644 --- a/tests/packagedcode/data/pypi/setup.py/oi_agents_common_code_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/oi_agents_common_code_setup.py-expected.json @@ -13,11 +13,12 @@ "type": "person", "role": "author", "name": "__author__", - "email": "juga@riseup.net", - "url": "https://lab.openintegrity.org/agents/agents-common-code" + "email": null, + "url": null } ], "keywords": [ + "agents development utils", "Development Status :: 3 - Alpha", "Environment :: Console", "Intended Audience :: Developers", @@ -51,7 +52,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/agents-common", - "repository_homepage_url": "https://pypi.org/project/agents_common", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", "repository_download_url": null, - "api_data_url": "http://pypi.python.org/pypi/agents_common/json" + "api_data_url": "https://pypi.org/pypi/agents_common/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/packageurl_python_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/packageurl_python_setup.py-expected.json index 3be6b52e177..780f402136c 100644 --- a/tests/packagedcode/data/pypi/setup.py/packageurl_python_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/packageurl_python_setup.py-expected.json @@ -14,10 +14,14 @@ "role": "author", "name": "the purl authors", "email": null, - "url": "https://github.com/package-url/packageurl-python" + "url": null } ], "keywords": [ + "package", + "url", + "package manager", + "package url", "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Operating System :: OS Independent", @@ -53,7 +57,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/packageurl-python@0.8.5", - "repository_homepage_url": "https://pypi.org/project/packageurl-python", - "repository_download_url": "https://pypi.io/packages/source/p/packageurl-python/packageurl-python-0.8.5.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/packageurl-python/0.8.5/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/packageurl-python/packageurl-python-0.8.5.tar.gz", + "api_data_url": "https://pypi.org/pypi/packageurl-python/0.8.5/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/pipdeptree_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/pipdeptree_setup.py-expected.json index cc8132aa7db..0b5f6f836f9 100644 --- a/tests/packagedcode/data/pypi/setup.py/pipdeptree_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/pipdeptree_setup.py-expected.json @@ -13,8 +13,8 @@ "type": "person", "role": "author", "name": "Vineet Naik", - "email": "naikvin@gmail.com", - "url": "https://github.com/naiquevin/pipdeptree" + "email": null, + "url": null } ], "keywords": [ @@ -52,7 +52,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/pipdeptree", - "repository_homepage_url": "https://pypi.org/project/pipdeptree", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", "repository_download_url": null, - "api_data_url": "http://pypi.python.org/pypi/pipdeptree/json" + "api_data_url": "https://pypi.org/pypi/pipdeptree/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/pydep_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/pydep_setup.py-expected.json index fdf9e6d8f6a..6fa04d05a0e 100644 --- a/tests/packagedcode/data/pypi/setup.py/pydep_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/pydep_setup.py-expected.json @@ -14,7 +14,7 @@ "role": "author", "name": "Beyang Liu", "email": null, - "url": "http://github.com/sourcegraph/pydep" + "url": null } ], "keywords": [], @@ -30,17 +30,14 @@ "vcs_url": null, "copyright": null, "license_expression": null, - "declared_license": { - "license": null, - "classifiers": [] - }, + "declared_license": {}, "notice_text": null, "root_path": null, "dependencies": [], "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/pydep@0.0", - "repository_homepage_url": "https://pypi.org/project/pydep", - "repository_download_url": "https://pypi.io/packages/source/p/pydep/pydep-0.0.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/pydep/0.0/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/pydep/pydep-0.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/pydep/0.0/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/pyrpm_2_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/pyrpm_2_setup.py-expected.json index 7e560ccb585..5ffcb9965ff 100644 --- a/tests/packagedcode/data/pypi/setup.py/pyrpm_2_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/pyrpm_2_setup.py-expected.json @@ -13,8 +13,8 @@ "type": "person", "role": "author", "name": "Stefan Richter", - "email": "stefan@02strich.de", - "url": "https://github.com/02strich/pyrpm" + "email": null, + "url": null } ], "keywords": [ @@ -54,7 +54,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/pyrpm-02strich@0.5.3", - "repository_homepage_url": "https://pypi.org/project/pyrpm-02strich", - "repository_download_url": "https://pypi.io/packages/source/p/pyrpm-02strich/pyrpm-02strich-0.5.3.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/pyrpm-02strich/0.5.3/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/pyrpm-02strich/pyrpm-02strich-0.5.3.tar.gz", + "api_data_url": "https://pypi.org/pypi/pyrpm-02strich/0.5.3/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/python_publicsuffix_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/python_publicsuffix_setup.py-expected.json index 9b5e50ba7cb..88ca5278ef0 100644 --- a/tests/packagedcode/data/pypi/setup.py/python_publicsuffix_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/python_publicsuffix_setup.py-expected.json @@ -13,7 +13,7 @@ "type": "person", "role": "author", "name": "Tomaz Solc", - "email": "tomaz.solc@tablix.org", + "email": null, "url": null } ], @@ -47,7 +47,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/publicsuffix@1.1.1", - "repository_homepage_url": "https://pypi.org/project/publicsuffix", - "repository_download_url": "https://pypi.io/packages/source/p/publicsuffix/publicsuffix-1.1.1.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/publicsuffix/1.1.1/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/publicsuffix/publicsuffix-1.1.1.tar.gz", + "api_data_url": "https://pypi.org/pypi/publicsuffix/1.1.1/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/repology_py_libversion_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/repology_py_libversion_setup.py-expected.json index 5dd12183a15..30471a27d23 100644 --- a/tests/packagedcode/data/pypi/setup.py/repology_py_libversion_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/repology_py_libversion_setup.py-expected.json @@ -13,8 +13,8 @@ "type": "person", "role": "author", "name": "Dmitry Marakasov", - "email": "amdmi3@amdmi3.ru", - "url": "https://github.com/repology/py-libversion" + "email": null, + "url": null } ], "keywords": [ @@ -52,7 +52,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/libversion", - "repository_homepage_url": "https://pypi.org/project/libversion", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", "repository_download_url": null, - "api_data_url": "http://pypi.python.org/pypi/libversion/json" + "api_data_url": "https://pypi.org/pypi/libversion/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/saneyaml_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/saneyaml_setup.py-expected.json index 3897ae52cd0..e302d949c83 100644 --- a/tests/packagedcode/data/pypi/setup.py/saneyaml_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/saneyaml_setup.py-expected.json @@ -13,11 +13,15 @@ "type": "person", "role": "author", "name": "AboutCode authors and others.", - "email": "info@nexb.com", - "url": "http://aboutcode.org" + "email": null, + "url": null } ], "keywords": [ + "yaml", + "block", + "flow", + "readable", "Development Status :: 4 - Beta", "Programming Language :: Python", "Programming Language :: Python :: 2", @@ -53,7 +57,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/saneyaml@0.2dev", - "repository_homepage_url": "https://pypi.org/project/saneyaml", - "repository_download_url": "https://pypi.io/packages/source/s/saneyaml/saneyaml-0.2dev.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/saneyaml/0.2dev/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/s/saneyaml/saneyaml-0.2dev.tar.gz", + "api_data_url": "https://pypi.org/pypi/saneyaml/0.2dev/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/setup.py-expected.json index da25bdae84c..7321a7eb40c 100644 --- a/tests/packagedcode/data/pypi/setup.py/setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/setup.py-expected.json @@ -13,11 +13,16 @@ "type": "person", "role": "author", "name": "ScanCode", - "email": "info@scancode.io", - "url": "https://github.com/nexB/scancode-toolkit" + "email": null, + "url": null } ], "keywords": [ + "license", + "filetype", + "urn", + "date", + "codec", "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Programming Language :: Python", @@ -49,7 +54,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/scancode-toolkit@1.5.0", - "repository_homepage_url": "https://pypi.org/project/scancode-toolkit", - "repository_download_url": "https://pypi.io/packages/source/s/scancode-toolkit/scancode-toolkit-1.5.0.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/scancode-toolkit/1.5.0/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/s/scancode-toolkit/scancode-toolkit-1.5.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/scancode-toolkit/1.5.0/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/setup.py-simple-expected.json b/tests/packagedcode/data/pypi/setup.py/setup.py-simple-expected.json new file mode 100644 index 00000000000..0f25f62eb88 --- /dev/null +++ b/tests/packagedcode/data/pypi/setup.py/setup.py-simple-expected.json @@ -0,0 +1,60 @@ +{ + "type": "pypi", + "namespace": null, + "name": "scancode-toolkit", + "version": "1.5.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "ScanCode is a tool to scan code for license, copyright and other interesting facts.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "ScanCode", + "email": "info@scancode.io", + "url": "https://github.com/nexB/scancode-toolkit" + } + ], + "keywords": [ + "license", + "filetype", + "urn", + "date", + "codec", + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Programming Language :: Python", + "Programming Language :: Python :: 2.7", + "Topic :: Utilities" + ], + "homepage_url": "https://github.com/nexB/scancode-toolkit", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": "(((apache-2.0 AND scancode-acknowledgment) AND cc0-1.0) AND unknown) AND apache-2.0 AND (free-unknown AND unknown)", + "declared_license": { + "license": "Apache-2.0 with ScanCode acknowledgment and CC0-1.0 and others", + "classifiers": [ + "License :: OSI Approved :: Apache Software License", + "License :: OSI Approved :: CC0" + ] + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/scancode-toolkit@1.5.0", + "repository_homepage_url": "https://pypi.org/project/scancode-toolkit", + "repository_download_url": "https://pypi.io/packages/source/s/scancode-toolkit/scancode-toolkit-1.5.0.tar.gz", + "api_data_url": "http://pypi.python.org/pypi/scancode-toolkit/1.5.0/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/setuppycheck_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/setuppycheck_setup.py-expected.json index 3b482b6de4a..c83882ba9c2 100644 --- a/tests/packagedcode/data/pypi/setup.py/setuppycheck_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/setuppycheck_setup.py-expected.json @@ -13,11 +13,13 @@ "type": "person", "role": "author", "name": "Marc Abramowitz", - "email": "msabramo@gmail.com", - "url": "https://github.com/msabramo/setuppycheck" + "email": null, + "url": null } ], - "keywords": [], + "keywords": [ + "setup.py pin dependencies" + ], "homepage_url": "https://github.com/msabramo/setuppycheck", "download_url": null, "size": null, @@ -31,8 +33,7 @@ "copyright": null, "license_expression": "mit", "declared_license": { - "license": "MIT", - "classifiers": [] + "license": "MIT" }, "notice_text": null, "root_path": null, @@ -40,7 +41,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/setuppycheck", - "repository_homepage_url": "https://pypi.org/project/setuppycheck", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", "repository_download_url": null, - "api_data_url": "http://pypi.python.org/pypi/setuppycheck/json" + "api_data_url": "https://pypi.org/pypi/setuppycheck/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/setup.py b/tests/packagedcode/data/pypi/setup.py/simple-setup.py similarity index 100% rename from tests/packagedcode/data/pypi/setup.py/setup.py rename to tests/packagedcode/data/pypi/setup.py/simple-setup.py diff --git a/tests/packagedcode/data/pypi/setup.py/url_py_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/url_py_setup.py-expected.json index be70d407790..18083010036 100644 --- a/tests/packagedcode/data/pypi/setup.py/url_py_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/url_py_setup.py-expected.json @@ -13,8 +13,8 @@ "type": "person", "role": "author", "name": "Dan Lecocq", - "email": "dan@seomoz.org", - "url": "http://github.com/nexB/url-py" + "email": null, + "url": null } ], "keywords": [ @@ -47,7 +47,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/urlpy@0.2.0.2", - "repository_homepage_url": "https://pypi.org/project/urlpy", - "repository_download_url": "https://pypi.io/packages/source/u/urlpy/urlpy-0.2.0.2.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/urlpy/0.2.0.2/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/u/urlpy/urlpy-0.2.0.2.tar.gz", + "api_data_url": "https://pypi.org/pypi/urlpy/0.2.0.2/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/venv_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/venv_setup.py-expected.json index dbf5e3b9451..413655fe51e 100644 --- a/tests/packagedcode/data/pypi/setup.py/venv_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/venv_setup.py-expected.json @@ -13,11 +13,12 @@ "type": "person", "role": "author", "name": "Ian Bicking", - "email": "ianb@colorstudy.com", - "url": "https://virtualenv.pypa.io/" + "email": null, + "url": null } ], "keywords": [ + "setuptools deployment installation distutils", "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Programming Language :: Python :: 2", @@ -52,7 +53,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/virtualenv", - "repository_homepage_url": "https://pypi.org/project/virtualenv", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", "repository_download_url": null, - "api_data_url": "http://pypi.python.org/pypi/virtualenv/json" + "api_data_url": "https://pypi.org/pypi/virtualenv/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/setup.py/xmltodict_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/xmltodict_setup.py-expected.json index fc9584c81ce..8fbec5c99f2 100644 --- a/tests/packagedcode/data/pypi/setup.py/xmltodict_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/xmltodict_setup.py-expected.json @@ -6,17 +6,9 @@ "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": null, + "description": "", "release_date": null, - "parties": [ - { - "type": "person", - "role": "author", - "name": null, - "email": "martinblech@gmail.com", - "url": "https://github.com/martinblech/xmltodict" - } - ], + "parties": [], "keywords": [ "Intended Audience :: Developers", "Operating System :: OS Independent", @@ -47,7 +39,6 @@ "copyright": null, "license_expression": "mit", "declared_license": { - "license": null, "classifiers": [ "License :: OSI Approved :: MIT License" ] @@ -58,7 +49,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/xmltodict", - "repository_homepage_url": "https://pypi.org/project/xmltodict", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", "repository_download_url": null, - "api_data_url": "http://pypi.python.org/pypi/xmltodict/json" + "api_data_url": "https://pypi.org/pypi/xmltodict/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpackage_source_parser-expected.json b/tests/packagedcode/data/pypi/unpackage_source_parser-expected.json deleted file mode 100644 index 2c75d4ff7d7..00000000000 --- a/tests/packagedcode/data/pypi/unpackage_source_parser-expected.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "type": "pypi", - "namespace": null, - "name": "TicketImport", - "version": "0.7a", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Import CSV and Excel files", - "release_date": null, - "parties": [ - { - "type": "person", - "role": "author", - "name": "Francois Granade", - "email": "fg@nexb.com", - "url": null - } - ], - "keywords": [], - "homepage_url": "http://nexb.com", - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": "unknown", - "declared_license": { - "license": "BSD" - }, - "notice_text": null, - "root_path": null, - "dependencies": [], - "contains_source_code": null, - "source_packages": [], - "purl": "pkg:pypi/ticketimport@0.7a", - "repository_homepage_url": "https://pypi.org/project/TicketImport", - "repository_download_url": "https://pypi.io/packages/source/T/TicketImport/TicketImport-0.7a.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/TicketImport/0.7a/json" -} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_sdist/develop-expected.json b/tests/packagedcode/data/pypi/unpacked_sdist/develop-expected.json new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info-METADATA-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info-METADATA-expected.json new file mode 100644 index 00000000000..9e70343b162 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info-METADATA-expected.json @@ -0,0 +1,63 @@ +{ + "type": "pypi", + "namespace": null, + "name": "pip", + "version": "20.2.2", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "The PyPA recommended tool for installing Python packages.\npip - The Python Package Installer\n==================================\n\n.. image:: https://img.shields.io/pypi/v/pip.svg\n :target: https://pypi.org/project/pip/\n\n.. image:: https://readthedocs.org/projects/pip/badge/?version=latest\n :target: https://pip.pypa.io/en/latest\n\npip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes.\n\nPlease take a look at our documentation for how to install and use pip:\n\n* `Installation`_\n* `Usage`_\n\nWe release updates regularly, with a new version every 3 months. Find more details in our documentation:\n\n* `Release notes`_\n* `Release process`_\n\nIn 2020, we're working on improvements to the heart of pip. Please `learn more and take our survey`_ to help us do it right.\n\nIf you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms:\n\n* `Issue tracking`_\n* `Discourse channel`_\n* `User IRC`_\n\nIf you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms:\n\n* `GitHub page`_\n* `Development documentation`_\n* `Development mailing list`_\n* `Development IRC`_\n\nCode of Conduct\n---------------\n\nEveryone interacting in the pip project's codebases, issue trackers, chat\nrooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_.\n\n.. _package installer: https://packaging.python.org/guides/tool-recommendations/\n.. _Python Package Index: https://pypi.org\n.. _Installation: https://pip.pypa.io/en/stable/installing.html\n.. _Usage: https://pip.pypa.io/en/stable/\n.. _Release notes: https://pip.pypa.io/en/stable/news.html\n.. _Release process: https://pip.pypa.io/en/latest/development/release-process/\n.. _GitHub page: https://github.com/pypa/pip\n.. _Development documentation: https://pip.pypa.io/en/latest/development\n.. _learn more and take our survey: https://pyfound.blogspot.com/2020/03/new-pip-resolver-to-roll-out-this-year.html\n.. _Issue tracking: https://github.com/pypa/pip/issues\n.. _Discourse channel: https://discuss.python.org/c/packaging\n.. _Development mailing list: https://mail.python.org/mailman3/lists/distutils-sig.python.org/\n.. _User IRC: https://webchat.freenode.net/?channels=%23pypa\n.. _Development IRC: https://webchat.freenode.net/?channels=%23pypa-dev\n.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "The pip developers", + "email": "distutils-sig@python.org", + "url": null + } + ], + "keywords": [ + "distutils easy_install egg setuptools wheel virtualenv", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Software Development :: Build Tools", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy" + ], + "homepage_url": "https://pip.pypa.io/", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": "Source, https://github.com/pypa/pip", + "vcs_url": null, + "copyright": null, + "license_expression": "mit", + "declared_license": { + "license": "MIT", + "classifiers": [ + "License :: OSI Approved :: MIT License" + ] + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/pip@20.2.2", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/pip/pip-20.2.2.tar.gz", + "api_data_url": "https://pypi.org/pypi/pip/20.2.2/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info-expected.json new file mode 100644 index 00000000000..9e70343b162 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info-expected.json @@ -0,0 +1,63 @@ +{ + "type": "pypi", + "namespace": null, + "name": "pip", + "version": "20.2.2", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "The PyPA recommended tool for installing Python packages.\npip - The Python Package Installer\n==================================\n\n.. image:: https://img.shields.io/pypi/v/pip.svg\n :target: https://pypi.org/project/pip/\n\n.. image:: https://readthedocs.org/projects/pip/badge/?version=latest\n :target: https://pip.pypa.io/en/latest\n\npip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes.\n\nPlease take a look at our documentation for how to install and use pip:\n\n* `Installation`_\n* `Usage`_\n\nWe release updates regularly, with a new version every 3 months. Find more details in our documentation:\n\n* `Release notes`_\n* `Release process`_\n\nIn 2020, we're working on improvements to the heart of pip. Please `learn more and take our survey`_ to help us do it right.\n\nIf you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms:\n\n* `Issue tracking`_\n* `Discourse channel`_\n* `User IRC`_\n\nIf you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms:\n\n* `GitHub page`_\n* `Development documentation`_\n* `Development mailing list`_\n* `Development IRC`_\n\nCode of Conduct\n---------------\n\nEveryone interacting in the pip project's codebases, issue trackers, chat\nrooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_.\n\n.. _package installer: https://packaging.python.org/guides/tool-recommendations/\n.. _Python Package Index: https://pypi.org\n.. _Installation: https://pip.pypa.io/en/stable/installing.html\n.. _Usage: https://pip.pypa.io/en/stable/\n.. _Release notes: https://pip.pypa.io/en/stable/news.html\n.. _Release process: https://pip.pypa.io/en/latest/development/release-process/\n.. _GitHub page: https://github.com/pypa/pip\n.. _Development documentation: https://pip.pypa.io/en/latest/development\n.. _learn more and take our survey: https://pyfound.blogspot.com/2020/03/new-pip-resolver-to-roll-out-this-year.html\n.. _Issue tracking: https://github.com/pypa/pip/issues\n.. _Discourse channel: https://discuss.python.org/c/packaging\n.. _Development mailing list: https://mail.python.org/mailman3/lists/distutils-sig.python.org/\n.. _User IRC: https://webchat.freenode.net/?channels=%23pypa\n.. _Development IRC: https://webchat.freenode.net/?channels=%23pypa-dev\n.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "The pip developers", + "email": "distutils-sig@python.org", + "url": null + } + ], + "keywords": [ + "distutils easy_install egg setuptools wheel virtualenv", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Software Development :: Build Tools", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy" + ], + "homepage_url": "https://pip.pypa.io/", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": "Source, https://github.com/pypa/pip", + "vcs_url": null, + "copyright": null, + "license_expression": "mit", + "declared_license": { + "license": "MIT", + "classifiers": [ + "License :: OSI Approved :: MIT License" + ] + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/pip@20.2.2", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/pip/pip-20.2.2.tar.gz", + "api_data_url": "https://pypi.org/pypi/pip/20.2.2/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/INSTALLER b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/INSTALLER new file mode 100644 index 00000000000..a1b589e38a3 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/LICENSE.txt b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/LICENSE.txt new file mode 100644 index 00000000000..737fec5c535 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2008-2019 The pip developers (see AUTHORS.txt file) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/METADATA b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/METADATA new file mode 100644 index 00000000000..959afb6b36c --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/METADATA @@ -0,0 +1,88 @@ +Metadata-Version: 2.1 +Name: pip +Version: 20.2.2 +Summary: The PyPA recommended tool for installing Python packages. +Home-page: https://pip.pypa.io/ +Author: The pip developers +Author-email: distutils-sig@python.org +License: MIT +Project-URL: Documentation, https://pip.pypa.io +Project-URL: Source, https://github.com/pypa/pip +Project-URL: Changelog, https://pip.pypa.io/en/stable/news/ +Keywords: distutils easy_install egg setuptools wheel virtualenv +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Topic :: Software Development :: Build Tools +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.* + +pip - The Python Package Installer +================================== + +.. image:: https://img.shields.io/pypi/v/pip.svg + :target: https://pypi.org/project/pip/ + +.. image:: https://readthedocs.org/projects/pip/badge/?version=latest + :target: https://pip.pypa.io/en/latest + +pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes. + +Please take a look at our documentation for how to install and use pip: + +* `Installation`_ +* `Usage`_ + +We release updates regularly, with a new version every 3 months. Find more details in our documentation: + +* `Release notes`_ +* `Release process`_ + +In 2020, we're working on improvements to the heart of pip. Please `learn more and take our survey`_ to help us do it right. + +If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms: + +* `Issue tracking`_ +* `Discourse channel`_ +* `User IRC`_ + +If you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms: + +* `GitHub page`_ +* `Development documentation`_ +* `Development mailing list`_ +* `Development IRC`_ + +Code of Conduct +--------------- + +Everyone interacting in the pip project's codebases, issue trackers, chat +rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_. + +.. _package installer: https://packaging.python.org/guides/tool-recommendations/ +.. _Python Package Index: https://pypi.org +.. _Installation: https://pip.pypa.io/en/stable/installing.html +.. _Usage: https://pip.pypa.io/en/stable/ +.. _Release notes: https://pip.pypa.io/en/stable/news.html +.. _Release process: https://pip.pypa.io/en/latest/development/release-process/ +.. _GitHub page: https://github.com/pypa/pip +.. _Development documentation: https://pip.pypa.io/en/latest/development +.. _learn more and take our survey: https://pyfound.blogspot.com/2020/03/new-pip-resolver-to-roll-out-this-year.html +.. _Issue tracking: https://github.com/pypa/pip/issues +.. _Discourse channel: https://discuss.python.org/c/packaging +.. _Development mailing list: https://mail.python.org/mailman3/lists/distutils-sig.python.org/ +.. _User IRC: https://webchat.freenode.net/?channels=%23pypa +.. _Development IRC: https://webchat.freenode.net/?channels=%23pypa-dev +.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + + diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/RECORD b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/RECORD new file mode 100644 index 00000000000..9fa9fdf739e --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/RECORD @@ -0,0 +1,804 @@ +pip/__init__.py,sha256=fZ401OZGdv55YGsuCEhsvdNa4YCZLmK457SN3qrstJk,455 +pip/__main__.py,sha256=bqCAM1cj1HwHCDx3WJa-LJxOBXimGxE8OjBqAvnhVg0,911 +pip/_internal/__init__.py,sha256=2si23JBW1erg19xIJ8CD6tfGknz0ijtXmzuXjGfGMGE,495 +pip/_internal/build_env.py,sha256=9_UaQ2fpsBvpKAji27f7bPAi2v3mb0cBvDYcejwFKNM,8088 +pip/_internal/cache.py,sha256=pT17VVxgzZK32aqY5FRS8GyAI73LKzNMF8ZelQ7Ojm0,12249 +pip/_internal/configuration.py,sha256=-Gxz2J-KuvxiqWIJ9F-XnYVZ5lKhNk7VO6ondEbH4EM,14115 +pip/_internal/exceptions.py,sha256=ZVpArxQrSlm4qAMtHaY3nHvG_t5eSi3WCnMowdm_m8I,12637 +pip/_internal/locations.py,sha256=7YjzJy2CroQD8GBMemnHWRl9448BSIt0lfH98B-Dkd8,6732 +pip/_internal/main.py,sha256=IVBnUQ-FG7DK6617uEXRB5_QJqspAsBFmTmTesYkbdQ,437 +pip/_internal/pyproject.py,sha256=VJKsrXORGiGoDPVKCQhuu4tWlQSTOhoiRlVLRNu4rx4,7400 +pip/_internal/self_outdated_check.py,sha256=q6_nqUHPpt-DScwD97h7FCSqd4nI1s-xkpOI4I5Za3Y,6779 +pip/_internal/wheel_builder.py,sha256=6w1VPXrpUvCCPlV0cI1wNaCqNz4laF6B6whvaxl9cns,9522 +pip/_internal/cli/__init__.py,sha256=FkHBgpxxb-_gd6r1FjnNhfMOzAUYyXoXKJ6abijfcFU,132 +pip/_internal/cli/autocompletion.py,sha256=ekGNtcDI0p7rFVc-7s4T9Tbss4Jgb7vsB649XJIblRg,6547 +pip/_internal/cli/base_command.py,sha256=BWTztM4b6h8hodDHDKjgJ82jaSeru2AILAJxi1d_IP8,8810 +pip/_internal/cli/cmdoptions.py,sha256=M_BtuqeyRpZAUUYytts3pguBCF2RaGukVpDPE0niroI,28782 +pip/_internal/cli/command_context.py,sha256=ygMVoTy2jpNilKT-6416gFSQpaBtrKRBbVbi2fy__EU,975 +pip/_internal/cli/main.py,sha256=Hxc9dZyW3xiDsYZX-_J2cGXT5DWNLNn_Y7o9oUme-Ec,2616 +pip/_internal/cli/main_parser.py,sha256=voAtjo4WVPIYeu7Fqabva9SXaB3BjG0gH93GBfe6jHQ,2843 +pip/_internal/cli/parser.py,sha256=4FfwW8xB84CrkLs35ud90ZkhCcWyVkx17XD6j3XCW7c,9480 +pip/_internal/cli/progress_bars.py,sha256=J1zykt2LI4gbBeXorfYRmYV5FgXhcW4x3r6xE_a7Z7c,9121 +pip/_internal/cli/req_command.py,sha256=Eiz8TVzeqzG-40t7qLC1vO-vzjCRvX9C-qXMyfw9D1I,15132 +pip/_internal/cli/spinners.py,sha256=PS9s53LB5aDPelIn8FhKerK3bOdgeefFH5wSWJ2PCzI,5509 +pip/_internal/cli/status_codes.py,sha256=F6uDG6Gj7RNKQJUDnd87QKqI16Us-t-B0wPF_4QMpWc,156 +pip/_internal/commands/__init__.py,sha256=yoLAnmEXjoQgYfDuwsuWG3RzzD19oeHobGEhmpIYsB4,4100 +pip/_internal/commands/cache.py,sha256=U3rLjls0AMMO8PxnhXVwIp7Biyvns8-gBThKTH3tX7Y,5676 +pip/_internal/commands/check.py,sha256=fqRrz2uKPC8Qsx2rgLygAD2Rbr-qxp1Q55zUoyZzB9Q,1677 +pip/_internal/commands/completion.py,sha256=ObssM77quf61qvbuSE6XLwUBdm_WcWIvXFI-Hy1RBsI,3081 +pip/_internal/commands/configuration.py,sha256=IN2QBF653sRiRU7-pHTpnZ6_gyiXNKUQkLiLaNRLKNw,9344 +pip/_internal/commands/debug.py,sha256=otBZnpnostX2kmYyOl6g6CeCLmk6H00Tsj2CDsCtFXw,7314 +pip/_internal/commands/download.py,sha256=EKFlj_ceGUEJj6yCDw7P6w7yUoB16IcNHhT2qnCFDNQ,4918 +pip/_internal/commands/freeze.py,sha256=vLBBP1d8wgEXrmlh06hbz_x_Q1mWHUdiWDa9NP2eKLE,3452 +pip/_internal/commands/hash.py,sha256=v2nYCiEsEI9nEam1p6GwdG8xyj5gFv-4WrqvNexKmeY,1843 +pip/_internal/commands/help.py,sha256=ryuMDt2tc7ic3NJYMjjoNRH5r6LrB2yQVZvehAm8bLs,1270 +pip/_internal/commands/install.py,sha256=h2L8vS6t2DbGAdttkdZmMucK2eJG2CYvcwhDa7AdKrQ,28683 +pip/_internal/commands/list.py,sha256=2o3rYw37ECrhe4-Bu5s_2C0bwhYgghh4833MxcWAEug,11312 +pip/_internal/commands/search.py,sha256=1HPAFU-tmgKrHhr4xNuk3xMoPeSzD_oDvDDiUFZZ15E,5756 +pip/_internal/commands/show.py,sha256=r69-G8HIepDKm4SeyeHj0Ez1P9xoihrpVUyXm6NmXYY,6996 +pip/_internal/commands/uninstall.py,sha256=Ys8hwFsg0kvvGtLGYG3ibL5BKvURhlSlCX50ZQ-hsHk,3311 +pip/_internal/commands/wheel.py,sha256=-HSISE5AV29I752Aqw4DdmulrGd8rB_ZTOdpbJ6T8iM,6419 +pip/_internal/distributions/__init__.py,sha256=ECBUW5Gtu9TjJwyFLvim-i6kUMYVuikNh9I5asL6tbA,959 +pip/_internal/distributions/base.py,sha256=ruprpM_L2T2HNi3KLUHlbHimZ1sWVw-3Q0Lb8O7TDAI,1425 +pip/_internal/distributions/installed.py,sha256=YqlkBKr6TVP1MAYS6SG8ojud21wVOYLMZ8jMLJe9MSU,760 +pip/_internal/distributions/sdist.py,sha256=D4XTMlCwgPlK69l62GLYkNSVTVe99fR5iAcVt2EbGok,4086 +pip/_internal/distributions/wheel.py,sha256=95uD-TfaYoq3KiKBdzk9YMN4RRqJ28LNoSTS2K46gek,1294 +pip/_internal/index/__init__.py,sha256=vpt-JeTZefh8a-FC22ZeBSXFVbuBcXSGiILhQZJaNpQ,30 +pip/_internal/index/collector.py,sha256=rMdGdAABOrvIl0DYlCMWXr7mIoqrU2VGeQpCuWiPu1Q,22838 +pip/_internal/index/package_finder.py,sha256=ISieDd20dOSndMNybafCu3pO2JR3BKOfHv92Bes0j0Q,37364 +pip/_internal/models/__init__.py,sha256=3DHUd_qxpPozfzouoqa9g9ts1Czr5qaHfFxbnxriepM,63 +pip/_internal/models/candidate.py,sha256=gACeCSHTIaWuB6RAeLmGJnbFFbKfp_47UERDoC_ldOU,1195 +pip/_internal/models/direct_url.py,sha256=MnBLPci1hE9Ndh6d3m0LAqB7hX3ci80CCJTE5eerFaQ,6900 +pip/_internal/models/format_control.py,sha256=RdnnmXxVJppCZWzWEmFTr-zD_m3G0izPLqJi6Iop75M,2823 +pip/_internal/models/index.py,sha256=carvxxaT7mJyoEkptaECHUZiNaA6R5NrsGF55zawNn8,1161 +pip/_internal/models/link.py,sha256=FMlxvqKmLoj7xTQSgKqfO2ehE1WcgD4C5DmEBuC_Qos,7470 +pip/_internal/models/scheme.py,sha256=EhPkT_6G0Md84JTLSVopYsp5H_K6BREYmFvU8H6wMK8,778 +pip/_internal/models/search_scope.py,sha256=Lum0mY4_pdR9DDBy6HV5xHGIMPp_kU8vMsqYKFHZip4,4751 +pip/_internal/models/selection_prefs.py,sha256=pgNjTfgePPiX1R5S2S8Yc6odOfU9NzG7YP_m_gnS0kw,2044 +pip/_internal/models/target_python.py,sha256=R7tAXI15B_cgw7Fgnq5cI9F-44goUZncH9JMtE8pXRw,4034 +pip/_internal/models/wheel.py,sha256=FTfzVb4WIbfIehxhdlAVvCil_MQ0-W44oyN56cE6NHc,2772 +pip/_internal/network/__init__.py,sha256=jf6Tt5nV_7zkARBrKojIXItgejvoegVJVKUbhAa5Ioc,50 +pip/_internal/network/auth.py,sha256=dt3NvTRJ8182S3VpdYFEZMPT0JhOKHyFtR-O-JMlJII,11652 +pip/_internal/network/cache.py,sha256=6cCD7XNrqh1d1lOSY5U-0ZXOG1YwEgMYs-VhRZVyzMA,2329 +pip/_internal/network/download.py,sha256=VTGDO01_nX-5MCdatd4Icv0F88_M8N3WnW6BevA6a0o,5151 +pip/_internal/network/lazy_wheel.py,sha256=RXcQILT5v5UO6kxgv76CSncLTqRL29o-OXbaW2aK7t4,8138 +pip/_internal/network/session.py,sha256=Zs0uiyPxTpfpgSv-ZI9hK9TjasmTplBuBivOTcUiJME,15208 +pip/_internal/network/utils.py,sha256=ZPHg7u6DEcg2EvILIdPECnvPLp21OPHxNVmeXfMy-n0,4172 +pip/_internal/network/xmlrpc.py,sha256=PFCiX_nnwYxC8SFIf7J3trP40ECGjA6fl2-IVNhbkPM,1882 +pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/operations/check.py,sha256=JYDsVLvpFyJuJq0ttStgg8TRKbc0myYFAMnfnnQOREM,5215 +pip/_internal/operations/freeze.py,sha256=_vJSZwHBNzBV0GpRUSXhUJz3BrGFdcT2aTcWxH1L4P0,10373 +pip/_internal/operations/prepare.py,sha256=Rt7Yh7w10_Q-vI3b7R1wkt2R6XPX8YVUdODk-TaGI9c,19903 +pip/_internal/operations/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/operations/build/metadata.py,sha256=2aILgWCQTF1aIhWuCH8TTSjv_kYmA3x1262fT2FQ6pQ,1254 +pip/_internal/operations/build/metadata_legacy.py,sha256=VgzBTk8naIO8-8N_ifEYF7ZAxWUDhphWVIaVlZ2FqYM,2011 +pip/_internal/operations/build/wheel.py,sha256=33vdkxTO-gNqrtWH1eNL_uZo4Irax85moDx2o9zae3M,1465 +pip/_internal/operations/build/wheel_legacy.py,sha256=N1aqNZyGURBX0Bj6wPmB0t4866oMbxoHUpC9pz6FyT0,3356 +pip/_internal/operations/install/__init__.py,sha256=mX7hyD2GNBO2mFGokDQ30r_GXv7Y_PLdtxcUv144e-s,51 +pip/_internal/operations/install/editable_legacy.py,sha256=rJ_xs2qtDUjpY2-n6eYlVyZiNoKbOtZXZrYrcnIELt4,1488 +pip/_internal/operations/install/legacy.py,sha256=zu3Gw54dgHtluyW5n8j5qKcAScidQXJvqB8fb0oLB-4,4281 +pip/_internal/operations/install/wheel.py,sha256=nJmOSOYY3keksXd_3GFuhAWeeoKvGOyoSGbjXABjZ40,31310 +pip/_internal/req/__init__.py,sha256=s-E5Vxxqqpcs7xfY5gY69oHogsWJ4sLbnUiDoWmkHOU,3133 +pip/_internal/req/constructors.py,sha256=LrSHbRHu52-h6HM1qJKG68o1Jw5q8MvJGfr4As6j2uU,16387 +pip/_internal/req/req_file.py,sha256=p7n3Y0q275Eisqfxd0vtfnxYvlT6TCCY0tj75p-yiOY,19448 +pip/_internal/req/req_install.py,sha256=hqQMm6s7f1a2RAGasyAhy47eZGom3OBKeiRM60xxdPg,33080 +pip/_internal/req/req_set.py,sha256=dxcfbieWYfYkTJNE07U8xaO40zLxl8BhWOcIHVFTmoo,7886 +pip/_internal/req/req_tracker.py,sha256=qWaiejNK6o6cqeyTOIGKIU1CoyrXCcqgMHYi3cqelOA,4690 +pip/_internal/req/req_uninstall.py,sha256=opMGDGb7ZaFippRbaarJaljtzl2CNZmBGEUSnTubE-A,23706 +pip/_internal/resolution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/resolution/base.py,sha256=xi72YmIS-lEjyK13PN_3qkGGthA4yGoK0C6qWynyHrE,682 +pip/_internal/resolution/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/resolution/legacy/resolver.py,sha256=d-qW6UUxbZqKyXmX2bqnW5C8UtnO0ZcsQuKw_QXualc,18755 +pip/_internal/resolution/resolvelib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/resolution/resolvelib/base.py,sha256=n8Rilea9jCzhlbtFiJKwCwIQSPW0ATjEKsCc0Vpm894,2342 +pip/_internal/resolution/resolvelib/candidates.py,sha256=RHo9r9g25FWzufKv93Ti9nS4hvAPUrhAjSDL7GCZFNQ,20339 +pip/_internal/resolution/resolvelib/factory.py,sha256=--ahYsr-r9zIhdyJJ1ZuETgaQrWiPIqwILWiMDn1IIU,17169 +pip/_internal/resolution/resolvelib/provider.py,sha256=BP8nh07Z1FlcT-Iaw4FblRM-DjUeUkiItKdKARYeM6M,6134 +pip/_internal/resolution/resolvelib/requirements.py,sha256=lGvoHRhkusRfaz4cFxYBoQNqxS6TeuO3K68qlui6g-0,4511 +pip/_internal/resolution/resolvelib/resolver.py,sha256=kI8g0NVlYIsDMRmDplWQdox6WO-0H7CI2wN-1ixnaew,10149 +pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/utils/appdirs.py,sha256=RZzUG-Bkh2b-miX0DSZ3v703_-bgK-v0PfWCCjwVE9g,1349 +pip/_internal/utils/compat.py,sha256=GoCSUMoUmTGeg5irQGLDZ7v12As87yHrMzBXEke-njg,8865 +pip/_internal/utils/compatibility_tags.py,sha256=EtBJj-pstj_U0STUZ8FjlG7YDTjuRZUy6GY1cM86yv8,5439 +pip/_internal/utils/datetime.py,sha256=KL-vIdGU9JIpGB5NYkmwXWkH-G_2mvvABlmRtoSZsao,295 +pip/_internal/utils/deprecation.py,sha256=pBnNogoA4UGTxa_JDnPXBRRYpKMbExAhXpBwAwklOBs,3318 +pip/_internal/utils/direct_url_helpers.py,sha256=bZCBNwPQVyZpYGjX_VcomvVvRHvKw-9JzEV-Ft09LQc,4359 +pip/_internal/utils/distutils_args.py,sha256=a56mblNxk9BGifbpEETG61mmBrqhjtjRkJ4HYn-oOEE,1350 +pip/_internal/utils/encoding.py,sha256=wHDJ25yCT_T4ySscCL3P978OpLrfDCpitg8D64IEXMY,1284 +pip/_internal/utils/entrypoints.py,sha256=vHcNpnksCv6mllihU6hfifdsKPEjwcaJ1aLIXEaynaU,1152 +pip/_internal/utils/filesystem.py,sha256=-fU3XteCAIJwf_9FvCZU7vhywvt3nuf_cqkCdwgy1Y8,6943 +pip/_internal/utils/filetypes.py,sha256=R2FwzoeX7b-rZALOXx5cuO8VPPMhUQ4ne7wm3n3IcWA,571 +pip/_internal/utils/glibc.py,sha256=LOeNGgawCKS-4ke9fii78fwXD73dtNav3uxz1Bf-Ab8,3297 +pip/_internal/utils/hashes.py,sha256=xHmrqNwC1eBN0oY0R_RXLJLXGvFdo5gwmbz_pas94k8,4358 +pip/_internal/utils/inject_securetransport.py,sha256=M17ZlFVY66ApgeASVjKKLKNz0LAfk-SyU0HZ4ZB6MmI,810 +pip/_internal/utils/logging.py,sha256=YIfuDUEkmdn9cIRQ_Ec8rgXs1m5nOwDECtZqM4CBH5U,13093 +pip/_internal/utils/misc.py,sha256=QQZWMJkKKADPSWQYmrwlasc8b03eCcghn0yDNprYgrI,28001 +pip/_internal/utils/models.py,sha256=HqiBVtTbW_b_Umvj2fjhDWOHo2RKhPwSz4iAYkQZ688,1201 +pip/_internal/utils/packaging.py,sha256=VtiwcAAL7LBi7tGL2je7LeW4bE11KMHGCsJ1NZY5XtM,3035 +pip/_internal/utils/parallel.py,sha256=7az3aaTMCkqpaLFbpYYOvk0rj7Hu5YH1NPXXomqjgf4,3404 +pip/_internal/utils/pkg_resources.py,sha256=ZX-k7V5q_aNWyDse92nN7orN1aCpRLsaxzpkBZ1XKzU,1254 +pip/_internal/utils/setuptools_build.py,sha256=E1KswI7wfNnCDE5R6G8c9ZbByENpu7NqocjY26PCQDw,5058 +pip/_internal/utils/subprocess.py,sha256=UkPe89gcjxBMx73uutoeJXgD3kwdlL6YO16BkjDdVSI,9924 +pip/_internal/utils/temp_dir.py,sha256=blmG0jEvEgdxbYUt_V15bgcTIJIrxZwAw8QZlCTJYDE,8378 +pip/_internal/utils/typing.py,sha256=xkYwOeHlf4zsHXBDC4310HtEqwhQcYXFPq2h35Tcrl0,1401 +pip/_internal/utils/unpacking.py,sha256=YFAckhqqvmehA8Kan5vd3b1kN_9TafqmOk4b-yz4fho,9488 +pip/_internal/utils/urls.py,sha256=q2rw1kMiiig_XZcoyJSsWMJQqYw-2wUmrMoST4mCW_I,1527 +pip/_internal/utils/virtualenv.py,sha256=fNGrRp-8QmNL5OzXajBd-z7PbwOsx1XY6G-AVMAhfso,3706 +pip/_internal/utils/wheel.py,sha256=wFzn3h8GqYvgsyWPZtUyn0Rb3MJzmtyP3owMOhKnmL0,7303 +pip/_internal/vcs/__init__.py,sha256=viJxJRqRE_mVScum85bgQIXAd6o0ozFt18VpC-qIJrM,617 +pip/_internal/vcs/bazaar.py,sha256=5rRR02uDZTLaxQT-R5Obd8FZDOMlShqYds-pwVSJJs8,3887 +pip/_internal/vcs/git.py,sha256=kvB729wrKY0OWMSgOS1pUly4LosZp8utrd3kOQsWalA,13985 +pip/_internal/vcs/mercurial.py,sha256=FzCGmYzVZvB-vyM73fKcQk2B4jMNXGnXlQ2bJ7nmglM,5162 +pip/_internal/vcs/subversion.py,sha256=rldcn9ZDt5twjNPzFn_FKRn4qdfkjlxHMJEsR2MFfoA,12399 +pip/_internal/vcs/versioncontrol.py,sha256=WpxeTRC0NoGB2uXJdmfq4pPxY-p7sk1rV_WkxMxgzQA,25966 +pip/_vendor/__init__.py,sha256=CsxnpYPbi_2agrDI79iQrCmQeZRcwwIF0C6cm_1RynU,4588 +pip/_vendor/appdirs.py,sha256=M6IYRJtdZgmSPCXCSMBRB0VT3P8MdFbWCDbSLrB2Ebg,25907 +pip/_vendor/contextlib2.py,sha256=5HjGflUzwWAUfcILhSmC2GqvoYdZZzFzVfIDztHigUs,16915 +pip/_vendor/distro.py,sha256=xxMIh2a3KmippeWEHzynTdHT3_jZM0o-pos0dAWJROM,43628 +pip/_vendor/ipaddress.py,sha256=-0RmurI31XgAaN20WCi0zrcuoat90nNA70_6yGlx2PU,79875 +pip/_vendor/pyparsing.py,sha256=J1b4z3S_KwyJW7hKGnoN-hXW9pgMIzIP6QThyY5yJq4,273394 +pip/_vendor/retrying.py,sha256=k3fflf5_Mm0XcIJYhB7Tj34bqCCPhUDkYbx1NvW2FPE,9972 +pip/_vendor/six.py,sha256=U4Z_yv534W5CNyjY9i8V1OXY2SjAny8y2L5vDLhhThM,34159 +pip/_vendor/vendor.txt,sha256=bWUiaRjMJhuUsqFZHEJkBH_6lJ_Avl9cOyszcI74IHs,437 +pip/_vendor/cachecontrol/__init__.py,sha256=pJtAaUxOsMPnytI1A3juAJkXYDr8krdSnsg4Yg3OBEg,302 +pip/_vendor/cachecontrol/_cmd.py,sha256=URGE0KrA87QekCG3SGPatlSPT571dZTDjNa-ZXX3pDc,1295 +pip/_vendor/cachecontrol/adapter.py,sha256=sSwaSYd93IIfCFU4tOMgSo6b2LCt_gBSaQUj8ktJFOA,4882 +pip/_vendor/cachecontrol/cache.py,sha256=1fc4wJP8HYt1ycnJXeEw5pCpeBL2Cqxx6g9Fb0AYDWQ,805 +pip/_vendor/cachecontrol/compat.py,sha256=kHNvMRdt6s_Xwqq_9qJmr9ou3wYMOMUMxPPcwNxT8Mc,695 +pip/_vendor/cachecontrol/controller.py,sha256=CWEX3pedIM9s60suf4zZPtm_JvVgnvogMGK_OiBG5F8,14149 +pip/_vendor/cachecontrol/filewrapper.py,sha256=vACKO8Llzu_ZWyjV1Fxn1MA4TGU60N5N3GSrAFdAY2Q,2533 +pip/_vendor/cachecontrol/heuristics.py,sha256=BFGHJ3yQcxvZizfo90LLZ04T_Z5XSCXvFotrp7Us0sc,4070 +pip/_vendor/cachecontrol/serialize.py,sha256=vIa4jvq4x_KSOLdEIedoknX2aXYHQujLDFV4-F21Dno,7091 +pip/_vendor/cachecontrol/wrapper.py,sha256=5LX0uJwkNQUtYSEw3aGmGu9WY8wGipd81mJ8lG0d0M4,690 +pip/_vendor/cachecontrol/caches/__init__.py,sha256=-gHNKYvaeD0kOk5M74eOrsSgIKUtC6i6GfbmugGweEo,86 +pip/_vendor/cachecontrol/caches/file_cache.py,sha256=nYVKsJtXh6gJXvdn1iWyrhxvkwpQrK-eKoMRzuiwkKk,4153 +pip/_vendor/cachecontrol/caches/redis_cache.py,sha256=HxelMpNCo-dYr2fiJDwM3hhhRmxUYtB5tXm1GpAAT4Y,856 +pip/_vendor/certifi/__init__.py,sha256=u1E_DrSGj_nnEkK5VglvEqP8D80KpghLVWL0A_pq41A,62 +pip/_vendor/certifi/__main__.py,sha256=1k3Cr95vCxxGRGDljrW3wMdpZdL3Nhf0u1n-k2qdsCY,255 +pip/_vendor/certifi/cacert.pem,sha256=GhT24f0R7_9y4YY_hkXwkO7BthZhRGDCEMO348E9S14,282394 +pip/_vendor/certifi/core.py,sha256=jBrwKEWpG0IKcuozK0BQ2HHGp8adXAOyBPC7ddgR6vM,2315 +pip/_vendor/chardet/__init__.py,sha256=YsP5wQlsHJ2auF1RZJfypiSrCA7_bQiRm3ES_NI76-Y,1559 +pip/_vendor/chardet/big5freq.py,sha256=D_zK5GyzoVsRes0HkLJziltFQX0bKCLOrFe9_xDvO_8,31254 +pip/_vendor/chardet/big5prober.py,sha256=kBxHbdetBpPe7xrlb-e990iot64g_eGSLd32lB7_h3M,1757 +pip/_vendor/chardet/chardistribution.py,sha256=3woWS62KrGooKyqz4zQSnjFbJpa6V7g02daAibTwcl8,9411 +pip/_vendor/chardet/charsetgroupprober.py,sha256=6bDu8YIiRuScX4ca9Igb0U69TA2PGXXDej6Cc4_9kO4,3787 +pip/_vendor/chardet/charsetprober.py,sha256=KSmwJErjypyj0bRZmC5F5eM7c8YQgLYIjZXintZNstg,5110 +pip/_vendor/chardet/codingstatemachine.py,sha256=VYp_6cyyki5sHgXDSZnXW4q1oelHc3cu9AyQTX7uug8,3590 +pip/_vendor/chardet/compat.py,sha256=PKTzHkSbtbHDqS9PyujMbX74q1a8mMpeQTDVsQhZMRw,1134 +pip/_vendor/chardet/cp949prober.py,sha256=TZ434QX8zzBsnUvL_8wm4AQVTZ2ZkqEEQL_lNw9f9ow,1855 +pip/_vendor/chardet/enums.py,sha256=Aimwdb9as1dJKZaFNUH2OhWIVBVd6ZkJJ_WK5sNY8cU,1661 +pip/_vendor/chardet/escprober.py,sha256=kkyqVg1Yw3DIOAMJ2bdlyQgUFQhuHAW8dUGskToNWSc,3950 +pip/_vendor/chardet/escsm.py,sha256=RuXlgNvTIDarndvllNCk5WZBIpdCxQ0kcd9EAuxUh84,10510 +pip/_vendor/chardet/eucjpprober.py,sha256=iD8Jdp0ISRjgjiVN7f0e8xGeQJ5GM2oeZ1dA8nbSeUw,3749 +pip/_vendor/chardet/euckrfreq.py,sha256=-7GdmvgWez4-eO4SuXpa7tBiDi5vRXQ8WvdFAzVaSfo,13546 +pip/_vendor/chardet/euckrprober.py,sha256=MqFMTQXxW4HbzIpZ9lKDHB3GN8SP4yiHenTmf8g_PxY,1748 +pip/_vendor/chardet/euctwfreq.py,sha256=No1WyduFOgB5VITUA7PLyC5oJRNzRyMbBxaKI1l16MA,31621 +pip/_vendor/chardet/euctwprober.py,sha256=13p6EP4yRaxqnP4iHtxHOJ6R2zxHq1_m8hTRjzVZ95c,1747 +pip/_vendor/chardet/gb2312freq.py,sha256=JX8lsweKLmnCwmk8UHEQsLgkr_rP_kEbvivC4qPOrlc,20715 +pip/_vendor/chardet/gb2312prober.py,sha256=gGvIWi9WhDjE-xQXHvNIyrnLvEbMAYgyUSZ65HUfylw,1754 +pip/_vendor/chardet/hebrewprober.py,sha256=c3SZ-K7hvyzGY6JRAZxJgwJ_sUS9k0WYkvMY00YBYFo,13838 +pip/_vendor/chardet/jisfreq.py,sha256=vpmJv2Bu0J8gnMVRPHMFefTRvo_ha1mryLig8CBwgOg,25777 +pip/_vendor/chardet/jpcntx.py,sha256=PYlNqRUQT8LM3cT5FmHGP0iiscFlTWED92MALvBungo,19643 +pip/_vendor/chardet/langbulgarianmodel.py,sha256=1HqQS9Pbtnj1xQgxitJMvw8X6kKr5OockNCZWfEQrPE,12839 +pip/_vendor/chardet/langcyrillicmodel.py,sha256=LODajvsetH87yYDDQKA2CULXUH87tI223dhfjh9Zx9c,17948 +pip/_vendor/chardet/langgreekmodel.py,sha256=8YAW7bU8YwSJap0kIJSbPMw1BEqzGjWzqcqf0WgUKAA,12688 +pip/_vendor/chardet/langhebrewmodel.py,sha256=JSnqmE5E62tDLTPTvLpQsg5gOMO4PbdWRvV7Avkc0HA,11345 +pip/_vendor/chardet/langhungarianmodel.py,sha256=RhapYSG5l0ZaO-VV4Fan5sW0WRGQqhwBM61yx3yxyOA,12592 +pip/_vendor/chardet/langthaimodel.py,sha256=8l0173Gu_W6G8mxmQOTEF4ls2YdE7FxWf3QkSxEGXJQ,11290 +pip/_vendor/chardet/langturkishmodel.py,sha256=W22eRNJsqI6uWAfwXSKVWWnCerYqrI8dZQTm_M0lRFk,11102 +pip/_vendor/chardet/latin1prober.py,sha256=S2IoORhFk39FEFOlSFWtgVybRiP6h7BlLldHVclNkU8,5370 +pip/_vendor/chardet/mbcharsetprober.py,sha256=AR95eFH9vuqSfvLQZN-L5ijea25NOBCoXqw8s5O9xLQ,3413 +pip/_vendor/chardet/mbcsgroupprober.py,sha256=h6TRnnYq2OxG1WdD5JOyxcdVpn7dG0q-vB8nWr5mbh4,2012 +pip/_vendor/chardet/mbcssm.py,sha256=SY32wVIF3HzcjY3BaEspy9metbNSKxIIB0RKPn7tjpI,25481 +pip/_vendor/chardet/sbcharsetprober.py,sha256=LDSpCldDCFlYwUkGkwD2oFxLlPWIWXT09akH_2PiY74,5657 +pip/_vendor/chardet/sbcsgroupprober.py,sha256=1IprcCB_k1qfmnxGC6MBbxELlKqD3scW6S8YIwdeyXA,3546 +pip/_vendor/chardet/sjisprober.py,sha256=IIt-lZj0WJqK4rmUZzKZP4GJlE8KUEtFYVuY96ek5MQ,3774 +pip/_vendor/chardet/universaldetector.py,sha256=qL0174lSZE442eB21nnktT9_VcAye07laFWUeUrjttY,12485 +pip/_vendor/chardet/utf8prober.py,sha256=IdD8v3zWOsB8OLiyPi-y_fqwipRFxV9Nc1eKBLSuIEw,2766 +pip/_vendor/chardet/version.py,sha256=sp3B08mrDXB-pf3K9fqJ_zeDHOCLC8RrngQyDFap_7g,242 +pip/_vendor/chardet/cli/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +pip/_vendor/chardet/cli/chardetect.py,sha256=DI8dlV3FBD0c0XA_y3sQ78z754DUv1J8n34RtDjOXNw,2774 +pip/_vendor/colorama/__init__.py,sha256=DqjXH9URVP3IJwmMt7peYw50ns1RNAymIB9-XdPEFV8,239 +pip/_vendor/colorama/ansi.py,sha256=Fi0un-QLqRm-v7o_nKiOqyC8PapBJK7DLV_q9LKtTO0,2524 +pip/_vendor/colorama/ansitowin32.py,sha256=u8QaqdqS_xYSfNkPM1eRJLHz6JMWPodaJaP0mxgHCDc,10462 +pip/_vendor/colorama/initialise.py,sha256=PprovDNxMTrvoNHFcL2NZjpH2XzDc8BLxLxiErfUl4k,1915 +pip/_vendor/colorama/win32.py,sha256=bJ8Il9jwaBN5BJ8bmN6FoYZ1QYuMKv2j8fGrXh7TJjw,5404 +pip/_vendor/colorama/winterm.py,sha256=2y_2b7Zsv34feAsP67mLOVc-Bgq51mdYGo571VprlrM,6438 +pip/_vendor/distlib/__init__.py,sha256=3veAk2rPznOB2gsK6tjbbh0TQMmGE5P82eE9wXq6NIk,581 +pip/_vendor/distlib/compat.py,sha256=ADA56xiAxar3mU6qemlBhNbsrFPosXRhO44RzsbJPqk,41408 +pip/_vendor/distlib/database.py,sha256=Kl0YvPQKc4OcpVi7k5cFziydM1xOK8iqdxLGXgbZHV4,51059 +pip/_vendor/distlib/index.py,sha256=SXKzpQCERctxYDMp_OLee2f0J0e19ZhGdCIoMlUfUQM,21066 +pip/_vendor/distlib/locators.py,sha256=c9E4cDEacJ_uKbuE5BqAVocoWp6rsuBGTkiNDQq3zV4,52100 +pip/_vendor/distlib/manifest.py,sha256=nQEhYmgoreaBZzyFzwYsXxJARu3fo4EkunU163U16iE,14811 +pip/_vendor/distlib/markers.py,sha256=6Ac3cCfFBERexiESWIOXmg-apIP8l2esafNSX3KMy-8,4387 +pip/_vendor/distlib/metadata.py,sha256=z2KPy3h3tcDnb9Xs7nAqQ5Oz0bqjWAUFmKWcFKRoodg,38962 +pip/_vendor/distlib/resources.py,sha256=2FGv0ZHF14KXjLIlL0R991lyQQGcewOS4mJ-5n-JVnc,10766 +pip/_vendor/distlib/scripts.py,sha256=_MAj3sMuv56kuM8FsiIWXqbT0gmumPGaOR_atOzn4a4,17180 +pip/_vendor/distlib/t32.exe,sha256=NS3xBCVAld35JVFNmb-1QRyVtThukMrwZVeXn4LhaEQ,96768 +pip/_vendor/distlib/t64.exe,sha256=oAqHes78rUWVM0OtVqIhUvequl_PKhAhXYQWnUf7zR0,105984 +pip/_vendor/distlib/util.py,sha256=f2jZCPrcLCt6LcnC0gUy-Fur60tXD8reA7k4rDpHMDw,59845 +pip/_vendor/distlib/version.py,sha256=_n7F6juvQGAcn769E_SHa7fOcf5ERlEVymJ_EjPRwGw,23391 +pip/_vendor/distlib/w32.exe,sha256=lJtnZdeUxTZWya_EW5DZos_K5rswRECGspIl8ZJCIXs,90112 +pip/_vendor/distlib/w64.exe,sha256=0aRzoN2BO9NWW4ENy4_4vHkHR4qZTFZNVSAJJYlODTI,99840 +pip/_vendor/distlib/wheel.py,sha256=v6DnwTqhNHwrEVFr8_YeiTW6G4ftP_evsywNgrmdb2o,41144 +pip/_vendor/distlib/_backport/__init__.py,sha256=bqS_dTOH6uW9iGgd0uzfpPjo6vZ4xpPZ7kyfZJ2vNaw,274 +pip/_vendor/distlib/_backport/misc.py,sha256=KWecINdbFNOxSOP1fGF680CJnaC6S4fBRgEtaYTw0ig,971 +pip/_vendor/distlib/_backport/shutil.py,sha256=IX_G2NPqwecJibkIDje04bqu0xpHkfSQ2GaGdEVqM5Y,25707 +pip/_vendor/distlib/_backport/sysconfig.cfg,sha256=swZKxq9RY5e9r3PXCrlvQPMsvOdiWZBTHLEbqS8LJLU,2617 +pip/_vendor/distlib/_backport/sysconfig.py,sha256=BQHFlb6pubCl_dvT1NjtzIthylofjKisox239stDg0U,26854 +pip/_vendor/distlib/_backport/tarfile.py,sha256=Ihp7rXRcjbIKw8COm9wSePV9ARGXbSF9gGXAMn2Q-KU,92628 +pip/_vendor/html5lib/__init__.py,sha256=BYzcKCqeEii52xDrqBFruhnmtmkiuHXFyFh-cglQ8mk,1160 +pip/_vendor/html5lib/_ihatexml.py,sha256=ifOwF7pXqmyThIXc3boWc96s4MDezqRrRVp7FwDYUFs,16728 +pip/_vendor/html5lib/_inputstream.py,sha256=jErNASMlkgs7MpOM9Ve_VdLDJyFFweAjLuhVutZz33U,32353 +pip/_vendor/html5lib/_tokenizer.py,sha256=04mgA2sNTniutl2fxFv-ei5bns4iRaPxVXXHh_HrV_4,77040 +pip/_vendor/html5lib/_utils.py,sha256=Dx9AKntksRjFT1veBj7I362pf5OgIaT0zglwq43RnfU,4931 +pip/_vendor/html5lib/constants.py,sha256=Ll-yzLU_jcjyAI_h57zkqZ7aQWE5t5xA4y_jQgoUUhw,83464 +pip/_vendor/html5lib/html5parser.py,sha256=anr-aXre_ImfrkQ35c_rftKXxC80vJCREKe06Tq15HA,117186 +pip/_vendor/html5lib/serializer.py,sha256=_PpvcZF07cwE7xr9uKkZqh5f4UEaI8ltCU2xPJzaTpk,15759 +pip/_vendor/html5lib/_trie/__init__.py,sha256=nqfgO910329BEVJ5T4psVwQtjd2iJyEXQ2-X8c1YxwU,109 +pip/_vendor/html5lib/_trie/_base.py,sha256=CaybYyMro8uERQYjby2tTeSUatnWDfWroUN9N7ety5w,1013 +pip/_vendor/html5lib/_trie/py.py,sha256=wXmQLrZRf4MyWNyg0m3h81m9InhLR7GJ002mIIZh-8o,1775 +pip/_vendor/html5lib/filters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/html5lib/filters/alphabeticalattributes.py,sha256=lViZc2JMCclXi_5gduvmdzrRxtO5Xo9ONnbHBVCsykU,919 +pip/_vendor/html5lib/filters/base.py,sha256=z-IU9ZAYjpsVsqmVt7kuWC63jR11hDMr6CVrvuao8W0,286 +pip/_vendor/html5lib/filters/inject_meta_charset.py,sha256=egDXUEHXmAG9504xz0K6ALDgYkvUrC2q15YUVeNlVQg,2945 +pip/_vendor/html5lib/filters/lint.py,sha256=jk6q56xY0ojiYfvpdP-OZSm9eTqcAdRqhCoPItemPYA,3643 +pip/_vendor/html5lib/filters/optionaltags.py,sha256=8lWT75J0aBOHmPgfmqTHSfPpPMp01T84NKu0CRedxcE,10588 +pip/_vendor/html5lib/filters/sanitizer.py,sha256=m6oGmkBhkGAnn2nV6D4hE78SCZ6WEnK9rKdZB3uXBIc,26897 +pip/_vendor/html5lib/filters/whitespace.py,sha256=8eWqZxd4UC4zlFGW6iyY6f-2uuT8pOCSALc3IZt7_t4,1214 +pip/_vendor/html5lib/treeadapters/__init__.py,sha256=A0rY5gXIe4bJOiSGRO_j_tFhngRBO8QZPzPtPw5dFzo,679 +pip/_vendor/html5lib/treeadapters/genshi.py,sha256=CH27pAsDKmu4ZGkAUrwty7u0KauGLCZRLPMzaO3M5vo,1715 +pip/_vendor/html5lib/treeadapters/sax.py,sha256=BKS8woQTnKiqeffHsxChUqL4q2ZR_wb5fc9MJ3zQC8s,1776 +pip/_vendor/html5lib/treebuilders/__init__.py,sha256=AysSJyvPfikCMMsTVvaxwkgDieELD5dfR8FJIAuq7hY,3592 +pip/_vendor/html5lib/treebuilders/base.py,sha256=z-o51vt9r_l2IDG5IioTOKGzZne4Fy3_Fc-7ztrOh4I,14565 +pip/_vendor/html5lib/treebuilders/dom.py,sha256=22whb0C71zXIsai5mamg6qzBEiigcBIvaDy4Asw3at0,8925 +pip/_vendor/html5lib/treebuilders/etree.py,sha256=w5ZFpKk6bAxnrwD2_BrF5EVC7vzz0L3LMi9Sxrbc_8w,12836 +pip/_vendor/html5lib/treebuilders/etree_lxml.py,sha256=9gqDjs-IxsPhBYa5cpvv2FZ1KZlG83Giusy2lFmvIkE,14766 +pip/_vendor/html5lib/treewalkers/__init__.py,sha256=OBPtc1TU5mGyy18QDMxKEyYEz0wxFUUNj5v0-XgmYhY,5719 +pip/_vendor/html5lib/treewalkers/base.py,sha256=ouiOsuSzvI0KgzdWP8PlxIaSNs9falhbiinAEc_UIJY,7476 +pip/_vendor/html5lib/treewalkers/dom.py,sha256=EHyFR8D8lYNnyDU9lx_IKigVJRyecUGua0mOi7HBukc,1413 +pip/_vendor/html5lib/treewalkers/etree.py,sha256=xo1L5m9VtkfpFJK0pFmkLVajhqYYVisVZn3k9kYpPkI,4551 +pip/_vendor/html5lib/treewalkers/etree_lxml.py,sha256=_b0LAVWLcVu9WaU_-w3D8f0IRSpCbjf667V-3NRdhTw,6357 +pip/_vendor/html5lib/treewalkers/genshi.py,sha256=4D2PECZ5n3ZN3qu3jMl9yY7B81jnQApBQSVlfaIuYbA,2309 +pip/_vendor/idna/__init__.py,sha256=9Nt7xpyet3DmOrPUGooDdAwmHZZu1qUAy2EaJ93kGiQ,58 +pip/_vendor/idna/codec.py,sha256=lvYb7yu7PhAqFaAIAdWcwgaWI2UmgseUua-1c0AsG0A,3299 +pip/_vendor/idna/compat.py,sha256=R-h29D-6mrnJzbXxymrWUW7iZUvy-26TQwZ0ij57i4U,232 +pip/_vendor/idna/core.py,sha256=jCoaLb3bA2tS_DDx9PpGuNTEZZN2jAzB369aP-IHYRE,11951 +pip/_vendor/idna/idnadata.py,sha256=gmzFwZWjdms3kKZ_M_vwz7-LP_SCgYfSeE03B21Qpsk,42350 +pip/_vendor/idna/intranges.py,sha256=TY1lpxZIQWEP6tNqjZkFA5hgoMWOj1OBmnUG8ihT87E,1749 +pip/_vendor/idna/package_data.py,sha256=bxBjpLnE06_1jSYKEy5svOMu1zM3OMztXVUb1tPlcp0,22 +pip/_vendor/idna/uts46data.py,sha256=lMdw2zdjkH1JUWXPPEfFUSYT3Fyj60bBmfLvvy5m7ko,202084 +pip/_vendor/msgpack/__init__.py,sha256=2gJwcsTIaAtCM0GMi2rU-_Y6kILeeQuqRkrQ22jSANc,1118 +pip/_vendor/msgpack/_version.py,sha256=hu7lzmZ_ClOaOOmRsWb4xomhzQ4UIsLsvv8KY6UysHE,20 +pip/_vendor/msgpack/exceptions.py,sha256=dCTWei8dpkrMsQDcjQk74ATl9HsIBH0ybt8zOPNqMYc,1081 +pip/_vendor/msgpack/ext.py,sha256=nV19BzE9Be8SJHrxxYJHFbvEHJaXcP3avRkHVp5wovM,6034 +pip/_vendor/msgpack/fallback.py,sha256=Z8V3iYUUPqKVy4WWTk64Vq3G0PylQIOmlWvgnMhmkdU,37133 +pip/_vendor/packaging/__about__.py,sha256=PNMsaZn4UcCHyubgROH1bl6CluduPjI5kFrSp_Zgklo,736 +pip/_vendor/packaging/__init__.py,sha256=6enbp5XgRfjBjsI9-bn00HjHf5TH21PDMOKkJW8xw-w,562 +pip/_vendor/packaging/_compat.py,sha256=MXdsGpSE_W-ZrHoC87andI4LV2FAwU7HLL-eHe_CjhU,1128 +pip/_vendor/packaging/_structures.py,sha256=ozkCX8Q8f2qE1Eic3YiQ4buDVfgz2iYevY9e7R2y3iY,2022 +pip/_vendor/packaging/_typing.py,sha256=VgA0AAvsc97KB5nF89zoudOyCMEsV7FlaXzZbYqEkzA,1824 +pip/_vendor/packaging/markers.py,sha256=V_RdoQqOUbSfy7y9o2vRk7BkzAh3yneC82cuWpKrqOg,9491 +pip/_vendor/packaging/requirements.py,sha256=F93hkn7i8NKRZP-FtdTIlhz1PUsRjhe6eRbsBXX0Uh4,4903 +pip/_vendor/packaging/specifiers.py,sha256=uYp9l13F0LcknS6d4N60ytiBgFmIhKideOq9AnsxTco,31944 +pip/_vendor/packaging/tags.py,sha256=NKMS37Zo_nWrZxgsD6zbXsXgc9edn9m160cBiLmHJdE,24067 +pip/_vendor/packaging/utils.py,sha256=RShlvnjO2CtYSD8uri32frMMFMTmB-3ihsq1-ghzLEw,1811 +pip/_vendor/packaging/version.py,sha256=Cnbm-OO9D_qd8ZTFxzFcjSavexSYFZmyeaoPvMsjgPc,15470 +pip/_vendor/pep517/__init__.py,sha256=r5uA106NGJa3slspaD2m32aFpFUiZX-mZ9vIlzAEOp4,84 +pip/_vendor/pep517/_in_process.py,sha256=XrKOTURJdia5R7i3i_OQmS89LASFXE3HQXfX63qZBIE,8438 +pip/_vendor/pep517/build.py,sha256=DN4ouyj_bd00knOKqv0KHRtN0-JezJoNNZQmcDi4juk,3335 +pip/_vendor/pep517/check.py,sha256=YoaNE3poJGpz96biVCYwtcDshwEGE2HRU5KKya9yfpY,5961 +pip/_vendor/pep517/colorlog.py,sha256=Tk9AuYm_cLF3BKTBoSTJt9bRryn0aFojIQOwbfVUTxQ,4098 +pip/_vendor/pep517/compat.py,sha256=M-5s4VNp8rjyT76ZZ_ibnPD44DYVzSQlyCEHayjtDPw,780 +pip/_vendor/pep517/dirtools.py,sha256=2mkAkAL0mRz_elYFjRKuekTJVipH1zTn4tbf1EDev84,1129 +pip/_vendor/pep517/envbuild.py,sha256=szKUFlO50X1ahQfXwz4hD9V2VE_bz9MLVPIeidsFo4w,6041 +pip/_vendor/pep517/meta.py,sha256=8mnM5lDnT4zXQpBTliJbRGfesH7iioHwozbDxALPS9Y,2463 +pip/_vendor/pep517/wrappers.py,sha256=yFU4Lp7TIYbmuVOTY-pXnlyGZ3F_grIi-JlLkpGN8Gk,10783 +pip/_vendor/pkg_resources/__init__.py,sha256=XpGBfvS9fafA6bm5rx7vnxdxs7yqyoc_NnpzKApkJ64,108277 +pip/_vendor/pkg_resources/py31compat.py,sha256=CRk8fkiPRDLsbi5pZcKsHI__Pbmh_94L8mr9Qy9Ab2U,562 +pip/_vendor/progress/__init__.py,sha256=fcbQQXo5np2CoQyhSH5XprkicwLZNLePR3uIahznSO0,4857 +pip/_vendor/progress/bar.py,sha256=QuDuVNcmXgpxtNtxO0Fq72xKigxABaVmxYGBw4J3Z_E,2854 +pip/_vendor/progress/counter.py,sha256=MznyBrvPWrOlGe4MZAlGUb9q3aODe6_aNYeAE_VNoYA,1372 +pip/_vendor/progress/spinner.py,sha256=k8JbDW94T0-WXuXfxZIFhdoNPYp3jfnpXqBnfRv5fGs,1380 +pip/_vendor/requests/__init__.py,sha256=orzv4-1uejMDc2v3LnTVneINGXiwqXSfrASoFBsYblE,4465 +pip/_vendor/requests/__version__.py,sha256=Xwky1FMlMkJJGidBM50JC7FKcosWzkjIW-WhQGrBdFM,441 +pip/_vendor/requests/_internal_utils.py,sha256=Zx3PnEUccyfsB-ie11nZVAW8qClJy0gx1qNME7rgT18,1096 +pip/_vendor/requests/adapters.py,sha256=e-bmKEApNVqFdylxuMJJfiaHdlmS_zhWhIMEzlHvGuc,21548 +pip/_vendor/requests/api.py,sha256=PlHM-HT3PQ5lyufoeGmV-nJxRi7UnUyGVh7OV7B9XV4,6496 +pip/_vendor/requests/auth.py,sha256=OMoJIVKyRLy9THr91y8rxysZuclwPB-K1Xg1zBomUhQ,10207 +pip/_vendor/requests/certs.py,sha256=nXRVq9DtGmv_1AYbwjTu9UrgAcdJv05ZvkNeaoLOZxY,465 +pip/_vendor/requests/compat.py,sha256=LQWuCR4qXk6w7-qQopXyz0WNHUdAD40k0mKnaAEf1-g,2045 +pip/_vendor/requests/cookies.py,sha256=Y-bKX6TvW3FnYlE6Au0SXtVVWcaNdFvuAwQxw-G0iTI,18430 +pip/_vendor/requests/exceptions.py,sha256=d9fJJw8YFBB9VzG9qhvxLuOx6be3c_Dwbck-dVUEAcs,3173 +pip/_vendor/requests/help.py,sha256=SJPVcoXeo7KfK4AxJN5eFVQCjr0im87tU2n7ubLsksU,3578 +pip/_vendor/requests/hooks.py,sha256=QReGyy0bRcr5rkwCuObNakbYsc7EkiKeBwG4qHekr2Q,757 +pip/_vendor/requests/models.py,sha256=_tKIbrscbGvaTdX1UHCwRaiYmPF9VBIuBeydr4Qx1Tg,34287 +pip/_vendor/requests/packages.py,sha256=njJmVifY4aSctuW3PP5EFRCxjEwMRDO6J_feG2dKWsI,695 +pip/_vendor/requests/sessions.py,sha256=OBtwQs1vjkB1xamFdi_p5y8BVeX16BJoQcwSwx_Y3fI,29316 +pip/_vendor/requests/status_codes.py,sha256=gT79Pbs_cQjBgp-fvrUgg1dn2DQO32bDj4TInjnMPSc,4188 +pip/_vendor/requests/structures.py,sha256=msAtr9mq1JxHd-JRyiILfdFlpbJwvvFuP3rfUQT_QxE,3005 +pip/_vendor/requests/utils.py,sha256=VBs99cvV8Z29WGXeWZqHzZ80_nu1AwwjYzJfe0wQIvs,30176 +pip/_vendor/resolvelib/__init__.py,sha256=sqMOy4CbVJQiaG9bCPj0oAntGAVy-RWdPfVaC9XDIEQ,537 +pip/_vendor/resolvelib/providers.py,sha256=TZDCmL-Ic-R5JRIZY8G4FLG5xB2343B0DfuK7aw2Yqw,4547 +pip/_vendor/resolvelib/reporters.py,sha256=ZPSJnVfK8WvXTbX8jE0Nren0-_Hg9ym4epCUPtU8Y0U,1405 +pip/_vendor/resolvelib/resolvers.py,sha256=lQTGcc-2fgHbmdiLzeNDUxVmGc5ZFjkAL6JrVqnqJIw,15018 +pip/_vendor/resolvelib/structs.py,sha256=yrdhd-n7DercimPGclXe20rgqhlxw8PnxC0wmcXO19Y,2016 +pip/_vendor/resolvelib/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/resolvelib/compat/collections_abc.py,sha256=mtTkpr3Gf3OGvU1PD8YuvrJRhVbioxV82T-niFPoX3o,127 +pip/_vendor/toml/__init__.py,sha256=rJ1pu933HgUtyeeNiusoPd5jJOPNhaKHhSSld3o8AQo,747 +pip/_vendor/toml/common.py,sha256=ViBccAduP6eZNJAb1POhRhjOAi56TDsNgWJ1TjgXAug,242 +pip/_vendor/toml/decoder.py,sha256=atpXmyFCzNGiqhkcYLySBuJQkPeSHDzBz47sEaX1amw,38696 +pip/_vendor/toml/encoder.py,sha256=fPqLyFdPAam17X9SELz2TMp9affkfHCmgWZxRKcmzhY,9955 +pip/_vendor/toml/ordered.py,sha256=UWt5Eka90IWVBYdvLgY5PXnkBcVYpHjnw9T67rM85T8,378 +pip/_vendor/toml/tz.py,sha256=DrAgI3wZxZiGcLuV_l8ueA_nPrYoxQ3hZA9tJSjWRsQ,618 +pip/_vendor/urllib3/__init__.py,sha256=rdFZCO1L7e8861ZTvo8AiSKwxCe9SnWQUQwJ599YV9c,2683 +pip/_vendor/urllib3/_collections.py,sha256=GouVsNzwg6jADZTmimMI6oqmwKSswnMo9dh5tGNVWO4,10792 +pip/_vendor/urllib3/connection.py,sha256=Fln8a_bkegdNMkFoSOwyI0PJvL1OqzVUO6ifihKOTpc,14461 +pip/_vendor/urllib3/connectionpool.py,sha256=egdaX-Db_LVXifDxv3JY0dHIpQqDv0wC0_9Eeh8FkPM,35725 +pip/_vendor/urllib3/exceptions.py,sha256=D2Jvab7M7m_n0rnmBmq481paoVT32VvVeB6VeQM0y-w,7172 +pip/_vendor/urllib3/fields.py,sha256=kroD76QK-GdHHW7f_AUN4XxDC3OQPI2FFrS9eSL4BCs,8553 +pip/_vendor/urllib3/filepost.py,sha256=vj0qbrpT1AFzvvW4SuC8M5kJiw7wftHcSr-7b8UpPpw,2440 +pip/_vendor/urllib3/poolmanager.py,sha256=iWEAIGrVNGoOmQyfiFwCqG-IyYy6GIQ-jJ9QCsX9li4,17861 +pip/_vendor/urllib3/request.py,sha256=hhoHvEEatyd9Tn5EbGjQ0emn-ENMCyY591yNWTneINA,6018 +pip/_vendor/urllib3/response.py,sha256=eo1Sfkn2x44FtjgP3qwwDsG9ak84spQAxEGy7Ovd4Pc,28221 +pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/contrib/_appengine_environ.py,sha256=bDbyOEhW2CKLJcQqAKAyrEHN-aklsyHFKq6vF8ZFsmk,957 +pip/_vendor/urllib3/contrib/appengine.py,sha256=gfdK4T7CRin7v9HRhHDbDh-Hbk66hHDWeoz7nV3PJo8,11034 +pip/_vendor/urllib3/contrib/ntlmpool.py,sha256=a402AwGN_Ll3N-4ur_AS6UrU-ycUtlnYqoBF76lORg8,4160 +pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=9gm5kpC0ScbDCWobeCrh5LDqS8HgU8FNhmk5v8qQ5Bs,16582 +pip/_vendor/urllib3/contrib/securetransport.py,sha256=vBDFjSnH2gWa-ztMKVaiwW46K1mlDZKqvo_VAonfdcY,32401 +pip/_vendor/urllib3/contrib/socks.py,sha256=nzDMgDIFJWVubKHqvIn2-SKCO91hhJInP92WgHChGzA,7036 +pip/_vendor/urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/contrib/_securetransport/bindings.py,sha256=mullWYFaghBdRWla6HYU-TBgFRTPLBEfxj3jplbeJmQ,16886 +pip/_vendor/urllib3/contrib/_securetransport/low_level.py,sha256=V7GnujxnWZh2N2sMsV5N4d9Imymokkm3zBwgt77_bSE,11956 +pip/_vendor/urllib3/packages/__init__.py,sha256=h4BLhD4tLaBx1adaDtKXfupsgqY0wWLXb_f1_yVlV6A,108 +pip/_vendor/urllib3/packages/six.py,sha256=adx4z-eM_D0Vvu0IIqVzFACQ_ux9l64y7DkSEfbxCDs,32536 +pip/_vendor/urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/packages/backports/makefile.py,sha256=005wrvH-_pWSnTFqQ2sdzzh4zVCtQUUQ4mR2Yyxwc0A,1418 +pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py,sha256=ywgKMtfHi1-DrXlzPfVAhzsLzzqcK7GT6eLgdode1Fg,688 +pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py,sha256=rvQDQviqQLtPJB6MfEgABnBFj3nXft7ZJ3Dx-BC0AQY,5696 +pip/_vendor/urllib3/util/__init__.py,sha256=bWNaav_OT-1L7-sxm59cGb59rDORlbhb_4noduM5m0U,1038 +pip/_vendor/urllib3/util/connection.py,sha256=NsxUAKQ98GKywta--zg57CdVpeTCI6N-GElCq78Dl8U,4637 +pip/_vendor/urllib3/util/queue.py,sha256=myTX3JDHntglKQNBf3b6dasHH-uF-W59vzGSQiFdAfI,497 +pip/_vendor/urllib3/util/request.py,sha256=C-6-AWffxZG03AdRGoY59uqsn4CVItKU6gjxz7Hc3Mc,3815 +pip/_vendor/urllib3/util/response.py,sha256=_WbTQr8xRQuJuY2rTIZxVdJD6mnEOtQupjaK_bF_Vj8,2573 +pip/_vendor/urllib3/util/retry.py,sha256=3wbv7SdzYNOxPcBiFkPCubTbK1_6vWSepznOXirhUfA,15543 +pip/_vendor/urllib3/util/ssl_.py,sha256=N7gqt2iqzKBsWGmc61YeKNSPri6Ns2iZ_MD5hV2y8tU,14523 +pip/_vendor/urllib3/util/timeout.py,sha256=3qawUo-TZq4q7tyeRToMIOdNGEOBjOOQVq7nHnLryP4,9947 +pip/_vendor/urllib3/util/url.py,sha256=S4YyAwWKJPjFFECC7l9Vp9EKqRH1XAb-uQFANn1Tak0,13981 +pip/_vendor/urllib3/util/wait.py,sha256=k46KzqIYu3Vnzla5YW3EvtInNlU_QycFqQAghIOxoAg,5406 +pip/_vendor/webencodings/__init__.py,sha256=qOBJIuPy_4ByYH6W_bNgJF-qYQ2DoU-dKsDu5yRWCXg,10579 +pip/_vendor/webencodings/labels.py,sha256=4AO_KxTddqGtrL9ns7kAPjb0CcN6xsCIxbK37HY9r3E,8979 +pip/_vendor/webencodings/mklabels.py,sha256=GYIeywnpaLnP0GSic8LFWgd0UVvO_l1Nc6YoF-87R_4,1305 +pip/_vendor/webencodings/tests.py,sha256=OtGLyjhNY1fvkW1GvLJ_FV9ZoqC9Anyjr7q3kxTbzNs,6563 +pip/_vendor/webencodings/x_user_defined.py,sha256=yOqWSdmpytGfUgh_Z6JYgDNhoc-BAHyyeeT15Fr42tM,4307 +pip-20.2.2.dist-info/LICENSE.txt,sha256=W6Ifuwlk-TatfRU2LR7W1JMcyMj5_y1NkRkOEJvnRDE,1090 +pip-20.2.2.dist-info/METADATA,sha256=ZMrQjU30hfRVRViE4qoVrwZzDSRyGCT8OdkDkkTMBv8,3708 +pip-20.2.2.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110 +pip-20.2.2.dist-info/entry_points.txt,sha256=HtfDOwpUlr9s73jqLQ6wF9V0_0qvUXJwCBz7Vwx0Ue0,125 +pip-20.2.2.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pip-20.2.2.dist-info/RECORD,, +pip/_internal/resolution/legacy/__init__.cpython-38.pyc,, +pip/_internal/distributions/base.cpython-38.pyc,, +pip/_vendor/requests/certs.cpython-38.pyc,, +pip/_vendor/colorama/winterm.cpython-38.pyc,, +pip/_vendor/requests/help.cpython-38.pyc,, +pip/_vendor/urllib3/packages/__init__.cpython-38.pyc,, +pip/_vendor/requests/compat.cpython-38.pyc,, +pip/_vendor/cachecontrol/caches/__init__.cpython-38.pyc,, +pip/_internal/operations/install/legacy.cpython-38.pyc,, +pip/_internal/utils/virtualenv.cpython-38.pyc,, +pip/_vendor/distlib/wheel.cpython-38.pyc,, +pip/_vendor/cachecontrol/controller.cpython-38.pyc,, +pip/_internal/index/__init__.cpython-38.pyc,, +pip/_vendor/chardet/charsetgroupprober.cpython-38.pyc,, +pip/_internal/operations/install/__init__.cpython-38.pyc,, +pip/_vendor/resolvelib/reporters.cpython-38.pyc,, +pip/_internal/models/__pycache__,, +pip/_vendor/distlib/compat.cpython-38.pyc,, +pip/_vendor/packaging/_structures.cpython-38.pyc,, +pip/_vendor/pep517/_in_process.cpython-38.pyc,, +pip/_vendor/html5lib/filters/lint.cpython-38.pyc,, +pip/_vendor/html5lib/treebuilders/dom.cpython-38.pyc,, +pip/_internal/utils/entrypoints.cpython-38.pyc,, +pip/_internal/utils/deprecation.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/low_level.cpython-38.pyc,, +pip/_vendor/distlib/markers.cpython-38.pyc,, +pip/_vendor/progress/bar.cpython-38.pyc,, +pip/_vendor/pep517/__pycache__,, +pip/_internal/utils/compatibility_tags.cpython-38.pyc,, +pip/_vendor/idna/idnadata.cpython-38.pyc,, +pip/_internal/commands/check.cpython-38.pyc,, +pip/_vendor/requests/status_codes.cpython-38.pyc,, +pip/_vendor/progress/counter.cpython-38.pyc,, +pip/_vendor/html5lib/html5parser.cpython-38.pyc,, +pip/_vendor/packaging/markers.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/appengine.cpython-38.pyc,, +pip/_internal/cli/__pycache__,, +pip/_vendor/chardet/langcyrillicmodel.cpython-38.pyc,, +pip/_vendor/cachecontrol/caches/__pycache__,, +pip/_vendor/colorama/__init__.cpython-38.pyc,, +pip/_internal/models/link.cpython-38.pyc,, +pip/_vendor/html5lib/treebuilders/etree_lxml.cpython-38.pyc,, +../../../bin/pip-3.8,, +pip/_internal/models/direct_url.cpython-38.pyc,, +pip/_vendor/idna/package_data.cpython-38.pyc,, +pip/_internal/cli/spinners.cpython-38.pyc,, +pip/_internal/build_env.cpython-38.pyc,, +pip/_vendor/chardet/utf8prober.cpython-38.pyc,, +pip/_vendor/urllib3/util/wait.cpython-38.pyc,, +pip/_vendor/retrying.cpython-38.pyc,, +pip/_vendor/cachecontrol/compat.cpython-38.pyc,, +pip/_vendor/requests/_internal_utils.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/requirements.cpython-38.pyc,, +pip/_vendor/progress/__pycache__,, +pip/_vendor/html5lib/treewalkers/genshi.cpython-38.pyc,, +pip/_internal/models/scheme.cpython-38.pyc,, +pip/_vendor/cachecontrol/filewrapper.cpython-38.pyc,, +pip/_internal/network/download.cpython-38.pyc,, +pip/_vendor/colorama/initialise.cpython-38.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__,, +pip/_vendor/toml/__init__.cpython-38.pyc,, +pip/_internal/cache.cpython-38.pyc,, +../../../bin/pip3,, +pip/_internal/models/search_scope.cpython-38.pyc,, +pip/_internal/configuration.cpython-38.pyc,, +pip/_internal/commands/__init__.cpython-38.pyc,, +pip/_vendor/chardet/enums.cpython-38.pyc,, +pip/_vendor/html5lib/__pycache__,, +pip/_vendor/urllib3/contrib/_securetransport/bindings.cpython-38.pyc,, +pip/_vendor/urllib3/__pycache__,, +pip/_internal/resolution/__pycache__,, +pip/_vendor/urllib3/contrib/pyopenssl.cpython-38.pyc,, +pip/_vendor/colorama/ansi.cpython-38.pyc,, +pip/_vendor/cachecontrol/heuristics.cpython-38.pyc,, +pip/_vendor/toml/encoder.cpython-38.pyc,, +pip/_internal/commands/download.cpython-38.pyc,, +pip/_vendor/cachecontrol/cache.cpython-38.pyc,, +pip/_vendor/chardet/langbulgarianmodel.cpython-38.pyc,, +pip/_vendor/html5lib/_trie/py.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/base.cpython-38.pyc,, +pip/_internal/commands/cache.cpython-38.pyc,, +pip/_vendor/packaging/__init__.cpython-38.pyc,, +pip/_internal/commands/uninstall.cpython-38.pyc,, +pip/_internal/cli/main.cpython-38.pyc,, +pip/_vendor/requests/cookies.cpython-38.pyc,, +pip/_internal/resolution/legacy/resolver.cpython-38.pyc,, +pip/_vendor/packaging/specifiers.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/securetransport.cpython-38.pyc,, +pip/_internal/req/req_install.cpython-38.pyc,, +pip/_internal/operations/install/__pycache__,, +pip/_internal/operations/build/__pycache__,, +pip/_vendor/chardet/gb2312freq.cpython-38.pyc,, +pip/_vendor/cachecontrol/wrapper.cpython-38.pyc,, +pip/_internal/utils/wheel.cpython-38.pyc,, +pip/_vendor/html5lib/treewalkers/base.cpython-38.pyc,, +pip/_internal/distributions/wheel.cpython-38.pyc,, +pip/_internal/cli/command_context.cpython-38.pyc,, +pip/_vendor/requests/hooks.cpython-38.pyc,, +pip/_vendor/chardet/chardistribution.cpython-38.pyc,, +pip/_internal/wheel_builder.cpython-38.pyc,, +pip/_vendor/toml/common.cpython-38.pyc,, +pip/_vendor/urllib3/util/__init__.cpython-38.pyc,, +pip/_internal/models/__init__.cpython-38.pyc,, +pip/_vendor/requests/__version__.cpython-38.pyc,, +pip/_internal/distributions/__pycache__,, +pip/_internal/operations/prepare.cpython-38.pyc,, +pip/_vendor/pyparsing.cpython-38.pyc,, +pip/_vendor/html5lib/filters/optionaltags.cpython-38.pyc,, +pip/_vendor/html5lib/filters/__init__.cpython-38.pyc,, +pip/_vendor/__pycache__,, +pip/_vendor/chardet/euckrprober.cpython-38.pyc,, +pip/_vendor/requests/adapters.cpython-38.pyc,, +pip/_vendor/pep517/__init__.cpython-38.pyc,, +pip/_vendor/html5lib/_ihatexml.cpython-38.pyc,, +pip/_internal/utils/distutils_args.cpython-38.pyc,, +pip/_internal/exceptions.cpython-38.pyc,, +pip-20.2.2.dist-info/__pycache__,, +pip/_vendor/resolvelib/compat/__pycache__,, +pip/_internal/vcs/bazaar.cpython-38.pyc,, +pip/_vendor/chardet/escsm.cpython-38.pyc,, +pip/_vendor/certifi/__init__.cpython-38.pyc,, +pip/_vendor/msgpack/ext.cpython-38.pyc,, +pip/_internal/cli/base_command.cpython-38.pyc,, +pip/_internal/utils/encoding.cpython-38.pyc,, +pip/_internal/utils/models.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/__pycache__,, +pip/_internal/utils/misc.cpython-38.pyc,, +pip/_vendor/toml/tz.cpython-38.pyc,, +pip/_internal/commands/__pycache__,, +pip/_vendor/html5lib/treeadapters/__pycache__,, +pip/_internal/operations/build/wheel.cpython-38.pyc,, +pip/_vendor/chardet/cli/__init__.cpython-38.pyc,, +pip/_vendor/html5lib/treewalkers/__init__.cpython-38.pyc,, +pip/_internal/commands/completion.cpython-38.pyc,, +pip/_vendor/contextlib2.cpython-38.pyc,, +pip/_vendor/resolvelib/compat/collections_abc.cpython-38.pyc,, +pip/_internal/utils/packaging.cpython-38.pyc,, +pip/_vendor/toml/ordered.cpython-38.pyc,, +pip/_internal/commands/wheel.cpython-38.pyc,, +pip/_vendor/requests/exceptions.cpython-38.pyc,, +pip/_internal/utils/urls.cpython-38.pyc,, +pip/_internal/operations/install/editable_legacy.cpython-38.pyc,, +pip/_vendor/html5lib/constants.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__,, +pip/_internal/utils/typing.cpython-38.pyc,, +pip/_internal/utils/filesystem.cpython-38.pyc,, +pip/_vendor/html5lib/__init__.cpython-38.pyc,, +pip/_vendor/distlib/index.cpython-38.pyc,, +pip/_internal/cli/req_command.cpython-38.pyc,, +pip/_internal/resolution/legacy/__pycache__,, +pip/_internal/main.cpython-38.pyc,, +pip/_internal/distributions/__init__.cpython-38.pyc,, +pip/_vendor/chardet/langhebrewmodel.cpython-38.pyc,, +pip/_internal/utils/__init__.cpython-38.pyc,, +pip/_vendor/chardet/escprober.cpython-38.pyc,, +pip/_vendor/chardet/compat.cpython-38.pyc,, +pip/_internal/vcs/__pycache__,, +pip/_internal/operations/install/wheel.cpython-38.pyc,, +pip/_internal/index/package_finder.cpython-38.pyc,, +pip/_vendor/pkg_resources/__init__.cpython-38.pyc,, +pip/_vendor/pep517/colorlog.cpython-38.pyc,, +pip/_vendor/chardet/version.cpython-38.pyc,, +pip/_vendor/packaging/_compat.cpython-38.pyc,, +pip/_internal/utils/compat.cpython-38.pyc,, +pip/_vendor/chardet/sbcsgroupprober.cpython-38.pyc,, +pip/_vendor/distro.cpython-38.pyc,, +pip/_vendor/chardet/jisfreq.cpython-38.pyc,, +pip/_internal/locations.cpython-38.pyc,, +pip/_vendor/html5lib/treewalkers/etree_lxml.cpython-38.pyc,, +pip/_vendor/pep517/build.cpython-38.pyc,, +pip/_vendor/packaging/version.cpython-38.pyc,, +pip/_vendor/html5lib/treeadapters/genshi.cpython-38.pyc,, +pip/_internal/network/__pycache__,, +pip/_vendor/html5lib/serializer.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/__init__.cpython-38.pyc,, +pip/_vendor/cachecontrol/caches/redis_cache.cpython-38.pyc,, +pip/_vendor/html5lib/_tokenizer.cpython-38.pyc,, +pip/_internal/commands/hash.cpython-38.pyc,, +pip/_vendor/urllib3/util/__pycache__,, +pip/_vendor/resolvelib/structs.cpython-38.pyc,, +pip/_vendor/urllib3/connectionpool.cpython-38.pyc,, +pip/_vendor/html5lib/treewalkers/dom.cpython-38.pyc,, +pip/_vendor/html5lib/treebuilders/__init__.cpython-38.pyc,, +pip/_vendor/html5lib/treeadapters/sax.cpython-38.pyc,, +pip/_vendor/urllib3/packages/backports/__init__.cpython-38.pyc,, +pip/_internal/vcs/subversion.cpython-38.pyc,, +pip/_internal/network/__init__.cpython-38.pyc,, +pip/_vendor/requests/structures.cpython-38.pyc,, +pip/_internal/vcs/git.cpython-38.pyc,, +pip/_vendor/msgpack/exceptions.cpython-38.pyc,, +pip/_vendor/cachecontrol/serialize.cpython-38.pyc,, +pip/_vendor/urllib3/util/url.cpython-38.pyc,, +pip/_internal/utils/temp_dir.cpython-38.pyc,, +pip/_vendor/html5lib/_trie/__pycache__,, +pip/_internal/distributions/sdist.cpython-38.pyc,, +pip/_vendor/html5lib/filters/base.cpython-38.pyc,, +pip/_internal/vcs/mercurial.cpython-38.pyc,, +pip/_vendor/pep517/check.cpython-38.pyc,, +pip/_vendor/chardet/langthaimodel.cpython-38.pyc,, +pip/_internal/req/__init__.cpython-38.pyc,, +pip/_vendor/packaging/requirements.cpython-38.pyc,, +pip/_internal/commands/help.cpython-38.pyc,, +pip/_internal/network/utils.cpython-38.pyc,, +pip/_vendor/idna/core.cpython-38.pyc,, +pip/_internal/operations/build/wheel_legacy.cpython-38.pyc,, +pip/_vendor/urllib3/packages/six.cpython-38.pyc,, +pip/_vendor/html5lib/filters/whitespace.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/candidates.cpython-38.pyc,, +pip/_vendor/html5lib/_trie/_base.cpython-38.pyc,, +pip/_internal/operations/check.cpython-38.pyc,, +pip/_internal/distributions/installed.cpython-38.pyc,, +pip/_vendor/html5lib/treebuilders/etree.cpython-38.pyc,, +pip/_vendor/chardet/langturkishmodel.cpython-38.pyc,, +pip/_internal/utils/direct_url_helpers.cpython-38.pyc,, +pip/_internal/operations/build/__init__.cpython-38.pyc,, +pip/_internal/pyproject.cpython-38.pyc,, +pip/_vendor/urllib3/_collections.cpython-38.pyc,, +pip/_vendor/urllib3/util/connection.cpython-38.pyc,, +pip/__pycache__,, +pip/_vendor/distlib/_backport/shutil.cpython-38.pyc,, +pip/_vendor/idna/__init__.cpython-38.pyc,, +pip/_internal/operations/__pycache__,, +pip/_internal/vcs/__init__.cpython-38.pyc,, +pip/_vendor/toml/decoder.cpython-38.pyc,, +pip/_vendor/cachecontrol/adapter.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/__pycache__,, +pip/_internal/utils/pkg_resources.cpython-38.pyc,, +pip/_vendor/chardet/mbcharsetprober.cpython-38.pyc,, +pip/_internal/network/auth.cpython-38.pyc,, +pip/_vendor/pkg_resources/__pycache__,, +pip/_vendor/html5lib/treeadapters/__init__.cpython-38.pyc,, +pip/_vendor/html5lib/filters/__pycache__,, +pip/_internal/operations/build/metadata_legacy.cpython-38.pyc,, +pip/_internal/commands/show.cpython-38.pyc,, +pip/_vendor/appdirs.cpython-38.pyc,, +pip/_vendor/webencodings/mklabels.cpython-38.pyc,, +pip/_vendor/urllib3/util/queue.cpython-38.pyc,, +pip/_vendor/urllib3/util/retry.cpython-38.pyc,, +pip/_vendor/colorama/__pycache__,, +pip/_vendor/webencodings/labels.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/__init__.cpython-38.pyc,, +pip/_vendor/msgpack/_version.cpython-38.pyc,, +pip/_vendor/resolvelib/compat/__init__.cpython-38.pyc,, +pip/_vendor/pep517/compat.cpython-38.pyc,, +pip/_vendor/html5lib/filters/sanitizer.cpython-38.pyc,, +pip/_vendor/urllib3/packages/backports/makefile.cpython-38.pyc,, +pip/_vendor/chardet/gb2312prober.cpython-38.pyc,, +pip/_vendor/requests/models.cpython-38.pyc,, +pip/_vendor/resolvelib/__init__.cpython-38.pyc,, +pip/_vendor/webencodings/__init__.cpython-38.pyc,, +pip/_vendor/distlib/__pycache__,, +pip/_vendor/cachecontrol/__init__.cpython-38.pyc,, +pip/_vendor/certifi/core.cpython-38.pyc,, +pip/_internal/req/req_file.cpython-38.pyc,, +pip/_internal/index/collector.cpython-38.pyc,, +pip/_vendor/requests/packages.cpython-38.pyc,, +pip/_vendor/chardet/cp949prober.cpython-38.pyc,, +pip/_vendor/progress/__init__.cpython-38.pyc,, +pip/_internal/operations/build/metadata.cpython-38.pyc,, +pip/_vendor/toml/__pycache__,, +pip/_vendor/html5lib/_inputstream.cpython-38.pyc,, +../../../bin/pip,, +pip/_vendor/idna/intranges.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/_appengine_environ.cpython-38.pyc,, +pip/_vendor/requests/__pycache__,, +pip/_vendor/requests/auth.cpython-38.pyc,, +pip/_internal/utils/setuptools_build.cpython-38.pyc,, +pip/_vendor/distlib/database.cpython-38.pyc,, +pip/_vendor/distlib/_backport/sysconfig.cpython-38.pyc,, +pip/__init__.cpython-38.pyc,, +pip/_vendor/idna/codec.cpython-38.pyc,, +pip/_internal/utils/inject_securetransport.cpython-38.pyc,, +pip/_vendor/distlib/metadata.cpython-38.pyc,, +pip/_vendor/pkg_resources/py31compat.cpython-38.pyc,, +pip/_internal/cli/parser.cpython-38.pyc,, +pip/_internal/resolution/__init__.cpython-38.pyc,, +pip/_internal/network/cache.cpython-38.pyc,, +pip/_vendor/urllib3/packages/backports/__pycache__,, +pip/_internal/network/session.cpython-38.pyc,, +pip/_vendor/urllib3/packages/__pycache__,, +pip/_vendor/urllib3/filepost.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/__pycache__,, +pip/_vendor/html5lib/treewalkers/etree.cpython-38.pyc,, +pip/_internal/__init__.cpython-38.pyc,, +pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__,, +pip/_vendor/chardet/charsetprober.cpython-38.pyc,, +pip/_vendor/chardet/latin1prober.cpython-38.pyc,, +pip/_vendor/pep517/dirtools.cpython-38.pyc,, +pip-20.2.2.virtualenv,, +pip/_vendor/resolvelib/__pycache__,, +pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.cpython-38.pyc,, +pip/_vendor/distlib/_backport/__pycache__,, +pip/_vendor/chardet/mbcssm.cpython-38.pyc,, +pip/_vendor/idna/__pycache__,, +pip/_internal/operations/__init__.cpython-38.pyc,, +pip/_vendor/packaging/utils.cpython-38.pyc,, +pip/_vendor/urllib3/util/timeout.cpython-38.pyc,, +pip/_vendor/distlib/util.cpython-38.pyc,, +pip/_vendor/cachecontrol/caches/file_cache.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/provider.cpython-38.pyc,, +pip/_vendor/chardet/mbcsgroupprober.cpython-38.pyc,, +pip/_vendor/pep517/meta.cpython-38.pyc,, +pip/_vendor/cachecontrol/__pycache__,, +pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.cpython-38.pyc,, +pip/_internal/req/constructors.cpython-38.pyc,, +pip/_internal/models/index.cpython-38.pyc,, +pip/_internal/models/format_control.cpython-38.pyc,, +pip/_vendor/chardet/big5prober.cpython-38.pyc,, +pip/_internal/utils/hashes.cpython-38.pyc,, +pip/_vendor/cachecontrol/_cmd.cpython-38.pyc,, +pip/_vendor/distlib/_backport/misc.cpython-38.pyc,, +pip/_internal/vcs/versioncontrol.cpython-38.pyc,, +pip/__main__.cpython-38.pyc,, +pip/_vendor/msgpack/__pycache__,, +pip/_vendor/colorama/win32.cpython-38.pyc,, +pip/_vendor/html5lib/filters/alphabeticalattributes.cpython-38.pyc,, +pip/_internal/req/req_uninstall.cpython-38.pyc,, +pip/_vendor/certifi/__pycache__,, +pip/_internal/network/xmlrpc.cpython-38.pyc,, +pip/_vendor/webencodings/tests.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/resolver.cpython-38.pyc,, +pip/_vendor/urllib3/exceptions.cpython-38.pyc,, +pip/_vendor/idna/uts46data.cpython-38.pyc,, +pip/_internal/cli/cmdoptions.cpython-38.pyc,, +pip/_vendor/html5lib/_trie/__init__.cpython-38.pyc,, +pip/_internal/cli/progress_bars.cpython-38.pyc,, +pip/_vendor/urllib3/util/ssl_.cpython-38.pyc,, +pip/_vendor/distlib/__init__.cpython-38.pyc,, +pip/_vendor/progress/spinner.cpython-38.pyc,, +pip/_internal/commands/search.cpython-38.pyc,, +pip/_internal/operations/freeze.cpython-38.pyc,, +pip/_internal/network/lazy_wheel.cpython-38.pyc,, +pip/_vendor/requests/__init__.cpython-38.pyc,, +pip/_vendor/packaging/__about__.cpython-38.pyc,, +pip/_vendor/chardet/langgreekmodel.cpython-38.pyc,, +pip/_internal/utils/logging.cpython-38.pyc,, +pip/_vendor/html5lib/treebuilders/base.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/factory.cpython-38.pyc,, +pip/_vendor/pep517/envbuild.cpython-38.pyc,, +pip/_internal/resolution/base.cpython-38.pyc,, +pip/_vendor/chardet/__init__.cpython-38.pyc,, +pip/_vendor/chardet/jpcntx.cpython-38.pyc,, +pip/_vendor/chardet/codingstatemachine.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/__init__.cpython-38.pyc,, +pip/_vendor/distlib/resources.cpython-38.pyc,, +pip/_vendor/resolvelib/resolvers.cpython-38.pyc,, +pip/_vendor/urllib3/fields.cpython-38.pyc,, +pip/_internal/cli/main_parser.cpython-38.pyc,, +pip/_internal/index/__pycache__,, +pip/_internal/utils/parallel.cpython-38.pyc,, +pip/_internal/commands/debug.cpython-38.pyc,, +pip/_vendor/colorama/ansitowin32.cpython-38.pyc,, +pip/_vendor/chardet/sbcharsetprober.cpython-38.pyc,, +pip/_internal/cli/autocompletion.cpython-38.pyc,, +pip/_vendor/urllib3/util/request.cpython-38.pyc,, +pip/_vendor/distlib/_backport/__init__.cpython-38.pyc,, +pip/_internal/models/selection_prefs.cpython-38.pyc,, +pip/_vendor/chardet/cli/chardetect.cpython-38.pyc,, +pip/_vendor/urllib3/request.cpython-38.pyc,, +pip/_internal/utils/__pycache__,, +pip/_internal/models/target_python.cpython-38.pyc,, +pip/_vendor/resolvelib/providers.cpython-38.pyc,, +pip/_vendor/packaging/tags.cpython-38.pyc,, +pip/_internal/commands/freeze.cpython-38.pyc,, +pip/_vendor/distlib/manifest.cpython-38.pyc,, +pip/_vendor/__init__.cpython-38.pyc,, +pip/_vendor/chardet/euctwprober.cpython-38.pyc,, +pip/_vendor/chardet/euckrfreq.cpython-38.pyc,, +pip/_vendor/webencodings/x_user_defined.cpython-38.pyc,, +pip/_internal/models/wheel.cpython-38.pyc,, +pip/_internal/cli/status_codes.cpython-38.pyc,, +pip/_internal/utils/appdirs.cpython-38.pyc,, +pip/_vendor/requests/sessions.cpython-38.pyc,, +pip/_vendor/six.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/ntlmpool.cpython-38.pyc,, +pip/_vendor/chardet/sjisprober.cpython-38.pyc,, +pip/_internal/utils/datetime.cpython-38.pyc,, +pip/_vendor/certifi/__main__.cpython-38.pyc,, +pip/_internal/self_outdated_check.cpython-38.pyc,, +pip/_vendor/chardet/eucjpprober.cpython-38.pyc,, +pip/_vendor/distlib/_backport/tarfile.cpython-38.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__,, +pip/_vendor/urllib3/response.cpython-38.pyc,, +pip/_internal/commands/list.cpython-38.pyc,, +pip/_vendor/html5lib/filters/inject_meta_charset.cpython-38.pyc,, +pip/_internal/req/req_tracker.cpython-38.pyc,, +pip/_vendor/urllib3/connection.cpython-38.pyc,, +pip/_internal/cli/__init__.cpython-38.pyc,, +pip/_vendor/idna/compat.cpython-38.pyc,, +../../../bin/pip3.8,, +pip/_vendor/msgpack/fallback.cpython-38.pyc,, +pip/_vendor/chardet/universaldetector.cpython-38.pyc,, +pip/_vendor/chardet/hebrewprober.cpython-38.pyc,, +pip/_vendor/pep517/wrappers.cpython-38.pyc,, +pip/_internal/commands/install.cpython-38.pyc,, +pip/_vendor/chardet/big5freq.cpython-38.pyc,, +pip/_vendor/requests/api.cpython-38.pyc,, +pip/_internal/utils/subprocess.cpython-38.pyc,, +pip/_internal/utils/filetypes.cpython-38.pyc,, +pip/_vendor/distlib/scripts.cpython-38.pyc,, +pip/_internal/req/req_set.cpython-38.pyc,, +pip-20.2.2.dist-info/INSTALLER,, +pip/_vendor/webencodings/__pycache__,, +pip/_vendor/msgpack/__init__.cpython-38.pyc,, +pip/_internal/req/__pycache__,, +pip/_vendor/chardet/cli/__pycache__,, +pip/_vendor/distlib/locators.cpython-38.pyc,, +pip/_vendor/urllib3/__init__.cpython-38.pyc,, +pip/_vendor/requests/utils.cpython-38.pyc,, +pip/_vendor/ipaddress.cpython-38.pyc,, +pip/_vendor/packaging/_typing.cpython-38.pyc,, +pip/_vendor/chardet/langhungarianmodel.cpython-38.pyc,, +pip/_vendor/chardet/euctwfreq.cpython-38.pyc,, +pip/_internal/utils/glibc.cpython-38.pyc,, +pip/_vendor/html5lib/_utils.cpython-38.pyc,, +pip/_internal/models/candidate.cpython-38.pyc,, +pip/_internal/utils/unpacking.cpython-38.pyc,, +pip/_vendor/packaging/__pycache__,, +pip/_vendor/distlib/version.cpython-38.pyc,, +pip/_internal/commands/configuration.cpython-38.pyc,, +pip/_vendor/urllib3/poolmanager.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/socks.cpython-38.pyc,, +pip/_internal/__pycache__,, +pip/_vendor/urllib3/util/response.cpython-38.pyc,, \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/WHEEL b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/WHEEL new file mode 100644 index 00000000000..ef99c6cf328 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.34.2) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/entry_points.txt b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/entry_points.txt new file mode 100644 index 00000000000..d48bd8a85e6 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/entry_points.txt @@ -0,0 +1,5 @@ +[console_scripts] +pip = pip._internal.cli.main:main +pip3 = pip._internal.cli.main:main +pip3.8 = pip._internal.cli.main:main + diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/top_level.txt b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/top_level.txt new file mode 100644 index 00000000000..a1b589e38a3 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/pip-20.2.2.dist-info/top_level.txt @@ -0,0 +1 @@ +pip diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info-METADATA-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info-METADATA-expected.json new file mode 100644 index 00000000000..8f2dc5929ca --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info-METADATA-expected.json @@ -0,0 +1,56 @@ +{ + "type": "pypi", + "namespace": null, + "name": "python-mimeparse", + "version": "1.6.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "A module provides basic functions for parsing mime-type names and matching them against a list of media-ranges.\nPython-MimeParse\n================\n\n.. image:: https://travis-ci.org/dbtsai/python-mimeparse.svg?branch=master\n :target: https://travis-ci.org/dbtsai/python-mimeparse\n\nThis module provides basic functions for handling mime-types. It can\nhandle matching mime-types against a list of media-ranges. See section\n5.3.2 of the HTTP 1.1 Semantics and Content specification [RFC 7231] for\na complete explanation: https://tools.ietf.org/html/rfc7231#section-5.3.2\n\nInstallation\n------------\n\nUse **pip**:\n\n.. code-block:: sh\n\n $ pip install python-mimeparse\n\nIt supports Python 2.7 - 3.5 and PyPy.\n\nFunctions\n---------\n\n**parse_mime_type()**\n\nParses a mime-type into its component parts.\n\n**parse_media_range()**\n\nMedia-ranges are mime-types with wild-cards and a \"q\" quality parameter.\n\n**quality()**\n\nDetermines the quality (\"q\") of a mime-type when compared against a list of\nmedia-ranges.\n\n**quality_parsed()**\n\nJust like ``quality()`` except the second parameter must be pre-parsed.\n\n**best_match()**\n\nChoose the mime-type with the highest quality (\"q\") from a list of candidates.\n\nTesting\n-------\n\nRun the tests by typing: ``python mimeparse_test.py``. The tests require Python 2.6.\n\nTo make sure that the package works in all the supported environments, you can\nrun **tox** tests:\n\n.. code-block:: sh\n\n $ pip install tox\n $ tox\n\nThe format of the JSON test data file is as follows: A top-level JSON object\nwhich has a key for each of the functions to be tested. The value corresponding\nto that key is a list of tests. Each test contains: the argument or arguments\nto the function being tested, the expected results and an optional description.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "DB Tsai", + "email": "dbtsai@dbtsai.com", + "url": null + } + ], + "keywords": [ + "mime-type", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Operating System :: OS Independent", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Software Development :: Libraries :: Python Modules" + ], + "homepage_url": "https://github.com/dbtsai/python-mimeparse", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": "https://github.com/dbtsai/python-mimeparse/tarball/1.6.0", + "copyright": null, + "license_expression": "mit", + "declared_license": { + "classifiers": [ + "License :: OSI Approved :: MIT License" + ] + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/python-mimeparse@1.6.0", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/python-mimeparse/python-mimeparse-1.6.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/python-mimeparse/1.6.0/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info-expected.json new file mode 100644 index 00000000000..8f2dc5929ca --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info-expected.json @@ -0,0 +1,56 @@ +{ + "type": "pypi", + "namespace": null, + "name": "python-mimeparse", + "version": "1.6.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "A module provides basic functions for parsing mime-type names and matching them against a list of media-ranges.\nPython-MimeParse\n================\n\n.. image:: https://travis-ci.org/dbtsai/python-mimeparse.svg?branch=master\n :target: https://travis-ci.org/dbtsai/python-mimeparse\n\nThis module provides basic functions for handling mime-types. It can\nhandle matching mime-types against a list of media-ranges. See section\n5.3.2 of the HTTP 1.1 Semantics and Content specification [RFC 7231] for\na complete explanation: https://tools.ietf.org/html/rfc7231#section-5.3.2\n\nInstallation\n------------\n\nUse **pip**:\n\n.. code-block:: sh\n\n $ pip install python-mimeparse\n\nIt supports Python 2.7 - 3.5 and PyPy.\n\nFunctions\n---------\n\n**parse_mime_type()**\n\nParses a mime-type into its component parts.\n\n**parse_media_range()**\n\nMedia-ranges are mime-types with wild-cards and a \"q\" quality parameter.\n\n**quality()**\n\nDetermines the quality (\"q\") of a mime-type when compared against a list of\nmedia-ranges.\n\n**quality_parsed()**\n\nJust like ``quality()`` except the second parameter must be pre-parsed.\n\n**best_match()**\n\nChoose the mime-type with the highest quality (\"q\") from a list of candidates.\n\nTesting\n-------\n\nRun the tests by typing: ``python mimeparse_test.py``. The tests require Python 2.6.\n\nTo make sure that the package works in all the supported environments, you can\nrun **tox** tests:\n\n.. code-block:: sh\n\n $ pip install tox\n $ tox\n\nThe format of the JSON test data file is as follows: A top-level JSON object\nwhich has a key for each of the functions to be tested. The value corresponding\nto that key is a list of tests. Each test contains: the argument or arguments\nto the function being tested, the expected results and an optional description.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "DB Tsai", + "email": "dbtsai@dbtsai.com", + "url": null + } + ], + "keywords": [ + "mime-type", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Operating System :: OS Independent", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Software Development :: Libraries :: Python Modules" + ], + "homepage_url": "https://github.com/dbtsai/python-mimeparse", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": "https://github.com/dbtsai/python-mimeparse/tarball/1.6.0", + "copyright": null, + "license_expression": "mit", + "declared_license": { + "classifiers": [ + "License :: OSI Approved :: MIT License" + ] + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/python-mimeparse@1.6.0", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/p/python-mimeparse/python-mimeparse-1.6.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/python-mimeparse/1.6.0/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/DESCRIPTION.rst b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/DESCRIPTION.rst new file mode 100644 index 00000000000..5d85d06eda5 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/DESCRIPTION.rst @@ -0,0 +1,65 @@ +Python-MimeParse +================ + +.. image:: https://travis-ci.org/dbtsai/python-mimeparse.svg?branch=master + :target: https://travis-ci.org/dbtsai/python-mimeparse + +This module provides basic functions for handling mime-types. It can +handle matching mime-types against a list of media-ranges. See section +5.3.2 of the HTTP 1.1 Semantics and Content specification [RFC 7231] for +a complete explanation: https://tools.ietf.org/html/rfc7231#section-5.3.2 + +Installation +------------ + +Use **pip**: + +.. code-block:: sh + + $ pip install python-mimeparse + +It supports Python 2.7 - 3.5 and PyPy. + +Functions +--------- + +**parse_mime_type()** + +Parses a mime-type into its component parts. + +**parse_media_range()** + +Media-ranges are mime-types with wild-cards and a "q" quality parameter. + +**quality()** + +Determines the quality ("q") of a mime-type when compared against a list of +media-ranges. + +**quality_parsed()** + +Just like ``quality()`` except the second parameter must be pre-parsed. + +**best_match()** + +Choose the mime-type with the highest quality ("q") from a list of candidates. + +Testing +------- + +Run the tests by typing: ``python mimeparse_test.py``. The tests require Python 2.6. + +To make sure that the package works in all the supported environments, you can +run **tox** tests: + +.. code-block:: sh + + $ pip install tox + $ tox + +The format of the JSON test data file is as follows: A top-level JSON object +which has a key for each of the functions to be tested. The value corresponding +to that key is a list of tests. Each test contains: the argument or arguments +to the function being tested, the expected results and an optional description. + + diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/METADATA b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/METADATA new file mode 100644 index 00000000000..c54c4cbad0b --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/METADATA @@ -0,0 +1,85 @@ +Metadata-Version: 2.0 +Name: python-mimeparse +Version: 1.6.0 +Summary: A module provides basic functions for parsing mime-type names and matching them against a list of media-ranges. +Home-page: https://github.com/dbtsai/python-mimeparse +Author: DB Tsai +Author-email: dbtsai@dbtsai.com +License: UNKNOWN +Download-URL: https://github.com/dbtsai/python-mimeparse/tarball/1.6.0 +Keywords: mime-type +Platform: UNKNOWN +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: Software Development :: Libraries :: Python Modules + +Python-MimeParse +================ + +.. image:: https://travis-ci.org/dbtsai/python-mimeparse.svg?branch=master + :target: https://travis-ci.org/dbtsai/python-mimeparse + +This module provides basic functions for handling mime-types. It can +handle matching mime-types against a list of media-ranges. See section +5.3.2 of the HTTP 1.1 Semantics and Content specification [RFC 7231] for +a complete explanation: https://tools.ietf.org/html/rfc7231#section-5.3.2 + +Installation +------------ + +Use **pip**: + +.. code-block:: sh + + $ pip install python-mimeparse + +It supports Python 2.7 - 3.5 and PyPy. + +Functions +--------- + +**parse_mime_type()** + +Parses a mime-type into its component parts. + +**parse_media_range()** + +Media-ranges are mime-types with wild-cards and a "q" quality parameter. + +**quality()** + +Determines the quality ("q") of a mime-type when compared against a list of +media-ranges. + +**quality_parsed()** + +Just like ``quality()`` except the second parameter must be pre-parsed. + +**best_match()** + +Choose the mime-type with the highest quality ("q") from a list of candidates. + +Testing +------- + +Run the tests by typing: ``python mimeparse_test.py``. The tests require Python 2.6. + +To make sure that the package works in all the supported environments, you can +run **tox** tests: + +.. code-block:: sh + + $ pip install tox + $ tox + +The format of the JSON test data file is as follows: A top-level JSON object +which has a key for each of the functions to be tested. The value corresponding +to that key is a list of tests. Each test contains: the argument or arguments +to the function being tested, the expected results and an optional description. + + diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/RECORD b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/RECORD new file mode 100644 index 00000000000..13f3fc3b169 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/RECORD @@ -0,0 +1,7 @@ +mimeparse.py,sha256=vVux7CH9sAPzG19VAutJYdsMXvI2-DDPwhKWrnZTYXk,6246 +python_mimeparse-1.6.0.dist-info/DESCRIPTION.rst,sha256=O3zpmkzVVZFRtB6S5rj77EghcW6U6GCHnUtCsImkmYk,1654 +python_mimeparse-1.6.0.dist-info/METADATA,sha256=dPCXpiGGyX1a5nUdWXxGabZ2x5DgLBF9x14W-_w_8Xc,2468 +python_mimeparse-1.6.0.dist-info/metadata.json,sha256=Th7feARhnxs9ymbP-272Nwl316_A-TeKgNObkz9nvok,935 +python_mimeparse-1.6.0.dist-info/RECORD,, +python_mimeparse-1.6.0.dist-info/top_level.txt,sha256=6YkoScDaYr1J_VKKBYKvUaTZAy1NBG770gnFsLGuzxg,10 +python_mimeparse-1.6.0.dist-info/WHEEL,sha256=AvR0WeTpDaxT645bl5FQxUK6NPsTls2ttpcGJg3j1Xg,110 diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/WHEEL b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/WHEEL new file mode 100644 index 00000000000..9dff69d8610 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.24.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/metadata.json b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/metadata.json new file mode 100644 index 00000000000..86952c2c6cc --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/metadata.json @@ -0,0 +1 @@ +{"name": "python-mimeparse", "metadata_version": "2.0", "generator": "bdist_wheel (0.24.0)", "download_url": "https://github.com/dbtsai/python-mimeparse/tarball/1.6.0", "summary": "A module provides basic functions for parsing mime-type names and matching them against a list of media-ranges.", "version": "1.6.0", "extensions": {"python.details": {"project_urls": {"Home": "https://github.com/dbtsai/python-mimeparse"}, "document_names": {"description": "DESCRIPTION.rst"}, "contacts": [{"role": "author", "email": "dbtsai@dbtsai.com", "name": "DB Tsai"}]}}, "keywords": ["mime-type"], "classifiers": ["Programming Language :: Python", "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries :: Python Modules"]} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/top_level.txt b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/top_level.txt new file mode 100644 index 00000000000..b3b48e9ca93 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/top_level.txt @@ -0,0 +1 @@ +mimeparse diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info-METADATA-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info-METADATA-expected.json new file mode 100644 index 00000000000..fab947da9fa --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info-METADATA-expected.json @@ -0,0 +1,65 @@ +{ + "type": "pypi", + "namespace": null, + "name": "toml", + "version": "0.10.1", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Python Library for Tom's Obvious, Minimal Language\n****\nTOML\n****\n\n.. image:: https://badge.fury.io/py/toml.svg\n :target: https://badge.fury.io/py/toml\n\n.. image:: https://travis-ci.org/uiri/toml.svg?branch=master\n :target: https://travis-ci.org/uiri/toml\n\n.. image:: https://img.shields.io/pypi/pyversions/toml.svg\n :target: https://pypi.org/project/toml/\n\n\nA Python library for parsing and creating `TOML `_.\n\nThe module passes `the TOML test suite `_.\n\nSee also:\n\n* `The TOML Standard `_\n* `The currently supported TOML specification `_\n\nInstallation\n============\n\nTo install the latest release on `PyPI `_,\nsimply run:\n\n::\n\n pip install toml\n\nOr to install the latest development version, run:\n\n::\n\n git clone https://github.com/uiri/toml.git\n cd toml\n python setup.py install\n\nQuick Tutorial\n==============\n\n*toml.loads* takes in a string containing standard TOML-formatted data and\nreturns a dictionary containing the parsed data.\n\n.. code:: pycon\n\n >>> import toml\n >>> toml_string = \"\"\"\n ... # This is a TOML document.\n ...\n ... title = \"TOML Example\"\n ...\n ... [owner]\n ... name = \"Tom Preston-Werner\"\n ... dob = 1979-05-27T07:32:00-08:00 # First class dates\n ...\n ... [database]\n ... server = \"192.168.1.1\"\n ... ports = [ 8001, 8001, 8002 ]\n ... connection_max = 5000\n ... enabled = true\n ...\n ... [servers]\n ...\n ... # Indentation (tabs and/or spaces) is allowed but not required\n ... [servers.alpha]\n ... ip = \"10.0.0.1\"\n ... dc = \"eqdc10\"\n ...\n ... [servers.beta]\n ... ip = \"10.0.0.2\"\n ... dc = \"eqdc10\"\n ...\n ... [clients]\n ... data = [ [\"gamma\", \"delta\"], [1, 2] ]\n ...\n ... # Line breaks are OK when inside arrays\n ... hosts = [\n ... \"alpha\",\n ... \"omega\"\n ... ]\n ... \"\"\"\n >>> parsed_toml = toml.loads(toml_string)\n\n\n*toml.dumps* takes a dictionary and returns a string containing the\ncorresponding TOML-formatted data.\n\n.. code:: pycon\n\n >>> new_toml_string = toml.dumps(parsed_toml)\n >>> print(new_toml_string)\n title = \"TOML Example\"\n [owner]\n name = \"Tom Preston-Werner\"\n dob = 1979-05-27T07:32:00Z\n [database]\n server = \"192.168.1.1\"\n ports = [ 8001, 8001, 8002,]\n connection_max = 5000\n enabled = true\n [clients]\n data = [ [ \"gamma\", \"delta\",], [ 1, 2,],]\n hosts = [ \"alpha\", \"omega\",]\n [servers.alpha]\n ip = \"10.0.0.1\"\n dc = \"eqdc10\"\n [servers.beta]\n ip = \"10.0.0.2\"\n dc = \"eqdc10\"\n\nFor more functions, view the API Reference below.\n\nNote\n----\n\nFor Numpy users, by default the data types ``np.floatX`` will not be translated to floats by toml, but will instead be encoded as strings. To get around this, specify the ``TomlNumpyEncoder`` when saving your data.\n\n.. code:: pycon\n\n >>> import toml\n >>> import numpy as np\n >>> a = np.arange(0, 10, dtype=np.double)\n >>> output = {'a': a}\n >>> toml.dumps(output)\n 'a = [ \"0.0\", \"1.0\", \"2.0\", \"3.0\", \"4.0\", \"5.0\", \"6.0\", \"7.0\", \"8.0\", \"9.0\",]\\n'\n >>> toml.dumps(output, encoder=toml.TomlNumpyEncoder())\n 'a = [ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0,]\\n'\n\nAPI Reference\n=============\n\n``toml.load(f, _dict=dict)``\n Parse a file or a list of files as TOML and return a dictionary.\n\n :Args:\n * ``f``: A path to a file, list of filepaths (to be read into single\n object) or a file descriptor\n * ``_dict``: The class of the dictionary object to be returned\n\n :Returns:\n A dictionary (or object ``_dict``) containing parsed TOML data\n\n :Raises:\n * ``TypeError``: When ``f`` is an invalid type or is a list containing\n invalid types\n * ``TomlDecodeError``: When an error occurs while decoding the file(s)\n\n``toml.loads(s, _dict=dict)``\n Parse a TOML-formatted string to a dictionary.\n\n :Args:\n * ``s``: The TOML-formatted string to be parsed\n * ``_dict``: Specifies the class of the returned toml dictionary\n\n :Returns:\n A dictionary (or object ``_dict``) containing parsed TOML data\n\n :Raises:\n * ``TypeError``: When a non-string object is passed\n * ``TomlDecodeError``: When an error occurs while decoding the\n TOML-formatted string\n\n``toml.dump(o, f, encoder=None)``\n Write a dictionary to a file containing TOML-formatted data\n\n :Args:\n * ``o``: An object to be converted into TOML\n * ``f``: A File descriptor where the TOML-formatted output should be stored\n * ``encoder``: An instance of ``TomlEncoder`` (or subclass) for encoding the object. If ``None``, will default to ``TomlEncoder``\n\n :Returns:\n A string containing the TOML-formatted data corresponding to object ``o``\n\n :Raises:\n * ``TypeError``: When anything other than file descriptor is passed\n\n``toml.dumps(o, encoder=None)``\n Create a TOML-formatted string from an input object\n\n :Args:\n * ``o``: An object to be converted into TOML\n * ``encoder``: An instance of ``TomlEncoder`` (or subclass) for encoding the object. If ``None``, will default to ``TomlEncoder``\n\n :Returns:\n A string containing the TOML-formatted data corresponding to object ``o``\n\n\n\nLicensing\n=========\n\nThis project is released under the terms of the MIT Open Source License. View\n*LICENSE.txt* for more information.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "William Pearson", + "email": "uiri@xqz.ca", + "url": null + } + ], + "keywords": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.6", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.3", + "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", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy" + ], + "homepage_url": "https://github.com/uiri/toml", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": "mit", + "declared_license": { + "license": "MIT", + "classifiers": [ + "License :: OSI Approved :: MIT License" + ] + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/toml@0.10.1", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/t/toml/toml-0.10.1.tar.gz", + "api_data_url": "https://pypi.org/pypi/toml/0.10.1/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info-expected.json new file mode 100644 index 00000000000..fab947da9fa --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info-expected.json @@ -0,0 +1,65 @@ +{ + "type": "pypi", + "namespace": null, + "name": "toml", + "version": "0.10.1", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Python Library for Tom's Obvious, Minimal Language\n****\nTOML\n****\n\n.. image:: https://badge.fury.io/py/toml.svg\n :target: https://badge.fury.io/py/toml\n\n.. image:: https://travis-ci.org/uiri/toml.svg?branch=master\n :target: https://travis-ci.org/uiri/toml\n\n.. image:: https://img.shields.io/pypi/pyversions/toml.svg\n :target: https://pypi.org/project/toml/\n\n\nA Python library for parsing and creating `TOML `_.\n\nThe module passes `the TOML test suite `_.\n\nSee also:\n\n* `The TOML Standard `_\n* `The currently supported TOML specification `_\n\nInstallation\n============\n\nTo install the latest release on `PyPI `_,\nsimply run:\n\n::\n\n pip install toml\n\nOr to install the latest development version, run:\n\n::\n\n git clone https://github.com/uiri/toml.git\n cd toml\n python setup.py install\n\nQuick Tutorial\n==============\n\n*toml.loads* takes in a string containing standard TOML-formatted data and\nreturns a dictionary containing the parsed data.\n\n.. code:: pycon\n\n >>> import toml\n >>> toml_string = \"\"\"\n ... # This is a TOML document.\n ...\n ... title = \"TOML Example\"\n ...\n ... [owner]\n ... name = \"Tom Preston-Werner\"\n ... dob = 1979-05-27T07:32:00-08:00 # First class dates\n ...\n ... [database]\n ... server = \"192.168.1.1\"\n ... ports = [ 8001, 8001, 8002 ]\n ... connection_max = 5000\n ... enabled = true\n ...\n ... [servers]\n ...\n ... # Indentation (tabs and/or spaces) is allowed but not required\n ... [servers.alpha]\n ... ip = \"10.0.0.1\"\n ... dc = \"eqdc10\"\n ...\n ... [servers.beta]\n ... ip = \"10.0.0.2\"\n ... dc = \"eqdc10\"\n ...\n ... [clients]\n ... data = [ [\"gamma\", \"delta\"], [1, 2] ]\n ...\n ... # Line breaks are OK when inside arrays\n ... hosts = [\n ... \"alpha\",\n ... \"omega\"\n ... ]\n ... \"\"\"\n >>> parsed_toml = toml.loads(toml_string)\n\n\n*toml.dumps* takes a dictionary and returns a string containing the\ncorresponding TOML-formatted data.\n\n.. code:: pycon\n\n >>> new_toml_string = toml.dumps(parsed_toml)\n >>> print(new_toml_string)\n title = \"TOML Example\"\n [owner]\n name = \"Tom Preston-Werner\"\n dob = 1979-05-27T07:32:00Z\n [database]\n server = \"192.168.1.1\"\n ports = [ 8001, 8001, 8002,]\n connection_max = 5000\n enabled = true\n [clients]\n data = [ [ \"gamma\", \"delta\",], [ 1, 2,],]\n hosts = [ \"alpha\", \"omega\",]\n [servers.alpha]\n ip = \"10.0.0.1\"\n dc = \"eqdc10\"\n [servers.beta]\n ip = \"10.0.0.2\"\n dc = \"eqdc10\"\n\nFor more functions, view the API Reference below.\n\nNote\n----\n\nFor Numpy users, by default the data types ``np.floatX`` will not be translated to floats by toml, but will instead be encoded as strings. To get around this, specify the ``TomlNumpyEncoder`` when saving your data.\n\n.. code:: pycon\n\n >>> import toml\n >>> import numpy as np\n >>> a = np.arange(0, 10, dtype=np.double)\n >>> output = {'a': a}\n >>> toml.dumps(output)\n 'a = [ \"0.0\", \"1.0\", \"2.0\", \"3.0\", \"4.0\", \"5.0\", \"6.0\", \"7.0\", \"8.0\", \"9.0\",]\\n'\n >>> toml.dumps(output, encoder=toml.TomlNumpyEncoder())\n 'a = [ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0,]\\n'\n\nAPI Reference\n=============\n\n``toml.load(f, _dict=dict)``\n Parse a file or a list of files as TOML and return a dictionary.\n\n :Args:\n * ``f``: A path to a file, list of filepaths (to be read into single\n object) or a file descriptor\n * ``_dict``: The class of the dictionary object to be returned\n\n :Returns:\n A dictionary (or object ``_dict``) containing parsed TOML data\n\n :Raises:\n * ``TypeError``: When ``f`` is an invalid type or is a list containing\n invalid types\n * ``TomlDecodeError``: When an error occurs while decoding the file(s)\n\n``toml.loads(s, _dict=dict)``\n Parse a TOML-formatted string to a dictionary.\n\n :Args:\n * ``s``: The TOML-formatted string to be parsed\n * ``_dict``: Specifies the class of the returned toml dictionary\n\n :Returns:\n A dictionary (or object ``_dict``) containing parsed TOML data\n\n :Raises:\n * ``TypeError``: When a non-string object is passed\n * ``TomlDecodeError``: When an error occurs while decoding the\n TOML-formatted string\n\n``toml.dump(o, f, encoder=None)``\n Write a dictionary to a file containing TOML-formatted data\n\n :Args:\n * ``o``: An object to be converted into TOML\n * ``f``: A File descriptor where the TOML-formatted output should be stored\n * ``encoder``: An instance of ``TomlEncoder`` (or subclass) for encoding the object. If ``None``, will default to ``TomlEncoder``\n\n :Returns:\n A string containing the TOML-formatted data corresponding to object ``o``\n\n :Raises:\n * ``TypeError``: When anything other than file descriptor is passed\n\n``toml.dumps(o, encoder=None)``\n Create a TOML-formatted string from an input object\n\n :Args:\n * ``o``: An object to be converted into TOML\n * ``encoder``: An instance of ``TomlEncoder`` (or subclass) for encoding the object. If ``None``, will default to ``TomlEncoder``\n\n :Returns:\n A string containing the TOML-formatted data corresponding to object ``o``\n\n\n\nLicensing\n=========\n\nThis project is released under the terms of the MIT Open Source License. View\n*LICENSE.txt* for more information.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "William Pearson", + "email": "uiri@xqz.ca", + "url": null + } + ], + "keywords": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.6", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.3", + "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", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy" + ], + "homepage_url": "https://github.com/uiri/toml", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "license_expression": "mit", + "declared_license": { + "license": "MIT", + "classifiers": [ + "License :: OSI Approved :: MIT License" + ] + }, + "notice_text": null, + "root_path": null, + "dependencies": [], + "contains_source_code": null, + "source_packages": [], + "purl": "pkg:pypi/toml@0.10.1", + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/t/toml/toml-0.10.1.tar.gz", + "api_data_url": "https://pypi.org/pypi/toml/0.10.1/json" +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/DESCRIPTION.rst b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/DESCRIPTION.rst new file mode 100644 index 00000000000..ba4481f7bae --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/DESCRIPTION.rst @@ -0,0 +1,199 @@ +**** +TOML +**** + +.. image:: https://badge.fury.io/py/toml.svg + :target: https://badge.fury.io/py/toml + +.. image:: https://travis-ci.org/uiri/toml.svg?branch=master + :target: https://travis-ci.org/uiri/toml + +.. image:: https://img.shields.io/pypi/pyversions/toml.svg + :target: https://pypi.org/project/toml/ + + +A Python library for parsing and creating `TOML `_. + +The module passes `the TOML test suite `_. + +See also: + +* `The TOML Standard `_ +* `The currently supported TOML specification `_ + +Installation +============ + +To install the latest release on `PyPI `_, +simply run: + +:: + + pip install toml + +Or to install the latest development version, run: + +:: + + git clone https://github.com/uiri/toml.git + cd toml + python setup.py install + +Quick Tutorial +============== + +*toml.loads* takes in a string containing standard TOML-formatted data and +returns a dictionary containing the parsed data. + +.. code:: pycon + + >>> import toml + >>> toml_string = """ + ... # This is a TOML document. + ... + ... title = "TOML Example" + ... + ... [owner] + ... name = "Tom Preston-Werner" + ... dob = 1979-05-27T07:32:00-08:00 # First class dates + ... + ... [database] + ... server = "192.168.1.1" + ... ports = [ 8001, 8001, 8002 ] + ... connection_max = 5000 + ... enabled = true + ... + ... [servers] + ... + ... # Indentation (tabs and/or spaces) is allowed but not required + ... [servers.alpha] + ... ip = "10.0.0.1" + ... dc = "eqdc10" + ... + ... [servers.beta] + ... ip = "10.0.0.2" + ... dc = "eqdc10" + ... + ... [clients] + ... data = [ ["gamma", "delta"], [1, 2] ] + ... + ... # Line breaks are OK when inside arrays + ... hosts = [ + ... "alpha", + ... "omega" + ... ] + ... """ + >>> parsed_toml = toml.loads(toml_string) + + +*toml.dumps* takes a dictionary and returns a string containing the +corresponding TOML-formatted data. + +.. code:: pycon + + >>> new_toml_string = toml.dumps(parsed_toml) + >>> print(new_toml_string) + title = "TOML Example" + [owner] + name = "Tom Preston-Werner" + dob = 1979-05-27T07:32:00Z + [database] + server = "192.168.1.1" + ports = [ 8001, 8001, 8002,] + connection_max = 5000 + enabled = true + [clients] + data = [ [ "gamma", "delta",], [ 1, 2,],] + hosts = [ "alpha", "omega",] + [servers.alpha] + ip = "10.0.0.1" + dc = "eqdc10" + [servers.beta] + ip = "10.0.0.2" + dc = "eqdc10" + +For more functions, view the API Reference below. + +Note +---- + +For Numpy users, by default the data types ``np.floatX`` will not be translated to floats by toml, but will instead be encoded as strings. To get around this, specify the ``TomlNumpyEncoder`` when saving your data. + +.. code:: pycon + + >>> import toml + >>> import numpy as np + >>> a = np.arange(0, 10, dtype=np.double) + >>> output = {'a': a} + >>> toml.dumps(output) + 'a = [ "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "9.0",]\n' + >>> toml.dumps(output, encoder=toml.TomlNumpyEncoder()) + 'a = [ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0,]\n' + +API Reference +============= + +``toml.load(f, _dict=dict)`` + Parse a file or a list of files as TOML and return a dictionary. + + :Args: + * ``f``: A path to a file, list of filepaths (to be read into single + object) or a file descriptor + * ``_dict``: The class of the dictionary object to be returned + + :Returns: + A dictionary (or object ``_dict``) containing parsed TOML data + + :Raises: + * ``TypeError``: When ``f`` is an invalid type or is a list containing + invalid types + * ``TomlDecodeError``: When an error occurs while decoding the file(s) + +``toml.loads(s, _dict=dict)`` + Parse a TOML-formatted string to a dictionary. + + :Args: + * ``s``: The TOML-formatted string to be parsed + * ``_dict``: Specifies the class of the returned toml dictionary + + :Returns: + A dictionary (or object ``_dict``) containing parsed TOML data + + :Raises: + * ``TypeError``: When a non-string object is passed + * ``TomlDecodeError``: When an error occurs while decoding the + TOML-formatted string + +``toml.dump(o, f, encoder=None)`` + Write a dictionary to a file containing TOML-formatted data + + :Args: + * ``o``: An object to be converted into TOML + * ``f``: A File descriptor where the TOML-formatted output should be stored + * ``encoder``: An instance of ``TomlEncoder`` (or subclass) for encoding the object. If ``None``, will default to ``TomlEncoder`` + + :Returns: + A string containing the TOML-formatted data corresponding to object ``o`` + + :Raises: + * ``TypeError``: When anything other than file descriptor is passed + +``toml.dumps(o, encoder=None)`` + Create a TOML-formatted string from an input object + + :Args: + * ``o``: An object to be converted into TOML + * ``encoder``: An instance of ``TomlEncoder`` (or subclass) for encoding the object. If ``None``, will default to ``TomlEncoder`` + + :Returns: + A string containing the TOML-formatted data corresponding to object ``o`` + + + +Licensing +========= + +This project is released under the terms of the MIT Open Source License. View +*LICENSE.txt* for more information. + + diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/INSTALLER b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/INSTALLER new file mode 100644 index 00000000000..a1b589e38a3 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/LICENSE.txt b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/LICENSE.txt new file mode 100644 index 00000000000..5010e3075e6 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/LICENSE.txt @@ -0,0 +1,27 @@ +The MIT License + +Copyright 2013-2019 William Pearson +Copyright 2015-2016 Julien Enselme +Copyright 2016 Google Inc. +Copyright 2017 Samuel Vasko +Copyright 2017 Nate Prewitt +Copyright 2017 Jack Evans +Copyright 2019 Filippo Broggini + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/METADATA b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/METADATA new file mode 100644 index 00000000000..589530f31df --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/METADATA @@ -0,0 +1,226 @@ +Metadata-Version: 2.0 +Name: toml +Version: 0.10.1 +Summary: Python Library for Tom's Obvious, Minimal Language +Home-page: https://github.com/uiri/toml +Author: William Pearson +Author-email: uiri@xqz.ca +License: MIT +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy + +**** +TOML +**** + +.. image:: https://badge.fury.io/py/toml.svg + :target: https://badge.fury.io/py/toml + +.. image:: https://travis-ci.org/uiri/toml.svg?branch=master + :target: https://travis-ci.org/uiri/toml + +.. image:: https://img.shields.io/pypi/pyversions/toml.svg + :target: https://pypi.org/project/toml/ + + +A Python library for parsing and creating `TOML `_. + +The module passes `the TOML test suite `_. + +See also: + +* `The TOML Standard `_ +* `The currently supported TOML specification `_ + +Installation +============ + +To install the latest release on `PyPI `_, +simply run: + +:: + + pip install toml + +Or to install the latest development version, run: + +:: + + git clone https://github.com/uiri/toml.git + cd toml + python setup.py install + +Quick Tutorial +============== + +*toml.loads* takes in a string containing standard TOML-formatted data and +returns a dictionary containing the parsed data. + +.. code:: pycon + + >>> import toml + >>> toml_string = """ + ... # This is a TOML document. + ... + ... title = "TOML Example" + ... + ... [owner] + ... name = "Tom Preston-Werner" + ... dob = 1979-05-27T07:32:00-08:00 # First class dates + ... + ... [database] + ... server = "192.168.1.1" + ... ports = [ 8001, 8001, 8002 ] + ... connection_max = 5000 + ... enabled = true + ... + ... [servers] + ... + ... # Indentation (tabs and/or spaces) is allowed but not required + ... [servers.alpha] + ... ip = "10.0.0.1" + ... dc = "eqdc10" + ... + ... [servers.beta] + ... ip = "10.0.0.2" + ... dc = "eqdc10" + ... + ... [clients] + ... data = [ ["gamma", "delta"], [1, 2] ] + ... + ... # Line breaks are OK when inside arrays + ... hosts = [ + ... "alpha", + ... "omega" + ... ] + ... """ + >>> parsed_toml = toml.loads(toml_string) + + +*toml.dumps* takes a dictionary and returns a string containing the +corresponding TOML-formatted data. + +.. code:: pycon + + >>> new_toml_string = toml.dumps(parsed_toml) + >>> print(new_toml_string) + title = "TOML Example" + [owner] + name = "Tom Preston-Werner" + dob = 1979-05-27T07:32:00Z + [database] + server = "192.168.1.1" + ports = [ 8001, 8001, 8002,] + connection_max = 5000 + enabled = true + [clients] + data = [ [ "gamma", "delta",], [ 1, 2,],] + hosts = [ "alpha", "omega",] + [servers.alpha] + ip = "10.0.0.1" + dc = "eqdc10" + [servers.beta] + ip = "10.0.0.2" + dc = "eqdc10" + +For more functions, view the API Reference below. + +Note +---- + +For Numpy users, by default the data types ``np.floatX`` will not be translated to floats by toml, but will instead be encoded as strings. To get around this, specify the ``TomlNumpyEncoder`` when saving your data. + +.. code:: pycon + + >>> import toml + >>> import numpy as np + >>> a = np.arange(0, 10, dtype=np.double) + >>> output = {'a': a} + >>> toml.dumps(output) + 'a = [ "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "9.0",]\n' + >>> toml.dumps(output, encoder=toml.TomlNumpyEncoder()) + 'a = [ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0,]\n' + +API Reference +============= + +``toml.load(f, _dict=dict)`` + Parse a file or a list of files as TOML and return a dictionary. + + :Args: + * ``f``: A path to a file, list of filepaths (to be read into single + object) or a file descriptor + * ``_dict``: The class of the dictionary object to be returned + + :Returns: + A dictionary (or object ``_dict``) containing parsed TOML data + + :Raises: + * ``TypeError``: When ``f`` is an invalid type or is a list containing + invalid types + * ``TomlDecodeError``: When an error occurs while decoding the file(s) + +``toml.loads(s, _dict=dict)`` + Parse a TOML-formatted string to a dictionary. + + :Args: + * ``s``: The TOML-formatted string to be parsed + * ``_dict``: Specifies the class of the returned toml dictionary + + :Returns: + A dictionary (or object ``_dict``) containing parsed TOML data + + :Raises: + * ``TypeError``: When a non-string object is passed + * ``TomlDecodeError``: When an error occurs while decoding the + TOML-formatted string + +``toml.dump(o, f, encoder=None)`` + Write a dictionary to a file containing TOML-formatted data + + :Args: + * ``o``: An object to be converted into TOML + * ``f``: A File descriptor where the TOML-formatted output should be stored + * ``encoder``: An instance of ``TomlEncoder`` (or subclass) for encoding the object. If ``None``, will default to ``TomlEncoder`` + + :Returns: + A string containing the TOML-formatted data corresponding to object ``o`` + + :Raises: + * ``TypeError``: When anything other than file descriptor is passed + +``toml.dumps(o, encoder=None)`` + Create a TOML-formatted string from an input object + + :Args: + * ``o``: An object to be converted into TOML + * ``encoder``: An instance of ``TomlEncoder`` (or subclass) for encoding the object. If ``None``, will default to ``TomlEncoder`` + + :Returns: + A string containing the TOML-formatted data corresponding to object ``o`` + + + +Licensing +========= + +This project is released under the terms of the MIT Open Source License. View +*LICENSE.txt* for more information. + + diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/RECORD b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/RECORD new file mode 100644 index 00000000000..c3abe73d502 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/RECORD @@ -0,0 +1,20 @@ +toml-0.10.1.dist-info/DESCRIPTION.rst,sha256=DbXlLTVqGT7OgxcZZqpt4vc4BwjkL9yMbN1XBbXcndQ,5262 +toml-0.10.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +toml-0.10.1.dist-info/LICENSE.txt,sha256=LZKUgj32yJNXyL5JJ_znk2HWVh5e51MtWSbmOTmqpTY,1252 +toml-0.10.1.dist-info/METADATA,sha256=9Fzdb4-SG8pwTPbBRT1kBBQBVLjLCbEKlBFjhlRrRf4,6371 +toml-0.10.1.dist-info/RECORD,, +toml-0.10.1.dist-info/WHEEL,sha256=AvR0WeTpDaxT645bl5FQxUK6NPsTls2ttpcGJg3j1Xg,110 +toml-0.10.1.dist-info/metadata.json,sha256=XIvIHJ0Gxk7lDwMajkORcVjVESfuKAXhPhMVrJHRqbw,1185 +toml-0.10.1.dist-info/top_level.txt,sha256=2BO8ZRNnvJWgXyiQv66LBb_v87qBzcoUtEBefA75Ouk,5 +toml/__init__.py,sha256=CtuG5aQNk6m6Mmxotrt6F52x9dRd53oyTiMYii97hn0,723 +toml/__pycache__/__init__.cpython-38.pyc,, +toml/__pycache__/common.cpython-38.pyc,, +toml/__pycache__/decoder.cpython-38.pyc,, +toml/__pycache__/encoder.cpython-38.pyc,, +toml/__pycache__/ordered.cpython-38.pyc,, +toml/__pycache__/tz.cpython-38.pyc,, +toml/common.py,sha256=ViBccAduP6eZNJAb1POhRhjOAi56TDsNgWJ1TjgXAug,242 +toml/decoder.py,sha256=gRgnNQ73I3Zw8Ys0ArBkbec9h317zeFjmRu4TMoXumw,38684 +toml/encoder.py,sha256=9HpekPtXkAdfhPpZqfHUxxfW82fMxJ9aybiLUzcbR30,9931 +toml/ordered.py,sha256=mz03lZmV0bmc9lsYRIUOuj7Dsu5Ptwq-UtGVq5FdVZ4,354 +toml/tz.py,sha256=DrAgI3wZxZiGcLuV_l8ueA_nPrYoxQ3hZA9tJSjWRsQ,618 diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/WHEEL b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/WHEEL new file mode 100644 index 00000000000..9dff69d8610 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.24.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/metadata.json b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/metadata.json new file mode 100644 index 00000000000..c92bcea13ff --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/metadata.json @@ -0,0 +1 @@ +{"summary": "Python Library for Tom's Obvious, Minimal Language", "classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "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", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy"], "extensions": {"python.details": {"contacts": [{"role": "author", "email": "uiri@xqz.ca", "name": "William Pearson"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "https://github.com/uiri/toml"}}}, "generator": "bdist_wheel (0.24.0)", "license": "MIT", "name": "toml", "metadata_version": "2.0", "version": "0.10.1"} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/top_level.txt b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/top_level.txt new file mode 100644 index 00000000000..bd79a658fe7 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/toml-0.10.1.dist-info/top_level.txt @@ -0,0 +1 @@ +toml diff --git a/tests/packagedcode/data/pypi/vmock/expected.json b/tests/packagedcode/data/pypi/vmock/expected.json deleted file mode 100644 index 5865aa96775..00000000000 --- a/tests/packagedcode/data/pypi/vmock/expected.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "type": "pypi", - "namespace": null, - "name": "vmock", - "version": "0.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Advanced Mock library following record and replay approach.", - "release_date": null, - "parties": [ - { - "type": "person", - "role": "author", - "name": "Volodymyr Burenin", - "email": "vburenin@gmail.com", - "url": null - } - ], - "keywords": [], - "homepage_url": "https://github.com/vburenin/vmock", - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": "mit", - "declared_license": { - "license": [ - "License :: MIT" - ], - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "root_path": null, - "dependencies": [], - "contains_source_code": null, - "source_packages": [], - "purl": "pkg:pypi/vmock@0.1", - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": null -} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/vmock/input.json b/tests/packagedcode/data/pypi/vmock/input.json deleted file mode 100644 index 2b10df0a998..00000000000 --- a/tests/packagedcode/data/pypi/vmock/input.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "info": { - "author": "Volodymyr Burenin", - "author_email": "vburenin@gmail.com", - "bugtrack_url": null, - "classifiers": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3.2", - "Programming Language :: Python :: 3.3", - "Programming Language :: Python :: 3.4", - "Topic :: Software Development :: Quality Assurance" - ], - "description": "UNKNOWN", - "description_content_type": null, - "docs_url": null, - "download_url": "UNKNOWN", - "downloads": { - "last_day": -1, - "last_month": -1, - "last_week": -1 - }, - "home_page": "https://github.com/vburenin/vmock", - "keywords": null, - "license": "License :: MIT", - "maintainer": null, - "maintainer_email": null, - "name": "vmock", - "package_url": "https://pypi.org/project/vmock/", - "platform": "UNKNOWN", - "project_url": "https://pypi.org/project/vmock/", - "project_urls": { - "Download": "UNKNOWN", - "Homepage": "https://github.com/vburenin/vmock" - }, - "release_url": "https://pypi.org/project/vmock/0.1/", - "requires_dist": null, - "requires_python": null, - "summary": "Advanced Mock library following record and replay approach.", - "version": "0.1" - }, - "last_serial": 1452759, - "releases": { - "0.1": [ - { - "comment_text": "", - "digests": { - "md5": "9e97e9147889ff892e3b002613734a10", - "sha256": "c716a855daadb6f3dc614061e0e260277ab93a35eca69da2b7ff29b97ca2712b" - }, - "downloads": -1, - "filename": "vmock-0.1.tar.gz", - "has_sig": false, - "md5_digest": "9e97e9147889ff892e3b002613734a10", - "packagetype": "sdist", - "python_version": "source", - "requires_python": null, - "size": 13756, - "upload_time": "2015-03-08T06:54:02", - "url": "https://files.pythonhosted.org/packages/95/dc/453d02d9f4ad3aa3e30244c97e3d07605bc0d39f8e37e3635f53fb99b22c/vmock-0.1.tar.gz" - } - ] - }, - "urls": [ - { - "comment_text": "", - "digests": { - "md5": "9e97e9147889ff892e3b002613734a10", - "sha256": "c716a855daadb6f3dc614061e0e260277ab93a35eca69da2b7ff29b97ca2712b" - }, - "downloads": -1, - "filename": "vmock-0.1.tar.gz", - "has_sig": false, - "md5_digest": "9e97e9147889ff892e3b002613734a10", - "packagetype": "sdist", - "python_version": "source", - "requires_python": null, - "size": 13756, - "upload_time": "2015-03-08T06:54:02", - "url": "https://files.pythonhosted.org/packages/95/dc/453d02d9f4ad3aa3e30244c97e3d07605bc0d39f8e37e3635f53fb99b22c/vmock-0.1.tar.gz" - } - ] -} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/wheel/parse-wheel-expected.json b/tests/packagedcode/data/pypi/wheel/atomicwrites-1.2.1-py2.py3-none-any.whl-expected.json similarity index 95% rename from tests/packagedcode/data/pypi/wheel/parse-wheel-expected.json rename to tests/packagedcode/data/pypi/wheel/atomicwrites-1.2.1-py2.py3-none-any.whl-expected.json index 89bf6b7dcb6..9d1386b0e0d 100644 --- a/tests/packagedcode/data/pypi/wheel/parse-wheel-expected.json +++ b/tests/packagedcode/data/pypi/wheel/atomicwrites-1.2.1-py2.py3-none-any.whl-expected.json @@ -6,7 +6,7 @@ "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "===================\npython-atomicwrites\n===================\n\n.. image:: https://travis-ci.org/untitaker/python-atomicwrites.svg?branch=master\n :target: https://travis-ci.org/untitaker/python-atomicwrites\n\n.. image:: https://ci.appveyor.com/api/projects/status/vadc4le3c27to59x/branch/master?svg=true\n :target: https://ci.appveyor.com/project/untitaker/python-atomicwrites/branch/master\n\nAtomic file writes.\n\n.. code-block:: python\n\n from atomicwrites import atomic_write\n\n with atomic_write('foo.txt', overwrite=True) as f:\n f.write('Hello world.')\n # \"foo.txt\" doesn't exist yet.\n\n # Now it does.\n\n\nFeatures that distinguish it from other similar libraries (see `Alternatives and Credit`_):\n\n- Race-free assertion that the target file doesn't yet exist. This can be\n controlled with the ``overwrite`` parameter.\n\n- Windows support, although not well-tested. The MSDN resources are not very\n explicit about which operations are atomic. I'm basing my assumptions off `a\n comment\n `_\n by `Doug Crook\n `_, who appears\n to be a Microsoft employee:\n\n FAQ: Is MoveFileEx atomic\n Frequently asked question: Is MoveFileEx atomic if the existing and new\n files are both on the same drive?\n\n The simple answer is \"usually, but in some cases it will silently fall-back\n to a non-atomic method, so don't count on it\".\n\n The implementation of MoveFileEx looks something like this: [...]\n\n The problem is if the rename fails, you might end up with a CopyFile, which\n is definitely not atomic.\n\n If you really need atomic-or-nothing, you can try calling\n NtSetInformationFile, which is unsupported but is much more likely to be\n atomic. \n\n- Simple high-level API that wraps a very flexible class-based API.\n\n- Consistent error handling across platforms.\n\n\nHow it works\n============\n\nIt uses a temporary file in the same directory as the given path. This ensures\nthat the temporary file resides on the same filesystem.\n\nThe temporary file will then be atomically moved to the target location: On\nPOSIX, it will use ``rename`` if files should be overwritten, otherwise a\ncombination of ``link`` and ``unlink``. On Windows, it uses MoveFileEx_ through\nstdlib's ``ctypes`` with the appropriate flags.\n\nNote that with ``link`` and ``unlink``, there's a timewindow where the file\nmight be available under two entries in the filesystem: The name of the\ntemporary file, and the name of the target file.\n\nAlso note that the permissions of the target file may change this way. In some\nsituations a ``chmod`` can be issued without any concurrency problems, but\nsince that is not always the case, this library doesn't do it by itself.\n\n.. _MoveFileEx: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365240%28v=vs.85%29.aspx\n\nfsync\n-----\n\nOn POSIX, ``fsync`` is invoked on the temporary file after it is written (to\nflush file content and metadata), and on the parent directory after the file is\nmoved (to flush filename).\n\n``fsync`` does not take care of disks' internal buffers, but there don't seem\nto be any standard POSIX APIs for that. On OS X, ``fcntl`` is used with\n``F_FULLFSYNC`` instead of ``fsync`` for that reason.\n\nOn Windows, `_commit `_\nis used, but there are no guarantees about disk internal buffers.\n\nAlternatives and Credit\n=======================\n\nAtomicwrites is directly inspired by the following libraries (and shares a\nminimal amount of code):\n\n- The Trac project's `utility functions\n `_,\n also used in `Werkzeug `_ and\n `mitsuhiko/python-atomicfile\n `_. The idea to use\n ``ctypes`` instead of ``PyWin32`` originated there.\n\n- `abarnert/fatomic `_. Windows support\n (based on ``PyWin32``) was originally taken from there.\n\nOther alternatives to atomicwrites include:\n\n- `sashka/atomicfile `_. Originally I\n considered using that, but at the time it was lacking a lot of features I\n needed (Windows support, overwrite-parameter, overriding behavior through\n subclassing).\n\n- The `Boltons library collection `_\n features a class for atomic file writes, which seems to have a very similar\n ``overwrite`` parameter. It is lacking Windows support though.\n\nLicense\n=======\n\nLicensed under the MIT, see ``LICENSE``.\n\n\n", + "description": "===================\npython-atomicwrites\n===================\n\n.. image:: https://travis-ci.org/untitaker/python-atomicwrites.svg?branch=master\n :target: https://travis-ci.org/untitaker/python-atomicwrites\n\n.. image:: https://ci.appveyor.com/api/projects/status/vadc4le3c27to59x/branch/master?svg=true\n :target: https://ci.appveyor.com/project/untitaker/python-atomicwrites/branch/master\n\nAtomic file writes.\n\n.. code-block:: python\n\n from atomicwrites import atomic_write\n\n with atomic_write('foo.txt', overwrite=True) as f:\n f.write('Hello world.')\n # \"foo.txt\" doesn't exist yet.\n\n # Now it does.\n\n\nFeatures that distinguish it from other similar libraries (see `Alternatives and Credit`_):\n\n- Race-free assertion that the target file doesn't yet exist. This can be\n controlled with the ``overwrite`` parameter.\n\n- Windows support, although not well-tested. The MSDN resources are not very\n explicit about which operations are atomic. I'm basing my assumptions off `a\n comment\n `_\n by `Doug Crook\n `_, who appears\n to be a Microsoft employee:\n\n FAQ: Is MoveFileEx atomic\n Frequently asked question: Is MoveFileEx atomic if the existing and new\n files are both on the same drive?\n\n The simple answer is \"usually, but in some cases it will silently fall-back\n to a non-atomic method, so don't count on it\".\n\n The implementation of MoveFileEx looks something like this: [...]\n\n The problem is if the rename fails, you might end up with a CopyFile, which\n is definitely not atomic.\n\n If you really need atomic-or-nothing, you can try calling\n NtSetInformationFile, which is unsupported but is much more likely to be\n atomic. \n\n- Simple high-level API that wraps a very flexible class-based API.\n\n- Consistent error handling across platforms.\n\n\nHow it works\n============\n\nIt uses a temporary file in the same directory as the given path. This ensures\nthat the temporary file resides on the same filesystem.\n\nThe temporary file will then be atomically moved to the target location: On\nPOSIX, it will use ``rename`` if files should be overwritten, otherwise a\ncombination of ``link`` and ``unlink``. On Windows, it uses MoveFileEx_ through\nstdlib's ``ctypes`` with the appropriate flags.\n\nNote that with ``link`` and ``unlink``, there's a timewindow where the file\nmight be available under two entries in the filesystem: The name of the\ntemporary file, and the name of the target file.\n\nAlso note that the permissions of the target file may change this way. In some\nsituations a ``chmod`` can be issued without any concurrency problems, but\nsince that is not always the case, this library doesn't do it by itself.\n\n.. _MoveFileEx: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365240%28v=vs.85%29.aspx\n\nfsync\n-----\n\nOn POSIX, ``fsync`` is invoked on the temporary file after it is written (to\nflush file content and metadata), and on the parent directory after the file is\nmoved (to flush filename).\n\n``fsync`` does not take care of disks' internal buffers, but there don't seem\nto be any standard POSIX APIs for that. On OS X, ``fcntl`` is used with\n``F_FULLFSYNC`` instead of ``fsync`` for that reason.\n\nOn Windows, `_commit `_\nis used, but there are no guarantees about disk internal buffers.\n\nAlternatives and Credit\n=======================\n\nAtomicwrites is directly inspired by the following libraries (and shares a\nminimal amount of code):\n\n- The Trac project's `utility functions\n `_,\n also used in `Werkzeug `_ and\n `mitsuhiko/python-atomicfile\n `_. The idea to use\n ``ctypes`` instead of ``PyWin32`` originated there.\n\n- `abarnert/fatomic `_. Windows support\n (based on ``PyWin32``) was originally taken from there.\n\nOther alternatives to atomicwrites include:\n\n- `sashka/atomicfile `_. Originally I\n considered using that, but at the time it was lacking a lot of features I\n needed (Windows support, overwrite-parameter, overriding behavior through\n subclassing).\n\n- The `Boltons library collection `_\n features a class for atomic file writes, which seems to have a very similar\n ``overwrite`` parameter. It is lacking Windows support though.\n\nLicense\n=======\n\nLicensed under the MIT, see ``LICENSE``.", "release_date": null, "parties": [ { @@ -50,7 +50,7 @@ "contains_source_code": null, "source_packages": [], "purl": "pkg:pypi/atomicwrites@1.2.1", - "repository_homepage_url": "https://pypi.org/project/atomicwrites", - "repository_download_url": "https://pypi.io/packages/source/a/atomicwrites/atomicwrites-1.2.1.tar.gz", - "api_data_url": "http://pypi.python.org/pypi/atomicwrites/1.2.1/json" + "repository_homepage_url": "https://pypi.org/project/https://pypi.org", + "repository_download_url": "https://pypi.org/packages/source/a/atomicwrites/atomicwrites-1.2.1.tar.gz", + "api_data_url": "https://pypi.org/pypi/atomicwrites/1.2.1/json" } \ No newline at end of file diff --git a/tests/packagedcode/data/recon/haxelib.json b/tests/packagedcode/data/recon/haxelib.json new file mode 100644 index 00000000000..92ad5bc358e --- /dev/null +++ b/tests/packagedcode/data/recon/haxelib.json @@ -0,0 +1,15 @@ +{ + "name": "selecthxml", + "license": "BSD", + "tags": ["cross","xml","utility","css","macro"], + "description": "Allows type-safe CSS-style selection on Xml objects.", + "contributors": ["simn","jason"], + "releasenote": "Update for Haxe 3.2 (Handle null case)", + "version": "0.5.1", + "url": "https://github.com/jasononeil/selecthxml", + "classPath": "src/", + "dependencies": { + "tink_core": "", + "tink_macro": "3.23" + } +} diff --git a/tests/packagedcode/data/pypi/DESCRIPTION.rst b/tests/packagedcode/data/recon/pypi/DESCRIPTION.rst similarity index 100% rename from tests/packagedcode/data/pypi/DESCRIPTION.rst rename to tests/packagedcode/data/recon/pypi/DESCRIPTION.rst diff --git a/tests/packagedcode/data/pypi/package/METADATA b/tests/packagedcode/data/recon/pypi/METADATA similarity index 100% rename from tests/packagedcode/data/pypi/package/METADATA rename to tests/packagedcode/data/recon/pypi/METADATA diff --git a/tests/packagedcode/data/pypi/PKG-INFO b/tests/packagedcode/data/recon/pypi/PKG-INFO similarity index 100% rename from tests/packagedcode/data/pypi/PKG-INFO rename to tests/packagedcode/data/recon/pypi/PKG-INFO diff --git a/tests/packagedcode/data/recon/pypi/Pipfile.lock b/tests/packagedcode/data/recon/pypi/Pipfile.lock new file mode 100644 index 00000000000..5f1bc99b2ab --- /dev/null +++ b/tests/packagedcode/data/recon/pypi/Pipfile.lock @@ -0,0 +1,184 @@ +{ + "_meta": { + "hash": { + "sha256": "6e45251662433bf51f96fb3d2204b65416fece329d60e6235c0f0edc416cfe24" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "2.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "atomicwrites": { + "hashes": [ + "sha256:240831ea22da9ab882b551b31d4225591e5e447a68c5e188db5b89ca1d487585", + "sha256:a24da68318b08ac9c9c45029f4a10371ab5b20e4226738e150e6e7c571630ae6" + ], + "version": "==1.1.5" + }, + "attrs": { + "hashes": [ + "sha256:4b90b09eeeb9b88c35bc642cbac057e45a5fd85367b985bd2809c62b7b939265", + "sha256:e0d0eb91441a3b53dab4d9b743eafc1ac44476296a2053b6ca3af0b139faf87b" + ], + "version": "==18.1.0" + }, + "contextlib2": { + "hashes": [ + "sha256:509f9419ee91cdd00ba34443217d5ca51f5a364a404e1dce9e8979cea969ca48", + "sha256:f5260a6e679d2ff42ec91ec5252f4eeffdcf21053db9113bd0a8e4d953769c00" + ], + "markers": "python_version == '2.7'", + "version": "==0.5.5" + }, + "coverage": { + "hashes": [ + "sha256:03481e81d558d30d230bc12999e3edffe392d244349a90f4ef9b88425fac74ba", + "sha256:0b136648de27201056c1869a6c0d4e23f464750fd9a9ba9750b8336a244429ed", + "sha256:10a46017fef60e16694a30627319f38a2b9b52e90182dddb6e37dcdab0f4bf95", + "sha256:198626739a79b09fa0a2f06e083ffd12eb55449b5f8bfdbeed1df4910b2ca640", + "sha256:23d341cdd4a0371820eb2b0bd6b88f5003a7438bbedb33688cd33b8eae59affd", + "sha256:28b2191e7283f4f3568962e373b47ef7f0392993bb6660d079c62bd50fe9d162", + "sha256:2a5b73210bad5279ddb558d9a2bfedc7f4bf6ad7f3c988641d83c40293deaec1", + "sha256:2eb564bbf7816a9d68dd3369a510be3327f1c618d2357fa6b1216994c2e3d508", + "sha256:337ded681dd2ef9ca04ef5d93cfc87e52e09db2594c296b4a0a3662cb1b41249", + "sha256:3a2184c6d797a125dca8367878d3b9a178b6fdd05fdc2d35d758c3006a1cd694", + "sha256:3c79a6f7b95751cdebcd9037e4d06f8d5a9b60e4ed0cd231342aa8ad7124882a", + "sha256:3d72c20bd105022d29b14a7d628462ebdc61de2f303322c0212a054352f3b287", + "sha256:3eb42bf89a6be7deb64116dd1cc4b08171734d721e7a7e57ad64cc4ef29ed2f1", + "sha256:4635a184d0bbe537aa185a34193898eee409332a8ccb27eea36f262566585000", + "sha256:56e448f051a201c5ebbaa86a5efd0ca90d327204d8b059ab25ad0f35fbfd79f1", + "sha256:5a13ea7911ff5e1796b6d5e4fbbf6952381a611209b736d48e675c2756f3f74e", + "sha256:69bf008a06b76619d3c3f3b1983f5145c75a305a0fea513aca094cae5c40a8f5", + "sha256:6bc583dc18d5979dc0f6cec26a8603129de0304d5ae1f17e57a12834e7235062", + "sha256:701cd6093d63e6b8ad7009d8a92425428bc4d6e7ab8d75efbb665c806c1d79ba", + "sha256:7608a3dd5d73cb06c531b8925e0ef8d3de31fed2544a7de6c63960a1e73ea4bc", + "sha256:76ecd006d1d8f739430ec50cc872889af1f9c1b6b8f48e29941814b09b0fd3cc", + "sha256:7aa36d2b844a3e4a4b356708d79fd2c260281a7390d678a10b91ca595ddc9e99", + "sha256:7d3f553904b0c5c016d1dad058a7554c7ac4c91a789fca496e7d8347ad040653", + "sha256:7e1fe19bd6dce69d9fd159d8e4a80a8f52101380d5d3a4d374b6d3eae0e5de9c", + "sha256:8c3cb8c35ec4d9506979b4cf90ee9918bc2e49f84189d9bf5c36c0c1119c6558", + "sha256:9d6dd10d49e01571bf6e147d3b505141ffc093a06756c60b053a859cb2128b1f", + "sha256:be6cfcd8053d13f5f5eeb284aa8a814220c3da1b0078fa859011c7fffd86dab9", + "sha256:c1bb572fab8208c400adaf06a8133ac0712179a334c09224fb11393e920abcdd", + "sha256:de4418dadaa1c01d497e539210cb6baa015965526ff5afc078c57ca69160108d", + "sha256:e05cb4d9aad6233d67e0541caa7e511fa4047ed7750ec2510d466e806e0255d6", + "sha256:f3f501f345f24383c0000395b26b726e46758b71393267aeae0bd36f8b3ade80" + ], + "version": "==4.5.1" + }, + "funcsigs": { + "hashes": [ + "sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca", + "sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50" + ], + "markers": "python_version < '3.0'", + "version": "==1.0.2" + }, + "mock": { + "hashes": [ + "sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1", + "sha256:b158b6df76edd239b8208d481dc46b6afd45a846b7812ff0ce58971cf5bc8bba" + ], + "markers": "python_version == '2.7'", + "version": "==2.0.0" + }, + "more-itertools": { + "hashes": [ + "sha256:2b6b9893337bfd9166bee6a62c2b0c9fe7735dcf85948b387ec8cba30e85d8e8", + "sha256:6703844a52d3588f951883005efcf555e49566a48afd4db4e965d69b883980d3", + "sha256:a18d870ef2ffca2b8463c0070ad17b5978056f403fb64e3f15fe62a52db21cc0" + ], + "version": "==4.2.0" + }, + "pbr": { + "hashes": [ + "sha256:1b8be50d938c9bb75d0eaf7eda111eec1bf6dc88a62a6412e33bf077457e0f45", + "sha256:b486975c0cafb6beeb50ca0e17ba047647f229087bd74e37f4a7e2cac17d2caa" + ], + "version": "==4.2.0" + }, + "pluggy": { + "hashes": [ + "sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff", + "sha256:d345c8fe681115900d6da8d048ba67c25df42973bda370783cd58826442dcd7c", + "sha256:e160a7fcf25762bb60efc7e171d4497ff1d8d2d75a3d0df7a21b76821ecbf5c5" + ], + "version": "==0.6.0" + }, + "py": { + "hashes": [ + "sha256:3fd59af7435864e1a243790d322d763925431213b6b8529c6ca71081ace3bbf7", + "sha256:e31fb2767eb657cbde86c454f02e99cb846d3cd9d61b318525140214fdc0e98e" + ], + "version": "==1.5.4" + }, + "pytest": { + "hashes": [ + "sha256:0453c8676c2bee6feb0434748b068d5510273a916295fd61d306c4f22fbfd752", + "sha256:4b208614ae6d98195430ad6bde03641c78553acee7c83cec2e85d613c0cd383d" + ], + "version": "==3.6.3" + }, + "pytest-cov": { + "hashes": [ + "sha256:03aa752cf11db41d281ea1d807d954c4eda35cfa1b21d6971966cc041bbf6e2d", + "sha256:890fe5565400902b0c78b5357004aab1c814115894f4f21370e2433256a3eeec" + ], + "index": "pypi", + "version": "==2.5.1" + }, + "pytest-vcr": { + "hashes": [ + "sha256:13f2e24ab4b8674e012ca23df50e34f0b322a8b8cf8aa80f2b432ae95a92e298", + "sha256:b3d1f0a470e172a5f8ef60b3f1daf3ff1ff60a43280a9cdfb24a8c53e3e9c12c" + ], + "index": "pypi", + "version": "==0.3.0" + }, + "pyyaml": { + "hashes": [ + "sha256:3d7da3009c0f3e783b2c873687652d83b1bbfd5c88e9813fb7e5b03c0dd3108b", + "sha256:3ef3092145e9b70e3ddd2c7ad59bdd0252a94dfe3949721633e41344de00a6bf", + "sha256:40c71b8e076d0550b2e6380bada1f1cd1017b882f7e16f09a65be98e017f211a", + "sha256:558dd60b890ba8fd982e05941927a3911dc409a63dcb8b634feaa0cda69330d3", + "sha256:a7c28b45d9f99102fa092bb213aa12e0aaf9a6a1f5e395d36166639c1f96c3a1", + "sha256:aa7dd4a6a427aed7df6fb7f08a580d68d9b118d90310374716ae90b710280af1", + "sha256:bc558586e6045763782014934bfaf39d48b8ae85a2713117d16c39864085c613", + "sha256:d46d7982b62e0729ad0175a9bc7e10a566fc07b224d2c79fafb5e032727eaa04", + "sha256:d5eef459e30b09f5a098b9cea68bebfeb268697f78d647bd255a085371ac7f3f", + "sha256:e01d3203230e1786cd91ccfdc8f8454c8069c91bee3962ad93b87a4b2860f537", + "sha256:e170a9e6fcfd19021dd29845af83bb79236068bf5fd4df3327c1be18182b2531" + ], + "version": "==3.13" + }, + "six": { + "hashes": [ + "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9", + "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb" + ], + "version": "==1.11.0" + }, + "vcrpy": { + "hashes": [ + "sha256:7031f9c78a70b9586d2db4a2ec135c4e04194cabff58695ef0cc95e7cd66bc01", + "sha256:dadb4b2798a44bdce5301ec01380351ab798a468fc7ee5a34271bdd8527d8f99" + ], + "version": "==1.13.0" + }, + "wrapt": { + "hashes": [ + "sha256:d4d560d479f2c21e1b5443bbd15fe7ec4b37fe7e53d335d3b9b0a7b1226fe3c6" + ], + "version": "==1.10.11" + } + }, + "develop": {} +} diff --git a/tests/packagedcode/data/pypi/package/atomicwrites-1.2.1-py2.py3-none-any.whl b/tests/packagedcode/data/recon/pypi/atomicwrites-1.2.1-py2.py3-none-any.whl similarity index 100% rename from tests/packagedcode/data/pypi/package/atomicwrites-1.2.1-py2.py3-none-any.whl rename to tests/packagedcode/data/recon/pypi/atomicwrites-1.2.1-py2.py3-none-any.whl diff --git a/tests/packagedcode/data/pypi/metadata.json b/tests/packagedcode/data/recon/pypi/metadata.json similarity index 100% rename from tests/packagedcode/data/pypi/metadata.json rename to tests/packagedcode/data/recon/pypi/metadata.json diff --git a/tests/packagedcode/data/recon/pypi/requirements.txt b/tests/packagedcode/data/recon/pypi/requirements.txt new file mode 100644 index 00000000000..a7fe44e5d16 --- /dev/null +++ b/tests/packagedcode/data/recon/pypi/requirements.txt @@ -0,0 +1,3 @@ +setuptools>=32.0.0 +nose>=1.3.7 +chardet>=3.0.4 diff --git a/tests/packagedcode/data/pypi/package/setup.py b/tests/packagedcode/data/recon/pypi/setup.py similarity index 100% rename from tests/packagedcode/data/pypi/package/setup.py rename to tests/packagedcode/data/recon/pypi/setup.py diff --git a/tests/packagedcode/test_pypi.py b/tests/packagedcode/test_pypi.py index 879626045b2..8969efbe52f 100644 --- a/tests/packagedcode/test_pypi.py +++ b/tests/packagedcode/test_pypi.py @@ -7,446 +7,318 @@ # See https://aboutcode.org for more information about nexB OSS projects. # +import json import os from unittest.case import skipIf from unittest.case import expectedFailure -import json import pytest from commoncode.system import on_windows -from packagedcode.models import DependentPackage from packagedcode import pypi + +from packages_test_utils import check_result_equals_expected_json from packages_test_utils import PackageTester -class TestPyPi(PackageTester): +class TestPyPiMetadata(PackageTester): test_data_dir = os.path.join(os.path.dirname(__file__), 'data') - def test_parse(self): - test_file = self.get_test_loc('pypi/setup.py/setup.py') - package = pypi.parse(test_file) - assert package.name == 'scancode-toolkit' - assert package.version == '1.5.0' - assert package.parties[0].name == 'ScanCode' - assert package.description == ('ScanCode is a tool to scan code for license, ' - 'copyright and other interesting facts.') - assert package.homepage_url == 'https://github.com/nexB/scancode-toolkit' - - def test_parse_metadata(self): - test_folder = self.get_test_loc('pypi') - test_file = os.path.join(test_folder, 'metadata.json') + def test_parse_metadata_format_v10(self): + test_file = self.get_test_loc('pypi/metadata/v10/PKG-INFO') package = pypi.parse_metadata(test_file) - assert package.name == 'six' - assert package.version == '1.10.0' - assert package.description == 'Python 2 and 3 compatibility utilities' - assert 'MIT' in package.declared_license['license'] - assert package.declared_license['classifiers'] == ['License :: OSI Approved :: MIT License'] - expected_classifiers = [ - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3", - "Intended Audience :: Developers", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities" - ] - assert package.keywords == expected_classifiers - expected = [ - dict([ - ('type', u'person'), ('role', u'contact'), - ('name', u'Benjamin Peterson'), ('email', None), ('url', None)]) - ] - assert [p.to_dict() for p in package.parties] == expected - assert package.homepage_url == 'http://pypi.python.org/pypi/six/' - - def test_parse_pkg_info(self): - test_file = self.get_test_loc('pypi/PKG-INFO') - package = pypi.parse_pkg_info(test_file) - assert package.name == 'TicketImport' - assert package.version == '0.7a' - assert package.description == 'Import CSV and Excel files' - assert 'BSD' in package.declared_license - assert package.homepage_url == 'http://nexb.com' - expected = [dict([('type', u'person'), ('role', u''), ('name', u'Francois Granade'), ('email', None), ('url', None)])] - assert [p.to_dict() for p in package.parties] == expected - - @skipIf(on_windows, 'Somehow this fails on Windows') - def test_parse_setup_py_arpy(self): - test_file = self.get_test_loc('pypi/setup.py/arpy_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/arpy_setup.py-expected.json') + expected_loc = self.get_test_loc('pypi/metadata/v10/PKG-INFO-expected.json') self.check_package(package, expected_loc, regen=False) - def test_parse_setup_py_boolean2_py(self): - test_file = self.get_test_loc('pypi/setup.py/boolean2_py_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/boolean2_py_setup.py-expected.json') - self.check_package(package, expected_loc, regen=False) - - def test_parse_setup_py_container_check(self): - test_file = self.get_test_loc('pypi/setup.py/container_check_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/container_check_setup.py-expected.json') - self.check_package(package, expected_loc, regen=False) - - def test_parse_setup_py_fb303_py(self): - test_file = self.get_test_loc('pypi/setup.py/fb303_py_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/fb303_py_setup.py-expected.json') - self.check_package(package, expected_loc, regen=False) - - def test_parse_setup_py_frell_src(self): - # setup.py is a temaplte with @vars - test_file = self.get_test_loc('pypi/setup.py/frell_src_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/frell_src_setup.py-expected.json') - self.check_package(package, expected_loc, regen=False) - - def test_parse_setup_py_gyp(self): - test_file = self.get_test_loc('pypi/setup.py/gyp_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/gyp_setup.py-expected.json') - self.check_package(package, expected_loc, regen=False) - - def test_parse_setup_py_interlap(self): - test_file = self.get_test_loc('pypi/setup.py/interlap_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/interlap_setup.py-expected.json') - self.check_package(package, expected_loc, regen=False) - - def test_parse_setup_py_mb(self): - test_file = self.get_test_loc('pypi/setup.py/mb_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/mb_setup.py-expected.json') - self.check_package(package, expected_loc, regen=False) - - def test_parse_setup_py_ntfs(self): - test_file = self.get_test_loc('pypi/setup.py/ntfs_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/ntfs_setup.py-expected.json') - self.check_package(package, expected_loc, regen=False) - - def test_parse_setup_py_nvchecker(self): - test_file = self.get_test_loc('pypi/setup.py/nvchecker_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/nvchecker_setup.py-expected.json') - self.check_package(package, expected_loc, regen=False) - - def test_parse_setup_py_oi_agents_common_code(self): - test_file = self.get_test_loc('pypi/setup.py/oi_agents_common_code_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/oi_agents_common_code_setup.py-expected.json') - self.check_package(package, expected_loc, regen=False) - - def test_parse_setup_py_packageurl_python(self): - test_file = self.get_test_loc('pypi/setup.py/packageurl_python_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/packageurl_python_setup.py-expected.json') + def test_parse_metadata_format_v11(self): + test_file = self.get_test_loc('pypi/metadata/v11/PKG-INFO') + package = pypi.parse_metadata(test_file) + expected_loc = self.get_test_loc('pypi/metadata/v11/PKG-INFO-expected.json') self.check_package(package, expected_loc, regen=False) - def test_parse_setup_py_pipdeptree(self): - test_file = self.get_test_loc('pypi/setup.py/pipdeptree_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/pipdeptree_setup.py-expected.json') + def test_parse_metadata_format_v12(self): + test_file = self.get_test_loc('pypi/metadata/v12/PKG-INFO') + package = pypi.parse_metadata(test_file) + expected_loc = self.get_test_loc('pypi/metadata/v12/PKG-INFO-expected.json') self.check_package(package, expected_loc, regen=False) - @expectedFailure - def test_parse_setup_py_pluggy(self): - test_file = self.get_test_loc('pypi/setup.py/pluggy_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/pluggy_setup.py-expected.json') + def test_parse_metadata_format_v20(self): + test_file = self.get_test_loc('pypi/metadata/v20/PKG-INFO') + package = pypi.parse_metadata(test_file) + expected_loc = self.get_test_loc('pypi/metadata/v20/PKG-INFO-expected.json') self.check_package(package, expected_loc, regen=False) - def test_parse_setup_py_pydep(self): - test_file = self.get_test_loc('pypi/setup.py/pydep_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/pydep_setup.py-expected.json') + def test_parse_metadata_format_v21(self): + test_file = self.get_test_loc('pypi/metadata/v21/PKG-INFO') + package = pypi.parse_metadata(test_file) + expected_loc = self.get_test_loc('pypi/metadata/v21/PKG-INFO-expected.json') self.check_package(package, expected_loc, regen=False) - @expectedFailure - def test_parse_setup_py_pygtrie(self): - # this uses a kwargs dict - test_file = self.get_test_loc('pypi/setup.py/pygtrie_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/pygtrie_setup.py-expected.json') + def test_parse_pkg_dash_info_basic(self): + test_file = self.get_test_loc('pypi/metadata/PKG-INFO') + package = pypi.parse_metadata(test_file) + expected_loc = self.get_test_loc('pypi/metadata/PKG-INFO-expected.json') self.check_package(package, expected_loc, regen=False) - def test_parse_setup_py_pyrpm_2(self): - test_file = self.get_test_loc('pypi/setup.py/pyrpm_2_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/pyrpm_2_setup.py-expected.json') + def test_parse_metadata_basic(self): + test_file = self.get_test_loc('pypi/metadata/METADATA') + package = pypi.parse_metadata(test_file) + expected_loc = self.get_test_loc('pypi/metadata/METADATA-expected.json') self.check_package(package, expected_loc, regen=False) - def test_parse_setup_py_python_publicsuffix(self): - test_file = self.get_test_loc('pypi/setup.py/python_publicsuffix_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/python_publicsuffix_setup.py-expected.json') - self.check_package(package, expected_loc, regen=False) - def test_parse_setup_py_repology_py_libversion(self): - test_file = self.get_test_loc('pypi/setup.py/repology_py_libversion_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/repology_py_libversion_setup.py-expected.json') - self.check_package(package, expected_loc, regen=False) +class TestPyPi(PackageTester): + test_data_dir = os.path.join(os.path.dirname(__file__), 'data') - def test_parse_setup_py_saneyaml(self): - test_file = self.get_test_loc('pypi/setup.py/saneyaml_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/saneyaml_setup.py-expected.json') + def test_develop_with_parse_unpacked_sdist(self): + test_file = self.get_test_loc('pypi/develop/scancode_toolkit.egg-info') + package = pypi.parse_unpacked_sdist(test_file) + expected_loc = self.get_test_loc('pypi/develop/scancode_toolkit.egg-info-expected-sdist.json') self.check_package(package, expected_loc, regen=False) - def test_parse_setup_py(self): - test_file = self.get_test_loc('pypi/setup.py/setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/setup.py-expected.json') + def test_develop_with_parse(self): + test_file = self.get_test_loc('pypi/develop/scancode_toolkit.egg-info') + package = pypi.parse(test_file) + expected_loc = self.get_test_loc('pypi/develop/scancode_toolkit.egg-info-expected-parse.json') self.check_package(package, expected_loc, regen=False) - def test_parse_setup_py_setuppycheck(self): - test_file = self.get_test_loc('pypi/setup.py/setuppycheck_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/setuppycheck_setup.py-expected.json') + def test_parse_wheel_with_wheelfile(self): + test_file = self.get_test_loc('pypi/wheel/atomicwrites-1.2.1-py2.py3-none-any.whl') + package = pypi.parse_wheel(test_file) + expected_loc = self.get_test_loc('pypi/wheel/atomicwrites-1.2.1-py2.py3-none-any.whl-expected.json') self.check_package(package, expected_loc, regen=False) - def test_parse_setup_py_url_py(self): - test_file = self.get_test_loc('pypi/setup.py/url_py_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/url_py_setup.py-expected.json') + def test_parse_with_wheelfile(self): + test_file = self.get_test_loc('pypi/wheel/atomicwrites-1.2.1-py2.py3-none-any.whl') + package = pypi.parse(test_file) + expected_loc = self.get_test_loc('pypi/wheel/atomicwrites-1.2.1-py2.py3-none-any.whl-expected.json') self.check_package(package, expected_loc, regen=False) - def test_parse_setup_py_venv(self): - test_file = self.get_test_loc('pypi/setup.py/venv_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/venv_setup.py-expected.json') + def test_parse_with_unpacked_wheel_1(self): + test_file = self.get_test_loc('pypi/unpacked_wheel/pip-20.2.2.dist-info/') + package = pypi.parse(test_file) + expected_loc = self.get_test_loc('pypi/unpacked_wheel/pip-20.2.2.dist-info-expected.json') self.check_package(package, expected_loc, regen=False) - def test_parse_setup_py_xmltodict(self): - test_file = self.get_test_loc('pypi/setup.py/xmltodict_setup.py') - package = pypi.parse_setup_py(test_file) - expected_loc = self.get_test_loc('pypi/setup.py/xmltodict_setup.py-expected.json') + def test_parse_with_unpacked_wheel_1_meta(self): + test_file = self.get_test_loc('pypi/unpacked_wheel/pip-20.2.2.dist-info/METADATA') + package = pypi.parse(test_file) + expected_loc = self.get_test_loc('pypi/unpacked_wheel/pip-20.2.2.dist-info-METADATA-expected.json') self.check_package(package, expected_loc, regen=False) - def test_pkginfo_parse_with_unpackaged_source(self): - test_file = self.get_test_loc('pypi') - package = pypi.parse_unpackaged_source(test_file) - expected_loc = self.get_test_loc('pypi/unpackage_source_parser-expected.json') + def test_parse_with_unpacked_wheel_2(self): + test_file = self.get_test_loc('pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/') + package = pypi.parse(test_file) + expected_loc = self.get_test_loc('pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info-expected.json') self.check_package(package, expected_loc, regen=False) - def test_pkginfo_parse_with_unpackaged_source_with_parse_function(self): - test_file = self.get_test_loc('pypi') + def test_parse_with_unpacked_wheel_2_meta(self): + test_file = self.get_test_loc('pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info/METADATA') package = pypi.parse(test_file) - expected_loc = self.get_test_loc('pypi/unpackage_source_parser-expected.json') + expected_loc = self.get_test_loc('pypi/unpacked_wheel/python_mimeparse-1.6.0.dist-info-METADATA-expected.json') self.check_package(package, expected_loc, regen=False) - def test_pkginfo_parse_with_wheelfile(self): - test_file = self.get_test_loc('pypi/wheel/atomicwrites-1.2.1-py2.py3-none-any.whl') - package = pypi.parse_wheel(test_file) - expected_loc = self.get_test_loc('pypi/wheel/parse-wheel-expected.json') + def test_parse_with_unpacked_wheel_3(self): + test_file = self.get_test_loc('pypi/unpacked_wheel/toml-0.10.1.dist-info/') + package = pypi.parse(test_file) + expected_loc = self.get_test_loc('pypi/unpacked_wheel/toml-0.10.1.dist-info-expected.json') self.check_package(package, expected_loc, regen=False) - def test_pkginfo_parse_with_wheelfile_with_parse_function(self): - test_file = self.get_test_loc('pypi/wheel/atomicwrites-1.2.1-py2.py3-none-any.whl') + def test_parse_with_unpacked_wheel_3_meta(self): + test_file = self.get_test_loc('pypi/unpacked_wheel/toml-0.10.1.dist-info/METADATA') package = pypi.parse(test_file) - expected_loc = self.get_test_loc('pypi/wheel/parse-wheel-expected.json') + expected_loc = self.get_test_loc('pypi/unpacked_wheel/toml-0.10.1.dist-info-METADATA-expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample1(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample1/requirements.txt') - package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample1/output.expected.json') - self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample2(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample2/sample-requirements.txt') - package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample2/output.expected.json') - self.check_package(package, expected_loc, regen=False) +class TestPyPiRequirements(PackageTester): + test_data_dir = os.path.join(os.path.dirname(__file__), 'data') - def test_requirements_txt_sample3(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample3/requirements-dev.txt') - package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample3/output.expected.json') - self.check_package(package, expected_loc, regen=False) + def test_parse_with_dparse_requirements(self): + test_file = self.get_test_loc('pypi/dparse/requirements.txt') + dependencies = [d.to_dict() for d in pypi.parse_with_dparse(test_file)] + expected_loc = self.get_test_loc('pypi/dparse/requirements.txt-expected.json') + check_result_equals_expected_json(dependencies, expected_loc, regen=False) - def test_requirements_txt_sample4(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample4/requirements.in') + def test_parse_requirements_txt_basic(self): + test_file = self.get_test_loc('pypi/requirements_txt/basic/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample4/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/basic/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample5(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample5/requirements-test.txt') + def test_parse_requirements_txt_pinned(self): + test_file = self.get_test_loc('pypi/requirements_txt/pinned/sample-requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample5/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/pinned/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample6(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample6/requirements-dev.in') + def test_parse_requirements_txt_dev(self): + test_file = self.get_test_loc('pypi/requirements_txt/dev/requirements-dev.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample6/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/dev/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample7(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample7/requirements-test.in') + def test_parse_requirements_txt_requirements_in(self): + test_file = self.get_test_loc('pypi/requirements_txt/requirements_in/requirements.in') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample7/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/requirements_in/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample8(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample8/requirements.txt') + def test_parse_requirements_txt_eol_comment(self): + test_file = self.get_test_loc('pypi/requirements_txt/eol_comment/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample8/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/eol_comment/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample9(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample9/requirements.txt') + def test_parse_requirements_txt_complex(self): + test_file = self.get_test_loc('pypi/requirements_txt/complex/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample9/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/complex/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample10(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample10/requirements.txt') + def test_parse_requirements_txt_editable(self): + test_file = self.get_test_loc('pypi/requirements_txt/editable/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample10/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/editable/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample11(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample11/requirements.txt') + def test_parse_requirements_txt_double_extras(self): + test_file = self.get_test_loc('pypi/requirements_txt/double_extras/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample11/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/double_extras/output.expected.json') self.check_package(package, expected_loc, regen=False) @expectedFailure - def test_requirements_txt_sample12(self): - # FAILURE: dparse library wrongly detect the dependencies - # we should return only a single value which should be the latest one - test_file = self.get_test_loc('pypi/requirements_txt/sample12/requirements.txt') + def test_parse_requirements_txt_repeated(self): + # FAILURE: dparse library wrongly detect the first of two repeated + # dependencies we should return only a single value which should be the + # last one + test_file = self.get_test_loc('pypi/requirements_txt/repeated/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample12/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/repeated/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample13(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample13/requirements.txt') + def test_parse_requirements_txt_vcs_eggs(self): + test_file = self.get_test_loc('pypi/requirements_txt/vcs_eggs/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample13/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/vcs_eggs/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample14(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample14/requirements.txt') + def test_parse_requirements_txt_local_paths_and_files(self): + test_file = self.get_test_loc('pypi/requirements_txt/local_paths_and_files/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample14/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/local_paths_and_files/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample15(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample15/requirements.txt') + def test_parse_requirements_txt_urls_wth_checksums(self): + test_file = self.get_test_loc('pypi/requirements_txt/urls_wth_checksums/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample15/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/urls_wth_checksums/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample16(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample16/requirements.txt') + def test_parse_requirements_txt_mixed(self): + test_file = self.get_test_loc('pypi/requirements_txt/mixed/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample16/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/mixed/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample17(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample17/requirements.txt') + def test_parse_requirements_txt_comments_and_empties(self): + test_file = self.get_test_loc('pypi/requirements_txt/comments_and_empties/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample17/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/comments_and_empties/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample18(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample18/requirements.txt') + def test_parse_requirements_txt_many_specs(self): + test_file = self.get_test_loc('pypi/requirements_txt/many_specs/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample18/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/many_specs/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample19(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample19/requirements.txt') + def test_parse_requirements_txt_vcs_editable(self): + test_file = self.get_test_loc('pypi/requirements_txt/vcs_editable/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample19/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/vcs_editable/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample20(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample20/vcs_git_extras_require_requirements.txt') + def test_parse_requirements_txt_vcs_extras_require(self): + test_file = self.get_test_loc('pypi/requirements_txt/vcs_extras_require/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample20/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/vcs_extras_require/output.expected.json') self.check_package(package, expected_loc, regen=False) - def test_requirements_txt_sample21(self): - test_file = self.get_test_loc('pypi/requirements_txt/sample21/vcs_git_requirements.txt') + def test_parse_requirements_txt_vcs_git(self): + test_file = self.get_test_loc('pypi/requirements_txt/vcs-git/requirements.txt') package = pypi.parse_requirements_txt(test_file) - expected_loc = self.get_test_loc('pypi/requirements_txt/sample21/output.expected.json') + expected_loc = self.get_test_loc('pypi/requirements_txt/vcs-git/output.expected.json') self.check_package(package, expected_loc, regen=False) + +class TestPyPiPipfile(PackageTester): + test_data_dir = os.path.join(os.path.dirname(__file__), 'data') + def test_pipfile_lock_sample1(self): test_file = self.get_test_loc('pypi/pipfile.lock/sample1/Pipfile.lock') package = pypi.parse_pipfile_lock(test_file) - expected_loc = self.get_test_loc('pypi/pipfile.lock/sample1/output.expected.json') + expected_loc = self.get_test_loc('pypi/pipfile.lock/sample1/Pipfile.lock-expected.json') self.check_package(package, expected_loc, regen=False) def test_pipfile_lock_sample2(self): test_file = self.get_test_loc('pypi/pipfile.lock/sample2/Pipfile.lock') package = pypi.parse_pipfile_lock(test_file) - expected_loc = self.get_test_loc('pypi/pipfile.lock/sample2/output.expected.json') + expected_loc = self.get_test_loc('pypi/pipfile.lock/sample2/Pipfile.lock-expected.json') self.check_package(package, expected_loc, regen=False) def test_pipfile_lock_sample3(self): test_file = self.get_test_loc('pypi/pipfile.lock/sample3/Pipfile.lock') package = pypi.parse_pipfile_lock(test_file) - expected_loc = self.get_test_loc('pypi/pipfile.lock/sample3/output.expected.json') + expected_loc = self.get_test_loc('pypi/pipfile.lock/sample3/Pipfile.lock-expected.json') self.check_package(package, expected_loc, regen=False) def test_pipfile_lock_sample4(self): test_file = self.get_test_loc('pypi/pipfile.lock/sample4/Pipfile.lock') package = pypi.parse_pipfile_lock(test_file) - expected_loc = self.get_test_loc('pypi/pipfile.lock/sample4/output.expected.json') + expected_loc = self.get_test_loc('pypi/pipfile.lock/sample4/Pipfile.lock-expected.json') self.check_package(package, expected_loc, regen=False) def test_pipfile_lock_sample5(self): test_file = self.get_test_loc('pypi/pipfile.lock/sample5/Pipfile.lock') package = pypi.parse_pipfile_lock(test_file) - expected_loc = self.get_test_loc('pypi/pipfile.lock/sample5/output.expected.json') + expected_loc = self.get_test_loc('pypi/pipfile.lock/sample5/Pipfile.lock-expected.json') self.check_package(package, expected_loc, regen=False) - def test_parse_with_dparse(self): - test_file = self.get_test_loc('pypi/dparse/requirements.txt') - dependencies = pypi.parse_with_dparse(test_file) - assert dependencies == [DependentPackage(purl='pkg:pypi/lxml@3.4.4', requirement='==3.4.4', scope='dependencies', is_resolved=True), - DependentPackage(purl='pkg:pypi/requests@2.7.0', requirement='==2.7.0', scope='dependencies', is_resolved=True)] - - -FILENAME_LIST = [ - ('requirements.txt', 'requirements.txt'), - ('sample-requirements.txt', 'requirements.txt'), - ('requirements-test.txt', 'requirements.txt'), - ('sample-requirements-test.txt', 'requirements.txt'), - ('requirements-dev.txt', 'requirements.txt'), - ('sample-requirements-dev.txt', 'requirements.txt'), - ('requirements.in', 'requirements.txt'), - ('sample-requirements.in', 'requirements.txt'), - ('requirements-test.in', 'requirements.txt'), - ('sample-requirements-test.in', 'requirements.txt'), - ('requirements-dev.in', 'requirements.txt'), - ('sample-requirements-dev.in', 'requirements.txt'), - ('Pipfile.lock', 'Pipfile.lock') -] - - -class TestFiletype(object): - - @pytest.mark.parametrize('filename, expected_filename', FILENAME_LIST) + +class TestRequirementsFiletype(object): + + requirement_files = [ + ('requirements.txt', 'requirements.txt'), + ('sample-requirements.txt', 'requirements.txt'), + ('requirements-test.txt', 'requirements.txt'), + ('sample-requirements-test.txt', 'requirements.txt'), + ('requirements-dev.txt', 'requirements.txt'), + ('sample-requirements-dev.txt', 'requirements.txt'), + ('requirements.in', 'requirements.txt'), + ('sample-requirements.in', 'requirements.txt'), + ('requirements-test.in', 'requirements.txt'), + ('sample-requirements-test.in', 'requirements.txt'), + ('requirements-dev.in', 'requirements.txt'), + ('sample-requirements-dev.in', 'requirements.txt'), + ('Pipfile.lock', 'Pipfile.lock') + ] + + @pytest.mark.parametrize('filename, expected_filename', requirement_files) def test_file_type(self, filename, expected_filename): - filename = pypi.get_dependency_type(filename) + filename = pypi.get_dparse_dependency_type(filename) assert filename == expected_filename -def get_setup_test_files(test_dir): +def get_setup_py_test_files(test_dir): """ - Yield tuples of (setup.py file, expected JSON file) from a test data - `test_dir` directory. + Yield tuples of (setup.py file, expected JSON file) from a `test_dir` test + data directory. """ for top, _, files in os.walk(test_dir): for tfile in files: - if tfile != 'setup.py': + if tfile.endswith('setup.py'): continue test_loc = os.path.join(top, tfile) expected_loc = test_loc + '-expected.json' @@ -460,7 +332,7 @@ class TestSetupPyVersions(object): 'setup.py-versions', )) - @pytest.mark.parametrize('test_loc, expected_loc', list(get_setup_test_files(test_data_dir))) + @pytest.mark.parametrize('test_loc, expected_loc', list(get_setup_py_test_files(test_data_dir))) def test_parse_setup_py_with_computed_versions(self, test_loc, expected_loc, regen=False): package = pypi.parse_setup_py(test_loc) if package: @@ -479,3 +351,163 @@ def test_parse_setup_py_with_computed_versions(self, test_loc, expected_loc, reg assert results == expected except AssertionError: assert json.dumps(results, indent=2) == json.dumps(expected, indent=2) + + +class TestPyPiSetupPy(PackageTester): + test_data_dir = os.path.join(os.path.dirname(__file__), 'data') + + @skipIf(on_windows, 'Somehow this fails on Windows') + def test_parse_setup_py_arpy(self): + test_file = self.get_test_loc('pypi/setup.py/arpy_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/arpy_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + @expectedFailure + def test_parse_setup_py_pluggy(self): + test_file = self.get_test_loc('pypi/setup.py/pluggy_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/pluggy_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + @expectedFailure + def test_parse_setup_py_pygtrie(self): + # this uses a kwargs dict + test_file = self.get_test_loc('pypi/setup.py/pygtrie_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/pygtrie_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_basic(self): + test_file = self.get_test_loc('pypi/setup.py/simple-setup.py') + package = pypi.parse(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_boolean2_py(self): + test_file = self.get_test_loc('pypi/setup.py/boolean2_py_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/boolean2_py_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_container_check(self): + test_file = self.get_test_loc('pypi/setup.py/container_check_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/container_check_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_fb303_py(self): + test_file = self.get_test_loc('pypi/setup.py/fb303_py_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/fb303_py_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_frell_src(self): + # setup.py is a temaplte with @vars + test_file = self.get_test_loc('pypi/setup.py/frell_src_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/frell_src_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_gyp(self): + test_file = self.get_test_loc('pypi/setup.py/gyp_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/gyp_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_interlap(self): + test_file = self.get_test_loc('pypi/setup.py/interlap_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/interlap_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_mb(self): + test_file = self.get_test_loc('pypi/setup.py/mb_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/mb_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_ntfs(self): + test_file = self.get_test_loc('pypi/setup.py/ntfs_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/ntfs_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_nvchecker(self): + test_file = self.get_test_loc('pypi/setup.py/nvchecker_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/nvchecker_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_oi_agents_common_code(self): + test_file = self.get_test_loc('pypi/setup.py/oi_agents_common_code_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/oi_agents_common_code_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_packageurl_python(self): + test_file = self.get_test_loc('pypi/setup.py/packageurl_python_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/packageurl_python_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_pipdeptree(self): + test_file = self.get_test_loc('pypi/setup.py/pipdeptree_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/pipdeptree_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_pydep(self): + test_file = self.get_test_loc('pypi/setup.py/pydep_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/pydep_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_pyrpm_2(self): + test_file = self.get_test_loc('pypi/setup.py/pyrpm_2_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/pyrpm_2_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_python_publicsuffix(self): + test_file = self.get_test_loc('pypi/setup.py/python_publicsuffix_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/python_publicsuffix_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_repology_py_libversion(self): + test_file = self.get_test_loc('pypi/setup.py/repology_py_libversion_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/repology_py_libversion_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_saneyaml(self): + test_file = self.get_test_loc('pypi/setup.py/saneyaml_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/saneyaml_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_setuppycheck(self): + test_file = self.get_test_loc('pypi/setup.py/setuppycheck_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/setuppycheck_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_url_py(self): + test_file = self.get_test_loc('pypi/setup.py/url_py_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/url_py_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_venv(self): + test_file = self.get_test_loc('pypi/setup.py/venv_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/venv_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + + def test_parse_setup_py_xmltodict(self): + test_file = self.get_test_loc('pypi/setup.py/xmltodict_setup.py') + package = pypi.parse_setup_py(test_file) + expected_loc = self.get_test_loc('pypi/setup.py/xmltodict_setup.py-expected.json') + self.check_package(package, expected_loc, regen=False) + diff --git a/tests/packagedcode/test_recognize.py b/tests/packagedcode/test_recognize.py index f78b92f5982..4a9d97243dd 100644 --- a/tests/packagedcode/test_recognize.py +++ b/tests/packagedcode/test_recognize.py @@ -7,20 +7,28 @@ # See https://aboutcode.org for more information about nexB OSS projects. # -import os.path +import os +from unittest.case import expectedFailure from commoncode.testcase import FileBasedTesting import packagedcode +from packagedcode.recognize import recognize_packages + +from packagedcode import bower +from packagedcode import cargo from packagedcode import freebsd +from packagedcode import haxe from packagedcode import maven from packagedcode import npm -from packagedcode import cargo +from packagedcode import nuget from packagedcode import opam from packagedcode import phpcomposer from packagedcode import rpm -from packagedcode.recognize import recognize_packages -from packagedcode import nuget +from packagedcode import win_pe +from packagedcode import pypi +from packagedcode import golang +from packagedcode import models class TestRecognize(FileBasedTesting): @@ -127,6 +135,12 @@ def test_recognize_composer(self): assert packages assert isinstance(packages[0], phpcomposer.PHPComposerPackage) + def test_recognize_haxe(self): + test_file = self.get_test_loc('recon/haxelib.json') + packages = recognize_packages(test_file) + assert packages + assert isinstance(packages[0], haxe.HaxePackage) + def test_recognize_freebsd(self): test_file = self.get_test_loc('freebsd/multi_license/+COMPACT_MANIFEST') packages = recognize_packages(test_file) @@ -138,3 +152,70 @@ def test_recognize_nuget(self): packages = recognize_packages(test_file) assert packages assert isinstance(packages[0], nuget.NugetPackage) + + def test_recognize_winexe(self): + test_file = self.get_test_loc('win_pe/tre4.dll') + packages = recognize_packages(test_file) + assert packages + assert isinstance(packages[0], win_pe.WindowsExecutable) + + def test_recognize_bower(self): + test_file = self.get_test_loc('bower/basic/bower.json') + packages = recognize_packages(test_file) + assert packages + assert isinstance(packages[0], bower.BowerPackage) + + @expectedFailure + def test_recognize_cpan(self): + test_file = self.get_test_loc('cpan/MANIFEST') + packages = recognize_packages(test_file) + assert packages + assert isinstance(packages[0], models.CpanModule) + + def test_recognize_python2(self): + test_file = self.get_test_loc('recon/pypi/atomicwrites-1.2.1-py2.py3-none-any.whl') + packages = recognize_packages(test_file) + assert packages + assert isinstance(packages[0], pypi.PythonPackage) + + def test_recognize_python3(self): + test_file = self.get_test_loc('recon/pypi/METADATA') + packages = recognize_packages(test_file) + assert packages + assert isinstance(packages[0], pypi.PythonPackage) + + def test_recognize_python5(self): + test_file = self.get_test_loc('recon/pypi/PKG-INFO') + packages = recognize_packages(test_file) + assert packages + assert isinstance(packages[0], pypi.PythonPackage) + + def test_recognize_python6(self): + test_file = self.get_test_loc('recon/pypi/setup.py') + packages = recognize_packages(test_file) + assert packages + assert isinstance(packages[0], pypi.PythonPackage) + + def test_recognize_python7(self): + test_file = self.get_test_loc('recon/pypi/Pipfile.lock') + packages = recognize_packages(test_file) + assert packages + assert isinstance(packages[0], pypi.PythonPackage) + + def test_recognize_python8(self): + test_file = self.get_test_loc('recon/pypi/requirements.txt') + packages = recognize_packages(test_file) + assert packages + assert isinstance(packages[0], pypi.PythonPackage) + + def test_recognize_go_mod(self): + test_file = self.get_test_loc('golang/gomod/kingpin/go.mod') + packages = recognize_packages(test_file) + assert packages + assert isinstance(packages[0], golang.GolangPackage) + + def test_recognize_go_sum(self): + test_file = self.get_test_loc('golang/gosum/sample1/go.sum') + packages = recognize_packages(test_file) + assert packages + assert isinstance(packages[0], golang.GolangPackage)