From bc85a15a7f36045357cb8170e73338106a33ca3c Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Wed, 29 Nov 2023 12:23:47 +0100 Subject: [PATCH 01/15] Some cleanups; replace final pypi data retrieval using asyncio. Signed-off-by: Thomas Neidhart --- requirements.txt | 29 ++++++------ setup.cfg | 2 + src/python_inspector/api.py | 47 +++++++++---------- src/python_inspector/package_data.py | 68 ++++++++++++++-------------- src/python_inspector/resolution.py | 1 - src/python_inspector/utils.py | 18 +++++++- 6 files changed, 92 insertions(+), 73 deletions(-) diff --git a/requirements.txt b/requirements.txt index 610856c..ee5b7ea 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ -attrs==22.1.0 -beautifulsoup4==4.11.1 -certifi==2022.6.15 -charset-normalizer==2.1.0 -click==8.1.3 -colorama==0.4.5 -commoncode==30.2.0 +attrs==23.1.0 +beautifulsoup4==4.12.2 +certifi==2023.11.17 +charset-normalizer==3.3.2 +click==8.1.7 +colorama==0.4.6 +commoncode==31.0.3 dparse2==0.7.0 idna==3.3 importlib-metadata==4.12.0 @@ -14,13 +14,14 @@ packaging==21.3 packvers==21.5 pip-requirements-parser==32.0.1 pkginfo2==30.0.0 -pyparsing==3.0.9 -PyYAML==6.0 -requests==2.28.1 +pyparsing==3.1.1 +PyYAML==6.0.1 +requests==2.31.0 resolvelib >= 1.0.0 -saneyaml==0.5.2 -soupsieve==2.3.2.post1 +saneyaml==0.6.0 +soupsieve==2.5 text-unidecode==1.3 toml==0.10.2 -urllib3==1.26.11 -zipp==3.8.1 +urllib3==2.1.0 +zipp==3.17.0 +aiohttp==3.9.1 diff --git a/setup.cfg b/setup.cfg index 6d8f566..1fdc638 100644 --- a/setup.cfg +++ b/setup.cfg @@ -69,6 +69,8 @@ install_requires = toml >= 0.10.0 mock >= 3.0.5 packvers >= 21.5 + aiohttp >= 3.9 + [options.packages.find] where = src diff --git a/src/python_inspector/api.py b/src/python_inspector/api.py index a64d0c1..182d82f 100644 --- a/src/python_inspector/api.py +++ b/src/python_inspector/api.py @@ -8,7 +8,7 @@ # See https://aboutcode-orgnexB/python-inspector for support or download. # See https://aboutcode.org for more information about nexB OSS projects. # - +import asyncio import os from netrc import netrc from typing import Dict @@ -26,7 +26,6 @@ from _packagedcode.pypi import PipRequirementsFileHandler from _packagedcode.pypi import PythonSetupPyHandler from _packagedcode.pypi import can_process_dependent_package -from python_inspector import DEFAULT_PYTHON_VERSION from python_inspector import dependencies from python_inspector import utils from python_inspector import utils_pypi @@ -238,7 +237,7 @@ def resolve_dependencies( if not direct_dependencies: return Resolution( packages=[], - resolution=[], + resolution={}, files=files, ) @@ -297,19 +296,21 @@ def resolve_dependencies( ignore_errors=ignore_errors, ) - packages = [] + async def gather_pypi_data(): + async def get_pypi_data(package): + if verbose: + printer(f" package '{package}'") - for package in purls: - packages.extend( - [ - pkg.to_dict() - for pkg in list( - get_pypi_data_from_purl( - package, repos=repos, environment=environment, prefer_source=prefer_source - ) - ) - ], - ) + return await get_pypi_data_from_purl( + package, repos=repos, environment=environment, prefer_source=prefer_source + ) + + if verbose: + printer(f"retrieve data from pypi:") + + return await asyncio.gather(*[get_pypi_data(package) for package in purls]) + + packages = [pkg.to_dict() for pkg in asyncio.run(gather_pypi_data()) if pkg is not None] if verbose: printer("done!") @@ -325,14 +326,14 @@ def resolve_dependencies( def resolve( - direct_dependencies, - environment, - repos=tuple(), - as_tree=False, - max_rounds=200000, - pdt_output=False, - analyze_setup_py_insecurely=False, - ignore_errors=False, + direct_dependencies: List[DependentPackage], + environment: Environment, + repos: Sequence[utils_pypi.PypiSimpleRepository] = tuple(), + as_tree: bool = False, + max_rounds: int = 200000, + pdt_output: bool = False, + analyze_setup_py_insecurely: bool = False, + ignore_errors: bool = False, ): """ Resolve dependencies given a ``direct_dependencies`` list of diff --git a/src/python_inspector/package_data.py b/src/python_inspector/package_data.py index a320bf8..9cbce48 100644 --- a/src/python_inspector/package_data.py +++ b/src/python_inspector/package_data.py @@ -9,7 +9,7 @@ # See https://aboutcode.org for more information about nexB OSS projects. # -from typing import List +from typing import List, Iterable, Optional from packageurl import PackageURL @@ -24,9 +24,9 @@ from python_inspector.utils_pypi import PypiSimpleRepository -def get_pypi_data_from_purl( +async def get_pypi_data_from_purl( purl: str, environment: Environment, repos: List[PypiSimpleRepository], prefer_source: bool -) -> PackageData: +) -> Optional[PackageData]: """ Generate `Package` object from the `purl` string of pypi type @@ -36,18 +36,19 @@ def get_pypi_data_from_purl( ``prefer_source`` is a boolean value to prefer source distribution over wheel, if no source distribution is available then wheel is used """ - purl = PackageURL.from_string(purl) - name = purl.name - version = purl.version + parsed_purl = PackageURL.from_string(purl) + name = parsed_purl.name + version = parsed_purl.version if not version: raise Exception("Version is not specified in the purl") base_path = "https://pypi.org/pypi" api_url = f"{base_path}/{name}/{version}/json" - from python_inspector.resolution import get_response - response = get_response(api_url) + from python_inspector.utils import get_response_async + response = await get_response_async(api_url) if not response: - return [] + return None + info = response.get("info") or {} homepage_url = info.get("home_page") project_urls = info.get("project_urls") or {} @@ -57,20 +58,16 @@ def get_pypi_data_from_purl( python_version=environment.python_version) valid_distribution_urls = [] - valid_distribution_urls.append( - get_sdist_download_url( - purl=purl, - repos=repos, - python_version=python_version, - ) - ) + sdist_url = get_sdist_download_url(purl=parsed_purl, repos=repos, python_version=python_version) + if sdist_url: + valid_distribution_urls.append(sdist_url) # if prefer_source is True then only source distribution is used # in case of no source distribution available then wheel is used if not valid_distribution_urls or not prefer_source: wheel_urls = list( get_wheel_download_urls( - purl=purl, + purl=parsed_purl, repos=repos, environment=environment, python_version=python_version, @@ -78,16 +75,19 @@ def get_pypi_data_from_purl( ) wheel_url = choose_single_wheel(wheel_urls) if wheel_url: - valid_distribution_urls.append(wheel_url) + valid_distribution_urls.insert(0, wheel_url) - urls = response.get("urls") or [] - for url in urls: - dist_url = url.get("url") - if dist_url not in valid_distribution_urls: + urls = {url.get("url"): url for url in response.get("urls", [])} + # iterate over the valid distribution urls and return the first + # one that is matching. + for dist_url in valid_distribution_urls: + if dist_url not in urls: continue - digests = url.get("digests") or {} - yield PackageData( + url_data = urls.get(dist_url) + digests = url_data.get("digests", {}) + + return PackageData( primary_language="Python", description=get_description(info), homepage_url=homepage_url, @@ -96,10 +96,10 @@ def get_pypi_data_from_purl( code_view_url=code_view_url, declared_license=get_declared_license(info), download_url=dist_url, - size=url.get("size"), - md5=digests.get("md5") or url.get("md5_digest"), + size=url_data.get("size"), + md5=digests.get("md5") or url_data.get("md5_digest"), sha256=digests.get("sha256"), - release_date=url.get("upload_time"), + release_date=url_data.get("upload_time"), keywords=get_keywords(info), parties=get_parties( info, @@ -108,9 +108,11 @@ def get_pypi_data_from_purl( maintainer_key="maintainer", maintainer_email_key="maintainer_email", ), - **purl.to_dict(), + **parsed_purl.to_dict(), ) + return None + def choose_single_wheel(wheel_urls): """ @@ -123,18 +125,18 @@ def choose_single_wheel(wheel_urls): def get_pypi_bugtracker_url(project_urls): bug_tracking_url = project_urls.get("Tracker") - if not (bug_tracking_url): + if not bug_tracking_url: bug_tracking_url = project_urls.get("Issue Tracker") - if not (bug_tracking_url): + if not bug_tracking_url: bug_tracking_url = project_urls.get("Bug Tracker") return bug_tracking_url def get_pypi_codeview_url(project_urls): code_view_url = project_urls.get("Source") - if not (code_view_url): + if not code_view_url: code_view_url = project_urls.get("Code") - if not (code_view_url): + if not code_view_url: code_view_url = project_urls.get("Source Code") return code_view_url @@ -144,7 +146,7 @@ def get_wheel_download_urls( repos: List[PypiSimpleRepository], environment: Environment, python_version: str, -) -> List[str]: +) -> Iterable[str]: """ Return a list of download urls for the given purl. """ diff --git a/src/python_inspector/resolution.py b/src/python_inspector/resolution.py index f160b11..f2708c6 100644 --- a/src/python_inspector/resolution.py +++ b/src/python_inspector/resolution.py @@ -10,7 +10,6 @@ import ast import operator import os -import re import tarfile from typing import Dict from typing import Generator diff --git a/src/python_inspector/utils.py b/src/python_inspector/utils.py index 9f5b090..4dbfcce 100644 --- a/src/python_inspector/utils.py +++ b/src/python_inspector/utils.py @@ -11,10 +11,11 @@ import json import os -from typing import Dict +from typing import Dict, Optional from typing import List from typing import NamedTuple +import aiohttp import requests @@ -67,13 +68,26 @@ class Candidate(NamedTuple): def get_response(url: str) -> Dict: """ Return a mapping of the JSON response from fetching ``url`` - or None if the ``url`` cannot be fetched.. + or None if the ``url`` cannot be fetched. """ resp = requests.get(url) if resp.status_code == 200: return resp.json() +async def get_response_async(url: str) -> Optional[Dict]: + """ + Return a mapping of the JSON response from fetching ``url`` + or None if the ``url`` cannot be fetched. + """ + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + if response.status == 200: + return await response.json() + else: + return None + + def remove_test_data_dir_variable_prefix(path, placeholder=""): """ Return a clean path, removing variable test path prefix or using a ``placeholder``. From 74e0c36b0b18ea0de6c7e75fc68425e1c4671275 Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Wed, 29 Nov 2023 18:59:15 +0100 Subject: [PATCH 02/15] More cleanups. Signed-off-by: Thomas Neidhart --- src/python_inspector/api.py | 15 ++++++--------- src/python_inspector/dependencies.py | 19 +++++++++---------- src/python_inspector/package_data.py | 14 ++++++++------ src/python_inspector/resolution.py | 22 +++++++++++----------- src/python_inspector/utils_pypi.py | 11 ++++++----- 5 files changed, 40 insertions(+), 41 deletions(-) diff --git a/src/python_inspector/api.py b/src/python_inspector/api.py index 182d82f..86205d0 100644 --- a/src/python_inspector/api.py +++ b/src/python_inspector/api.py @@ -11,7 +11,7 @@ import asyncio import os from netrc import netrc -from typing import Dict +from typing import Dict, Tuple from typing import List from typing import NamedTuple from typing import Sequence @@ -374,14 +374,14 @@ def get_resolved_dependencies( pdt_output: bool = False, analyze_setup_py_insecurely: bool = False, ignore_errors: bool = False, -): +) -> Tuple[List[Dict], List[str]]: """ Return resolved dependencies of a ``requirements`` list of Requirement for - an ``enviroment`` Environment. The resolved dependencies are formatted as + an ``environment`` Environment. The resolved dependencies are formatted as parent/children or a nested tree if ``as_tree`` is True. Used the provided ``repos`` list of PypiSimpleRepository. - If empty, use instead the PyPI.org JSON API exclusively instead + If empty, use instead the PyPI.org JSON API exclusively instead. """ resolver = Resolver( provider=PythonInputProvider( @@ -396,11 +396,8 @@ def get_resolved_dependencies( requirements=requirements, max_rounds=max_rounds) package_list = get_package_list(results=resolver_results) if pdt_output: - return (format_pdt_tree(resolver_results), package_list) - return ( - format_resolution(resolver_results, as_tree=as_tree), - package_list, - ) + return format_pdt_tree(resolver_results), package_list + return format_resolution(resolver_results, as_tree=as_tree), package_list def get_requirements_from_direct_dependencies( diff --git a/src/python_inspector/dependencies.py b/src/python_inspector/dependencies.py index bfb060f..47cdc36 100644 --- a/src/python_inspector/dependencies.py +++ b/src/python_inspector/dependencies.py @@ -8,26 +8,26 @@ # See https://github.com/nexB/skeleton for support or download. # See https://aboutcode.org for more information about nexB OSS projects. # +from typing import Iterable, Mapping from packageurl import PackageURL from packvers.requirements import Requirement -from pip_requirements_parser import InstallRequirement from _packagedcode import models +from _packagedcode.models import DependentPackage from _packagedcode.pypi import PipRequirementsFileHandler from _packagedcode.pypi import get_requirements_txt_dependencies """ -Utilities to resolve dependencies . +Utilities to resolve dependencies. """ TRACE = False -def get_dependencies_from_requirements(requirements_file="requirements.txt"): +def get_dependencies_from_requirements(requirements_file="requirements.txt") -> Iterable[DependentPackage]: """ - Yield DependentPackage for each requirement in a `requirement` - file. + Yield DependentPackage for each requirement in a `requirement` file. """ dependent_packages, _ = get_requirements_txt_dependencies( location=requirements_file, include_nested=True @@ -41,21 +41,20 @@ def get_dependencies_from_requirements(requirements_file="requirements.txt"): yield dependent_package -def get_extra_data_from_requirements(requirements_file="requirements.txt"): +def get_extra_data_from_requirements(requirements_file="requirements.txt") -> Iterable[Mapping]: """ - Yield extra_data for each requirement in a `requirement` - file. + Yield extra_data for each requirement in a `requirement` file. """ for package_data in PipRequirementsFileHandler.parse(location=requirements_file): yield package_data.extra_data -def is_requirement_pinned(requirement: Requirement): +def is_requirement_pinned(requirement: Requirement) -> bool: specifiers = requirement.specifier return specifiers and len(specifiers) == 1 and next(iter(specifiers)).operator in {"==", "==="} -def get_dependency(specifier): +def get_dependency(specifier) -> DependentPackage: """ Return a DependentPackage given a requirement ``specifier`` string. diff --git a/src/python_inspector/package_data.py b/src/python_inspector/package_data.py index 9cbce48..17bbcdc 100644 --- a/src/python_inspector/package_data.py +++ b/src/python_inspector/package_data.py @@ -9,7 +9,7 @@ # See https://aboutcode.org for more information about nexB OSS projects. # -from typing import List, Iterable, Optional +from typing import List, Iterable, Optional, Dict from packageurl import PackageURL @@ -77,7 +77,7 @@ async def get_pypi_data_from_purl( if wheel_url: valid_distribution_urls.insert(0, wheel_url) - urls = {url.get("url"): url for url in response.get("urls", [])} + urls = {url.get("url"): url for url in response.get("urls") or []} # iterate over the valid distribution urls and return the first # one that is matching. for dist_url in valid_distribution_urls: @@ -85,7 +85,7 @@ async def get_pypi_data_from_purl( continue url_data = urls.get(dist_url) - digests = url_data.get("digests", {}) + digests = url_data.get("digests") or {} return PackageData( primary_language="Python", @@ -114,16 +114,18 @@ async def get_pypi_data_from_purl( return None -def choose_single_wheel(wheel_urls): +def choose_single_wheel(wheel_urls: List[str]) -> Optional[str]: """ Sort wheel urls descendingly and return the first one """ wheel_urls.sort(reverse=True) if wheel_urls: return wheel_urls[0] + else: + return None -def get_pypi_bugtracker_url(project_urls): +def get_pypi_bugtracker_url(project_urls: Dict) -> Optional[str]: bug_tracking_url = project_urls.get("Tracker") if not bug_tracking_url: bug_tracking_url = project_urls.get("Issue Tracker") @@ -132,7 +134,7 @@ def get_pypi_bugtracker_url(project_urls): return bug_tracking_url -def get_pypi_codeview_url(project_urls): +def get_pypi_codeview_url(project_urls: Dict) -> Optional[str]: code_view_url = project_urls.get("Source") if not code_view_url: code_view_url = project_urls.get("Code") diff --git a/src/python_inspector/resolution.py b/src/python_inspector/resolution.py index f2708c6..68aaba5 100644 --- a/src/python_inspector/resolution.py +++ b/src/python_inspector/resolution.py @@ -11,7 +11,7 @@ import operator import os import tarfile -from typing import Dict +from typing import Dict, Iterable, Optional from typing import Generator from typing import List from typing import NamedTuple @@ -70,7 +70,7 @@ class Result(NamedTuple): def get_requirements_from_distribution( - handler: BasePypiHandler, + handler: type[BasePypiHandler], location: str, ) -> List[Requirement]: """ @@ -84,7 +84,7 @@ def get_requirements_from_distribution( reqs = [] for package_data in handler.parse(location): dependencies = package_data.dependencies - reqs.extend(get_requirements_from_dependencies(dependencies=dependencies)) + reqs.extend(get_requirements_from_dependencies(dependencies=dependencies)) return reqs @@ -103,7 +103,7 @@ def get_deps_from_distribution( deps = [] for package_data in handler.parse(location): dependencies = package_data.dependencies - deps.extend(dependencies=dependencies) + deps.extend(dependencies) return deps @@ -256,7 +256,7 @@ def remove_extras(identifier: str) -> str: return name -def get_reqs_from_requirements_file_in_sdist(sdist_location: str, files: str) -> List[Requirement]: +def get_reqs_from_requirements_file_in_sdist(sdist_location: str, files: List) -> List[Requirement]: """ Return a list of parsed requirements from the ``sdist_location`` sdist location """ @@ -284,7 +284,7 @@ def get_requirements_from_python_manifest( """ Return a list of parsed requirements from the ``sdist_location`` sdist location """ - # Look in requirements file if and only if they are refered in setup.py or setup.cfg + # Look in requirements file if and only if they are referred in setup.py or setup.cfg # And no deps have been yielded by requirements file. requirements = list( get_reqs_from_requirements_file_in_sdist( @@ -391,7 +391,7 @@ def get_preference( return transitive, identifier def get_versions_for_package( - self, name: str, repo: Union[List[PypiSimpleRepository], None] = None + self, name: str, repo: Optional[PypiSimpleRepository] = None ) -> List[Version]: """ Return a list of versions for a package. @@ -447,7 +447,7 @@ def get_versions_for_package_from_pypi_json_api(self, name: str) -> List[Version def get_requirements_for_package( self, purl: PackageURL, candidate: Candidate - ) -> Generator[Requirement, None, None]: + ) -> Iterable[Requirement]: """ Yield requirements for a package. """ @@ -531,7 +531,7 @@ def get_requirements_for_package_from_pypi_simple( def get_requirements_for_package_from_pypi_json_api( self, purl: PackageURL - ) -> List[Requirement]: + ) -> Iterable[Requirement]: """ Return requirements for a package from the PyPI.org JSON API """ @@ -555,7 +555,7 @@ def get_candidates( bad_versions: List[str], name: str, extras: Dict, - ) -> Generator[Candidate, None, None]: + ) -> Iterable[Candidate]: """ Generate candidates for the given identifier. Overridden. """ @@ -582,7 +582,7 @@ def _iter_matches( incompatibilities: Dict, ) -> Generator[Candidate, None, None]: """ - Yield candidates for the given identifier, requirements and incompatibilities + Yield candidates for the given identifier, requirements and incompatibilities. """ name = remove_extras(identifier=identifier) bad_versions = {c.version for c in incompatibilities[identifier]} diff --git a/src/python_inspector/utils_pypi.py b/src/python_inspector/utils_pypi.py index 2af5d57..06b70a7 100644 --- a/src/python_inspector/utils_pypi.py +++ b/src/python_inspector/utils_pypi.py @@ -98,7 +98,7 @@ """ TRACE = False -TRACE_DEEP = False +TRACE_DEEP = True TRACE_ULTRA_DEEP = False # Supported environments @@ -260,7 +260,7 @@ def download_wheel( fetched_wheel_filenames.append(fetched_wheel_filename) if fetched_wheel_filenames: - # do not futher fetch from other repos if we find in first, typically PyPI + # do not further fetch from other repos if we find in first, typically PyPI break return fetched_wheel_filenames @@ -1765,7 +1765,7 @@ def get_remote_file_content( ): """ Fetch and return a tuple of (headers, content) at `url`. Return content as a - text string if `as_text` is True. Otherwise return the content as bytes. + text string if `as_text` is True. Otherwise, return the content as bytes. If `header_only` is True, return only (headers, None). Headers is a mapping of HTTP headers. @@ -1774,7 +1774,7 @@ def get_remote_file_content( """ time.sleep(_delay) headers = headers or {} - # using a GET with stream=True ensure we get the the final header from + # using a GET with stream=True ensure we get the final header from # several redirects and that we can ignore content there. A HEAD request may # not get us this last header if verbose and not echo_func: @@ -1829,7 +1829,7 @@ def fetch_and_save( ): """ Fetch content at ``path_or_url`` URL or path and save this to - ``dest_dir/filername``. Return the fetched content. Raise an Exception on + ``dest_dir/filename``. Return the fetched content. Raise an Exception on errors. Treats the content as text if as_text is True otherwise as treat as binary. """ @@ -1840,6 +1840,7 @@ def fetch_and_save( verbose=verbose, echo_func=echo_func, ) + output = os.path.join(dest_dir, filename) wmode = "w" if as_text else "wb" with open(output, wmode) as fo: From 10da3676072f9340cfda91ebf0424f64e0991648 Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Thu, 30 Nov 2023 08:34:14 +0100 Subject: [PATCH 03/15] Continue using asyncio. Signed-off-by: Thomas Neidhart --- src/python_inspector/api.py | 49 ++++++++-- src/python_inspector/package_data.py | 37 +++---- src/python_inspector/resolution.py | 138 +++++++++++++++------------ src/python_inspector/utils_pypi.py | 137 +++++++++++++------------- 4 files changed, 201 insertions(+), 160 deletions(-) diff --git a/src/python_inspector/api.py b/src/python_inspector/api.py index 86205d0..cca3751 100644 --- a/src/python_inspector/api.py +++ b/src/python_inspector/api.py @@ -294,17 +294,21 @@ def resolve_dependencies( pdt_output=pdt_output, analyze_setup_py_insecurely=analyze_setup_py_insecurely, ignore_errors=ignore_errors, + verbose=verbose, + printer=printer ) async def gather_pypi_data(): async def get_pypi_data(package): - if verbose: - printer(f" package '{package}'") - - return await get_pypi_data_from_purl( + data = await get_pypi_data_from_purl( package, repos=repos, environment=environment, prefer_source=prefer_source ) + if verbose: + printer(f" retrieved package '{package}'") + + return data + if verbose: printer(f"retrieve data from pypi:") @@ -334,6 +338,8 @@ def resolve( pdt_output: bool = False, analyze_setup_py_insecurely: bool = False, ignore_errors: bool = False, + verbose: bool = False, + printer=print ): """ Resolve dependencies given a ``direct_dependencies`` list of @@ -360,6 +366,8 @@ def resolve( pdt_output=pdt_output, analyze_setup_py_insecurely=analyze_setup_py_insecurely, ignore_errors=ignore_errors, + verbose=verbose, + printer=printer ) return resolved_dependencies, packages @@ -374,6 +382,8 @@ def get_resolved_dependencies( pdt_output: bool = False, analyze_setup_py_insecurely: bool = False, ignore_errors: bool = False, + verbose: bool = False, + printer=print ) -> Tuple[List[Dict], List[str]]: """ Return resolved dependencies of a ``requirements`` list of Requirement for @@ -383,17 +393,36 @@ def get_resolved_dependencies( Used the provided ``repos`` list of PypiSimpleRepository. If empty, use instead the PyPI.org JSON API exclusively instead. """ + provider = PythonInputProvider( + environment=environment, + repos=repos, + analyze_setup_py_insecurely=analyze_setup_py_insecurely, + ignore_errors=ignore_errors, + ) + + async def gather_version_data(): + async def get_version_data(name: str): + versions = await provider.fill_versions_for_package(name) + + if verbose: + printer(f" retrieved versions for package '{name}'") + + return versions + + if verbose: + printer(f"versions:") + + return await asyncio.gather(*[get_version_data(requirement.name) for requirement in requirements]) + + asyncio.run(gather_version_data()) + resolver = Resolver( - provider=PythonInputProvider( - environment=environment, - repos=repos, - analyze_setup_py_insecurely=analyze_setup_py_insecurely, - ignore_errors=ignore_errors, - ), + provider=provider, reporter=BaseReporter(), ) resolver_results = resolver.resolve( requirements=requirements, max_rounds=max_rounds) + package_list = get_package_list(results=resolver_results) if pdt_output: return format_pdt_tree(resolver_results), package_list diff --git a/src/python_inspector/package_data.py b/src/python_inspector/package_data.py index 17bbcdc..2409ca5 100644 --- a/src/python_inspector/package_data.py +++ b/src/python_inspector/package_data.py @@ -57,22 +57,23 @@ async def get_pypi_data_from_purl( python_version = get_python_version_from_env_tag( python_version=environment.python_version) valid_distribution_urls = [] - - sdist_url = get_sdist_download_url(purl=parsed_purl, repos=repos, python_version=python_version) + sdist_url = await get_sdist_download_url(purl=parsed_purl, repos=repos, python_version=python_version) if sdist_url: valid_distribution_urls.append(sdist_url) # if prefer_source is True then only source distribution is used # in case of no source distribution available then wheel is used if not valid_distribution_urls or not prefer_source: - wheel_urls = list( - get_wheel_download_urls( - purl=parsed_purl, - repos=repos, - environment=environment, - python_version=python_version, - ) - ) + wheel_urls = \ + [ + item + for item in await get_wheel_download_urls( + purl=parsed_purl, + repos=repos, + environment=environment, + python_version=python_version, + ) + ] wheel_url = choose_single_wheel(wheel_urls) if wheel_url: valid_distribution_urls.insert(0, wheel_url) @@ -143,38 +144,40 @@ def get_pypi_codeview_url(project_urls: Dict) -> Optional[str]: return code_view_url -def get_wheel_download_urls( +async def get_wheel_download_urls( purl: PackageURL, repos: List[PypiSimpleRepository], environment: Environment, python_version: str, -) -> Iterable[str]: +) -> List[str]: """ Return a list of download urls for the given purl. """ + download_urls = [] for repo in repos: - for wheel in utils_pypi.get_supported_and_valid_wheels( + for wheel in await utils_pypi.get_supported_and_valid_wheels( repo=repo, name=purl.name, version=purl.version, environment=environment, python_version=python_version, ): - yield wheel.download_url + download_urls.append(await wheel.download_url) + return download_urls -def get_sdist_download_url( +async def get_sdist_download_url( purl: PackageURL, repos: List[PypiSimpleRepository], python_version: str ) -> str: """ Return a list of download urls for the given purl. """ for repo in repos: - sdist = utils_pypi.get_valid_sdist( + sdist = await utils_pypi.get_valid_sdist( repo=repo, name=purl.name, version=purl.version, python_version=python_version, ) if sdist: - return sdist.download_url + return await sdist.download_url diff --git a/src/python_inspector/resolution.py b/src/python_inspector/resolution.py index 68aaba5..51cbf83 100644 --- a/src/python_inspector/resolution.py +++ b/src/python_inspector/resolution.py @@ -8,10 +8,11 @@ # import ast +import asyncio import operator import os import tarfile -from typing import Dict, Iterable, Optional +from typing import Dict, Iterable, Mapping from typing import Generator from typing import List from typing import NamedTuple @@ -40,7 +41,7 @@ from python_inspector.setup_py_live_eval import iter_requirements from python_inspector.utils import Candidate from python_inspector.utils import contain_string -from python_inspector.utils import get_response +from python_inspector.utils import get_response_async from python_inspector.utils_pypi import PypiSimpleRepository @@ -178,7 +179,7 @@ def get_python_version_from_env_tag(python_version: str) -> str: return python_version -def fetch_and_extract_sdist( +async def fetch_and_extract_sdist( repos: List[PypiSimpleRepository], candidate: Candidate, python_version: str ) -> Union[str, None]: """ @@ -191,7 +192,7 @@ def fetch_and_extract_sdist( the required ``python_version``. Raise an Exception if extraction fails. """ - sdist = utils_pypi.download_sdist( + sdist = await utils_pypi.download_sdist( name=candidate.name, version=str(candidate.version), repos=repos, @@ -363,7 +364,7 @@ def __init__( self.environment_marker = get_environment_marker_from_environment( self.environment) self.repos = repos or [] - self.versions_by_package = {} + self.versions_by_package: Dict[str, List[Version]] = {} self.dependencies_by_purl = {} self.wheel_or_sdist_by_package = {} self.analyze_setup_py_insecurely = analyze_setup_py_insecurely @@ -390,25 +391,38 @@ def get_preference( transitive = all(p is not None for _, p in information[identifier]) return transitive, identifier - def get_versions_for_package( - self, name: str, repo: Optional[PypiSimpleRepository] = None - ) -> List[Version]: + def get_versions_for_package(self, name: str) -> List[Version]: """ Return a list of versions for a package. """ - if repo and self.environment: - return self.get_versions_for_package_from_repo(name, repo) + versions = self.versions_by_package.get(name) + if not versions: + return asyncio.run(self.fill_versions_for_package(name)) + else: + return versions + + async def fill_versions_for_package(self, name: str) -> List[Version]: + versions = self.versions_by_package.get(name) or [] + if versions: + return versions + + if self.repos and self.environment: + for repo in self.repos: + versions.extend(await self._get_versions_for_package_from_repo(name, repo)) else: - return self.get_versions_for_package_from_pypi_json_api(name) + versions.extend(await self._get_versions_for_package_from_pypi_json_api(name)) - def get_versions_for_package_from_repo( + self.versions_by_package[name] = versions + return versions + + async def _get_versions_for_package_from_repo( self, name: str, repo: PypiSimpleRepository ) -> List[Version]: """ Return a list of versions for a package name from a repo """ versions = [] - for version, package in repo.get_package_versions(name).items(): + for version, package in (await repo.get_package_versions(name)).items(): python_version = parse_version( get_python_version_from_env_tag( python_version=self.environment.python_version) @@ -431,32 +445,45 @@ def get_versions_for_package_from_repo( versions.append(version) return versions - def get_versions_for_package_from_pypi_json_api(self, name: str) -> List[Version]: + async def _get_versions_for_package_from_pypi_json_api(self, name: str) -> List[Version]: """ Return a list of versions for a package name from the PyPI.org JSON API """ - if name not in self.versions_by_package: - api_url = f"https://pypi.org/pypi/{name}/json" - resp = get_response(api_url) - if not resp: - self.versions_by_package[name] = [] - releases = resp.get("releases") or {} - self.versions_by_package[name] = releases.keys() or [] - versions = self.versions_by_package[name] - return versions + api_url = f"https://pypi.org/pypi/{name}/json" + resp = await get_response_async(api_url) + if not resp: + self.versions_by_package[name] = [] + releases = resp.get("releases") or {} + return releases.keys() or [] def get_requirements_for_package( self, purl: PackageURL, candidate: Candidate - ) -> Iterable[Requirement]: + ) -> List[Requirement]: + dependencies = self.dependencies_by_purl.get(str(purl)) + if not dependencies: + return asyncio.run(self.fill_requirements_for_package(purl, candidate)) + else: + return dependencies + + async def fill_requirements_for_package( + self, purl: PackageURL, candidate: Candidate + ) -> List[Requirement]: """ Yield requirements for a package. """ + dependencies = self.dependencies_by_purl.get(str(purl)) or [] + if dependencies: + return dependencies + if self.repos and self.environment: - return self.get_requirements_for_package_from_pypi_simple(candidate) + dependencies.extend(await self._get_requirements_for_package_from_pypi_simple(candidate)) else: - return self.get_requirements_for_package_from_pypi_json_api(purl) + dependencies.extend(await self._get_requirements_for_package_from_pypi_json_api(purl)) + + self.dependencies_by_purl[str(purl)] = dependencies + return dependencies - def get_requirements_for_package_from_pypi_simple( + async def _get_requirements_for_package_from_pypi_simple( self, candidate: Candidate ) -> List[Requirement]: """ @@ -467,7 +494,7 @@ def get_requirements_for_package_from_pypi_simple( python_version=self.environment.python_version) ) - wheels = utils_pypi.download_wheel( + wheels = await utils_pypi.download_wheel( name=candidate.name, version=str(candidate.version), environment=self.environment, @@ -483,17 +510,14 @@ def get_requirements_for_package_from_pypi_simple( handler=PypiWheelHandler, location=wheel_location, ) - if requirements: - yield from requirements # We are only looking at the first wheel and not other wheels - break - + return requirements else: - sdist_location = fetch_and_extract_sdist( + sdist_location = await fetch_and_extract_sdist( repos=self.repos, candidate=candidate, python_version=python_version ) if not sdist_location: - return + return [] setup_py_location = os.path.join( sdist_location, @@ -505,9 +529,7 @@ def get_requirements_for_package_from_pypi_simple( ) if self.analyze_setup_py_insecurely: - yield from get_reqs_insecurely( - setup_py_location=setup_py_location, - ) + return get_reqs_insecurely(setup_py_location=setup_py_location) else: requirements = list( get_setup_requirements( @@ -517,35 +539,31 @@ def get_requirements_for_package_from_pypi_simple( ) ) if requirements: - yield from requirements + return requirements else: - # Look in requirements file if and only if thy are refered in setup.py or setup.cfg + # Look in requirements file if and only if thy are referred in setup.py or setup.cfg # And no deps have been yielded by requirements file - - yield from get_requirements_from_python_manifest( + return get_requirements_from_python_manifest( sdist_location=sdist_location, setup_py_location=setup_py_location, files=[setup_cfg_location, setup_py_location], analyze_setup_py_insecurely=self.analyze_setup_py_insecurely, ) - def get_requirements_for_package_from_pypi_json_api( + async def _get_requirements_for_package_from_pypi_json_api( self, purl: PackageURL - ) -> Iterable[Requirement]: + ) -> List[Requirement]: """ Return requirements for a package from the PyPI.org JSON API """ # if no repos are provided use the incorrect but fast JSON API - if str(purl) not in self.dependencies_by_purl: - api_url = f"https://pypi.org/pypi/{purl.name}/{purl.version}/json" - resp = get_response(api_url) - if not resp: - self.dependencies_by_purl[str(purl)] = [] - info = resp.get("info") or {} - requires_dist = info.get("requires_dist") or [] - self.dependencies_by_purl[str(purl)] = requires_dist - for dependency in self.dependencies_by_purl[str(purl)]: - yield Requirement(dependency) + api_url = f"https://pypi.org/pypi/{purl.name}/{purl.version}/json" + resp = await get_response_async(api_url) + if not resp: + return [] + info = resp.get("info") or {} + requires_dist = info.get("requires_dist") or [] + return requires_dist def get_candidates( self, @@ -578,7 +596,7 @@ def get_candidates( def _iter_matches( self, identifier: str, - requirements: Dict, + requirements: Mapping[str, List[Requirement]], incompatibilities: Dict, ) -> Generator[Candidate, None, None]: """ @@ -587,13 +605,7 @@ def _iter_matches( name = remove_extras(identifier=identifier) bad_versions = {c.version for c in incompatibilities[identifier]} extras = {e for r in requirements[identifier] for e in r.extras} - versions = [] - if not self.repos: - versions.extend(self.get_versions_for_package(name=name)) - else: - for repo in self.repos: - versions.extend( - self.get_versions_for_package(name=name, repo=repo)) + versions = self.get_versions_for_package(name) if not versions: if self.ignore_errors: @@ -613,7 +625,7 @@ def _iter_matches( def find_matches( self, identifier: str, - requirements: List[Requirement], + requirements: Mapping[str, List[Requirement]], incompatibilities: Dict, ) -> List[Candidate]: """Find all possible candidates that satisfy given constraints. Overridden.""" @@ -632,7 +644,7 @@ def is_satisfied_by(self, requirement: Requirement, candidate: Candidate) -> boo return True return False - def _iter_dependencies(self, candidate: Candidate) -> Generator[Requirement, None, None]: + def _iter_dependencies(self, candidate: Candidate) -> Iterable[Requirement]: """ Yield dependencies for the given candidate. """ diff --git a/src/python_inspector/utils_pypi.py b/src/python_inspector/utils_pypi.py index 06b70a7..33752cb 100644 --- a/src/python_inspector/utils_pypi.py +++ b/src/python_inspector/utils_pypi.py @@ -8,6 +8,7 @@ # See https://github.com/nexB/skeleton for support or download. # See https://aboutcode.org for more information about nexB OSS projects. # + import email import itertools import os @@ -17,13 +18,14 @@ import tempfile import time from collections import defaultdict -from typing import List +from typing import List, Dict from typing import NamedTuple from urllib.parse import quote_plus from urllib.parse import unquote from urllib.parse import urlparse from urllib.parse import urlunparse +import aiohttp import attr import packageurl import requests @@ -98,7 +100,7 @@ """ TRACE = False -TRACE_DEEP = True +TRACE_DEEP = False TRACE_ULTRA_DEEP = False # Supported environments @@ -216,7 +218,7 @@ class DistributionNotFound(Exception): pass -def download_wheel( +async def download_wheel( name, version, environment, @@ -242,7 +244,7 @@ def download_wheel( fetched_wheel_filenames = [] for repo in repos: - supported_and_valid_wheels = get_supported_and_valid_wheels( + supported_and_valid_wheels = await get_supported_and_valid_wheels( repo, name, version, environment, python_version ) if not supported_and_valid_wheels: @@ -252,7 +254,7 @@ def download_wheel( ) continue for wheel in supported_and_valid_wheels: - fetched_wheel_filename = wheel.download( + fetched_wheel_filename = await wheel.download( dest_dir=dest_dir, verbose=verbose, echo_func=echo_func, @@ -265,8 +267,8 @@ def download_wheel( return fetched_wheel_filenames -def get_valid_sdist(repo, name, version, python_version=DEFAULT_PYTHON_VERSION): - package = repo.get_package_version(name=name, version=version) +async def get_valid_sdist(repo, name, version, python_version=DEFAULT_PYTHON_VERSION): + package = await repo.get_package_version(name=name, version=version) if not package: if TRACE_DEEP: print( @@ -287,13 +289,13 @@ def get_valid_sdist(repo, name, version, python_version=DEFAULT_PYTHON_VERSION): return sdist -def get_supported_and_valid_wheels( +async def get_supported_and_valid_wheels( repo, name, version, environment, python_version=DEFAULT_PYTHON_VERSION ) -> List: """ Return a list of wheels matching the ``environment`` Environment constraints. """ - package = repo.get_package_version(name=name, version=version) + package = await repo.get_package_version(name=name, version=version) if not package: if TRACE_DEEP: print( @@ -331,7 +333,7 @@ def valid_python_version(python_version, python_requires): return python_version in SpecifierSet(python_requires) -def download_sdist( +async def download_sdist( name, version, dest_dir=CACHE_THIRDPARTY_DIR, @@ -356,19 +358,19 @@ def download_sdist( fetched_sdist_filename = None for repo in repos: - sdist = get_valid_sdist(repo, name, version, python_version=python_version) + sdist = await get_valid_sdist(repo, name, version, python_version=python_version) if not sdist: if TRACE_DEEP: print(f" download_sdist: No valid sdist for {name}=={version}") continue - fetched_sdist_filename = sdist.download( + fetched_sdist_filename = await sdist.download( dest_dir=dest_dir, verbose=verbose, echo_func=echo_func, ) if fetched_sdist_filename: - # do not futher fetch from other repos if we find in first, typically PyPI + # do not further fetch from other repos if we find in first, typically PyPI break return fetched_sdist_filename @@ -607,10 +609,10 @@ def package_url(self): ) @property - def download_url(self): - return self.get_best_download_url() + async def download_url(self): + return await self.get_best_download_url() - def get_best_download_url(self, repos=tuple()): + async def get_best_download_url(self, repos=tuple()): """ Return the best download URL for this distribution where best means this is the first URL found for this distribution found in the list of @@ -623,7 +625,7 @@ def get_best_download_url(self, repos=tuple()): repos = DEFAULT_PYPI_REPOS for repo in repos: - package = repo.get_package_version(name=self.name, version=self.version) + package = await repo.get_package_version(name=self.name, version=self.version) if not package: if TRACE: print( @@ -640,7 +642,7 @@ def get_best_download_url(self, repos=tuple()): f" get_best_download_url: {self.filename} not found in {repo.index_url}" ) - def download( + async def download( self, dest_dir=CACHE_THIRDPARTY_DIR, verbose=False, @@ -658,7 +660,7 @@ def download( ) # FIXME: - fetch_and_save( + await fetch_and_save( path_or_url=self.path_or_url, dest_dir=dest_dir, credentials=self.credentials, @@ -1263,12 +1265,12 @@ def package_from_dists(cls, dists): return package @classmethod - def packages_from_links(cls, links: List[Link]): + async def packages_from_links(cls, links: List[Link]): """ Yield PypiPackages built from a list of paths or URLs. These are sorted by name and then by version from oldest to newest. """ - dists = PypiPackage.dists_from_links(links) + dists = await PypiPackage.dists_from_links(links) if TRACE_ULTRA_DEEP: print("packages_from_many_paths_or_urls: dists:", dists) @@ -1284,7 +1286,7 @@ def packages_from_links(cls, links: List[Link]): yield package @classmethod - def dists_from_links(cls, links: List[Link]): + async def dists_from_links(cls, links: List[Link]): """ Return a list of Distribution given a list of ``paths_or_urls`` to wheels or source distributions. @@ -1329,7 +1331,7 @@ def dists_from_links(cls, links: List[Link]): dist, "\n ", "with URL:", - dist.download_url, + await dist.download_url, "\n ", "from URL:", link.url, @@ -1499,7 +1501,7 @@ class PypiSimpleRepository: credentials = attr.ib(type=dict, default=None) - def _get_package_versions_map( + async def _get_package_versions_map( self, name, verbose=False, @@ -1515,7 +1517,7 @@ def _get_package_versions_map( if not versions and normalized_name not in self.fetched_package_normalized_names: self.fetched_package_normalized_names.add(normalized_name) try: - links = self.fetch_links( + links = await self.fetch_links( normalized_name=normalized_name, verbose=verbose, echo_func=echo_func, @@ -1523,7 +1525,7 @@ def _get_package_versions_map( # note that this is sorted so the mapping is also sorted versions = { package.version: package - for package in PypiPackage.packages_from_links(links=links) + async for package in PypiPackage.packages_from_links(links=links) } self.packages[normalized_name] = versions except RemoteNotFetchedException as e: @@ -1535,26 +1537,26 @@ def _get_package_versions_map( return versions - def get_package_versions( + async def get_package_versions( self, name, verbose=False, echo_func=None, - ): + ) -> Dict: """ Return a mapping of all available PypiPackage version as{version: package} for this package name. The mapping may be empty but not None. It is sorted by version from oldest to newest. """ return dict( - self._get_package_versions_map( + await self._get_package_versions_map( name=name, verbose=verbose, echo_func=echo_func, ) ) - def get_package_version( + async def get_package_version( self, name, version=None, @@ -1567,22 +1569,22 @@ def get_package_version( """ if not version: versions = list( - self._get_package_versions_map( + (await self._get_package_versions_map( name=name, verbose=verbose, echo_func=echo_func, - ).values() + )).values() ) # return the latest version return versions and versions[-1] else: - return self._get_package_versions_map( + return (await self._get_package_versions_map( name=name, verbose=verbose, echo_func=echo_func, - ).get(version) + )).get(version) - def fetch_links( + async def fetch_links( self, normalized_name, verbose=False, @@ -1593,7 +1595,7 @@ def fetch_links( name using the `index_url` of this repository. """ package_url = f"{self.index_url}/{normalized_name}" - text = CACHE.get( + text = await CACHE.get( path_or_url=package_url, credentials=self.credentials, as_text=True, @@ -1663,7 +1665,7 @@ class Cache: def __attrs_post_init__(self): os.makedirs(self.directory, exist_ok=True) - def get( + async def get( self, credentials, path_or_url, @@ -1684,7 +1686,7 @@ def get( if force or not os.path.exists(cached): if TRACE_DEEP: print(f" FILE CACHE MISS: {path_or_url}") - content = get_file_content( + content = await get_file_content( path_or_url=path_or_url, credentials=credentials, as_text=as_text, @@ -1704,7 +1706,7 @@ def get( CACHE = Cache() -def get_file_content( +async def get_file_content( path_or_url, credentials, as_text=True, @@ -1718,7 +1720,7 @@ def get_file_content( if path_or_url.startswith("https://"): if TRACE_DEEP: print(f"Fetching: {path_or_url}") - _headers, content = get_remote_file_content( + _headers, content = await get_remote_file_content( url=path_or_url, credentials=credentials, as_text=as_text, @@ -1753,7 +1755,7 @@ class RemoteNotFetchedException(Exception): pass -def get_remote_file_content( +async def get_remote_file_content( url, credentials, as_text=True, @@ -1786,39 +1788,34 @@ def get_remote_file_content( if credentials: auth = (credentials.get("login"), credentials.get("password")) - stream = requests.get( - url, - allow_redirects=True, - stream=True, - headers=headers, - auth=auth, - ) - - with stream as response: - status = response.status_code - if status != requests.codes.ok: # NOQA - if status == 429 and _delay < 20: - # too many requests: start some exponential delay - increased_delay = (_delay * 2) or 1 - - return get_remote_file_content( - url, - credentials=credentials, - as_text=as_text, - headers_only=headers_only, - _delay=increased_delay, - ) + async with aiohttp.ClientSession() as session: + async with session.get(url, allow_redirects=True, + headers=headers, + auth=auth) as response: + status = response.status + if status != requests.codes.ok: # NOQA + if status == 429 and _delay < 20: + # too many requests: start some exponential delay + increased_delay = (_delay * 2) or 1 + + return await get_remote_file_content( + url, + credentials=credentials, + as_text=as_text, + headers_only=headers_only, + _delay=increased_delay, + ) - else: - raise RemoteNotFetchedException(f"Failed HTTP request from {url} with {status}") + else: + raise RemoteNotFetchedException(f"Failed HTTP request from {url} with {status}") - if headers_only: - return response.headers, None + if headers_only: + return response.headers, None - return response.headers, response.text if as_text else response.content + return response.headers, await response.text() if as_text else await response.read() -def fetch_and_save( +async def fetch_and_save( path_or_url, dest_dir, filename, @@ -1833,7 +1830,7 @@ def fetch_and_save( errors. Treats the content as text if as_text is True otherwise as treat as binary. """ - content = CACHE.get( + content = await CACHE.get( path_or_url=path_or_url, credentials=credentials, as_text=as_text, From b4b84c565033899efe183db995111d047335f7b7 Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Thu, 30 Nov 2023 13:21:54 +0100 Subject: [PATCH 04/15] Test fixes, getting dependencies for pinned requirements in advance. Signed-off-by: Thomas Neidhart --- requirements-dev.txt | 3 ++- requirements.txt | 1 + setup.cfg | 2 ++ src/python_inspector/api.py | 31 ++++++++++++++++++++++++++--- src/python_inspector/resolution.py | 3 ++- src/python_inspector/utils_pypi.py | 32 ++++++++++++++++-------------- tests/test_utils.py | 19 ++++++++++-------- 7 files changed, 63 insertions(+), 28 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 6514e9e..7741277 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -38,4 +38,5 @@ tomli==1.2.3 tqdm==4.64.0 twine==3.8.0 typed-ast==1.5.4 -webencodings==0.5.1 \ No newline at end of file +webencodings==0.5.1 +pytest-asyncio==0.21.1 diff --git a/requirements.txt b/requirements.txt index ee5b7ea..517fe8d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,3 +25,4 @@ toml==0.10.2 urllib3==2.1.0 zipp==3.17.0 aiohttp==3.9.1 +aiofiles==23.2.1 diff --git a/setup.cfg b/setup.cfg index 1fdc638..034c26b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -70,6 +70,7 @@ install_requires = mock >= 3.0.5 packvers >= 21.5 aiohttp >= 3.9 + aiofiles >= 23.1 [options.packages.find] where = src @@ -88,6 +89,7 @@ testing = black isort pytest-rerunfailures + pytest-asyncio >= 0.21 docs = Sphinx>=5.0.2 diff --git a/src/python_inspector/api.py b/src/python_inspector/api.py index cca3751..8b2857d 100644 --- a/src/python_inspector/api.py +++ b/src/python_inspector/api.py @@ -23,7 +23,7 @@ from _packagedcode.models import DependentPackage from _packagedcode.models import PackageData -from _packagedcode.pypi import PipRequirementsFileHandler +from _packagedcode.pypi import PipRequirementsFileHandler, get_resolved_purl from _packagedcode.pypi import PythonSetupPyHandler from _packagedcode.pypi import can_process_dependent_package from python_inspector import dependencies @@ -38,6 +38,7 @@ from python_inspector.resolution import get_python_version_from_env_tag from python_inspector.resolution import get_reqs_insecurely from python_inspector.resolution import get_requirements_from_python_manifest +from python_inspector.utils import Candidate from python_inspector.utils_pypi import PLATFORMS_BY_OS from python_inspector.utils_pypi import PYPI_SIMPLE_URL from python_inspector.utils_pypi import Environment @@ -237,7 +238,7 @@ def resolve_dependencies( if not direct_dependencies: return Resolution( packages=[], - resolution={}, + resolution=[], files=files, ) @@ -310,7 +311,7 @@ async def get_pypi_data(package): return data if verbose: - printer(f"retrieve data from pypi:") + printer(f"retrieve package data from pypi:") return await asyncio.gather(*[get_pypi_data(package) for package in purls]) @@ -400,6 +401,8 @@ def get_resolved_dependencies( ignore_errors=ignore_errors, ) + # gather version data for all requirements concurrently in advance. + async def gather_version_data(): async def get_version_data(name: str): versions = await provider.fill_versions_for_package(name) @@ -416,6 +419,28 @@ async def get_version_data(name: str): asyncio.run(gather_version_data()) + # gather dependencies for all pinned requirements concurrently in advance. + + async def gather_dependencies(): + async def get_dependencies(requirement: Requirement): + purl = PackageURL(type="pypi", name=requirement.name) + resolved_purl = get_resolved_purl(purl=purl, specifiers=requirement.specifier) + + if resolved_purl: + purl = resolved_purl.purl + candidate = Candidate(requirement.name, purl.version, requirement.extras) + await provider.fill_requirements_for_package(purl, candidate) + + if verbose: + printer(f" retrieved dependencies for requirement '{str(purl)}'") + + if verbose: + printer(f"dependencies:") + + return await asyncio.gather(*[get_dependencies(requirement) for requirement in requirements]) + + asyncio.run(gather_dependencies()) + resolver = Resolver( provider=provider, reporter=BaseReporter(), diff --git a/src/python_inspector/resolution.py b/src/python_inspector/resolution.py index 51cbf83..57189c4 100644 --- a/src/python_inspector/resolution.py +++ b/src/python_inspector/resolution.py @@ -443,6 +443,7 @@ async def _get_versions_for_package_from_repo( ) if valid_wheel_present or pypi_valid_python_version: versions.append(version) + return versions async def _get_versions_for_package_from_pypi_json_api(self, name: str) -> List[Version]: @@ -563,7 +564,7 @@ async def _get_requirements_for_package_from_pypi_json_api( return [] info = resp.get("info") or {} requires_dist = info.get("requires_dist") or [] - return requires_dist + return list(map(lambda r: Requirement(r), requires_dist)) def get_candidates( self, diff --git a/src/python_inspector/utils_pypi.py b/src/python_inspector/utils_pypi.py index 33752cb..7d583b7 100644 --- a/src/python_inspector/utils_pypi.py +++ b/src/python_inspector/utils_pypi.py @@ -18,13 +18,14 @@ import tempfile import time from collections import defaultdict -from typing import List, Dict +from typing import List, Dict, Union, Tuple from typing import NamedTuple from urllib.parse import quote_plus from urllib.parse import unquote from urllib.parse import urlparse from urllib.parse import urlunparse +import aiofiles import aiohttp import attr import packageurl @@ -1595,7 +1596,7 @@ async def fetch_links( name using the `index_url` of this repository. """ package_url = f"{self.index_url}/{normalized_name}" - text = await CACHE.get( + text, _ = await CACHE.get( path_or_url=package_url, credentials=self.credentials, as_text=True, @@ -1673,7 +1674,7 @@ async def get( force=False, verbose=False, echo_func=None, - ): + ) -> Tuple[Union[str, bytes], str]: """ Return the content fetched from a ``path_or_url`` through the cache. Raise an Exception on errors. Treats the content as text if as_text is @@ -1694,13 +1695,13 @@ async def get( echo_func=echo_func, ) wmode = "w" if as_text else "wb" - with open(cached, wmode) as fo: - fo.write(content) - return content + async with aiofiles.open(cached, mode=wmode) as fo: + await fo.write(content) + return content, cached else: if TRACE_DEEP: print(f" FILE CACHE HIT: {path_or_url}") - return get_local_file_content(path=cached, as_text=as_text) + return await get_local_file_content(path=cached, as_text=as_text), cached CACHE = Cache() @@ -1732,13 +1733,13 @@ async def get_file_content( elif path_or_url.startswith("file://") or ( path_or_url.startswith("/") and os.path.exists(path_or_url) ): - return get_local_file_content(path=path_or_url, as_text=as_text) + return await get_local_file_content(path=path_or_url, as_text=as_text) else: raise Exception(f"Unsupported URL scheme: {path_or_url}") -def get_local_file_content(path, as_text=True): +async def get_local_file_content(path: str, as_text=True) -> str: """ Return the content at `url` as text. Return the content as bytes is `as_text` is False. @@ -1747,8 +1748,8 @@ def get_local_file_content(path, as_text=True): path = path[7:] mode = "r" if as_text else "rb" - with open(path, mode) as fo: - return fo.read() + async with aiofiles.open(path, mode=mode) as fo: + return await fo.read() class RemoteNotFetchedException(Exception): @@ -1830,7 +1831,7 @@ async def fetch_and_save( errors. Treats the content as text if as_text is True otherwise as treat as binary. """ - content = await CACHE.get( + content, path = await CACHE.get( path_or_url=path_or_url, credentials=credentials, as_text=as_text, @@ -1839,7 +1840,8 @@ async def fetch_and_save( ) output = os.path.join(dest_dir, filename) - wmode = "w" if as_text else "wb" - with open(output, wmode) as fo: - fo.write(content) + if os.path.exists(output): + os.remove(output) + + os.symlink(os.path.abspath(path), output) return content diff --git a/tests/test_utils.py b/tests/test_utils.py index b60f67a..789d11c 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -14,6 +14,7 @@ from netrc import netrc from unittest import mock +import pytest from commoncode.testcase import FileDrivenTesting from test_cli import check_json_file_results @@ -47,22 +48,23 @@ def test_get_netrc_auth_with_no_matching_url(): assert get_netrc_auth(url="https://pypi2.org/simple", netrc=parsed_netrc) == (None, None) +@pytest.mark.asyncio @mock.patch("python_inspector.utils_pypi.CACHE.get") -def test_fetch_links(mock_get): +async def test_fetch_links(mock_get): file_name = test_env.get_test_loc("psycopg2.html") with open(file_name) as file: mock_get.return_value = file.read() - links = PypiSimpleRepository().fetch_links(normalized_name="psycopg2") + links = await PypiSimpleRepository().fetch_links(normalized_name="psycopg2") result_file = test_env.get_temp_file("json") expected_file = test_env.get_test_loc("psycopg2-links-expected.json", must_exist=False) with open(result_file, "w") as file: json.dump(links, file, indent=4) check_json_file_results(result_file, expected_file) # Testing relative links - realtive_links_file = test_env.get_test_loc("fetch_links_test.html") - with open(realtive_links_file) as realtive_file: - mock_get.return_value = realtive_file.read() - relative_links = PypiSimpleRepository().fetch_links(normalized_name="sources.whl") + relative_links_file = test_env.get_test_loc("fetch_links_test.html") + with open(relative_links_file) as relative_file: + mock_get.return_value = relative_file.read() + relative_links = await PypiSimpleRepository().fetch_links(normalized_name="sources.whl") relative_links_result_file = test_env.get_temp_file("json") relative_links_expected_file = test_env.get_test_loc( "relative-links-expected.json", must_exist=False @@ -83,8 +85,9 @@ def test_parse_reqs(): check_json_file_results(result_file, expected_file) -def test_get_sdist_file(): - sdist_file = fetch_and_extract_sdist( +@pytest.mark.asyncio +async def test_get_sdist_file(): + sdist_file = await fetch_and_extract_sdist( repos=tuple([PypiSimpleRepository()]), candidate=Candidate(name="psycopg2", version="2.7.5", extras=None), python_version="3.8", From 5ef1019a23bb4e670d06107590bff607b6e0d377 Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Thu, 30 Nov 2023 14:23:24 +0100 Subject: [PATCH 05/15] Revert pinned requirements to previous versions. Signed-off-by: Thomas Neidhart --- requirements.txt | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/requirements.txt b/requirements.txt index 517fe8d..cdc87d5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ -attrs==23.1.0 -beautifulsoup4==4.12.2 -certifi==2023.11.17 -charset-normalizer==3.3.2 -click==8.1.7 -colorama==0.4.6 -commoncode==31.0.3 +attrs==22.1.0 +beautifulsoup4==4.11.1 +certifi==2022.6.15 +charset-normalizer==2.1.0 +click==8.1.3 +colorama==0.4.5 +commoncode==30.2.0 dparse2==0.7.0 idna==3.3 importlib-metadata==4.12.0 @@ -14,15 +14,15 @@ packaging==21.3 packvers==21.5 pip-requirements-parser==32.0.1 pkginfo2==30.0.0 -pyparsing==3.1.1 -PyYAML==6.0.1 -requests==2.31.0 +pyparsing==3.0.9 +PyYAML==6.0 +requests==2.28.1 resolvelib >= 1.0.0 -saneyaml==0.6.0 -soupsieve==2.5 +saneyaml==0.5.2 +soupsieve==2.3.2.post1 text-unidecode==1.3 toml==0.10.2 -urllib3==2.1.0 -zipp==3.17.0 +urllib3==1.26.11 +zipp==3.8.1 aiohttp==3.9.1 aiofiles==23.2.1 From 23ef4066dcea954276992d9180e356493db47e15 Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Thu, 30 Nov 2023 14:29:44 +0100 Subject: [PATCH 06/15] Use latest version of aiohttp that supports 3.7. --- requirements.txt | 2 +- setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index cdc87d5..91fd48a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -24,5 +24,5 @@ text-unidecode==1.3 toml==0.10.2 urllib3==1.26.11 zipp==3.8.1 -aiohttp==3.9.1 +aiohttp==3.8.6 aiofiles==23.2.1 diff --git a/setup.cfg b/setup.cfg index 034c26b..7ec4f26 100644 --- a/setup.cfg +++ b/setup.cfg @@ -69,7 +69,7 @@ install_requires = toml >= 0.10.0 mock >= 3.0.5 packvers >= 21.5 - aiohttp >= 3.9 + aiohttp >= 3.8 aiofiles >= 23.1 [options.packages.find] From c7739779079f728011073e7ae7708630bc84d2b9 Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Thu, 30 Nov 2023 14:33:17 +0100 Subject: [PATCH 07/15] Fix python3.7 error. --- src/python_inspector/resolution.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python_inspector/resolution.py b/src/python_inspector/resolution.py index 57189c4..fdb5f62 100644 --- a/src/python_inspector/resolution.py +++ b/src/python_inspector/resolution.py @@ -12,7 +12,7 @@ import operator import os import tarfile -from typing import Dict, Iterable, Mapping +from typing import Dict, Iterable, Mapping, Type from typing import Generator from typing import List from typing import NamedTuple @@ -71,7 +71,7 @@ class Result(NamedTuple): def get_requirements_from_distribution( - handler: type[BasePypiHandler], + handler: Type[BasePypiHandler], location: str, ) -> List[Requirement]: """ From 82326ce5b19a582c02a91ce06a7d72096604e33e Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Thu, 30 Nov 2023 14:41:26 +0100 Subject: [PATCH 08/15] Run black. --- src/python_inspector/api.py | 16 ++++++++++------ src/python_inspector/dependencies.py | 4 +++- src/python_inspector/package_data.py | 24 +++++++++++++----------- src/python_inspector/resolution.py | 4 +++- src/python_inspector/utils_pypi.py | 28 +++++++++++++++------------- 5 files changed, 44 insertions(+), 32 deletions(-) diff --git a/src/python_inspector/api.py b/src/python_inspector/api.py index 8b2857d..1955828 100644 --- a/src/python_inspector/api.py +++ b/src/python_inspector/api.py @@ -296,7 +296,7 @@ def resolve_dependencies( analyze_setup_py_insecurely=analyze_setup_py_insecurely, ignore_errors=ignore_errors, verbose=verbose, - printer=printer + printer=printer, ) async def gather_pypi_data(): @@ -340,7 +340,7 @@ def resolve( analyze_setup_py_insecurely: bool = False, ignore_errors: bool = False, verbose: bool = False, - printer=print + printer=print, ): """ Resolve dependencies given a ``direct_dependencies`` list of @@ -368,7 +368,7 @@ def resolve( analyze_setup_py_insecurely=analyze_setup_py_insecurely, ignore_errors=ignore_errors, verbose=verbose, - printer=printer + printer=printer, ) return resolved_dependencies, packages @@ -384,7 +384,7 @@ def get_resolved_dependencies( analyze_setup_py_insecurely: bool = False, ignore_errors: bool = False, verbose: bool = False, - printer=print + printer=print, ) -> Tuple[List[Dict], List[str]]: """ Return resolved dependencies of a ``requirements`` list of Requirement for @@ -415,7 +415,9 @@ async def get_version_data(name: str): if verbose: printer(f"versions:") - return await asyncio.gather(*[get_version_data(requirement.name) for requirement in requirements]) + return await asyncio.gather( + *[get_version_data(requirement.name) for requirement in requirements] + ) asyncio.run(gather_version_data()) @@ -437,7 +439,9 @@ async def get_dependencies(requirement: Requirement): if verbose: printer(f"dependencies:") - return await asyncio.gather(*[get_dependencies(requirement) for requirement in requirements]) + return await asyncio.gather( + *[get_dependencies(requirement) for requirement in requirements] + ) asyncio.run(gather_dependencies()) diff --git a/src/python_inspector/dependencies.py b/src/python_inspector/dependencies.py index 47cdc36..3db30bc 100644 --- a/src/python_inspector/dependencies.py +++ b/src/python_inspector/dependencies.py @@ -25,7 +25,9 @@ TRACE = False -def get_dependencies_from_requirements(requirements_file="requirements.txt") -> Iterable[DependentPackage]: +def get_dependencies_from_requirements( + requirements_file="requirements.txt", +) -> Iterable[DependentPackage]: """ Yield DependentPackage for each requirement in a `requirement` file. """ diff --git a/src/python_inspector/package_data.py b/src/python_inspector/package_data.py index 2409ca5..19ce5a6 100644 --- a/src/python_inspector/package_data.py +++ b/src/python_inspector/package_data.py @@ -45,6 +45,7 @@ async def get_pypi_data_from_purl( api_url = f"{base_path}/{name}/{version}/json" from python_inspector.utils import get_response_async + response = await get_response_async(api_url) if not response: return None @@ -57,23 +58,24 @@ async def get_pypi_data_from_purl( python_version = get_python_version_from_env_tag( python_version=environment.python_version) valid_distribution_urls = [] - sdist_url = await get_sdist_download_url(purl=parsed_purl, repos=repos, python_version=python_version) + sdist_url = await get_sdist_download_url( + purl=parsed_purl, repos=repos, python_version=python_version + ) if sdist_url: valid_distribution_urls.append(sdist_url) # if prefer_source is True then only source distribution is used # in case of no source distribution available then wheel is used if not valid_distribution_urls or not prefer_source: - wheel_urls = \ - [ - item - for item in await get_wheel_download_urls( - purl=parsed_purl, - repos=repos, - environment=environment, - python_version=python_version, - ) - ] + wheel_urls = [ + item + for item in await get_wheel_download_urls( + purl=parsed_purl, + repos=repos, + environment=environment, + python_version=python_version, + ) + ] wheel_url = choose_single_wheel(wheel_urls) if wheel_url: valid_distribution_urls.insert(0, wheel_url) diff --git a/src/python_inspector/resolution.py b/src/python_inspector/resolution.py index fdb5f62..9dbbf55 100644 --- a/src/python_inspector/resolution.py +++ b/src/python_inspector/resolution.py @@ -477,7 +477,9 @@ async def fill_requirements_for_package( return dependencies if self.repos and self.environment: - dependencies.extend(await self._get_requirements_for_package_from_pypi_simple(candidate)) + dependencies.extend( + await self._get_requirements_for_package_from_pypi_simple(candidate) + ) else: dependencies.extend(await self._get_requirements_for_package_from_pypi_json_api(purl)) diff --git a/src/python_inspector/utils_pypi.py b/src/python_inspector/utils_pypi.py index 7d583b7..3020057 100644 --- a/src/python_inspector/utils_pypi.py +++ b/src/python_inspector/utils_pypi.py @@ -1570,20 +1570,24 @@ async def get_package_version( """ if not version: versions = list( - (await self._get_package_versions_map( - name=name, - verbose=verbose, - echo_func=echo_func, - )).values() + ( + await self._get_package_versions_map( + name=name, + verbose=verbose, + echo_func=echo_func, + ) + ).values() ) # return the latest version return versions and versions[-1] else: - return (await self._get_package_versions_map( - name=name, - verbose=verbose, - echo_func=echo_func, - )).get(version) + return ( + await self._get_package_versions_map( + name=name, + verbose=verbose, + echo_func=echo_func, + ) + ).get(version) async def fetch_links( self, @@ -1790,9 +1794,7 @@ async def get_remote_file_content( auth = (credentials.get("login"), credentials.get("password")) async with aiohttp.ClientSession() as session: - async with session.get(url, allow_redirects=True, - headers=headers, - auth=auth) as response: + async with session.get(url, allow_redirects=True, headers=headers, auth=auth) as response: status = response.status if status != requests.codes.ok: # NOQA if status == 429 and _delay < 20: From d48e078bf7e7981bb1eadc50b224fb8242d1b519 Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Thu, 30 Nov 2023 18:01:32 +0100 Subject: [PATCH 09/15] Fix some unit tests. --- .../data/setup/simple-setup.py-expected.json | 130 ------------------ tests/test_utils.py | 4 +- 2 files changed, 2 insertions(+), 132 deletions(-) diff --git a/tests/data/setup/simple-setup.py-expected.json b/tests/data/setup/simple-setup.py-expected.json index c848334..0ee974f 100644 --- a/tests/data/setup/simple-setup.py-expected.json +++ b/tests/data/setup/simple-setup.py-expected.json @@ -139,67 +139,6 @@ "datasource_id": null, "purl": "pkg:pypi/boolean-py@3.8" }, - { - "type": "pypi", - "namespace": null, - "name": "boolean-py", - "version": "3.8", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Define boolean algebras, create and parse boolean expressions and create custom boolean DSL.\nThis library helps you deal with boolean expressions and algebra with variables\nand the boolean functions AND, OR, NOT.\n\nYou can parse expressions from strings and simplify and compare expressions.\nYou can also easily create your custom algreba and mini DSL and create custom\ntokenizers to handle custom expressions.\n\nFor extensive documentation look either into the docs directory or view it online, at\nhttps://booleanpy.readthedocs.org/en/latest/\n\nhttps://github.com/bastikr/boolean.py\n\nCopyright (c) 2009-2020 Sebastian Kraemer, basti.kr@gmail.com and others\nSPDX-License-Identifier: BSD-2-Clause", - "release_date": "2020-06-10T22:06:07", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Sebastian Kraemer", - "email": "basti.kr@gmail.com", - "url": null - } - ], - "keywords": [ - "boolean expression", - "boolean algebra", - "logic", - "expression parser", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Topic :: Scientific/Engineering :: Mathematics", - "Topic :: Software Development :: Compilers", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/bastikr/boolean.py", - "download_url": "https://files.pythonhosted.org/packages/a1/eb/b37ef5647243ade8308f7bb46b1a45e6204790c163cbd8cf6df990d5c1c1/boolean.py-3.8.tar.gz", - "size": 32196, - "sha1": null, - "md5": "83ccc145ba74a585637124c8bc648333", - "sha256": "cc24e20f985d60cd4a3a5a1c0956dd12611159d32a75081dabd0c9ab981acaa4", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-2-Clause" - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/boolean-py/3.8/json", - "datasource_id": null, - "purl": "pkg:pypi/boolean-py@3.8" - }, { "type": "pypi", "namespace": null, @@ -268,75 +207,6 @@ "api_data_url": "https://pypi.org/pypi/license-expression/1.0/json", "datasource_id": null, "purl": "pkg:pypi/license-expression@1.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "license-expression", - "version": "1.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "license-expression is small utility library to parse, compare, simplify and normalize license expressions (such as SPDX license expressions) using boolean logic.", - "release_date": "2019-10-16T17:48:47", - "parties": [ - { - "type": "person", - "role": "author", - "name": "nexB Inc.", - "email": "info@nexb.com", - "url": null - } - ], - "keywords": [ - "license", - "spdx", - "license expression", - "open source", - "boolean", - "parse expression", - "normalize expression", - "compare expression", - "licence", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/nexB/license-expression", - "download_url": "https://files.pythonhosted.org/packages/27/71/a8d8d78f7866a75f6a940cc53d1557a5edf1ae4a281fe8797cf36077105d/license-expression-1.0.tar.gz", - "size": 53559, - "sha1": null, - "md5": "81477f779099f55071c6a7b88a29bb01", - "sha256": "8aaa455c5b97c4f2174090178b19792b2a1c620e80591aafd4e0a99b713f9e8d", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "apache-2.0", - "classifiers": [ - "License :: OSI Approved :: Apache Software License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/license-expression/1.0/json", - "datasource_id": null, - "purl": "pkg:pypi/license-expression@1.0" } ], "resolved_dependencies_graph": [ diff --git a/tests/test_utils.py b/tests/test_utils.py index 789d11c..34b45a8 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -53,7 +53,7 @@ def test_get_netrc_auth_with_no_matching_url(): async def test_fetch_links(mock_get): file_name = test_env.get_test_loc("psycopg2.html") with open(file_name) as file: - mock_get.return_value = file.read() + mock_get.return_value = file.read(), file_name links = await PypiSimpleRepository().fetch_links(normalized_name="psycopg2") result_file = test_env.get_temp_file("json") expected_file = test_env.get_test_loc("psycopg2-links-expected.json", must_exist=False) @@ -63,7 +63,7 @@ async def test_fetch_links(mock_get): # Testing relative links relative_links_file = test_env.get_test_loc("fetch_links_test.html") with open(relative_links_file) as relative_file: - mock_get.return_value = relative_file.read() + mock_get.return_value = relative_file.read(), relative_links_file relative_links = await PypiSimpleRepository().fetch_links(normalized_name="sources.whl") relative_links_result_file = test_env.get_temp_file("json") relative_links_expected_file = test_env.get_test_loc( From 24156dbb993dab808d4a2a90ce311eda57f8e6cd Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Thu, 30 Nov 2023 20:13:31 +0100 Subject: [PATCH 10/15] Fix more tests. --- tests/data/test-api-expected.json | 243 +- tests/data/test-api-pdt-expected.json | 243 +- ...t-api-with-recursive-requirement-file.json | 249 - .../data/test-api-with-requirement-file.json | 6540 +++-------------- 4 files changed, 1060 insertions(+), 6215 deletions(-) diff --git a/tests/data/test-api-expected.json b/tests/data/test-api-expected.json index 3c0a9c8..e1887e5 100644 --- a/tests/data/test-api-expected.json +++ b/tests/data/test-api-expected.json @@ -55,60 +55,6 @@ "datasource_id": null, "purl": "pkg:pypi/click@8.1.7" }, - { - "type": "pypi", - "namespace": null, - "name": "click", - "version": "8.1.7", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Composable command line interface toolkit\n\\$ click\\_\n==========\n\nClick is a Python package for creating beautiful command line interfaces\nin a composable way with as little code as necessary. It's the \"Command\nLine Interface Creation Kit\". It's highly configurable but comes with\nsensible defaults out of the box.\n\nIt aims to make the process of writing command line tools quick and fun\nwhile also preventing any frustration caused by the inability to\nimplement an intended CLI API.\n\nClick in three points:\n\n- Arbitrary nesting of commands\n- Automatic help page generation\n- Supports lazy loading of subcommands at runtime\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U click\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n import click\n\n @click.command()\n @click.option(\"--count\", default=1, help=\"Number of greetings.\")\n @click.option(\"--name\", prompt=\"Your name\", help=\"The person to greet.\")\n def hello(count, name):\n \"\"\"Simple program that greets NAME for a total of COUNT times.\"\"\"\n for _ in range(count):\n click.echo(f\"Hello, {name}!\")\n\n if __name__ == '__main__':\n hello()\n\n.. code-block:: text\n\n $ python hello.py --count=3\n Your name: Click\n Hello, Click!\n Hello, Click!\n Hello, Click!\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Click and other popular\npackages. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://click.palletsprojects.com/\n- Changes: https://click.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/click/\n- Source Code: https://github.com/pallets/click\n- Issue Tracker: https://github.com/pallets/click/issues\n- Chat: https://discord.gg/pallets", - "release_date": "2023-08-17T17:29:11", - "parties": [ - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python" - ], - "homepage_url": "https://palletsprojects.com/p/click/", - "download_url": "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", - "size": 336121, - "sha1": null, - "md5": "7c3b52c56fd30699f453a7dc7b42cecb", - "sha256": "ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/click/issues/", - "code_view_url": "https://github.com/pallets/click/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/click/8.1.7/json", - "datasource_id": null, - "purl": "pkg:pypi/click@8.1.7" - }, { "type": "pypi", "namespace": null, @@ -176,73 +122,6 @@ "datasource_id": null, "purl": "pkg:pypi/flask@2.1.2" }, - { - "type": "pypi", - "namespace": null, - "name": "flask", - "version": "2.1.2", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A simple framework for building complex web applications.\nFlask\n=====\n\nFlask is a lightweight `WSGI`_ web application framework. It is designed\nto make getting started quick and easy, with the ability to scale up to\ncomplex applications. It began as a simple wrapper around `Werkzeug`_\nand `Jinja`_ and has become one of the most popular Python web\napplication frameworks.\n\nFlask offers suggestions, but doesn't enforce any dependencies or\nproject layout. It is up to the developer to choose the tools and\nlibraries they want to use. There are many extensions provided by the\ncommunity that make adding new functionality easy.\n\n.. _WSGI: https://wsgi.readthedocs.io/\n.. _Werkzeug: https://werkzeug.palletsprojects.com/\n.. _Jinja: https://jinja.palletsprojects.com/\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U Flask\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n # save this as app.py\n from flask import Flask\n\n app = Flask(__name__)\n\n @app.route(\"/\")\n def hello():\n return \"Hello, World!\"\n\n.. code-block:: text\n\n $ flask run\n * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)\n\n\nContributing\n------------\n\nFor guidance on setting up a development environment and how to make a\ncontribution to Flask, see the `contributing guidelines`_.\n\n.. _contributing guidelines: https://github.com/pallets/flask/blob/main/CONTRIBUTING.rst\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Flask and the libraries\nit uses. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://flask.palletsprojects.com/\n- Changes: https://flask.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/Flask/\n- Source Code: https://github.com/pallets/flask/\n- Issue Tracker: https://github.com/pallets/flask/issues/\n- Website: https://palletsprojects.com/p/flask/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2022-04-28T17:47:40", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Framework :: Flask", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Internet :: WWW/HTTP :: WSGI", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - "Topic :: Software Development :: Libraries :: Application Frameworks" - ], - "homepage_url": "https://palletsprojects.com/p/flask", - "download_url": "https://files.pythonhosted.org/packages/d3/3c/94f38d4db919a9326a706ad56f05a7e6f0c8f7b7d93e2997cca54d3bc14b/Flask-2.1.2.tar.gz", - "size": 631846, - "sha1": null, - "md5": "93f1832e5be704ef6ff2a4124579cd85", - "sha256": "315ded2ddf8a6281567edb27393010fe3406188bafbfe65a3339d5787d89e477", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/flask/issues/", - "code_view_url": "https://github.com/pallets/flask/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/flask/2.1.2/json", - "datasource_id": null, - "purl": "pkg:pypi/flask@2.1.2" - }, { "type": "pypi", "namespace": null, @@ -304,67 +183,6 @@ "datasource_id": null, "purl": "pkg:pypi/itsdangerous@2.1.2" }, - { - "type": "pypi", - "namespace": null, - "name": "itsdangerous", - "version": "2.1.2", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Safely pass data to untrusted environments and back.\nItsDangerous\n============\n\n... so better sign this\n\nVarious helpers to pass data to untrusted environments and to get it\nback safe and sound. Data is cryptographically signed to ensure that a\ntoken has not been tampered with.\n\nIt's possible to customize how data is serialized. Data is compressed as\nneeded. A timestamp can be added and verified automatically while\nloading a token.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U itsdangerous\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\nHere's how you could generate a token for transmitting a user's id and\nname between web requests.\n\n.. code-block:: python\n\n from itsdangerous import URLSafeSerializer\n auth_s = URLSafeSerializer(\"secret key\", \"auth\")\n token = auth_s.dumps({\"id\": 5, \"name\": \"itsdangerous\"})\n\n print(token)\n # eyJpZCI6NSwibmFtZSI6Iml0c2Rhbmdlcm91cyJ9.6YP6T0BaO67XP--9UzTrmurXSmg\n\n data = auth_s.loads(token)\n print(data[\"name\"])\n # itsdangerous\n\n\nDonate\n------\n\nThe Pallets organization develops and supports ItsDangerous and other\npopular packages. In order to grow the community of contributors and\nusers, and allow the maintainers to devote more time to the projects,\n`please donate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://itsdangerous.palletsprojects.com/\n- Changes: https://itsdangerous.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/ItsDangerous/\n- Source Code: https://github.com/pallets/itsdangerous/\n- Issue Tracker: https://github.com/pallets/itsdangerous/issues/\n- Website: https://palletsprojects.com/p/itsdangerous/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2022-03-24T15:12:15", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python" - ], - "homepage_url": "https://palletsprojects.com/p/itsdangerous/", - "download_url": "https://files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", - "size": 56143, - "sha1": null, - "md5": "c1bc730ddf53b8374eaa823f24eb6438", - "sha256": "5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/itsdangerous/issues/", - "code_view_url": "https://github.com/pallets/itsdangerous/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/itsdangerous/2.1.2/json", - "datasource_id": null, - "purl": "pkg:pypi/itsdangerous@2.1.2" - }, { "type": "pypi", "namespace": null, @@ -651,65 +469,6 @@ "api_data_url": "https://pypi.org/pypi/werkzeug/3.0.1/json", "datasource_id": null, "purl": "pkg:pypi/werkzeug@3.0.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "werkzeug", - "version": "3.0.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "The comprehensive WSGI web application library.\nWerkzeug\n========\n\n*werkzeug* German noun: \"tool\". Etymology: *werk* (\"work\"), *zeug* (\"stuff\")\n\nWerkzeug is a comprehensive `WSGI`_ web application library. It began as\na simple collection of various utilities for WSGI applications and has\nbecome one of the most advanced WSGI utility libraries.\n\nIt includes:\n\n- An interactive debugger that allows inspecting stack traces and\n source code in the browser with an interactive interpreter for any\n frame in the stack.\n- A full-featured request object with objects to interact with\n headers, query args, form data, files, and cookies.\n- A response object that can wrap other WSGI applications and handle\n streaming data.\n- A routing system for matching URLs to endpoints and generating URLs\n for endpoints, with an extensible system for capturing variables\n from URLs.\n- HTTP utilities to handle entity tags, cache control, dates, user\n agents, cookies, files, and more.\n- A threaded WSGI server for use while developing applications\n locally.\n- A test client for simulating HTTP requests during testing without\n requiring running a server.\n\nWerkzeug doesn't enforce any dependencies. It is up to the developer to\nchoose a template engine, database adapter, and even how to handle\nrequests. It can be used to build all sorts of end user applications\nsuch as blogs, wikis, or bulletin boards.\n\n`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while\nproviding more structure and patterns for defining powerful\napplications.\n\n.. _WSGI: https://wsgi.readthedocs.io/en/latest/\n.. _Flask: https://www.palletsprojects.com/p/flask/\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U Werkzeug\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n from werkzeug.wrappers import Request, Response\n\n @Request.application\n def application(request):\n return Response('Hello, World!')\n\n if __name__ == '__main__':\n from werkzeug.serving import run_simple\n run_simple('localhost', 4000, application)\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Werkzeug and other\npopular packages. In order to grow the community of contributors and\nusers, and allow the maintainers to devote more time to the projects,\n`please donate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://werkzeug.palletsprojects.com/\n- Changes: https://werkzeug.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/Werkzeug/\n- Source Code: https://github.com/pallets/werkzeug/\n- Issue Tracker: https://github.com/pallets/werkzeug/issues/\n- Chat: https://discord.gg/pallets", - "release_date": "2023-10-24T20:57:50", - "parties": [ - { - "type": "person", - "role": "maintainer", - "name": null, - "email": "Pallets ", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Internet :: WWW/HTTP :: WSGI", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware", - "Topic :: Software Development :: Libraries :: Application Frameworks" - ], - "homepage_url": "", - "download_url": "https://files.pythonhosted.org/packages/0d/cc/ff1904eb5eb4b455e442834dabf9427331ac0fa02853bf83db817a7dd53d/werkzeug-3.0.1.tar.gz", - "size": 801436, - "sha1": null, - "md5": "b8cb17df4a7d86b7c5cdffcd5657197a", - "sha256": "507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/werkzeug/issues/", - "code_view_url": "https://github.com/pallets/werkzeug/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/werkzeug/3.0.1/json", - "datasource_id": null, - "purl": "pkg:pypi/werkzeug@3.0.1" } ], "resolution": [ @@ -747,4 +506,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/tests/data/test-api-pdt-expected.json b/tests/data/test-api-pdt-expected.json index d927914..a6de6a9 100644 --- a/tests/data/test-api-pdt-expected.json +++ b/tests/data/test-api-pdt-expected.json @@ -55,60 +55,6 @@ "datasource_id": null, "purl": "pkg:pypi/click@8.1.7" }, - { - "type": "pypi", - "namespace": null, - "name": "click", - "version": "8.1.7", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Composable command line interface toolkit\n\\$ click\\_\n==========\n\nClick is a Python package for creating beautiful command line interfaces\nin a composable way with as little code as necessary. It's the \"Command\nLine Interface Creation Kit\". It's highly configurable but comes with\nsensible defaults out of the box.\n\nIt aims to make the process of writing command line tools quick and fun\nwhile also preventing any frustration caused by the inability to\nimplement an intended CLI API.\n\nClick in three points:\n\n- Arbitrary nesting of commands\n- Automatic help page generation\n- Supports lazy loading of subcommands at runtime\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U click\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n import click\n\n @click.command()\n @click.option(\"--count\", default=1, help=\"Number of greetings.\")\n @click.option(\"--name\", prompt=\"Your name\", help=\"The person to greet.\")\n def hello(count, name):\n \"\"\"Simple program that greets NAME for a total of COUNT times.\"\"\"\n for _ in range(count):\n click.echo(f\"Hello, {name}!\")\n\n if __name__ == '__main__':\n hello()\n\n.. code-block:: text\n\n $ python hello.py --count=3\n Your name: Click\n Hello, Click!\n Hello, Click!\n Hello, Click!\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Click and other popular\npackages. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://click.palletsprojects.com/\n- Changes: https://click.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/click/\n- Source Code: https://github.com/pallets/click\n- Issue Tracker: https://github.com/pallets/click/issues\n- Chat: https://discord.gg/pallets", - "release_date": "2023-08-17T17:29:11", - "parties": [ - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python" - ], - "homepage_url": "https://palletsprojects.com/p/click/", - "download_url": "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", - "size": 336121, - "sha1": null, - "md5": "7c3b52c56fd30699f453a7dc7b42cecb", - "sha256": "ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/click/issues/", - "code_view_url": "https://github.com/pallets/click/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/click/8.1.7/json", - "datasource_id": null, - "purl": "pkg:pypi/click@8.1.7" - }, { "type": "pypi", "namespace": null, @@ -176,73 +122,6 @@ "datasource_id": null, "purl": "pkg:pypi/flask@2.1.2" }, - { - "type": "pypi", - "namespace": null, - "name": "flask", - "version": "2.1.2", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A simple framework for building complex web applications.\nFlask\n=====\n\nFlask is a lightweight `WSGI`_ web application framework. It is designed\nto make getting started quick and easy, with the ability to scale up to\ncomplex applications. It began as a simple wrapper around `Werkzeug`_\nand `Jinja`_ and has become one of the most popular Python web\napplication frameworks.\n\nFlask offers suggestions, but doesn't enforce any dependencies or\nproject layout. It is up to the developer to choose the tools and\nlibraries they want to use. There are many extensions provided by the\ncommunity that make adding new functionality easy.\n\n.. _WSGI: https://wsgi.readthedocs.io/\n.. _Werkzeug: https://werkzeug.palletsprojects.com/\n.. _Jinja: https://jinja.palletsprojects.com/\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U Flask\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n # save this as app.py\n from flask import Flask\n\n app = Flask(__name__)\n\n @app.route(\"/\")\n def hello():\n return \"Hello, World!\"\n\n.. code-block:: text\n\n $ flask run\n * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)\n\n\nContributing\n------------\n\nFor guidance on setting up a development environment and how to make a\ncontribution to Flask, see the `contributing guidelines`_.\n\n.. _contributing guidelines: https://github.com/pallets/flask/blob/main/CONTRIBUTING.rst\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Flask and the libraries\nit uses. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://flask.palletsprojects.com/\n- Changes: https://flask.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/Flask/\n- Source Code: https://github.com/pallets/flask/\n- Issue Tracker: https://github.com/pallets/flask/issues/\n- Website: https://palletsprojects.com/p/flask/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2022-04-28T17:47:40", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Framework :: Flask", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Internet :: WWW/HTTP :: WSGI", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - "Topic :: Software Development :: Libraries :: Application Frameworks" - ], - "homepage_url": "https://palletsprojects.com/p/flask", - "download_url": "https://files.pythonhosted.org/packages/d3/3c/94f38d4db919a9326a706ad56f05a7e6f0c8f7b7d93e2997cca54d3bc14b/Flask-2.1.2.tar.gz", - "size": 631846, - "sha1": null, - "md5": "93f1832e5be704ef6ff2a4124579cd85", - "sha256": "315ded2ddf8a6281567edb27393010fe3406188bafbfe65a3339d5787d89e477", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/flask/issues/", - "code_view_url": "https://github.com/pallets/flask/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/flask/2.1.2/json", - "datasource_id": null, - "purl": "pkg:pypi/flask@2.1.2" - }, { "type": "pypi", "namespace": null, @@ -304,67 +183,6 @@ "datasource_id": null, "purl": "pkg:pypi/itsdangerous@2.1.2" }, - { - "type": "pypi", - "namespace": null, - "name": "itsdangerous", - "version": "2.1.2", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Safely pass data to untrusted environments and back.\nItsDangerous\n============\n\n... so better sign this\n\nVarious helpers to pass data to untrusted environments and to get it\nback safe and sound. Data is cryptographically signed to ensure that a\ntoken has not been tampered with.\n\nIt's possible to customize how data is serialized. Data is compressed as\nneeded. A timestamp can be added and verified automatically while\nloading a token.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U itsdangerous\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\nHere's how you could generate a token for transmitting a user's id and\nname between web requests.\n\n.. code-block:: python\n\n from itsdangerous import URLSafeSerializer\n auth_s = URLSafeSerializer(\"secret key\", \"auth\")\n token = auth_s.dumps({\"id\": 5, \"name\": \"itsdangerous\"})\n\n print(token)\n # eyJpZCI6NSwibmFtZSI6Iml0c2Rhbmdlcm91cyJ9.6YP6T0BaO67XP--9UzTrmurXSmg\n\n data = auth_s.loads(token)\n print(data[\"name\"])\n # itsdangerous\n\n\nDonate\n------\n\nThe Pallets organization develops and supports ItsDangerous and other\npopular packages. In order to grow the community of contributors and\nusers, and allow the maintainers to devote more time to the projects,\n`please donate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://itsdangerous.palletsprojects.com/\n- Changes: https://itsdangerous.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/ItsDangerous/\n- Source Code: https://github.com/pallets/itsdangerous/\n- Issue Tracker: https://github.com/pallets/itsdangerous/issues/\n- Website: https://palletsprojects.com/p/itsdangerous/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2022-03-24T15:12:15", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python" - ], - "homepage_url": "https://palletsprojects.com/p/itsdangerous/", - "download_url": "https://files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", - "size": 56143, - "sha1": null, - "md5": "c1bc730ddf53b8374eaa823f24eb6438", - "sha256": "5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/itsdangerous/issues/", - "code_view_url": "https://github.com/pallets/itsdangerous/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/itsdangerous/2.1.2/json", - "datasource_id": null, - "purl": "pkg:pypi/itsdangerous@2.1.2" - }, { "type": "pypi", "namespace": null, @@ -651,65 +469,6 @@ "api_data_url": "https://pypi.org/pypi/werkzeug/3.0.1/json", "datasource_id": null, "purl": "pkg:pypi/werkzeug@3.0.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "werkzeug", - "version": "3.0.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "The comprehensive WSGI web application library.\nWerkzeug\n========\n\n*werkzeug* German noun: \"tool\". Etymology: *werk* (\"work\"), *zeug* (\"stuff\")\n\nWerkzeug is a comprehensive `WSGI`_ web application library. It began as\na simple collection of various utilities for WSGI applications and has\nbecome one of the most advanced WSGI utility libraries.\n\nIt includes:\n\n- An interactive debugger that allows inspecting stack traces and\n source code in the browser with an interactive interpreter for any\n frame in the stack.\n- A full-featured request object with objects to interact with\n headers, query args, form data, files, and cookies.\n- A response object that can wrap other WSGI applications and handle\n streaming data.\n- A routing system for matching URLs to endpoints and generating URLs\n for endpoints, with an extensible system for capturing variables\n from URLs.\n- HTTP utilities to handle entity tags, cache control, dates, user\n agents, cookies, files, and more.\n- A threaded WSGI server for use while developing applications\n locally.\n- A test client for simulating HTTP requests during testing without\n requiring running a server.\n\nWerkzeug doesn't enforce any dependencies. It is up to the developer to\nchoose a template engine, database adapter, and even how to handle\nrequests. It can be used to build all sorts of end user applications\nsuch as blogs, wikis, or bulletin boards.\n\n`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while\nproviding more structure and patterns for defining powerful\napplications.\n\n.. _WSGI: https://wsgi.readthedocs.io/en/latest/\n.. _Flask: https://www.palletsprojects.com/p/flask/\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U Werkzeug\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n from werkzeug.wrappers import Request, Response\n\n @Request.application\n def application(request):\n return Response('Hello, World!')\n\n if __name__ == '__main__':\n from werkzeug.serving import run_simple\n run_simple('localhost', 4000, application)\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Werkzeug and other\npopular packages. In order to grow the community of contributors and\nusers, and allow the maintainers to devote more time to the projects,\n`please donate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://werkzeug.palletsprojects.com/\n- Changes: https://werkzeug.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/Werkzeug/\n- Source Code: https://github.com/pallets/werkzeug/\n- Issue Tracker: https://github.com/pallets/werkzeug/issues/\n- Chat: https://discord.gg/pallets", - "release_date": "2023-10-24T20:57:50", - "parties": [ - { - "type": "person", - "role": "maintainer", - "name": null, - "email": "Pallets ", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Internet :: WWW/HTTP :: WSGI", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware", - "Topic :: Software Development :: Libraries :: Application Frameworks" - ], - "homepage_url": "", - "download_url": "https://files.pythonhosted.org/packages/0d/cc/ff1904eb5eb4b455e442834dabf9427331ac0fa02853bf83db817a7dd53d/werkzeug-3.0.1.tar.gz", - "size": 801436, - "sha1": null, - "md5": "b8cb17df4a7d86b7c5cdffcd5657197a", - "sha256": "507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/werkzeug/issues/", - "code_view_url": "https://github.com/pallets/werkzeug/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/werkzeug/3.0.1/json", - "datasource_id": null, - "purl": "pkg:pypi/werkzeug@3.0.1" } ], "resolution": [ @@ -759,4 +518,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/tests/data/test-api-with-recursive-requirement-file.json b/tests/data/test-api-with-recursive-requirement-file.json index 2f717a3..c68c696 100644 --- a/tests/data/test-api-with-recursive-requirement-file.json +++ b/tests/data/test-api-with-recursive-requirement-file.json @@ -177,71 +177,6 @@ "datasource_id": null, "purl": "pkg:pypi/pyyaml@6.0" }, - { - "type": "pypi", - "namespace": null, - "name": "pyyaml", - "version": "6.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "YAML parser and emitter for Python\nYAML is a data serialization format designed for human readability\nand interaction with scripting languages. PyYAML is a YAML parser\nand emitter for Python.\n\nPyYAML features a complete YAML 1.1 parser, Unicode support, pickle\nsupport, capable extension API, and sensible error messages. PyYAML\nsupports standard YAML tags and provides Python-specific tags that\nallow to represent an arbitrary Python object.\n\nPyYAML is applicable for a broad range of tasks from complex\nconfiguration files to object serialization and persistence.", - "release_date": "2021-10-13T19:40:57", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Kirill Simonov", - "email": "xi@resolvent.net", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Cython", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Text Processing :: Markup" - ], - "homepage_url": "https://pyyaml.org/", - "download_url": "https://files.pythonhosted.org/packages/36/2b/61d51a2c4f25ef062ae3f74576b01638bebad5e045f747ff12643df63844/PyYAML-6.0.tar.gz", - "size": 124996, - "sha1": null, - "md5": "1d19c798f25e58e3e582f0f8c977dbb8", - "sha256": "68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", - "sha512": null, - "bug_tracking_url": "https://github.com/yaml/pyyaml/issues", - "code_view_url": "https://github.com/yaml/pyyaml", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pyyaml/6.0/json", - "datasource_id": null, - "purl": "pkg:pypi/pyyaml@6.0" - }, { "type": "pypi", "namespace": null, @@ -373,76 +308,6 @@ "datasource_id": null, "purl": "pkg:pypi/shapely@1.7.1" }, - { - "type": "pypi", - "namespace": null, - "name": "shapely", - "version": "1.7.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Geometric objects, predicates, and operations\n=======\nShapely\n=======\n\n|travis| |appveyor| |coveralls|\n\n.. |travis| image:: https://travis-ci.org/Toblerity/Shapely.svg?branch=maint-1.7\n :target: https://travis-ci.org/Toblerity/Shapely\n\n.. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/Toblerity/Shapely?branch=maint-1.7&svg=true\n :target: https://ci.appveyor.com/project/frsci/shapely?branch=maint-1.7\n\n.. |coveralls| image:: https://coveralls.io/repos/github/Toblerity/Shapely/badge.svg?branch=maint-1.7\n :target: https://coveralls.io/github/Toblerity/Shapely?branch=maint-1.7\n\nManipulation and analysis of geometric objects in the Cartesian plane.\n\n.. image:: https://c2.staticflickr.com/6/5560/31301790086_b3472ea4e9_c.jpg\n :width: 800\n :height: 378\n\nShapely is a BSD-licensed Python package for manipulation and analysis of\nplanar geometric objects. It is based on the widely deployed `GEOS\n`__ (the engine of `PostGIS\n`__) and `JTS\n`__ (from which GEOS is ported)\nlibraries. Shapely is not concerned with data formats or coordinate systems,\nbut can be readily integrated with packages that are. For more details, see:\n\n* `Shapely GitHub repository `__\n* `Shapely documentation and manual `__\n\nUsage\n=====\n\nHere is the canonical example of building an approximately circular patch by\nbuffering a point.\n\n.. code-block:: pycon\n\n >>> from shapely.geometry import Point\n >>> patch = Point(0.0, 0.0).buffer(10.0)\n >>> patch\n \n >>> patch.area\n 313.65484905459385\n\nSee the manual for more examples and guidance.\n\nRequirements\n============\n\nShapely 1.7 requires\n\n* Python 2.7, >=3.5\n* GEOS >=3.3\n\nInstalling Shapely\n==================\n\nShapely may be installed from a source distribution or one of several kinds\nof built distribution.\n\nBuilt distributions\n-------------------\n\nBuilt distributions are the only option for users who do not have or do not\nknow how to use their platform's compiler and Python SDK, and a good option for\nusers who would rather not bother.\n\nLinux, OS X, and Windows users can get Shapely wheels with GEOS included from the\nPython Package Index with a recent version of pip (8+):\n\n.. code-block:: console\n\n $ pip install shapely\n\nShapely is available via system package management tools like apt, yum, and\nHomebrew, and is also provided by popular Python distributions like Canopy and\nAnaconda. If you use the Conda package manager to install Shapely, be sure to\nuse the conda-forge channel.\n\nWindows users have another good installation options: the wheels published at\nhttps://www.lfd.uci.edu/~gohlke/pythonlibs/#shapely. These can be installed\nusing pip by specifying the entire URL.\n\nSource distributions\n--------------------\n\nIf you want to build Shapely from source for compatibility with other modules\nthat depend on GEOS (such as cartopy or osgeo.ogr) or want to use a different\nversion of GEOS than the one included in the project wheels you should first\ninstall the GEOS library, Cython, and Numpy on your system (using apt, yum,\nbrew, or other means) and then direct pip to ignore the binary wheels.\n\n.. code-block:: console\n\n $ pip install shapely --no-binary shapely\n\nIf you've installed GEOS to a standard location, the geos-config program will\nbe used to get compiler and linker options. If geos-config is not on your\nexecutable, it can be specified with a GEOS_CONFIG environment variable, e.g.:\n\n.. code-block:: console\n\n $ GEOS_CONFIG=/path/to/geos-config pip install shapely\n\nIntegration\n===========\n\nShapely does not read or write data files, but it can serialize and deserialize\nusing several well known formats and protocols. The shapely.wkb and shapely.wkt\nmodules provide dumpers and loaders inspired by Python's pickle module.\n\n.. code-block:: pycon\n\n >>> from shapely.wkt import dumps, loads\n >>> dumps(loads('POINT (0 0)'))\n 'POINT (0.0000000000000000 0.0000000000000000)'\n\nShapely can also integrate with other Python GIS packages using GeoJSON-like\ndicts.\n\n.. code-block:: pycon\n\n >>> import json\n >>> from shapely.geometry import mapping, shape\n >>> s = shape(json.loads('{\"type\": \"Point\", \"coordinates\": [0.0, 0.0]}'))\n >>> s\n \n >>> print(json.dumps(mapping(s)))\n {\"type\": \"Point\", \"coordinates\": [0.0, 0.0]}\n\nDevelopment and Testing\n=======================\n\nDependencies for developing Shapely are listed in requirements-dev.txt. Cython\nand Numpy are not required for production installations, only for development.\nUse of a virtual environment is strongly recommended.\n\n.. code-block:: console\n\n $ virtualenv .\n $ source bin/activate\n (env)$ pip install -r requirements-dev.txt\n (env)$ pip install -e .\n\nThe project uses pytest to run Shapely's suite of unittests and doctests.\n\n.. code-block:: console\n\n (env)$ python -m pytest\n\nSupport\n=======\n\nQuestions about using Shapely may be asked on the `GIS StackExchange\n`__ using the \"shapely\"\ntag.\n\nBugs may be reported at https://github.com/Toblerity/Shapely/issues.\n\n\nCredits\n=======\n\nShapely is written by:\n\n* Allan Adair \n* Andrew Blakey \n* Andy Freeland \n* Ariel Kadouri \n* Aron Bierbaum \n* Bart Broere <2715782+bartbroere@users.noreply.github.com>\n* Bas Couwenberg \n* Benjamin Root \n* BertrandGervais \n* Brad Hards \n* Brandon Wood \n* Chad Hawkins \n* Christian Prior \n* Christian Quest \n* Christophe Pradal \n* Daniele Esposti \n* Dave Collins \n* David Baumgold \n* David Swinkels \n* Denis Rykov \n* Erwin Sterrenburg \n* Felix Yan \n* Filipe Fernandes \n* Fr\u00e9d\u00e9ric Junod \n* Gabi Davar \n* Gerrit Holl \n* Hannes \n* Hao Zheng \n* Henry Walshaw \n* Howard Butler \n* Hugo \n* Jacob Wasserman \n* James Douglass \n* James Gaboardi \n* James Lamb \n* James McBride \n* James Spencer \n* Jamie Hall \n* Jason Sanford \n* Jeethu Rao \n* Jeremiah England <34973839+Jeremiah-England@users.noreply.github.com>\n* Jinkun Wang \n* Johan Euphrosine \n* Johannes Sch\u00f6nberger \n* Jonathan Schoonhoven \n* Joris Van den Bossche \n* Joshua Arnott \n* Juan Luis Cano Rodr\u00edguez \n* Kai Lautaportti \n* Kelsey Jordahl \n* Kevin Wurster \n* Konstantin Veretennicov \n* Koshy Thomas \n* Kristian Evers \n* Kyle Barron \n* Leandro Lima \n* Lukasz \n* Luke Lee \n* Maarten Vermeyen \n* Marc Jansen \n* Marco De Nadai \n* Mathieu \n* Matt Amos \n* Michel Blancard \n* Mike Taves \n* Morris Tweed \n* Naveen Michaud-Agrawal \n* Oliver Tonnhofer \n* Pave\u0142 Ty\u015blacki \n* Peter Sagerson \n* Phil Elson \n* Pierre PACI \n* Ricardo Zilleruelo <51384295+zetaatlyft@users.noreply.github.com>\n* S Murthy \n* Sampo Syrjanen \n* Samuel Chin \n* Sean Gillies \n* Sobolev Nikita \n* Stephan H\u00fcgel \n* Steve M. Kim \n* Taro Matsuzawa aka. btm \n* Thibault Deutsch \n* Thomas Kluyver \n* Tobias Sauerwein \n* Tom Caruso \n* Tom Clancy <17627475+clncy@users.noreply.github.com>\n* WANG Aiyong \n* Will May \n* Zachary Ware \n* cclauss \n* clefrks <33859587+clefrks@users.noreply.github.com>\n* davidh-ssec \n* georgeouzou \n* giumas \n* joelostblom \n* ljwolf \n* mindw \n* rsmb \n* shongololo \n* solarjoe \n* stephenworsley <49274989+stephenworsley@users.noreply.github.com>\n\nSee also: https://github.com/Toblerity/Shapely/graphs/contributors.\n\nAdditional help from:\n\n* Justin Bronn (GeoDjango) for ctypes inspiration\n* Martin Davis (JTS)\n* Sandro Santilli, Mateusz Loskot, Paul Ramsey, et al (GEOS Project)\n\nMajor portions of this work were supported by a grant (for Pleiades_) from the\nU.S. National Endowment for the Humanities (https://www.neh.gov).\n\n.. _Pleiades: https://pleiades.stoa.org\n\n\nChanges\n=======\n\n1.7.1 (2020-08-20)\n------------------\n\n- ``STRtree`` now safely implements the pickle protocol (#915).\n- Documentation has been added for ``minimum_clearance`` (#875, #874).\n- In ``STRtree.__del__()`` we guard against calling ``GEOSSTRtree_destroy``\n when the lgeos module has already been torn down on exit (#897, #830).\n- Documentation for the ``overlaps()`` method has been corrected (#920).\n- Correct the test in ``shapely.geometry.base.BaseGeometry.empty()`` to\n eliminate memory leaks like the one reported in #745.\n- Get free() not from libc but from the processes global symbols (#891),\n fixing a bug that manifests on OS X 10.15 and 10.16.\n- Extracting substrings from complex lines has been made more correct (#848,\n #849).\n- Splitting of complex geometries has been sped up by preparing the input\n geometry (#871).\n- Fix bug in concatenation of function argtypes (#866).\n- Improved documentation of STRtree usage (#857).\n- Improved handling for empty list or list of lists in GeoJSON coordinates\n (#852).\n- The polylabel algorithm now accounts for polygon holes (#851, #817).\n\n1.7.0 (2020-01-28)\n------------------\n\nThis is the final 1.7.0 release. There have been no changes since 1.7b1.\n\n1.7b1 (2020-01-13)\n------------------\n\nFirst beta release.\n\n1.7a3 (2019-12-31)\n------------------\n\nNew features:\n\n- The buffer operation can now be single-sides (#806, #727).\n\nBug fixes:\n\n- Add /usr/local/lib to the list of directories to be searched for the GEOS\n shared library (#795).\n- ops.substring now returns a line with coords in end-to-front order when given\n a start position that is greater than the end position (#628).\n- Implement ``__bool__()`` for geometry base classes so that ``bool(geom)``\n returns the logical complement of ``geom.is_empty`` (#754).\n- Remove assertion on the number of version-like strings found in the GEOS\n version string. It could be 2 or 3.\n\n1.7a2 (2019-06-21)\n------------------\n\n- Nearest neighbor search has been added to STRtree (#668).\n- Disallow sequences of MultiPolygons as arguments to the MultiPolygon\n constructor, resolving #588.\n- Removed vendorized `functools` functions previously used to support\n Python 2.5.\n\nBug fixes:\n\n- Avoid reloading the GEOS shared library when using an installed binary wheel\n on OS X (#735), resolving issue #553.\n- The shapely.ops.orient function can now orient multi polygons and geometry\n collections as well as polygons (#733).\n- Polygons can now be constructed from sequences of point objects as well as\n sequences of x, y sequences (#732).\n- The exterior of an empty polygon is now equal to an empty linear ring (#731).\n- The bounds property of an empty point object now returns an empty tuple,\n consistent with other geometry types (#723).\n- Segmentation faults when non-string values are passed to the WKT loader are\n avoided by #700.\n- Failure of ops.substring when the sub linestring coincides with the beginning\n of the linestring has been fixed (#658).\n- Segmentation faults from interpolating on an empty linestring are prevented\n by #655.\n- A missing special case for rectangular polygons has been added to the\n polylabel algorithm (#644).\n- LinearRing can be created from a LineString (#638).\n- The prepared geoemtry validation condition has been tightened in #632 to fix\n the bug reported in #631.\n- Attempting to interpolate an empty geometry no longer results in a\n segmentation fault, raising `ValueError` instead (#653).\n\n1.7a1 (2018-07-29)\n------------------\n\nNew features:\n\n- A Python version check is made by the package setup script. Shapely 1.7\n supports only Python versions 2.7 and 3.4+ (#610).\n- Added a new `EmptyGeometry` class to support GeoPandas (#514).\n- Added new `shapely.ops.substring` function (#459).\n- Added new `shapely.ops.clip_by_rect` function (#583).\n- Use DLLs indicated in sys._MEIPASS' to support PyInstaller frozen apps\n (#523).\n- `shapely.wkb.dumps` now accepts an `srid` integer keyword argument to write\n WKB data including a spatial reference ID in the output data (#593).\n\nBug fixes:\n\n- `shapely.geometry.shape` can now marshal empty GeoJSON representations\n (#573).\n- An exception is raised when an attempt is made to `prepare`\n a `PreparedGeometry` (#577, #595).\n- Keyword arguments have been removed from a geometry object's `wkt` property\n getter (#581, #594).\n\n1.6.4.post1 (2018-01-24)\n------------------------\n\n- Fix broken markup in this change log, which restores our nicely formatted\n readme on PyPI.\n\n1.6.4 (2018-01-24)\n------------------\n\n- Handle a ``TypeError`` that can occur when geometries are torn down (#473,\n #528).\n\n\n1.6.3 (2017-12-09)\n------------------\n\n- AttributeError is no longer raised when accessing __geo_interface__ of an\n empty polygon (#450).\n- ``asShape`` now handles empty coordinates in mappings as ``shape`` does\n (#542). Please note that ``asShape`` is likely to be deprecated in a future\n version of Shapely.\n- Check for length of LineString coordinates in speed mode, preventing crashes\n when using LineStrings with only one coordinate (#546).\n\n1.6.2 (2017-10-30)\n------------------\n\n- A 1.6.2.post1 release has been made to fix a problem with macosx wheels\n uploaded to PyPI.\n\n1.6.2 (2017-10-26)\n------------------\n\n- Splitting a linestring by one of its end points will now succeed instead of\n failing with a ``ValueError`` (#524, #533).\n- Missing documentation of a geometry's ``overlaps`` predicate has been added\n (#522).\n\n1.6.1 (2017-09-01)\n------------------\n\n- Avoid ``STRTree`` crashes due to dangling references (#505) by maintaining\n references to added geometries.\n- Reduce log level to debug when reporting on calls to ctypes ``CDLL()`` that\n don't succeed and are retried (#515).\n- Clarification: applications like GeoPandas that need an empty geometry object\n should use ``BaseGeometry()`` instead of ``Point()`` or ``Polygon()``. An\n ``EmptyGeometry`` class has been added in the master development branch and\n will be available in the next non-bugfix release.\n\n1.6.0 (2017-08-21)\n------------------\n\nShapely 1.6.0 adds new attributes to existing geometry classes and new\nfunctions (``split()`` and ``polylabel()``) to the shapely.ops module.\nExceptions are consolidated in a shapely.errors module and logging practices\nhave been improved. Shapely's optional features depending on Numpy are now\ngathered into a requirements set named \"vectorized\" and these may be installed\nlike ``pip install shapely[vectorized]``.\n\nMuch of the work on 1.6.0 was aimed to improve the project's build and\npackaging scripts and to minimize run-time dependencies. Shapely now vendorizes\npackaging to use during builds only and never again invokes the geos-config\nutility at run-time.\n\nIn addition to the changes listed under the alpha and beta pre-releases below,\nthe following change has been made to the project:\n\n- Project documentation is now hosted at \n https://shapely.readthedocs.io/en/latest/.\n\nThank you all for using, promoting, and contributing to the Shapely project.\n\n1.6b5 (2017-08-18)\n------------------\n\nBug fixes:\n\n- Passing a single coordinate to ``LineString()`` with speedups disabled now\n raises a ValueError as happens with speedups enabled. This resolves #509.\n\n1.6b4 (2017-02-15)\n------------------\n\nBug fixes:\n\n- Isolate vendorized packaging in a _vendor directory, remove obsolete\n dist-info, and remove packaging from project requirements (resolves #468).\n\n1.6b3 (2016-12-31)\n------------------\n\nBug fixes:\n\n- Level for log messages originating from the GEOS notice handler reduced from\n WARNING to INFO (#447).\n- Permit speedups to be imported again without Numpy (#444).\n\n1.6b2 (2016-12-12)\n------------------\n\nNew features:\n\n- Add support for GeometryCollection to shape and asShape functions (#422).\n\n1.6b1 (2016-12-12)\n------------------\n\nBug fixes:\n\n- Implemented __array_interface__ for empty Points and LineStrings (#403).\n\n1.6a3 (2016-12-01)\n------------------\n\nBug fixes:\n\n- Remove accidental hard requirement of Numpy (#431).\n\nPackaging:\n\n- Put Numpy in an optional requirement set named \"vectorized\" (#431).\n\n1.6a2 (2016-11-09)\n------------------\n\nBug fixes:\n\n- Shapely no longer configures logging in ``geos.py`` (#415).\n\nRefactoring:\n\n- Consolidation of exceptions in ``shapely.errors``.\n- ``UnsupportedGEOSVersionError`` is raised when GEOS < 3.3.0 (#407).\n\nPackaging:\n\n- Added new library search paths to assist Anaconda (#413).\n- geos-config will now be bypassed when NO_GEOS_CONFIG env var is set. This\n allows configuration of Shapely builds on Linux systems that for whatever\n reasons do not include the geos-config program (#322).\n\n1.6a1 (2016-09-14)\n------------------\n\nNew features:\n\n- A new error derived from NotImplementedError, with a more useful message, is\n raised when the GEOS backend doesn't support a called method (#216).\n- The ``project()`` method of LineString has been extended to LinearRing\n geometries (#286).\n- A new ``minimum_rotated_rectangle`` attribute has been added to the base\n geometry class (#354).\n- A new ``shapely.ops.polylabel()`` function has been added. It\n computes a point suited for labeling concave polygons (#395).\n- A new ``shapely.ops.split()`` function has been added. It splits a\n geometry by another geometry of lesser dimension: polygon by line, line by\n point (#293, #371).\n- ``Polygon.from_bounds()`` constructs a Polygon from bounding coordinates\n (#392).\n- Support for testing with Numpy 1.4.1 has been added (#301).\n- Support creating all kinds of empty geometries from empty lists of Python\n objects (#397, #404).\n\nRefactoring:\n\n- Switch from ``SingleSidedBuffer()`` to ``OffsetCurve()`` for GEOS >= 3.3\n (#270).\n- Cython speedups are now enabled by default (#252).\n\nPackaging:\n\n- Packaging 16.7, a setup dependency, is vendorized (#314).\n- Infrastructure for building manylinux1 wheels has been added (#391).\n- The system's ``geos-config`` program is now only checked when ``setup.py``\n is executed, never during normal use of the module (#244).\n- Added new library search paths to assist PyInstaller (#382) and Windows\n (#343).\n\n1.5.17 (2016-08-31)\n-------------------\n- Bug fix: eliminate memory leak in geom_factory() (#408).\n- Bug fix: remove mention of negative distances in parallel_offset and note\n that vertices of right hand offset lines are reversed (#284).\n\n1.5.16 (2016-05-26)\n-------------------\n- Bug fix: eliminate memory leak when unpickling geometry objects (#384, #385).\n- Bug fix: prevent crashes when attempting to pickle a prepared geometry,\n raising ``PicklingError`` instead (#386).\n- Packaging: extension modules in the OS X wheels uploaded to PyPI link only\n libgeos_c.dylib now (you can verify and compare to previous releases with\n ``otool -L shapely/vectorized/_vectorized.so``).\n\n1.5.15 (2016-03-29)\n-------------------\n- Bug fix: use uintptr_t to store pointers instead of long in _geos.pxi,\n preventing an overflow error (#372, #373). Note that this bug fix was\n erroneously reported to have been made in 1.5.14, but was not.\n\n1.5.14 (2016-03-27)\n-------------------\n- Bug fix: use ``type()`` instead of ``isinstance()`` when evaluating geometry\n equality, preventing instances of base and derived classes from \n being mistaken for equals (#317).\n- Bug fix: ensure that empty geometries are created when constructors have no\n args (#332, #333).\n- Bug fix: support app \"freezing\" better on Windows by not relying on the\n ``__file__`` attribute (#342, #377).\n- Bug fix: ensure that empty polygons evaluate to be ``==`` (#355).\n- Bug fix: filter out empty geometries that can cause segfaults when creating\n and loading STRtrees (#345, #348).\n- Bug fix: no longer attempt to reuse GEOS DLLs already loaded by Rasterio\n or Fiona on OS X (#374, #375).\n\n1.5.13 (2015-10-09)\n-------------------\n- Restore setup and runtime discovery and loading of GEOS shared library to\n state at version 1.5.9 (#326).\n- On OS X we try to reuse any GEOS shared library that may have been loaded\n via import of Fiona or Rasterio in order to avoid a bug involving the\n GEOS AbstractSTRtree (#324, #327).\n\n1.5.12 (2015-08-27)\n-------------------\n- Remove configuration of root logger from libgeos.py (#312).\n- Skip test_fallbacks on Windows (#308).\n- Call setlocale(locale.LC_ALL, \"\") instead of resetlocale() on Windows when\n tearing down the locale test (#308).\n- Fix for Sphinx warnings (#309).\n- Addition of .cache, .idea, .pyd, .pdb to .gitignore (#310).\n\n1.5.11 (2015-08-23)\n-------------------\n- Remove packaging module requirement added in 1.5.10 (#305). Distutils can't \n parse versions using 'rc', but if we stick to 'a' and 'b' we will be fine.\n\n1.5.10 (2015-08-22)\n-------------------\n- Monkey patch affinity module by absolute reference (#299).\n- Raise TopologicalError in relate() instead of crashing (#294, #295, #303).\n\n1.5.9 (2015-05-27)\n------------------\n- Fix for 64 bit speedups compatibility (#274).\n\n1.5.8 (2015-04-29)\n------------------\n- Setup file encoding bug fix (#254).\n- Support for pyinstaller (#261).\n- Major prepared geometry operation fix for Windows (#268, #269).\n- Major fix for OS X binary wheel (#262).\n\n1.5.7 (2015-03-16)\n------------------\n- Test and fix buggy error and notice handlers (#249).\n\n1.5.6 (2015-02-02)\n------------------\n- Fix setup regression (#232, #234).\n- SVG representation improvements (#233, #237).\n\n1.5.5 (2015-01-20)\n------------------\n- MANIFEST changes to restore _geox.pxi (#231).\n\n1.5.4 (2015-01-19)\n------------------\n- Fixed OS X binary wheel library load path (#224).\n\n1.5.3 (2015-01-12)\n------------------\n- Fixed ownership and potential memory leak in polygonize (#223).\n- Wider release of binary wheels for OS X.\n\n1.5.2 (2015-01-04)\n------------------\n- Fail installation if GEOS dependency is not met, preventing update breakage\n (#218, #219).\n\n1.5.1 (2014-12-04)\n------------------\n- Restore geometry hashing (#209).\n\n1.5.0 (2014-12-02)\n------------------\n- Affine transformation speedups (#197).\n- New `==` rich comparison (#195).\n- Geometry collection constructor (#200).\n- ops.snap() backed by GEOSSnap (#201).\n- Clearer exceptions in cases of topological invalidity (#203).\n\n1.4.4 (2014-11-02)\n------------------\n- Proper conversion of numpy float32 vals to coords (#186).\n\n1.4.3 (2014-10-01)\n------------------\n- Fix for endianness bug in WKB writer (#174).\n\n1.4.2 (2014-09-29)\n------------------\n- Fix bungled 1.4.1 release (#176).\n\n1.4.1 (2014-09-23)\n------------------\n- Return of support for GEOS 3.2 (#176, #178).\n\n1.4.0 (2014-09-08)\n------------------\n- SVG representations for IPython's inline image protocol.\n- Efficient and fast vectorized contains().\n- Change mitre_limit default to 5.0; raise ValueError with 0.0 (#139).\n- Allow mix of tuples and Points in sped-up LineString ctor (#152).\n- New STRtree class (#73).\n- Add ops.nearest_points() (#147).\n- Faster creation of geometric objects from others (cloning) (#165).\n- Removal of tests from package.\n\n1.3.3 (2014-07-23)\n------------------\n- Allow single-part geometries as argument to ops.cacaded_union() (#135).\n- Support affine transformations of LinearRings (#112).\n\n1.3.2 (2014-05-13)\n------------------\n- Let LineString() take a sequence of Points (#130).\n\n1.3.1 (2014-04-22)\n------------------\n- More reliable proxy cleanup on exit (#106).\n- More robust DLL loading on all platforms (#114).\n\n1.3.0 (2013-12-31)\n------------------\n- Include support for Python 3.2 and 3.3 (#56), minimum version is now 2.6.\n- Switch to GEOS WKT/WKB Reader/Writer API, with defaults changed to enable 3D\n output dimensions, and to 'trim' WKT output for GEOS >=3.3.0.\n- Use GEOS version instead of GEOS C API version to determine library\n capabilities (#65).\n\n1.2.19 (2013-12-30)\n-------------------\n- Add buffering style options (#55).\n\n1.2.18 (2013-07-23)\n--------------------\n- Add shapely.ops.transform.\n- Permit empty sequences in collection constructors (#49, #50).\n- Individual polygons in MultiPolygon.__geo_interface__ are changed to tuples\n to match Polygon.__geo_interface__ (#51).\n- Add shapely.ops.polygonize_full (#57).\n\n1.2.17 (2013-01-27)\n-------------------\n- Avoid circular import between wkt/wkb and geometry.base by moving calls\n to GEOS serializers to the latter module.\n- Set _ndim when unpickling (issue #6).\n- Don't install DLLs to Python's DLL directory (#37).\n- Add affinity module of affine transformation (#31).\n- Fix NameError that blocked installation with PyPy (#40, #41).\n\n1.2.16 (2012-09-18)\n-------------------\n- Add ops.unary_union function.\n- Alias ops.cascaded_union to ops.unary_union when GEOS CAPI >= (1,7,0).\n- Add geos_version_string attribute to shapely.geos.\n- Ensure parent is set when child geometry is accessed.\n- Generate _speedups.c using Cython when building from repo when missing,\n stale, or the build target is \"sdist\".\n- The is_simple predicate of invalid, self-intersecting linear rings now\n returns ``False``.\n- Remove VERSION.txt from repo, it's now written by the distutils setup script\n with value of shapely.__version__.\n\n1.2.15 (2012-06-27)\n-------------------\n- Eliminate numerical sensitivity in a method chaining test (Debian bug\n #663210).\n- Account for cascaded union of random buffered test points being a polygon\n or multipolygon (Debian bug #666655).\n- Use Cython to build speedups if it is installed.\n- Avoid stumbling over SVN revision numbers in GEOS C API version strings.\n\n1.2.14 (2012-01-23)\n-------------------\n- A geometry's coords property is now sliceable, yielding a list of coordinate\n values.\n- Homogeneous collections are now sliceable, yielding a new collection of the\n same type.\n\n1.2.13 (2011-09-16)\n-------------------\n- Fixed errors in speedups on 32bit systems when GEOS references memory above\n 2GB.\n- Add shapely.__version__ attribute.\n- Update the manual.\n\n1.2.12 (2011-08-15)\n-------------------\n- Build Windows distributions with VC7 or VC9 as appropriate.\n- More verbose report on failure to speed up.\n- Fix for prepared geometries broken in 1.2.11.\n- DO NOT INSTALL 1.2.11\n\n1.2.11 (2011-08-04)\n-------------------\n- Ignore AttributeError during exit.\n- PyPy 1.5 support.\n- Prevent operation on prepared geometry crasher (#12).\n- Optional Cython speedups for Windows.\n- Linux 3 platform support.\n\n1.2.10 (2011-05-09)\n-------------------\n- Add optional Cython speedups.\n- Add is_cww predicate to LinearRing.\n- Add function that forces orientation of Polygons.\n- Disable build of speedups on Windows pending packaging work.\n\n1.2.9 (2011-03-31)\n------------------\n- Remove extra glob import.\n- Move examples to shapely.examples.\n- Add box() constructor for rectangular polygons.\n- Fix extraneous imports.\n\n1.2.8 (2011-12-03)\n------------------\n- New parallel_offset method (#6).\n- Support for Python 2.4.\n\n1.2.7 (2010-11-05)\n------------------\n- Support for Windows eggs.\n\n1.2.6 (2010-10-21)\n------------------\n- The geoms property of an empty collection yields [] instead of a ValueError\n (#3).\n- The coords and geometry type sproperties have the same behavior as above.\n- Ensure that z values carry through into products of operations (#4).\n\n1.2.5 (2010-09-19)\n------------------\n- Stop distributing docs/_build.\n- Include library fallbacks in test_dlls.py for linux platform.\n\n1.2.4 (2010-09-09)\n------------------\n- Raise AttributeError when there's no backend support for a method.\n- Raise OSError if libgeos_c.so (or variants) can't be found and loaded.\n- Add geos_c DLL loading support for linux platforms where find_library doesn't\n work.\n\n1.2.3 (2010-08-17)\n------------------\n- Add mapping function.\n- Fix problem with GEOSisValidReason symbol for GEOS < 3.1.\n\n1.2.2 (2010-07-23)\n------------------\n- Add representative_point method.\n\n1.2.1 (2010-06-23)\n------------------\n- Fixed bounds of singular polygons.\n- Added shapely.validation.explain_validity function (#226).\n\n1.2 (2010-05-27)\n----------------\n- Final release.\n\n1.2rc2 (2010-05-26)\n-------------------\n- Add examples and tests to MANIFEST.in.\n- Release candidate 2.\n\n1.2rc1 (2010-05-25)\n-------------------\n- Release candidate.\n\n1.2b7 (2010-04-22)\n------------------\n- Memory leak associated with new empty geometry state fixed.\n\n1.2b6 (2010-04-13)\n------------------\n- Broken GeometryCollection fixed.\n\n1.2b5 (2010-04-09)\n------------------\n- Objects can be constructed from others of the same type, thereby making\n copies. Collections can be constructed from sequences of objects, also making\n copies.\n- Collections are now iterators over their component objects.\n- New code for manual figures, using the descartes package.\n\n1.2b4 (2010-03-19)\n------------------\n- Adds support for the \"sunos5\" platform.\n\n1.2b3 (2010-02-28)\n------------------\n- Only provide simplification implementations for GEOS C API >= 1.5.\n\n1.2b2 (2010-02-19)\n------------------\n- Fix cascaded_union bug introduced in 1.2b1 (#212).\n\n1.2b1 (2010-02-18)\n------------------\n- Update the README. Remove cruft from setup.py. Add some version 1.2 metadata\n regarding required Python version (>=2.5,<3) and external dependency\n (libgeos_c >= 3.1).\n\n1.2a6 (2010-02-09)\n------------------\n- Add accessor for separate arrays of X and Y values (#210).\n\nTODO: fill gap here\n\n1.2a1 (2010-01-20)\n------------------\n- Proper prototyping of WKB writer, and avoidance of errors on 64-bit systems\n (#191).\n- Prototype libgeos_c functions in a way that lets py2exe apps import shapely\n (#189).\n\n1.2 Branched (2009-09-19)\n\n1.0.12 (2009-04-09)\n-------------------\n- Fix for references held by topology and predicate descriptors.\n\n1.0.11 (2008-11-20)\n-------------------\n- Work around bug in GEOS 2.2.3, GEOSCoordSeq_getOrdinate not exported properly\n (#178).\n\n1.0.10 (2008-11-17)\n-------------------\n- Fixed compatibility with GEOS 2.2.3 that was broken in 1.0.8 release (#176).\n\n1.0.9 (2008-11-16)\n------------------\n- Find and load MacPorts libgeos.\n\n1.0.8 (2008-11-01)\n------------------\n- Fill out GEOS function result and argument types to prevent faults on a\n 64-bit arch.\n\n1.0.7 (2008-08-22)\n------------------\n- Polygon rings now have the same dimensions as parent (#168).\n- Eliminated reference cycles in polygons (#169).\n\n1.0.6 (2008-07-10)\n------------------\n- Fixed adaptation of multi polygon data.\n- Raise exceptions earlier from binary predicates.\n- Beginning distributing new windows DLLs (#166).\n\n1.0.5 (2008-05-20)\n------------------\n- Added access to GEOS polygonizer function.\n- Raise exception when insufficient coordinate tuples are passed to LinearRing\n constructor (#164).\n\n1.0.4 (2008-05-01)\n------------------\n- Disentangle Python and topological equality (#163).\n- Add shape(), a factory that copies coordinates from a geo interface provider.\n To be used instead of asShape() unless you really need to store coordinates\n outside shapely for efficient use in other code.\n- Cache GEOS geometries in adapters (#163).\n\n1.0.3 (2008-04-09)\n------------------\n- Do not release GIL when calling GEOS functions (#158).\n- Prevent faults when chaining multiple GEOS operators (#159).\n\n1.0.2 (2008-02-26)\n------------------\n- Fix loss of dimensionality in polygon rings (#155).\n\n1.0.1 (2008-02-08)\n------------------\n- Allow chaining expressions involving coordinate sequences and geometry parts\n (#151).\n- Protect against abnormal use of coordinate accessors (#152).\n- Coordinate sequences now implement the numpy array protocol (#153).\n\n1.0 (2008-01-18)\n----------------\n- Final release.\n\n1.0 RC2 (2008-01-16)\n--------------------\n- Added temporary solution for #149.\n\n1.0 RC1 (2008-01-14)\n--------------------\n- First release candidate", - "release_date": "2020-08-20T23:31:42", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Sean Gillies", - "email": "sean.gillies@gmail.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Sean Gillies", - "email": "sean.gillies@gmail.com", - "url": null - } - ], - "keywords": [ - "geometry topology gis", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Intended Audience :: Science/Research", - "Operating System :: OS Independent", - "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", - "Topic :: Scientific/Engineering :: GIS" - ], - "homepage_url": "https://github.com/Toblerity/Shapely", - "download_url": "https://files.pythonhosted.org/packages/42/f3/0e1bc2c4f15e05e30c6b99322b9ddaa2babb3f43bc7df2698efdc1553439/Shapely-1.7.1.tar.gz", - "size": 383194, - "sha1": null, - "md5": "2bf7bc1199b3a88b13c12109cd3d2429", - "sha256": "1641724c1055459a7e2b8bbe47ba25bdc89554582e62aec23cb3f3ca25f9b129", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/shapely/1.7.1/json", - "datasource_id": null, - "purl": "pkg:pypi/shapely@1.7.1" - }, { "type": "pypi", "namespace": null, @@ -501,64 +366,6 @@ "datasource_id": null, "purl": "pkg:pypi/simplekml@1.3.5" }, - { - "type": "pypi", - "namespace": null, - "name": "simplekml", - "version": "1.3.5", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A Simple KML creator\nSimplekml is a python package which enables you to generate KML with as little effort as possible.\n\nAt the time of making this package nothing was available (at least I could not find anything) that could create KML files easily. You needed a lot of bloated code to even create a simple point. This is understandable because the KML standard is quite extensive, but what if you just work with the simple elements of KML like Document, Folder, Point, LineString and Polygon? This package supports those elements and everything documented in the KML Reference. With simplekml creating a KML file containing a point as simple as:\n\n```python\nimport simplekml\nkml = simplekml.Kml()\nkml.newpoint(name=\"Kirstenbosch\", coords=[(18.432314,-33.988862)])\nkml.save(\"botanicalgarden.kml\")\n```\n\nSee the [Homepage](http://readthedocs.org/projects/simplekml/) for usage, documentation and a reference.", - "release_date": "2020-04-02T12:19:42", - "parties": [ - { - "type": "person", - "role": "author", - "name": "2011-2016 Kyle Lancaster | 2019 Patrick Eisoldt", - "email": "patrick@eisoldt.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Topic :: Scientific/Engineering :: GIS", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "http://readthedocs.org/projects/simplekml/", - "download_url": "https://files.pythonhosted.org/packages/62/de/a75c0c8341a2edd186e14648c231c92c9e672dd38c544089615140c28ac6/simplekml-1.3.5.tar.gz", - "size": 39069, - "sha1": null, - "md5": "23f9cf9efa5e08981b7b004ce0ce5cb3", - "sha256": "657b4e20177299a4e80bacfafff1f91102010bc23dc0ce7a7ae43bdd4246049e", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "GNU Lesser General Public License v3+", - "classifiers": [ - "License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/simplekml/1.3.5/json", - "datasource_id": null, - "purl": "pkg:pypi/simplekml@1.3.5" - }, { "type": "pypi", "namespace": null, @@ -614,62 +421,6 @@ "api_data_url": "https://pypi.org/pypi/six/1.16.0/json", "datasource_id": null, "purl": "pkg:pypi/six@1.16.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "six", - "version": "1.16.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Python 2 and 3 compatibility utilities\n.. image:: https://img.shields.io/pypi/v/six.svg\n :target: https://pypi.org/project/six/\n :alt: six on PyPI\n\n.. image:: https://travis-ci.org/benjaminp/six.svg?branch=master\n :target: https://travis-ci.org/benjaminp/six\n :alt: six on TravisCI\n\n.. image:: https://readthedocs.org/projects/six/badge/?version=latest\n :target: https://six.readthedocs.io/\n :alt: six's documentation on Read the Docs\n\n.. image:: https://img.shields.io/badge/license-MIT-green.svg\n :target: https://github.com/benjaminp/six/blob/master/LICENSE\n :alt: MIT License badge\n\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 Python 2.7 and 3.3+. 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://six.readthedocs.io/.\n\nBugs can be reported to https://github.com/benjaminp/six. The code can also\nbe found there.", - "release_date": "2021-05-05T14:18:18", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Benjamin Peterson", - "email": "benjamin@python.org", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/benjaminp/six", - "download_url": "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", - "size": 34041, - "sha1": null, - "md5": "a7c927740e4964dd29b72cebfc1429bb", - "sha256": "1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/six/1.16.0/json", - "datasource_id": null, - "purl": "pkg:pypi/six@1.16.0" } ], "resolution": [ diff --git a/tests/data/test-api-with-requirement-file.json b/tests/data/test-api-with-requirement-file.json index 2e80b4a..9c7f28b 100644 --- a/tests/data/test-api-with-requirement-file.json +++ b/tests/data/test-api-with-requirement-file.json @@ -1545,78 +1545,6 @@ "datasource_id": null, "purl": "pkg:pypi/aboutcode-toolkit@7.0.2" }, - { - "type": "pypi", - "namespace": null, - "name": "aboutcode-toolkit", - "version": "7.0.2", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "AboutCode-toolkit is a tool to document the provenance (origin and license) of third-party software using small text files. Collect inventories and generate attribution documentation.\n=================\nAboutCode Toolkit\n=================\n\nIntroduction\n------------\nThe AboutCode Toolkit and ABOUT files provide a simple way to document the\norigin, license, usage and other important or interesting information about\nthird-party software components that you use in your project.\n\nYou start by storing ABOUT files (a small YAML formatted text file with field/value pairs)\nside-by-side with each of the third-party software components you use.\nEach ABOUT file documents origin and license for one software.\nThere are many examples of ABOUT files (valid or invalid) in the testdata/\ndirectory of the whole repository.\n\nThe current version of the AboutCode Toolkit can read these ABOUT files so that you\ncan collect and validate the inventory of third-party components that you use.\n\nIn addition, this tool is able to generate attribution notices and\nidentify redistributable source code used in your project to help you comply\nwith open source licenses conditions.\n\nThis version of the AboutCode Toolkit follows the ABOUT specification version 3.2.3 at:\nhttps://aboutcode-toolkit.readthedocs.io/en/latest/specification.html\n\n\nBuild and tests status\n----------------------\n\n+-------+-----------------+--------------+\n|Branch | **Linux/macOS** | **Windows** |\n+=======+=================+==============+\n|Master | |master-posix| | |master-win| |\n+-------+-----------------+--------------+\n|Develop| |devel-posix| | |devel-win| |\n+-------+-----------------+--------------+\n\n\nREQUIREMENTS\n------------\nThe AboutCode Toolkit is tested with Python 3.6.2 or above only on Linux, Mac and Windows.\nYou will need to install a Python interpreter if you do not have one already\ninstalled.\n\nOn Linux and Mac, Python is typically pre-installed. To verify which\nversion may be pre-installed, open a terminal and type:\n\n python --version\n\nNote\n~~~~\n Debian has decided that distutils is not a core python package, so it is not included in the last versions of debian and debian-based OSes.\n A solution is to run: `sudo apt install python3-distutils`\n\nOn Windows or Mac, you can download the latest Python here:\n https://www.python.org/downloads/\n\nDownload the .msi installer for Windows or the .dmg archive for Mac.\nOpen and run the installer using all the default options.\n\nINSTALLATION\n------------\nCheckout or download and extract the AboutCode Toolkit from:\n https://github.com/nexB/aboutcode-toolkit/\n\nTo install all the needed dependencies in a virtualenv, run (on posix):\n ./configure\nor on windows:\n configure\n\nNote\n~~~~\n For MacOS users, it's a known issue the Python36 may case SSL Certificates error if the Certificates is not up to date.\n A solution is to run: `sudo /Applications/Python\\\\ 3.6/Install\\\\ Certificates.command` to upgrade the outdated certificates.\n\nACTIVATE the VIRTUALENV\n-----------------------\nTo activate the virtualenv, run (on posix):\n source venv/bin/activate\nor on windows:\n venv\\\\bin\\\\activate\n\n\nDEACTIVATE the VIRTUALENV\n-------------------------\nTo deactivate the virtualenv, run (on both posix and windows):\n deactivate\n\n\nVERSIONING SCHEMA\n-----------------\nStarting at AboutCode version 4.0.0, the AboutCode Toolkit will follow SemVer for the versioning schema.\n\ni.e. MAJOR.MINOR.PATCH format\n 1. MAJOR version when making incompatible API changes,\n 2. MINOR version when making functionality in a backwards compatible manner, and\n 3. PATCH version when making backwards compatible bug fixes.\n\n\nREFERENCE\n---------\nSee https://aboutcode-toolkit.readthedocs.io/en/latest/ for documentation.\n\nSee https://aboutcode-toolkit.readthedocs.io/en/latest/reference.html for reference.\n\nTESTS and DEVELOPMENT\n---------------------\nTo install all the needed development dependencies, run (on posix):\n ./configure --dev\nor on windows:\n configure --dev\n\nTo verify that everything works fine you can run the test suite with:\n pytest\n\n\nCLEAN BUILD AND INSTALLED FILES\n-------------------------------\nTo clean the built and installed files, run (on posix):\n ./configure --clean\nor on windows:\n configure --clean\n\n\nHELP and SUPPORT\n----------------\nIf you have a question or find a bug, enter a ticket at:\n\n https://github.com/nexB/aboutcode-toolkit\n\nFor issues, you can use:\n\n https://github.com/nexB/aboutcode-toolkit/issues\n\n\nSOURCE CODE\n-----------\nThe AboutCode Toolkit is available through GitHub. For the latest version visit:\n https://github.com/nexB/aboutcode-toolkit\n\n\nHACKING\n-------\nWe accept pull requests provided under the same license as this tool.\nYou agree to the http://developercertificate.org/\n\n\nLICENSE\n-------\nThe AboutCode Toolkit is released under the Apache 2.0 license.\nSee (of course) the about.ABOUT file for details.\n\n\n.. |master-posix| image:: https://api.travis-ci.org/nexB/aboutcode-toolkit.png?branch=master\n :target: https://travis-ci.org/nexB/aboutcode-toolkit\n :alt: Linux Master branch tests status\n.. |devel-posix| image:: https://api.travis-ci.org/nexB/aboutcode-toolkit.png?branch=develop\n :target: https://travis-ci.org/nexB/aboutcode-toolkit\n :alt: Linux Develop branch tests status\n\n.. |master-win| image:: https://ci.appveyor.com/api/projects/status/uwj2gh8i9ga1mqwn/branch/master?png=true\n :target: https://ci.appveyor.com/project/nexB/aboutcode-toolkit\n :alt: Windows Master branch tests status\n.. |devel-win| image:: https://ci.appveyor.com/api/projects/status/uwj2gh8i9ga1mqwn/branch/develop?png=true\n :target: https://ci.appveyor.com/project/nexB/aboutcode-toolkit\n :alt: Windows Develop branch tests status", - "release_date": "2022-05-10T14:10:19", - "parties": [ - { - "type": "person", - "role": "author", - "name": "nexB. Inc. and others", - "email": "info@aboutcode.org", - "url": null - } - ], - "keywords": [ - "license", - "about", - "metadata", - "package", - "copyright", - "attribution", - "software", - "inventory", - "open source", - "sca", - "SBOM", - "spdx", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Topic :: Software Development", - "Topic :: Software Development :: Documentation", - "Topic :: Software Development :: Quality Assurance", - "Topic :: System :: Software Distribution", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/nexB/aboutcode-toolkit", - "download_url": "https://files.pythonhosted.org/packages/22/11/fb1a48393106b470fc05450a01317f22ca128541d5c5f755ce092ffaebd0/aboutcode-toolkit-7.0.2.tar.gz", - "size": 380081, - "sha1": null, - "md5": "b29726a260d0da5c09caf5f07646d766", - "sha256": "b0bc22ff777187adf5ac50ceb81b3e44dcbf9d7239ecf8b1a80a1ac1ac87a2b5", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "Apache-2.0" - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/aboutcode-toolkit/7.0.2/json", - "datasource_id": null, - "purl": "pkg:pypi/aboutcode-toolkit@7.0.2" - }, { "type": "pypi", "namespace": null, @@ -1694,83 +1622,6 @@ "datasource_id": null, "purl": "pkg:pypi/attrs@21.4.0" }, - { - "type": "pypi", - "namespace": null, - "name": "attrs", - "version": "21.4.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Classes Without Boilerplate\n.. image:: https://www.attrs.org/en/stable/_static/attrs_logo.png\n :alt: attrs logo\n :align: center\n\n\n``attrs`` is the Python package that will bring back the **joy** of **writing classes** by relieving you from the drudgery of implementing object protocols (aka `dunder methods `_).\n`Trusted by NASA `_ for Mars missions since 2020!\n\nIts main goal is to help you to write **concise** and **correct** software without slowing down your code.\n\n.. teaser-end\n\nFor that, it gives you a class decorator and a way to declaratively define the attributes on that class:\n\n.. -code-begin-\n\n.. code-block:: pycon\n\n >>> from attrs import asdict, define, make_class, Factory\n\n >>> @define\n ... class SomeClass:\n ... a_number: int = 42\n ... list_of_numbers: list[int] = Factory(list)\n ...\n ... def hard_math(self, another_number):\n ... return self.a_number + sum(self.list_of_numbers) * another_number\n\n\n >>> sc = SomeClass(1, [1, 2, 3])\n >>> sc\n SomeClass(a_number=1, list_of_numbers=[1, 2, 3])\n\n >>> sc.hard_math(3)\n 19\n >>> sc == SomeClass(1, [1, 2, 3])\n True\n >>> sc != SomeClass(2, [3, 2, 1])\n True\n\n >>> asdict(sc)\n {'a_number': 1, 'list_of_numbers': [1, 2, 3]}\n\n >>> SomeClass()\n SomeClass(a_number=42, list_of_numbers=[])\n\n >>> C = make_class(\"C\", [\"a\", \"b\"])\n >>> C(\"foo\", \"bar\")\n C(a='foo', b='bar')\n\n\nAfter *declaring* your attributes ``attrs`` gives you:\n\n- a concise and explicit overview of the class's attributes,\n- a nice human-readable ``__repr__``,\n- a equality-checking methods,\n- an initializer,\n- and much more,\n\n*without* writing dull boilerplate code again and again and *without* runtime performance penalties.\n\n**Hate type annotations**!?\nNo problem!\nTypes are entirely **optional** with ``attrs``.\nSimply assign ``attrs.field()`` to the attributes instead of annotating them with types.\n\n----\n\nThis example uses ``attrs``'s modern APIs that have been introduced in version 20.1.0, and the ``attrs`` package import name that has been added in version 21.3.0.\nThe classic APIs (``@attr.s``, ``attr.ib``, plus their serious business aliases) and the ``attr`` package import name will remain **indefinitely**.\n\nPlease check out `On The Core API Names `_ for a more in-depth explanation.\n\n\nData Classes\n============\n\nOn the tin, ``attrs`` might remind you of ``dataclasses`` (and indeed, ``dataclasses`` are a descendant of ``attrs``).\nIn practice it does a lot more and is more flexible.\nFor instance it allows you to define `special handling of NumPy arrays for equality checks `_, or allows more ways to `plug into the initialization process `_.\n\nFor more details, please refer to our `comparison page `_.\n\n\n.. -getting-help-\n\nGetting Help\n============\n\nPlease use the ``python-attrs`` tag on `Stack Overflow `_ to get help.\n\nAnswering questions of your fellow developers is also a great way to help the project!\n\n\n.. -project-information-\n\nProject Information\n===================\n\n``attrs`` is released under the `MIT `_ license,\nits documentation lives at `Read the Docs `_,\nthe code on `GitHub `_,\nand the latest release on `PyPI `_.\nIt\u2019s rigorously tested on Python 2.7, 3.5+, and PyPy.\n\nWe collect information on **third-party extensions** in our `wiki `_.\nFeel free to browse and add your own!\n\nIf you'd like to contribute to ``attrs`` you're most welcome and we've written `a little guide `_ to get you started!\n\n\n``attrs`` for Enterprise\n------------------------\n\nAvailable as part of the Tidelift Subscription.\n\nThe maintainers of ``attrs`` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications.\nSave time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use.\n`Learn more. `_\n\n\nRelease Information\n===================\n\n21.4.0 (2021-12-29)\n-------------------\n\nChanges\n^^^^^^^\n\n- Fixed the test suite on PyPy3.8 where ``cloudpickle`` does not work.\n `#892 `_\n- Fixed ``coverage report`` for projects that use ``attrs`` and don't set a ``--source``.\n `#895 `_,\n `#896 `_\n\n`Full changelog `_.\n\nCredits\n=======\n\n``attrs`` is written and maintained by `Hynek Schlawack `_.\n\nThe development is kindly supported by `Variomedia AG `_.\n\nA full list of contributors can be found in `GitHub's overview `_.\n\nIt\u2019s the spiritual successor of `characteristic `_ and aspires to fix some of it clunkiness and unfortunate decisions.\nBoth were inspired by Twisted\u2019s `FancyEqMixin `_ but both are implemented using class decorators because `subclassing is bad for you `_, m\u2019kay?", - "release_date": "2021-12-29T13:15:09", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Hynek Schlawack", - "email": "hs@ox.cx", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Hynek Schlawack", - "email": "hs@ox.cx", - "url": null - } - ], - "keywords": [ - "class", - "attribute", - "boilerplate", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Natural Language :: English", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "https://www.attrs.org/", - "download_url": "https://files.pythonhosted.org/packages/d7/77/ebb15fc26d0f815839ecd897b919ed6d85c050feeb83e100e020df9153d2/attrs-21.4.0.tar.gz", - "size": 201839, - "sha1": null, - "md5": "5a9b5e9ceebc380a13fb93235b11bbda", - "sha256": "626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd", - "sha512": null, - "bug_tracking_url": "https://github.com/python-attrs/attrs/issues", - "code_view_url": "https://github.com/python-attrs/attrs", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/attrs/21.4.0/json", - "datasource_id": null, - "purl": "pkg:pypi/attrs@21.4.0" - }, { "type": "pypi", "namespace": null, @@ -1829,64 +1680,6 @@ "datasource_id": null, "purl": "pkg:pypi/beautifulsoup4@4.11.1" }, - { - "type": "pypi", - "namespace": null, - "name": "beautifulsoup4", - "version": "4.11.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Screen-scraping library\nBeautiful Soup is a library that makes it easy to scrape information\nfrom web pages. It sits atop an HTML or XML parser, providing Pythonic\nidioms for iterating, searching, and modifying the parse tree.\n\n# Quick start\n\n```\n>>> from bs4 import BeautifulSoup\n>>> soup = BeautifulSoup(\"

SomebadHTML\")\n>>> print(soup.prettify())\n\n \n

\n Some\n \n bad\n \n HTML\n \n \n

\n \n\n>>> soup.find(text=\"bad\")\n'bad'\n>>> soup.i\nHTML\n#\n>>> soup = BeautifulSoup(\"SomebadXML\", \"xml\")\n#\n>>> print(soup.prettify())\n\n\n Some\n \n bad\n \n XML\n \n\n```\n\nTo go beyond the basics, [comprehensive documentation is available](https://www.crummy.com/software/BeautifulSoup/bs4/doc/).\n\n# Links\n\n* [Homepage](https://www.crummy.com/software/BeautifulSoup/bs4/)\n* [Documentation](https://www.crummy.com/software/BeautifulSoup/bs4/doc/)\n* [Discussion group](https://groups.google.com/group/beautifulsoup/)\n* [Development](https://code.launchpad.net/beautifulsoup/)\n* [Bug tracker](https://bugs.launchpad.net/beautifulsoup/)\n* [Complete changelog](https://bazaar.launchpad.net/~leonardr/beautifulsoup/bs4/view/head:/CHANGELOG)\n\n# Note on Python 2 sunsetting\n\nBeautiful Soup's support for Python 2 was discontinued on December 31,\n2020: one year after the sunset date for Python 2 itself. From this\npoint onward, new Beautiful Soup development will exclusively target\nPython 3. The final release of Beautiful Soup 4 to support Python 2\nwas 4.9.3.\n\n# Supporting the project\n\nIf you use Beautiful Soup as part of your professional work, please consider a\n[Tidelift subscription](https://tidelift.com/subscription/pkg/pypi-beautifulsoup4?utm_source=pypi-beautifulsoup4&utm_medium=referral&utm_campaign=readme).\nThis will support many of the free software projects your organization\ndepends on, not just Beautiful Soup.\n\nIf you use Beautiful Soup for personal projects, the best way to say\nthank you is to read\n[Tool Safety](https://www.crummy.com/software/BeautifulSoup/zine/), a zine I\nwrote about what Beautiful Soup has taught me about software\ndevelopment.\n\n# Building the documentation\n\nThe bs4/doc/ directory contains full documentation in Sphinx\nformat. Run `make html` in that directory to create HTML\ndocumentation.\n\n# Running the unit tests\n\nBeautiful Soup supports unit test discovery using Pytest:\n\n```\n$ pytest\n```", - "release_date": "2022-04-08T21:22:48", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Leonard Richardson", - "email": "leonardr@segfault.org", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Text Processing :: Markup :: HTML", - "Topic :: Text Processing :: Markup :: SGML", - "Topic :: Text Processing :: Markup :: XML" - ], - "homepage_url": "https://www.crummy.com/software/BeautifulSoup/bs4/", - "download_url": "https://files.pythonhosted.org/packages/e8/b0/cd2b968000577ec5ce6c741a54d846dfa402372369b8b6861720aa9ecea7/beautifulsoup4-4.11.1.tar.gz", - "size": 517113, - "sha1": null, - "md5": "22f22f89cf9da41b22e1ece9639c66a3", - "sha256": "ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/beautifulsoup4/4.11.1/json", - "datasource_id": null, - "purl": "pkg:pypi/beautifulsoup4@4.11.1" - }, { "type": "pypi", "namespace": null, @@ -1951,70 +1744,6 @@ "datasource_id": null, "purl": "pkg:pypi/black@22.3.0" }, - { - "type": "pypi", - "namespace": null, - "name": "black", - "version": "22.3.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "The uncompromising code formatter.\n![Black Logo](https://raw.githubusercontent.com/psf/black/main/docs/_static/logo2-readme.png)\n\n

The Uncompromising Code Formatter

\n\n

\n\"Actions\n\"Documentation\n\"Coverage\n\"License:\n\"PyPI\"\n\"Downloads\"\n\"conda-forge\"\n\"Code\n

\n\n> \u201cAny color you like.\u201d\n\n_Black_ is the uncompromising Python code formatter. By using it, you agree to cede\ncontrol over minutiae of hand-formatting. In return, _Black_ gives you speed,\ndeterminism, and freedom from `pycodestyle` nagging about formatting. You will save time\nand mental energy for more important matters.\n\nBlackened code looks the same regardless of the project you're reading. Formatting\nbecomes transparent after a while and you can focus on the content instead.\n\n_Black_ makes code review faster by producing the smallest diffs possible.\n\nTry it out now using the [Black Playground](https://black.vercel.app). Watch the\n[PyCon 2019 talk](https://youtu.be/esZLCuWs_2Y) to learn more.\n\n---\n\n**[Read the documentation on ReadTheDocs!](https://black.readthedocs.io/en/stable)**\n\n---\n\n## Installation and usage\n\n### Installation\n\n_Black_ can be installed by running `pip install black`. It requires Python 3.6.2+ to\nrun. If you want to format Jupyter Notebooks, install with `pip install black[jupyter]`.\n\nIf you can't wait for the latest _hotness_ and want to install from GitHub, use:\n\n`pip install git+https://github.com/psf/black`\n\n### Usage\n\nTo get started right away with sensible defaults:\n\n```sh\nblack {source_file_or_directory}\n```\n\nYou can run _Black_ as a package if running it as a script doesn't work:\n\n```sh\npython -m black {source_file_or_directory}\n```\n\nFurther information can be found in our docs:\n\n- [Usage and Configuration](https://black.readthedocs.io/en/stable/usage_and_configuration/index.html)\n\n_Black_ is already [successfully used](https://github.com/psf/black#used-by) by many\nprojects, small and big. _Black_ has a comprehensive test suite, with efficient parallel\ntests, and our own auto formatting and parallel Continuous Integration runner. Now that\nwe have become stable, you should not expect large formatting to changes in the future.\nStylistic changes will mostly be responses to bug reports and support for new Python\nsyntax. For more information please refer to the\n[The Black Code Style](docs/the_black_code_style/index.rst).\n\nAlso, as a safety measure which slows down processing, _Black_ will check that the\nreformatted code still produces a valid AST that is effectively equivalent to the\noriginal (see the\n[Pragmatism](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#ast-before-and-after-formatting)\nsection for details). If you're feeling confident, use `--fast`.\n\n## The _Black_ code style\n\n_Black_ is a PEP 8 compliant opinionated formatter. _Black_ reformats entire files in\nplace. Style configuration options are deliberately limited and rarely added. It doesn't\ntake previous formatting into account (see\n[Pragmatism](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#pragmatism)\nfor exceptions).\n\nOur documentation covers the current _Black_ code style, but planned changes to it are\nalso documented. They're both worth taking a look:\n\n- [The _Black_ Code Style: Current style](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html)\n- [The _Black_ Code Style: Future style](https://black.readthedocs.io/en/stable/the_black_code_style/future_style.html)\n\nChanges to the _Black_ code style are bound by the Stability Policy:\n\n- [The _Black_ Code Style: Stability Policy](https://black.readthedocs.io/en/stable/the_black_code_style/index.html#stability-policy)\n\nPlease refer to this document before submitting an issue. What seems like a bug might be\nintended behaviour.\n\n### Pragmatism\n\nEarly versions of _Black_ used to be absolutist in some respects. They took after its\ninitial author. This was fine at the time as it made the implementation simpler and\nthere were not many users anyway. Not many edge cases were reported. As a mature tool,\n_Black_ does make some exceptions to rules it otherwise holds.\n\n- [The _Black_ code style: Pragmatism](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#pragmatism)\n\nPlease refer to this document before submitting an issue just like with the document\nabove. What seems like a bug might be intended behaviour.\n\n## Configuration\n\n_Black_ is able to read project-specific default values for its command line options\nfrom a `pyproject.toml` file. This is especially useful for specifying custom\n`--include` and `--exclude`/`--force-exclude`/`--extend-exclude` patterns for your\nproject.\n\nYou can find more details in our documentation:\n\n- [The basics: Configuration via a file](https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file)\n\nAnd if you're looking for more general configuration documentation:\n\n- [Usage and Configuration](https://black.readthedocs.io/en/stable/usage_and_configuration/index.html)\n\n**Pro-tip**: If you're asking yourself \"Do I need to configure anything?\" the answer is\n\"No\". _Black_ is all about sensible defaults. Applying those defaults will have your\ncode in compliance with many other _Black_ formatted projects.\n\n## Used by\n\nThe following notable open-source projects trust _Black_ with enforcing a consistent\ncode style: pytest, tox, Pyramid, Django, Django Channels, Hypothesis, attrs,\nSQLAlchemy, Poetry, PyPA applications (Warehouse, Bandersnatch, Pipenv, virtualenv),\npandas, Pillow, Twisted, LocalStack, every Datadog Agent Integration, Home Assistant,\nZulip, Kedro, OpenOA, FLORIS, ORBIT, WOMBAT, and many more.\n\nThe following organizations use _Black_: Facebook, Dropbox, KeepTruckin, Mozilla, Quora,\nDuolingo, QuantumBlack, Tesla.\n\nAre we missing anyone? Let us know.\n\n## Testimonials\n\n**Mike Bayer**, [author of `SQLAlchemy`](https://www.sqlalchemy.org/):\n\n> I can't think of any single tool in my entire programming career that has given me a\n> bigger productivity increase by its introduction. I can now do refactorings in about\n> 1% of the keystrokes that it would have taken me previously when we had no way for\n> code to format itself.\n\n**Dusty Phillips**,\n[writer](https://smile.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=dusty+phillips):\n\n> _Black_ is opinionated so you don't have to be.\n\n**Hynek Schlawack**, [creator of `attrs`](https://www.attrs.org/), core developer of\nTwisted and CPython:\n\n> An auto-formatter that doesn't suck is all I want for Xmas!\n\n**Carl Meyer**, [Django](https://www.djangoproject.com/) core developer:\n\n> At least the name is good.\n\n**Kenneth Reitz**, creator of [`requests`](http://python-requests.org/) and\n[`pipenv`](https://readthedocs.org/projects/pipenv/):\n\n> This vastly improves the formatting of our code. Thanks a ton!\n\n## Show your style\n\nUse the badge in your project's README.md:\n\n```md\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n```\n\nUsing the badge in README.rst:\n\n```\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n```\n\nLooks like this:\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\n## License\n\nMIT\n\n## Contributing\n\nWelcome! Happy to see you willing to make the project better. You can get started by\nreading this:\n\n- [Contributing: The basics](https://black.readthedocs.io/en/latest/contributing/the_basics.html)\n\nYou can also take a look at the rest of the contributing docs or talk with the\ndevelopers:\n\n- [Contributing documentation](https://black.readthedocs.io/en/latest/contributing/index.html)\n- [Chat on Discord](https://discord.gg/RtVdv86PrH)\n\n## Change log\n\nThe log has become rather long. It moved to its own file.\n\nSee [CHANGES](https://black.readthedocs.io/en/latest/change_log.html).\n\n## Authors\n\nThe author list is quite long nowadays, so it lives in its own file.\n\nSee [AUTHORS.md](./AUTHORS.md)\n\n## Code of Conduct\n\nEveryone participating in the _Black_ project, and in particular in the issue tracker,\npull requests, and social media activity, is expected to treat other people with respect\nand more generally to follow the guidelines articulated in the\n[Python Community Code of Conduct](https://www.python.org/psf/codeofconduct/).\n\nAt the same time, humor is encouraged. In fact, basic familiarity with Monty Python's\nFlying Circus is expected. We are not savages.\n\nAnd if you _really_ need to slap somebody, do it with a fish while dancing.\n\n\n# Change Log\n\n## Unreleased\n\n### Highlights\n\n\n\n### Style\n\n\n\n### Preview style\n\n\n\n### _Blackd_\n\n\n\n### Configuration\n\n\n\n### Documentation\n\n\n\n### Integrations\n\n\n\n### Output\n\n\n\n### Packaging\n\n\n\n### Parser\n\n\n\n### Performance\n\n\n\n## 22.3.0\n\n### Preview style\n\n- Code cell separators `#%%` are now standardised to `# %%` (#2919)\n- Remove unnecessary parentheses from `except` statements (#2939)\n- Remove unnecessary parentheses from tuple unpacking in `for` loops (#2945)\n- Avoid magic-trailing-comma in single-element subscripts (#2942)\n\n### Configuration\n\n- Do not format `__pypackages__` directories by default (#2836)\n- Add support for specifying stable version with `--required-version` (#2832).\n- Avoid crashing when the user has no homedir (#2814)\n- Avoid crashing when md5 is not available (#2905)\n- Fix handling of directory junctions on Windows (#2904)\n\n### Documentation\n\n- Update pylint config documentation (#2931)\n\n### Integrations\n\n- Move test to disable plugin in Vim/Neovim, which speeds up loading (#2896)\n\n### Output\n\n- In verbose, mode, log when _Black_ is using user-level config (#2861)\n\n### Packaging\n\n- Fix Black to work with Click 8.1.0 (#2966)\n- On Python 3.11 and newer, use the standard library's `tomllib` instead of `tomli`\n (#2903)\n- `black-primer`, the deprecated internal devtool, has been removed and copied to a\n [separate repository](https://github.com/cooperlees/black-primer) (#2924)\n\n### Parser\n\n- Black can now parse starred expressions in the target of `for` and `async for`\n statements, e.g `for item in *items_1, *items_2: pass` (#2879).\n\n## 22.1.0\n\nAt long last, _Black_ is no longer a beta product! This is the first non-beta release\nand the first release covered by our new\n[stability policy](https://black.readthedocs.io/en/stable/the_black_code_style/index.html#stability-policy).\n\n### Highlights\n\n- **Remove Python 2 support** (#2740)\n- Introduce the `--preview` flag (#2752)\n\n### Style\n\n- Deprecate `--experimental-string-processing` and move the functionality under\n `--preview` (#2789)\n- For stubs, one blank line between class attributes and methods is now kept if there's\n at least one pre-existing blank line (#2736)\n- Black now normalizes string prefix order (#2297)\n- Remove spaces around power operators if both operands are simple (#2726)\n- Work around bug that causes unstable formatting in some cases in the presence of the\n magic trailing comma (#2807)\n- Use parentheses for attribute access on decimal float and int literals (#2799)\n- Don't add whitespace for attribute access on hexadecimal, binary, octal, and complex\n literals (#2799)\n- Treat blank lines in stubs the same inside top-level `if` statements (#2820)\n- Fix unstable formatting with semicolons and arithmetic expressions (#2817)\n- Fix unstable formatting around magic trailing comma (#2572)\n\n### Parser\n\n- Fix mapping cases that contain as-expressions, like `case {\"key\": 1 | 2 as password}`\n (#2686)\n- Fix cases that contain multiple top-level as-expressions, like `case 1 as a, 2 as b`\n (#2716)\n- Fix call patterns that contain as-expressions with keyword arguments, like\n `case Foo(bar=baz as quux)` (#2749)\n- Tuple unpacking on `return` and `yield` constructs now implies 3.8+ (#2700)\n- Unparenthesized tuples on annotated assignments (e.g\n `values: Tuple[int, ...] = 1, 2, 3`) now implies 3.8+ (#2708)\n- Fix handling of standalone `match()` or `case()` when there is a trailing newline or a\n comment inside of the parentheses. (#2760)\n- `from __future__ import annotations` statement now implies Python 3.7+ (#2690)\n\n### Performance\n\n- Speed-up the new backtracking parser about 4X in general (enabled when\n `--target-version` is set to 3.10 and higher). (#2728)\n- _Black_ is now compiled with [mypyc](https://github.com/mypyc/mypyc) for an overall 2x\n speed-up. 64-bit Windows, MacOS, and Linux (not including musl) are supported. (#1009,\n #2431)\n\n### Configuration\n\n- Do not accept bare carriage return line endings in pyproject.toml (#2408)\n- Add configuration option (`python-cell-magics`) to format cells with custom magics in\n Jupyter Notebooks (#2744)\n- Allow setting custom cache directory on all platforms with environment variable\n `BLACK_CACHE_DIR` (#2739).\n- Enable Python 3.10+ by default, without any extra need to specify\n `--target-version=py310`. (#2758)\n- Make passing `SRC` or `--code` mandatory and mutually exclusive (#2804)\n\n### Output\n\n- Improve error message for invalid regular expression (#2678)\n- Improve error message when parsing fails during AST safety check by embedding the\n underlying SyntaxError (#2693)\n- No longer color diff headers white as it's unreadable in light themed terminals\n (#2691)\n- Text coloring added in the final statistics (#2712)\n- Verbose mode also now describes how a project root was discovered and which paths will\n be formatted. (#2526)\n\n### Packaging\n\n- All upper version bounds on dependencies have been removed (#2718)\n- `typing-extensions` is no longer a required dependency in Python 3.10+ (#2772)\n- Set `click` lower bound to `8.0.0` (#2791)\n\n### Integrations\n\n- Update GitHub action to support containerized runs (#2748)\n\n### Documentation\n\n- Change protocol in pip installation instructions to `https://` (#2761)\n- Change HTML theme to Furo primarily for its responsive design and mobile support\n (#2793)\n- Deprecate the `black-primer` tool (#2809)\n- Document Python support policy (#2819)\n\n## 21.12b0\n\n### _Black_\n\n- Fix determination of f-string expression spans (#2654)\n- Fix bad formatting of error messages about EOF in multi-line statements (#2343)\n- Functions and classes in blocks now have more consistent surrounding spacing (#2472)\n\n#### Jupyter Notebook support\n\n- Cell magics are now only processed if they are known Python cell magics. Earlier, all\n cell magics were tokenized, leading to possible indentation errors e.g. with\n `%%writefile`. (#2630)\n- Fix assignment to environment variables in Jupyter Notebooks (#2642)\n\n#### Python 3.10 support\n\n- Point users to using `--target-version py310` if we detect 3.10-only syntax (#2668)\n- Fix `match` statements with open sequence subjects, like `match a, b:` or\n `match a, *b:` (#2639) (#2659)\n- Fix `match`/`case` statements that contain `match`/`case` soft keywords multiple\n times, like `match re.match()` (#2661)\n- Fix `case` statements with an inline body (#2665)\n- Fix styling of starred expressions inside `match` subject (#2667)\n- Fix parser error location on invalid syntax in a `match` statement (#2649)\n- Fix Python 3.10 support on platforms without ProcessPoolExecutor (#2631)\n- Improve parsing performance on code that uses `match` under `--target-version py310`\n up to ~50% (#2670)\n\n### Packaging\n\n- Remove dependency on `regex` (#2644) (#2663)\n\n## 21.11b1\n\n### _Black_\n\n- Bumped regex version minimum to 2021.4.4 to fix Pattern class usage (#2621)\n\n## 21.11b0\n\n### _Black_\n\n- Warn about Python 2 deprecation in more cases by improving Python 2 only syntax\n detection (#2592)\n- Add experimental PyPy support (#2559)\n- Add partial support for the match statement. As it's experimental, it's only enabled\n when `--target-version py310` is explicitly specified (#2586)\n- Add support for parenthesized with (#2586)\n- Declare support for Python 3.10 for running Black (#2562)\n\n### Integrations\n\n- Fixed vim plugin with Python 3.10 by removing deprecated distutils import (#2610)\n- The vim plugin now parses `skip_magic_trailing_comma` from pyproject.toml (#2613)\n\n## 21.10b0\n\n### _Black_\n\n- Document stability policy, that will apply for non-beta releases (#2529)\n- Add new `--workers` parameter (#2514)\n- Fixed feature detection for positional-only arguments in lambdas (#2532)\n- Bumped typed-ast version minimum to 1.4.3 for 3.10 compatibility (#2519)\n- Fixed a Python 3.10 compatibility issue where the loop argument was still being passed\n even though it has been removed (#2580)\n- Deprecate Python 2 formatting support (#2523)\n\n### _Blackd_\n\n- Remove dependency on aiohttp-cors (#2500)\n- Bump required aiohttp version to 3.7.4 (#2509)\n\n### _Black-Primer_\n\n- Add primer support for --projects (#2555)\n- Print primer summary after individual failures (#2570)\n\n### Integrations\n\n- Allow to pass `target_version` in the vim plugin (#1319)\n- Install build tools in docker file and use multi-stage build to keep the image size\n down (#2582)\n\n## 21.9b0\n\n### Packaging\n\n- Fix missing modules in self-contained binaries (#2466)\n- Fix missing toml extra used during installation (#2475)\n\n## 21.8b0\n\n### _Black_\n\n- Add support for formatting Jupyter Notebook files (#2357)\n- Move from `appdirs` dependency to `platformdirs` (#2375)\n- Present a more user-friendly error if .gitignore is invalid (#2414)\n- The failsafe for accidentally added backslashes in f-string expressions has been\n hardened to handle more edge cases during quote normalization (#2437)\n- Avoid changing a function return type annotation's type to a tuple by adding a\n trailing comma (#2384)\n- Parsing support has been added for unparenthesized walruses in set literals, set\n comprehensions, and indices (#2447).\n- Pin `setuptools-scm` build-time dependency version (#2457)\n- Exclude typing-extensions version 3.10.0.1 due to it being broken on Python 3.10\n (#2460)\n\n### _Blackd_\n\n- Replace sys.exit(-1) with raise ImportError as it plays more nicely with tools that\n scan installed packages (#2440)\n\n### Integrations\n\n- The provided pre-commit hooks no longer specify `language_version` to avoid overriding\n `default_language_version` (#2430)\n\n## 21.7b0\n\n### _Black_\n\n- Configuration files using TOML features higher than spec v0.5.0 are now supported\n (#2301)\n- Add primer support and test for code piped into black via STDIN (#2315)\n- Fix internal error when `FORCE_OPTIONAL_PARENTHESES` feature is enabled (#2332)\n- Accept empty stdin (#2346)\n- Provide a more useful error when parsing fails during AST safety checks (#2304)\n\n### Docker\n\n- Add new `latest_release` tag automation to follow latest black release on docker\n images (#2374)\n\n### Integrations\n\n- The vim plugin now searches upwards from the directory containing the current buffer\n instead of the current working directory for pyproject.toml. (#1871)\n- The vim plugin now reads the correct string normalization option in pyproject.toml\n (#1869)\n- The vim plugin no longer crashes Black when there's boolean values in pyproject.toml\n (#1869)\n\n## 21.6b0\n\n### _Black_\n\n- Fix failure caused by `fmt: skip` and indentation (#2281)\n- Account for += assignment when deciding whether to split string (#2312)\n- Correct max string length calculation when there are string operators (#2292)\n- Fixed option usage when using the `--code` flag (#2259)\n- Do not call `uvloop.install()` when _Black_ is used as a library (#2303)\n- Added `--required-version` option to require a specific version to be running (#2300)\n- Fix incorrect custom breakpoint indices when string group contains fake f-strings\n (#2311)\n- Fix regression where `R` prefixes would be lowercased for docstrings (#2285)\n- Fix handling of named escapes (`\\N{...}`) when `--experimental-string-processing` is\n used (#2319)\n\n### Integrations\n\n- The official Black action now supports choosing what version to use, and supports the\n major 3 OSes. (#1940)\n\n## 21.5b2\n\n### _Black_\n\n- A space is no longer inserted into empty docstrings (#2249)\n- Fix handling of .gitignore files containing non-ASCII characters on Windows (#2229)\n- Respect `.gitignore` files in all levels, not only `root/.gitignore` file (apply\n `.gitignore` rules like `git` does) (#2225)\n- Restored compatibility with Click 8.0 on Python 3.6 when LANG=C used (#2227)\n- Add extra uvloop install + import support if in python env (#2258)\n- Fix --experimental-string-processing crash when matching parens are not found (#2283)\n- Make sure to split lines that start with a string operator (#2286)\n- Fix regular expression that black uses to identify f-expressions (#2287)\n\n### _Blackd_\n\n- Add a lower bound for the `aiohttp-cors` dependency. Only 0.4.0 or higher is\n supported. (#2231)\n\n### Packaging\n\n- Release self-contained x86_64 MacOS binaries as part of the GitHub release pipeline\n (#2198)\n- Always build binaries with the latest available Python (#2260)\n\n### Documentation\n\n- Add discussion of magic comments to FAQ page (#2272)\n- `--experimental-string-processing` will be enabled by default in the future (#2273)\n- Fix typos discovered by codespell (#2228)\n- Fix Vim plugin installation instructions. (#2235)\n- Add new Frequently Asked Questions page (#2247)\n- Fix encoding + symlink issues preventing proper build on Windows (#2262)\n\n## 21.5b1\n\n### _Black_\n\n- Refactor `src/black/__init__.py` into many files (#2206)\n\n### Documentation\n\n- Replaced all remaining references to the\n [`master`](https://github.com/psf/black/tree/main) branch with the\n [`main`](https://github.com/psf/black/tree/main) branch. Some additional changes in\n the source code were also made. (#2210)\n- Sigificantly reorganized the documentation to make much more sense. Check them out by\n heading over to [the stable docs on RTD](https://black.readthedocs.io/en/stable/).\n (#2174)\n\n## 21.5b0\n\n### _Black_\n\n- Set `--pyi` mode if `--stdin-filename` ends in `.pyi` (#2169)\n- Stop detecting target version as Python 3.9+ with pre-PEP-614 decorators that are\n being called but with no arguments (#2182)\n\n### _Black-Primer_\n\n- Add `--no-diff` to black-primer to suppress formatting changes (#2187)\n\n## 21.4b2\n\n### _Black_\n\n- Fix crash if the user configuration directory is inaccessible. (#2158)\n\n- Clarify\n [circumstances](https://github.com/psf/black/blob/master/docs/the_black_code_style.md#pragmatism)\n in which _Black_ may change the AST (#2159)\n\n- Allow `.gitignore` rules to be overridden by specifying `exclude` in `pyproject.toml`\n or on the command line. (#2170)\n\n### _Packaging_\n\n- Install `primer.json` (used by `black-primer` by default) with black. (#2154)\n\n## 21.4b1\n\n### _Black_\n\n- Fix crash on docstrings ending with \"\\\\ \". (#2142)\n\n- Fix crash when atypical whitespace is cleaned out of dostrings (#2120)\n\n- Reflect the `--skip-magic-trailing-comma` and `--experimental-string-processing` flags\n in the name of the cache file. Without this fix, changes in these flags would not take\n effect if the cache had already been populated. (#2131)\n\n- Don't remove necessary parentheses from assignment expression containing assert /\n return statements. (#2143)\n\n### _Packaging_\n\n- Bump pathspec to >= 0.8.1 to solve invalid .gitignore exclusion handling\n\n## 21.4b0\n\n### _Black_\n\n- Fixed a rare but annoying formatting instability created by the combination of\n optional trailing commas inserted by `Black` and optional parentheses looking at\n pre-existing \"magic\" trailing commas. This fixes issue #1629 and all of its many many\n duplicates. (#2126)\n\n- `Black` now processes one-line docstrings by stripping leading and trailing spaces,\n and adding a padding space when needed to break up \"\"\"\". (#1740)\n\n- `Black` now cleans up leading non-breaking spaces in comments (#2092)\n\n- `Black` now respects `--skip-string-normalization` when normalizing multiline\n docstring quotes (#1637)\n\n- `Black` no longer removes all empty lines between non-function code and decorators\n when formatting typing stubs. Now `Black` enforces a single empty line. (#1646)\n\n- `Black` no longer adds an incorrect space after a parenthesized assignment expression\n in if/while statements (#1655)\n\n- Added `--skip-magic-trailing-comma` / `-C` to avoid using trailing commas as a reason\n to split lines (#1824)\n\n- fixed a crash when PWD=/ on POSIX (#1631)\n\n- fixed \"I/O operation on closed file\" when using --diff (#1664)\n\n- Prevent coloured diff output being interleaved with multiple files (#1673)\n\n- Added support for PEP 614 relaxed decorator syntax on python 3.9 (#1711)\n\n- Added parsing support for unparenthesized tuples and yield expressions in annotated\n assignments (#1835)\n\n- added `--extend-exclude` argument (PR #2005)\n\n- speed up caching by avoiding pathlib (#1950)\n\n- `--diff` correctly indicates when a file doesn't end in a newline (#1662)\n\n- Added `--stdin-filename` argument to allow stdin to respect `--force-exclude` rules\n (#1780)\n\n- Lines ending with `fmt: skip` will now be not formatted (#1800)\n\n- PR #2053: Black no longer relies on typed-ast for Python 3.8 and higher\n\n- PR #2053: Python 2 support is now optional, install with\n `python3 -m pip install black[python2]` to maintain support.\n\n- Exclude `venv` directory by default (#1683)\n\n- Fixed \"Black produced code that is not equivalent to the source\" when formatting\n Python 2 docstrings (#2037)\n\n### _Packaging_\n\n- Self-contained native _Black_ binaries are now provided for releases via GitHub\n Releases (#1743)\n\n## 20.8b1\n\n### _Packaging_\n\n- explicitly depend on Click 7.1.2 or newer as `Black` no longer works with versions\n older than 7.0\n\n## 20.8b0\n\n### _Black_\n\n- re-implemented support for explicit trailing commas: now it works consistently within\n any bracket pair, including nested structures (#1288 and duplicates)\n\n- `Black` now reindents docstrings when reindenting code around it (#1053)\n\n- `Black` now shows colored diffs (#1266)\n\n- `Black` is now packaged using 'py3' tagged wheels (#1388)\n\n- `Black` now supports Python 3.8 code, e.g. star expressions in return statements\n (#1121)\n\n- `Black` no longer normalizes capital R-string prefixes as those have a\n community-accepted meaning (#1244)\n\n- `Black` now uses exit code 2 when specified configuration file doesn't exit (#1361)\n\n- `Black` now works on AWS Lambda (#1141)\n\n- added `--force-exclude` argument (#1032)\n\n- removed deprecated `--py36` option (#1236)\n\n- fixed `--diff` output when EOF is encountered (#526)\n\n- fixed `# fmt: off` handling around decorators (#560)\n\n- fixed unstable formatting with some `# type: ignore` comments (#1113)\n\n- fixed invalid removal on organizing brackets followed by indexing (#1575)\n\n- introduced `black-primer`, a CI tool that allows us to run regression tests against\n existing open source users of Black (#1402)\n\n- introduced property-based fuzzing to our test suite based on Hypothesis and\n Hypothersmith (#1566)\n\n- implemented experimental and disabled by default long string rewrapping (#1132),\n hidden under a `--experimental-string-processing` flag while it's being worked on;\n this is an undocumented and unsupported feature, you lose Internet points for\n depending on it (#1609)\n\n### Vim plugin\n\n- prefer virtualenv packages over global packages (#1383)\n\n## 19.10b0\n\n- added support for PEP 572 assignment expressions (#711)\n\n- added support for PEP 570 positional-only arguments (#943)\n\n- added support for async generators (#593)\n\n- added support for pre-splitting collections by putting an explicit trailing comma\n inside (#826)\n\n- added `black -c` as a way to format code passed from the command line (#761)\n\n- --safe now works with Python 2 code (#840)\n\n- fixed grammar selection for Python 2-specific code (#765)\n\n- fixed feature detection for trailing commas in function definitions and call sites\n (#763)\n\n- `# fmt: off`/`# fmt: on` comment pairs placed multiple times within the same block of\n code now behave correctly (#1005)\n\n- _Black_ no longer crashes on Windows machines with more than 61 cores (#838)\n\n- _Black_ no longer crashes on standalone comments prepended with a backslash (#767)\n\n- _Black_ no longer crashes on `from` ... `import` blocks with comments (#829)\n\n- _Black_ no longer crashes on Python 3.7 on some platform configurations (#494)\n\n- _Black_ no longer fails on comments in from-imports (#671)\n\n- _Black_ no longer fails when the file starts with a backslash (#922)\n\n- _Black_ no longer merges regular comments with type comments (#1027)\n\n- _Black_ no longer splits long lines that contain type comments (#997)\n\n- removed unnecessary parentheses around `yield` expressions (#834)\n\n- added parentheses around long tuples in unpacking assignments (#832)\n\n- added parentheses around complex powers when they are prefixed by a unary operator\n (#646)\n\n- fixed bug that led _Black_ format some code with a line length target of 1 (#762)\n\n- _Black_ no longer introduces quotes in f-string subexpressions on string boundaries\n (#863)\n\n- if _Black_ puts parenthesis around a single expression, it moves comments to the\n wrapped expression instead of after the brackets (#872)\n\n- `blackd` now returns the version of _Black_ in the response headers (#1013)\n\n- `blackd` can now output the diff of formats on source code when the `X-Diff` header is\n provided (#969)\n\n## 19.3b0\n\n- new option `--target-version` to control which Python versions _Black_-formatted code\n should target (#618)\n\n- deprecated `--py36` (use `--target-version=py36` instead) (#724)\n\n- _Black_ no longer normalizes numeric literals to include `_` separators (#696)\n\n- long `del` statements are now split into multiple lines (#698)\n\n- type comments are no longer mangled in function signatures\n\n- improved performance of formatting deeply nested data structures (#509)\n\n- _Black_ now properly formats multiple files in parallel on Windows (#632)\n\n- _Black_ now creates cache files atomically which allows it to be used in parallel\n pipelines (like `xargs -P8`) (#673)\n\n- _Black_ now correctly indents comments in files that were previously formatted with\n tabs (#262)\n\n- `blackd` now supports CORS (#622)\n\n## 18.9b0\n\n- numeric literals are now formatted by _Black_ (#452, #461, #464, #469):\n\n - numeric literals are normalized to include `_` separators on Python 3.6+ code\n\n - added `--skip-numeric-underscore-normalization` to disable the above behavior and\n leave numeric underscores as they were in the input\n\n - code with `_` in numeric literals is recognized as Python 3.6+\n\n - most letters in numeric literals are lowercased (e.g., in `1e10`, `0x01`)\n\n - hexadecimal digits are always uppercased (e.g. `0xBADC0DE`)\n\n- added `blackd`, see\n [its documentation](https://github.com/psf/black/blob/18.9b0/README.md#blackd) for\n more info (#349)\n\n- adjacent string literals are now correctly split into multiple lines (#463)\n\n- trailing comma is now added to single imports that don't fit on a line (#250)\n\n- cache is now populated when `--check` is successful for a file which speeds up\n consecutive checks of properly formatted unmodified files (#448)\n\n- whitespace at the beginning of the file is now removed (#399)\n\n- fixed mangling [pweave](http://mpastell.com/pweave/) and\n [Spyder IDE](https://www.spyder-ide.org/) special comments (#532)\n\n- fixed unstable formatting when unpacking big tuples (#267)\n\n- fixed parsing of `__future__` imports with renames (#389)\n\n- fixed scope of `# fmt: off` when directly preceding `yield` and other nodes (#385)\n\n- fixed formatting of lambda expressions with default arguments (#468)\n\n- fixed `async for` statements: _Black_ no longer breaks them into separate lines (#372)\n\n- note: the Vim plugin stopped registering `,=` as a default chord as it turned out to\n be a bad idea (#415)\n\n## 18.6b4\n\n- hotfix: don't freeze when multiple comments directly precede `# fmt: off` (#371)\n\n## 18.6b3\n\n- typing stub files (`.pyi`) now have blank lines added after constants (#340)\n\n- `# fmt: off` and `# fmt: on` are now much more dependable:\n\n - they now work also within bracket pairs (#329)\n\n - they now correctly work across function/class boundaries (#335)\n\n - they now work when an indentation block starts with empty lines or misaligned\n comments (#334)\n\n- made Click not fail on invalid environments; note that Click is right but the\n likelihood we'll need to access non-ASCII file paths when dealing with Python source\n code is low (#277)\n\n- fixed improper formatting of f-strings with quotes inside interpolated expressions\n (#322)\n\n- fixed unnecessary slowdown when long list literals where found in a file\n\n- fixed unnecessary slowdown on AST nodes with very many siblings\n\n- fixed cannibalizing backslashes during string normalization\n\n- fixed a crash due to symbolic links pointing outside of the project directory (#338)\n\n## 18.6b2\n\n- added `--config` (#65)\n\n- added `-h` equivalent to `--help` (#316)\n\n- fixed improper unmodified file caching when `-S` was used\n\n- fixed extra space in string unpacking (#305)\n\n- fixed formatting of empty triple quoted strings (#313)\n\n- fixed unnecessary slowdown in comment placement calculation on lines without comments\n\n## 18.6b1\n\n- hotfix: don't output human-facing information on stdout (#299)\n\n- hotfix: don't output cake emoji on non-zero return code (#300)\n\n## 18.6b0\n\n- added `--include` and `--exclude` (#270)\n\n- added `--skip-string-normalization` (#118)\n\n- added `--verbose` (#283)\n\n- the header output in `--diff` now actually conforms to the unified diff spec\n\n- fixed long trivial assignments being wrapped in unnecessary parentheses (#273)\n\n- fixed unnecessary parentheses when a line contained multiline strings (#232)\n\n- fixed stdin handling not working correctly if an old version of Click was used (#276)\n\n- _Black_ now preserves line endings when formatting a file in place (#258)\n\n## 18.5b1\n\n- added `--pyi` (#249)\n\n- added `--py36` (#249)\n\n- Python grammar pickle caches are stored with the formatting caches, making _Black_\n work in environments where site-packages is not user-writable (#192)\n\n- _Black_ now enforces a PEP 257 empty line after a class-level docstring (and/or\n fields) and the first method\n\n- fixed invalid code produced when standalone comments were present in a trailer that\n was omitted from line splitting on a large expression (#237)\n\n- fixed optional parentheses being removed within `# fmt: off` sections (#224)\n\n- fixed invalid code produced when stars in very long imports were incorrectly wrapped\n in optional parentheses (#234)\n\n- fixed unstable formatting when inline comments were moved around in a trailer that was\n omitted from line splitting on a large expression (#238)\n\n- fixed extra empty line between a class declaration and the first method if no class\n docstring or fields are present (#219)\n\n- fixed extra empty line between a function signature and an inner function or inner\n class (#196)\n\n## 18.5b0\n\n- call chains are now formatted according to the\n [fluent interfaces](https://en.wikipedia.org/wiki/Fluent_interface) style (#67)\n\n- data structure literals (tuples, lists, dictionaries, and sets) are now also always\n exploded like imports when they don't fit in a single line (#152)\n\n- slices are now formatted according to PEP 8 (#178)\n\n- parentheses are now also managed automatically on the right-hand side of assignments\n and return statements (#140)\n\n- math operators now use their respective priorities for delimiting multiline\n expressions (#148)\n\n- optional parentheses are now omitted on expressions that start or end with a bracket\n and only contain a single operator (#177)\n\n- empty parentheses in a class definition are now removed (#145, #180)\n\n- string prefixes are now standardized to lowercase and `u` is removed on Python 3.6+\n only code and Python 2.7+ code with the `unicode_literals` future import (#188, #198,\n #199)\n\n- typing stub files (`.pyi`) are now formatted in a style that is consistent with PEP\n 484 (#207, #210)\n\n- progress when reformatting many files is now reported incrementally\n\n- fixed trailers (content with brackets) being unnecessarily exploded into their own\n lines after a dedented closing bracket (#119)\n\n- fixed an invalid trailing comma sometimes left in imports (#185)\n\n- fixed non-deterministic formatting when multiple pairs of removable parentheses were\n used (#183)\n\n- fixed multiline strings being unnecessarily wrapped in optional parentheses in long\n assignments (#215)\n\n- fixed not splitting long from-imports with only a single name\n\n- fixed Python 3.6+ file discovery by also looking at function calls with unpacking.\n This fixed non-deterministic formatting if trailing commas where used both in function\n signatures with stars and function calls with stars but the former would be\n reformatted to a single line.\n\n- fixed crash on dealing with optional parentheses (#193)\n\n- fixed \"is\", \"is not\", \"in\", and \"not in\" not considered operators for splitting\n purposes\n\n- fixed crash when dead symlinks where encountered\n\n## 18.4a4\n\n- don't populate the cache on `--check` (#175)\n\n## 18.4a3\n\n- added a \"cache\"; files already reformatted that haven't changed on disk won't be\n reformatted again (#109)\n\n- `--check` and `--diff` are no longer mutually exclusive (#149)\n\n- generalized star expression handling, including double stars; this fixes\n multiplication making expressions \"unsafe\" for trailing commas (#132)\n\n- _Black_ no longer enforces putting empty lines behind control flow statements (#90)\n\n- _Black_ now splits imports like \"Mode 3 + trailing comma\" of isort (#127)\n\n- fixed comment indentation when a standalone comment closes a block (#16, #32)\n\n- fixed standalone comments receiving extra empty lines if immediately preceding a\n class, def, or decorator (#56, #154)\n\n- fixed `--diff` not showing entire path (#130)\n\n- fixed parsing of complex expressions after star and double stars in function calls\n (#2)\n\n- fixed invalid splitting on comma in lambda arguments (#133)\n\n- fixed missing splits of ternary expressions (#141)\n\n## 18.4a2\n\n- fixed parsing of unaligned standalone comments (#99, #112)\n\n- fixed placement of dictionary unpacking inside dictionary literals (#111)\n\n- Vim plugin now works on Windows, too\n\n- fixed unstable formatting when encountering unnecessarily escaped quotes in a string\n (#120)\n\n## 18.4a1\n\n- added `--quiet` (#78)\n\n- added automatic parentheses management (#4)\n\n- added [pre-commit](https://pre-commit.com) integration (#103, #104)\n\n- fixed reporting on `--check` with multiple files (#101, #102)\n\n- fixed removing backslash escapes from raw strings (#100, #105)\n\n## 18.4a0\n\n- added `--diff` (#87)\n\n- add line breaks before all delimiters, except in cases like commas, to better comply\n with PEP 8 (#73)\n\n- standardize string literals to use double quotes (almost) everywhere (#75)\n\n- fixed handling of standalone comments within nested bracketed expressions; _Black_\n will no longer produce super long lines or put all standalone comments at the end of\n the expression (#22)\n\n- fixed 18.3a4 regression: don't crash and burn on empty lines with trailing whitespace\n (#80)\n\n- fixed 18.3a4 regression: `# yapf: disable` usage as trailing comment would cause\n _Black_ to not emit the rest of the file (#95)\n\n- when CTRL+C is pressed while formatting many files, _Black_ no longer freaks out with\n a flurry of asyncio-related exceptions\n\n- only allow up to two empty lines on module level and only single empty lines within\n functions (#74)\n\n## 18.3a4\n\n- `# fmt: off` and `# fmt: on` are implemented (#5)\n\n- automatic detection of deprecated Python 2 forms of print statements and exec\n statements in the formatted file (#49)\n\n- use proper spaces for complex expressions in default values of typed function\n arguments (#60)\n\n- only return exit code 1 when --check is used (#50)\n\n- don't remove single trailing commas from square bracket indexing (#59)\n\n- don't omit whitespace if the previous factor leaf wasn't a math operator (#55)\n\n- omit extra space in kwarg unpacking if it's the first argument (#46)\n\n- omit extra space in\n [Sphinx auto-attribute comments](http://www.sphinx-doc.org/en/stable/ext/autodoc.html#directive-autoattribute)\n (#68)\n\n## 18.3a3\n\n- don't remove single empty lines outside of bracketed expressions (#19)\n\n- added ability to pipe formatting from stdin to stdin (#25)\n\n- restored ability to format code with legacy usage of `async` as a name (#20, #42)\n\n- even better handling of numpy-style array indexing (#33, again)\n\n## 18.3a2\n\n- changed positioning of binary operators to occur at beginning of lines instead of at\n the end, following\n [a recent change to PEP 8](https://github.com/python/peps/commit/c59c4376ad233a62ca4b3a6060c81368bd21e85b)\n (#21)\n\n- ignore empty bracket pairs while splitting. This avoids very weirdly looking\n formattings (#34, #35)\n\n- remove a trailing comma if there is a single argument to a call\n\n- if top level functions were separated by a comment, don't put four empty lines after\n the upper function\n\n- fixed unstable formatting of newlines with imports\n\n- fixed unintentional folding of post scriptum standalone comments into last statement\n if it was a simple statement (#18, #28)\n\n- fixed missing space in numpy-style array indexing (#33)\n\n- fixed spurious space after star-based unary expressions (#31)\n\n## 18.3a1\n\n- added `--check`\n\n- only put trailing commas in function signatures and calls if it's safe to do so. If\n the file is Python 3.6+ it's always safe, otherwise only safe if there are no `*args`\n or `**kwargs` used in the signature or call. (#8)\n\n- fixed invalid spacing of dots in relative imports (#6, #13)\n\n- fixed invalid splitting after comma on unpacked variables in for-loops (#23)\n\n- fixed spurious space in parenthesized set expressions (#7)\n\n- fixed spurious space after opening parentheses and in default arguments (#14, #17)\n\n- fixed spurious space after unary operators when the operand was a complex expression\n (#15)\n\n## 18.3a0\n\n- first published version, Happy \ud83c\udf70 Day 2018!\n\n- alpha quality\n\n- date-versioned (see: )", - "release_date": "2022-03-28T19:10:43", - "parties": [ - { - "type": "person", - "role": "author", - "name": "\u0141ukasz Langa", - "email": "lukasz@langa.pl", - "url": null - } - ], - "keywords": [ - "automation formatter yapf autopep8 pyfmt gofmt rustfmt", - "Development Status :: 5 - Production/Stable", - "Environment :: Console", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Software Development :: Quality Assurance" - ], - "homepage_url": "https://github.com/psf/black", - "download_url": "https://files.pythonhosted.org/packages/ee/1f/b29c7371958ab41a800f8718f5d285bf4333b8d0b5a5a8650234463ee644/black-22.3.0.tar.gz", - "size": 554277, - "sha1": null, - "md5": "1ae8332ebbdc492dcb53c9e8df2ec4f9", - "sha256": "35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/black/22.3.0/json", - "datasource_id": null, - "purl": "pkg:pypi/black@22.3.0" - }, { "type": "pypi", "namespace": null, @@ -2081,71 +1810,8 @@ { "type": "pypi", "namespace": null, - "name": "bleach", - "version": "4.1.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "An easy safelist-based HTML-sanitizing tool.\n======\nBleach\n======\n\n.. image:: https://github.com/mozilla/bleach/workflows/Test/badge.svg\n :target: https://github.com/mozilla/bleach/actions?query=workflow%3ATest\n\n.. image:: https://github.com/mozilla/bleach/workflows/Lint/badge.svg\n :target: https://github.com/mozilla/bleach/actions?query=workflow%3ALint\n\n.. image:: https://badge.fury.io/py/bleach.svg\n :target: http://badge.fury.io/py/bleach\n\nBleach is an allowed-list-based HTML sanitizing library that escapes or strips\nmarkup and attributes.\n\nBleach can also linkify text safely, applying filters that Django's ``urlize``\nfilter cannot, and optionally setting ``rel`` attributes, even on links already\nin the text.\n\nBleach is intended for sanitizing text from *untrusted* sources. If you find\nyourself jumping through hoops to allow your site administrators to do lots of\nthings, you're probably outside the use cases. Either trust those users, or\ndon't.\n\nBecause it relies on html5lib_, Bleach is as good as modern browsers at dealing\nwith weird, quirky HTML fragments. And *any* of Bleach's methods will fix\nunbalanced or mis-nested tags.\n\nThe version on GitHub_ is the most up-to-date and contains the latest bug\nfixes. You can find full documentation on `ReadTheDocs`_.\n\n:Code: https://github.com/mozilla/bleach\n:Documentation: https://bleach.readthedocs.io/\n:Issue tracker: https://github.com/mozilla/bleach/issues\n:License: Apache License v2; see LICENSE file\n\n\nReporting Bugs\n==============\n\nFor regular bugs, please report them `in our issue tracker\n`_.\n\nIf you believe that you've found a security vulnerability, please `file a secure\nbug report in our bug tracker\n`_\nor send an email to *security AT mozilla DOT org*.\n\nFor more information on security-related bug disclosure and the PGP key to use\nfor sending encrypted mail or to verify responses received from that address,\nplease read our wiki page at\n``_.\n\n\nSecurity\n========\n\nBleach is a security-focused library.\n\nWe have a responsible security vulnerability reporting process. Please use\nthat if you're reporting a security issue.\n\nSecurity issues are fixed in private. After we land such a fix, we'll do a\nrelease.\n\nFor every release, we mark security issues we've fixed in the ``CHANGES`` in\nthe **Security issues** section. We include any relevant CVE links.\n\n\nInstalling Bleach\n=================\n\nBleach is available on PyPI_, so you can install it with ``pip``::\n\n $ pip install bleach\n\n\nUpgrading Bleach\n================\n\n.. warning::\n\n Before doing any upgrades, read through `Bleach Changes\n `_ for backwards\n incompatible changes, newer versions, etc.\n\n Bleach follows `semver 2`_ versioning. Vendored libraries will not\n be changed in patch releases.\n\n\nBasic use\n=========\n\nThe simplest way to use Bleach is:\n\n.. code-block:: python\n\n >>> import bleach\n\n >>> bleach.clean('an example')\n u'an <script>evil()</script> example'\n\n >>> bleach.linkify('an http://example.com url')\n u'an http://example.com url'\n\n\nCode of Conduct\n===============\n\nThis project and repository is governed by Mozilla's code of conduct and\netiquette guidelines. For more details please see the `CODE_OF_CONDUCT.md\n`_\n\n\n.. _html5lib: https://github.com/html5lib/html5lib-python\n.. _GitHub: https://github.com/mozilla/bleach\n.. _ReadTheDocs: https://bleach.readthedocs.io/\n.. _PyPI: https://pypi.org/project/bleach/\n.. _semver 2: https://semver.org/\n\n\nBleach changes\n==============\n\nVersion 4.1.0 (August 25th, 2021)\n---------------------------------\n\n**Features**\n\n* Python 3.9 support\n\n**Bug fixes**\n\n* Update sanitizer clean to use vendored 3.6.14 stdlib urllib.parse to\n fix test failures on Python 3.9 #536\n\nVersion 4.0.0 (August 3rd, 2021)\n--------------------------------\n\n**Backwards incompatible changes**\n\n* Drop support for unsupported Python versions <3.6 #520\n\n**Security fixes**\n\nNone\n\n**Features**\n\n* fix attribute name in the linkify docs (thanks @CheesyFeet!)\n\nVersion 3.3.1 (July 14th, 2021)\n-------------------------------\n\n**Security fixes**\n\nNone\n\n**Features**\n\n* add more tests for CVE-2021-23980 / GHSA-vv2x-vrpj-qqpq\n* bump python version to 3.8 for tox doc, vendorverify, and lint targets\n* update bug report template tag\n* update vendorverify script to detect and fail when extra files are vendored\n* update release process docs to check vendorverify passes locally\n\n**Bug fixes**\n\n* remove extra vendored django present in the v3.3.0 whl #595\n* duplicate h1 header doc fix (thanks Nguy\u1ec5n Gia Phong / @McSinyx!)\n\nVersion 3.3.0 (February 1st, 2021)\n----------------------------------\n\n**Backwards incompatible changes**\n\n* clean escapes HTML comments even when strip_comments=False\n\n**Security fixes**\n\n* Fix bug 1621692 / GHSA-m6xf-fq7q-8743. See the advisory for details.\n\n**Features**\n\nNone\n\n**Bug fixes**\n\nNone\n\nVersion 3.2.3 (January 26th, 2021)\n----------------------------------\n\n**Security fixes**\n\nNone\n\n**Features**\n\nNone\n\n**Bug fixes**\n\n* fix clean and linkify raising ValueErrors for certain inputs. Thank you @Google-Autofuzz.\n\nVersion 3.2.2 (January 20th, 2021)\n----------------------------------\n\n**Security fixes**\n\nNone\n\n**Features**\n\n* Migrate CI to Github Actions. Thank you @hugovk.\n\n**Bug fixes**\n\n* fix linkify raising an IndexError on certain inputs. Thank you @Google-Autofuzz.\n\nVersion 3.2.1 (September 18th, 2020)\n------------------------------------\n\n**Security fixes**\n\nNone\n\n**Features**\n\nNone\n\n**Bug fixes**\n\n* change linkifier to add rel=\"nofollow\" as documented. Thank you @mitar.\n* suppress html5lib sanitizer DeprecationWarnings #557\n\nVersion 3.2.0 (September 16th, 2020)\n------------------------------------\n\n**Security fixes**\n\nNone\n\n**Features**\n\nNone\n\n**Bug fixes**\n\n* ``html5lib`` dependency to version 1.1.0. Thank you Sam Sneddon.\n* update tests_website terminology. Thank you Thomas Grainger.\n\nVersion 3.1.5 (April 29th, 2020)\n--------------------------------\n\n**Security fixes**\n\nNone\n\n**Features**\n\nNone\n\n**Bug fixes**\n\n* replace missing ``setuptools`` dependency with ``packaging``. Thank you Benjamin Peterson.\n\nVersion 3.1.4 (March 24th, 2020)\n--------------------------------\n\n**Security fixes**\n\n* ``bleach.clean`` behavior parsing style attributes could result in a\n regular expression denial of service (ReDoS).\n\n Calls to ``bleach.clean`` with an allowed tag with an allowed\n ``style`` attribute were vulnerable to ReDoS. For example,\n ``bleach.clean(..., attributes={'a': ['style']})``.\n\n This issue was confirmed in Bleach versions v3.1.3, v3.1.2, v3.1.1,\n v3.1.0, v3.0.0, v2.1.4, and v2.1.3. Earlier versions used a similar\n regular expression and should be considered vulnerable too.\n\n Anyone using Bleach <=v3.1.3 is encouraged to upgrade.\n\n https://bugzilla.mozilla.org/show_bug.cgi?id=1623633\n\n**Backwards incompatible changes**\n\n* Style attributes with dashes, or single or double quoted values are\n cleaned instead of passed through.\n\n**Features**\n\nNone\n\n**Bug fixes**\n\nNone\n\nVersion 3.1.3 (March 17th, 2020)\n--------------------------------\n\n**Security fixes**\n\nNone\n\n**Backwards incompatible changes**\n\nNone\n\n**Features**\n\n* Add relative link to code of conduct. (#442)\n\n* Drop deprecated 'setup.py test' support. (#507)\n\n* Fix typo: curren -> current in tests/test_clean.py (#504)\n\n* Test on PyPy 7\n\n* Drop test support for end of life Python 3.4\n\n**Bug fixes**\n\nNone\n\nVersion 3.1.2 (March 11th, 2020)\n--------------------------------\n\n**Security fixes**\n\n* ``bleach.clean`` behavior parsing embedded MathML and SVG content\n with RCDATA tags did not match browser behavior and could result in\n a mutation XSS.\n\n Calls to ``bleach.clean`` with ``strip=False`` and ``math`` or\n ``svg`` tags and one or more of the RCDATA tags ``script``,\n ``noscript``, ``style``, ``noframes``, ``iframe``, ``noembed``, or\n ``xmp`` in the allowed tags whitelist were vulnerable to a mutation\n XSS.\n\n This security issue was confirmed in Bleach version v3.1.1. Earlier\n versions are likely affected too.\n\n Anyone using Bleach <=v3.1.1 is encouraged to upgrade.\n\n https://bugzilla.mozilla.org/show_bug.cgi?id=1621692\n\n**Backwards incompatible changes**\n\nNone\n\n**Features**\n\nNone\n\n**Bug fixes**\n\nNone\n\nVersion 3.1.1 (February 13th, 2020)\n-----------------------------------\n\n**Security fixes**\n\n* ``bleach.clean`` behavior parsing ``noscript`` tags did not match\n browser behavior.\n\n Calls to ``bleach.clean`` allowing ``noscript`` and one or more of\n the raw text tags (``title``, ``textarea``, ``script``, ``style``,\n ``noembed``, ``noframes``, ``iframe``, and ``xmp``) were vulnerable\n to a mutation XSS.\n\n This security issue was confirmed in Bleach versions v2.1.4, v3.0.2,\n and v3.1.0. Earlier versions are probably affected too.\n\n Anyone using Bleach <=v3.1.0 is highly encouraged to upgrade.\n\n https://bugzilla.mozilla.org/show_bug.cgi?id=1615315\n\n**Backwards incompatible changes**\n\nNone\n\n**Features**\n\nNone\n\n**Bug fixes**\n\nNone\n\nVersion 3.1.0 (January 9th, 2019)\n---------------------------------\n\n**Security fixes**\n\nNone\n\n**Backwards incompatible changes**\n\nNone\n\n**Features**\n\n* Add ``recognized_tags`` argument to the linkify ``Linker`` class. This\n fixes issues when linkifying on its own and having some tags get escaped.\n It defaults to a list of HTML5 tags. Thank you, Chad Birch! (#409)\n\n**Bug fixes**\n\n* Add ``six>=1.9`` to requirements. Thank you, Dave Shawley (#416)\n\n* Fix cases where attribute names could have invalid characters in them.\n (#419)\n\n* Fix problems with ``LinkifyFilter`` not being able to match links\n across ``&``. (#422)\n\n* Fix ``InputStreamWithMemory`` when the ``BleachHTMLParser`` is\n parsing ``meta`` tags. (#431)\n\n* Fix doctests. (#357)\n\n\nVersion 3.0.2 (October 11th, 2018)\n----------------------------------\n\n**Security fixes**\n\nNone\n\n**Backwards incompatible changes**\n\nNone\n\n**Features**\n\nNone\n\n**Bug fixes**\n\n* Merge ``Characters`` tokens after sanitizing them. This fixes issues in the\n ``LinkifyFilter`` where it was only linkifying parts of urls. (#374)\n\n\nVersion 3.0.1 (October 9th, 2018)\n---------------------------------\n\n**Security fixes**\n\nNone\n\n**Backwards incompatible changes**\n\nNone\n\n**Features**\n\n* Support Python 3.7. It supported Python 3.7 just fine, but we added 3.7 to\n the list of Python environments we test so this is now officially supported.\n (#377)\n\n**Bug fixes**\n\n* Fix ``list`` object has no attribute ``lower`` in ``clean``. (#398)\n* Fix ``abbr`` getting escaped in ``linkify``. (#400)\n\n\nVersion 3.0.0 (October 3rd, 2018)\n---------------------------------\n\n**Security fixes**\n\nNone\n\n**Backwards incompatible changes**\n\n* A bunch of functions were moved from one module to another.\n\n These were moved from ``bleach.sanitizer`` to ``bleach.html5lib_shim``:\n\n * ``convert_entity``\n * ``convert_entities``\n * ``match_entity``\n * ``next_possible_entity``\n * ``BleachHTMLSerializer``\n * ``BleachHTMLTokenizer``\n * ``BleachHTMLParser``\n\n These functions and classes weren't documented and aren't part of the\n public API, but people read code and might be using them so we're\n considering it an incompatible API change.\n\n If you're using them, you'll need to update your code.\n\n**Features**\n\n* Bleach no longer depends on html5lib. html5lib==1.0.1 is now vendored into\n Bleach. You can remove it from your requirements file if none of your other\n requirements require html5lib.\n\n This means Bleach will now work fine with other libraries that depend on\n html5lib regardless of what version of html5lib they require. (#386)\n\n**Bug fixes**\n\n* Fixed tags getting added when using clean or linkify. This was a\n long-standing regression from the Bleach 2.0 rewrite. (#280, #392)\n\n* Fixed ```` getting replaced with a string. Now it gets escaped or\n stripped depending on whether it's in the allowed tags or not. (#279)\n\n\nVersion 2.1.4 (August 16th, 2018)\n---------------------------------\n\n**Security fixes**\n\nNone\n\n**Backwards incompatible changes**\n\n* Dropped support for Python 3.3. (#328)\n\n**Features**\n\nNone\n\n**Bug fixes**\n\n* Handle ambiguous ampersands in correctly. (#359)\n\n\nVersion 2.1.3 (March 5th, 2018)\n-------------------------------\n\n**Security fixes**\n\n* Attributes that have URI values weren't properly sanitized if the\n values contained character entities. Using character entities, it\n was possible to construct a URI value with a scheme that was not\n allowed that would slide through unsanitized.\n\n This security issue was introduced in Bleach 2.1. Anyone using\n Bleach 2.1 is highly encouraged to upgrade.\n\n https://bugzilla.mozilla.org/show_bug.cgi?id=1442745\n\n**Backwards incompatible changes**\n\nNone\n\n**Features**\n\nNone\n\n**Bug fixes**\n\n* Fixed some other edge cases for attribute URI value sanitizing and\n improved testing of this code.\n\n\nVersion 2.1.2 (December 7th, 2017)\n----------------------------------\n\n**Security fixes**\n\nNone\n\n**Backwards incompatible changes**\n\nNone\n\n**Features**\n\nNone\n\n**Bug fixes**\n\n* Support html5lib-python 1.0.1. (#337)\n\n* Add deprecation warning for supporting html5lib-python < 1.0.\n\n* Switch to semver.\n\n\nVersion 2.1.1 (October 2nd, 2017)\n---------------------------------\n\n**Security fixes**\n\nNone\n\n**Backwards incompatible changes**\n\nNone\n\n**Features**\n\nNone\n\n**Bug fixes**\n\n* Fix ``setup.py`` opening files when ``LANG=``. (#324)\n\n\nVersion 2.1 (September 28th, 2017)\n----------------------------------\n\n**Security fixes**\n\n* Convert control characters (backspace particularly) to \"?\" preventing\n malicious copy-and-paste situations. (#298)\n\n See ``_ for more details.\n\n This affects all previous versions of Bleach. Check the comments on that\n issue for ways to alleviate the issue if you can't upgrade to Bleach 2.1.\n\n\n**Backwards incompatible changes**\n\n* Redid versioning. ``bleach.VERSION`` is no longer available. Use the string\n version at ``bleach.__version__`` and parse it with\n ``pkg_resources.parse_version``. (#307)\n\n* clean, linkify: linkify and clean should only accept text types; thank you,\n Janusz! (#292)\n\n* clean, linkify: accept only unicode or utf-8-encoded str (#176)\n\n\n**Features**\n\n\n**Bug fixes**\n\n* ``bleach.clean()`` no longer unescapes entities including ones that are missing\n a ``;`` at the end which can happen in urls and other places. (#143)\n\n* linkify: fix http links inside of mailto links; thank you, sedrubal! (#300)\n\n* clarify security policy in docs (#303)\n\n* fix dependency specification for html5lib 1.0b8, 1.0b9, and 1.0b10; thank you,\n Zolt\u00e1n! (#268)\n\n* add Bleach vs. html5lib comparison to README; thank you, Stu Cox! (#278)\n\n* fix KeyError exceptions on tags without href attr; thank you, Alex Defsen!\n (#273)\n\n* add test website and scripts to test ``bleach.clean()`` output in browser;\n thank you, Greg Guthe!\n\n\nVersion 2.0 (March 8th, 2017)\n-----------------------------\n\n**Security fixes**\n\n* None\n\n\n**Backwards incompatible changes**\n\n* Removed support for Python 2.6. #206\n\n* Removed support for Python 3.2. #224\n\n* Bleach no longer supports html5lib < 0.99999999 (8 9s).\n\n This version is a rewrite to use the new sanitizing API since the old\n one was dropped in html5lib 0.99999999 (8 9s).\n\n If you're using 0.9999999 (7 9s) upgrade to 0.99999999 (8 9s) or higher.\n\n If you're using 1.0b8 (equivalent to 0.9999999 (7 9s)), upgrade to 1.0b9\n (equivalent to 0.99999999 (8 9s)) or higher.\n\n* ``bleach.clean`` and friends were rewritten\n\n ``clean`` was reimplemented as an html5lib filter and happens at a different\n step in the HTML parsing -> traversing -> serializing process. Because of\n that, there are some differences in clean's output as compared with previous\n versions.\n\n Amongst other things, this version will add end tags even if the tag in\n question is to be escaped.\n\n* ``bleach.clean`` and friends attribute callables now take three arguments:\n tag, attribute name and attribute value. Previously they only took attribute\n name and attribute value.\n\n All attribute callables will need to be updated.\n\n* ``bleach.linkify`` was rewritten\n\n ``linkify`` was reimplemented as an html5lib Filter. As such, it no longer\n accepts a ``tokenizer`` argument.\n\n The callback functions for adjusting link attributes now takes a namespaced\n attribute.\n\n Previously you'd do something like this::\n\n def check_protocol(attrs, is_new):\n if not attrs.get('href', '').startswith('http:', 'https:')):\n return None\n return attrs\n\n Now it's more like this::\n\n def check_protocol(attrs, is_new):\n if not attrs.get((None, u'href'), u'').startswith(('http:', 'https:')):\n # ^^^^^^^^^^^^^^^\n return None\n return attrs\n\n Further, you need to make sure you're always using unicode values. If you\n don't then html5lib will raise an assertion error that the value is not\n unicode.\n\n All linkify filters will need to be updated.\n\n* ``bleach.linkify`` and friends had a ``skip_pre`` argument--that's been\n replaced with a more general ``skip_tags`` argument.\n\n Before, you might do::\n\n bleach.linkify(some_text, skip_pre=True)\n\n The equivalent with Bleach 2.0 is::\n\n bleach.linkify(some_text, skip_tags=['pre'])\n\n You can skip other tags, too, like ``style`` or ``script`` or other places\n where you don't want linkification happening.\n\n All uses of linkify that use ``skip_pre`` will need to be updated.\n\n\n**Changes**\n\n* Supports Python 3.6.\n\n* Supports html5lib >= 0.99999999 (8 9s).\n\n* There's a ``bleach.sanitizer.Cleaner`` class that you can instantiate with your\n favorite clean settings for easy reuse.\n\n* There's a ``bleach.linkifier.Linker`` class that you can instantiate with your\n favorite linkify settings for easy reuse.\n\n* There's a ``bleach.linkifier.LinkifyFilter`` which is an htm5lib filter that\n you can pass as a filter to ``bleach.sanitizer.Cleaner`` allowing you to clean\n and linkify in one pass.\n\n* ``bleach.clean`` and friends can now take a callable as an attributes arg value.\n\n* Tons of bug fixes.\n\n* Cleaned up tests.\n\n* Documentation fixes.\n\n\nVersion 1.5 (November 4th, 2016)\n--------------------------------\n\n**Security fixes**\n\n* None\n\n**Backwards incompatible changes**\n\n* clean: The list of ``ALLOWED_PROTOCOLS`` now defaults to http, https and\n mailto.\n\n Previously it was a long list of protocols something like ed2k, ftp, http,\n https, irc, mailto, news, gopher, nntp, telnet, webcal, xmpp, callto, feed,\n urn, aim, rsync, tag, ssh, sftp, rtsp, afs, data. #149\n\n**Changes**\n\n* clean: Added ``protocols`` to arguments list to let you override the list of\n allowed protocols. Thank you, Andreas Malecki! #149\n\n* linkify: Fix a bug involving periods at the end of an email address. Thank you,\n Lorenz Schori! #219\n\n* linkify: Fix linkification of non-ascii ports. Thank you Alexandre, Macabies!\n #207\n\n* linkify: Fix linkify inappropriately removing node tails when dropping nodes.\n #132\n\n* Fixed a test that failed periodically. #161\n\n* Switched from nose to py.test. #204\n\n* Add test matrix for all supported Python and html5lib versions. #230\n\n* Limit to html5lib ``>=0.999,!=0.9999,!=0.99999,<0.99999999`` because 0.9999\n and 0.99999 are busted.\n\n* Add support for ``python setup.py test``. #97\n\n\nVersion 1.4.3 (May 23rd, 2016)\n------------------------------\n\n**Security fixes**\n\n* None\n\n**Changes**\n\n* Limit to html5lib ``>=0.999,<0.99999999`` because of impending change to\n sanitizer api. #195\n\n\nVersion 1.4.2 (September 11, 2015)\n----------------------------------\n\n**Changes**\n\n* linkify: Fix hang in linkify with ``parse_email=True``. #124\n\n* linkify: Fix crash in linkify when removing a link that is a first-child. #136\n\n* Updated TLDs.\n\n* linkify: Don't remove exterior brackets when linkifying. #146\n\n\nVersion 1.4.1 (December 15, 2014)\n---------------------------------\n\n**Changes**\n\n* Consistent order of attributes in output.\n\n* Python 3.4 support.\n\n\nVersion 1.4 (January 12, 2014)\n------------------------------\n\n**Changes**\n\n* linkify: Update linkify to use etree type Treewalker instead of simpletree.\n\n* Updated html5lib to version ``>=0.999``.\n\n* Update all code to be compatible with Python 3 and 2 using six.\n\n* Switch to Apache License.\n\n\nVersion 1.3\n-----------\n\n* Used by Python 3-only fork.\n\n\nVersion 1.2.2 (May 18, 2013)\n----------------------------\n\n* Pin html5lib to version 0.95 for now due to major API break.\n\n\nVersion 1.2.1 (February 19, 2013)\n---------------------------------\n\n* ``clean()`` no longer considers ``feed:`` an acceptable protocol due to\n inconsistencies in browser behavior.\n\n\nVersion 1.2 (January 28, 2013)\n------------------------------\n\n* ``linkify()`` has changed considerably. Many keyword arguments have been\n replaced with a single callbacks list. Please see the documentation for more\n information.\n\n* Bleach will no longer consider unacceptable protocols when linkifying.\n\n* ``linkify()`` now takes a tokenizer argument that allows it to skip\n sanitization.\n\n* ``delinkify()`` is gone.\n\n* Removed exception handling from ``_render``. ``clean()`` and ``linkify()`` may\n now throw.\n\n* ``linkify()`` correctly ignores case for protocols and domain names.\n\n* ``linkify()`` correctly handles markup within an tag.\n\n\nVersion 1.1.5\n-------------\n\n\nVersion 1.1.4\n-------------\n\n\nVersion 1.1.3 (July 10, 2012)\n-----------------------------\n\n* Fix parsing bare URLs when parse_email=True.\n\n\nVersion 1.1.2 (June 1, 2012)\n----------------------------\n\n* Fix hang in style attribute sanitizer. (#61)\n\n* Allow ``/`` in style attribute values.\n\n\nVersion 1.1.1 (February 17, 2012)\n---------------------------------\n\n* Fix tokenizer for html5lib 0.9.5.\n\n\nVersion 1.1.0 (October 24, 2011)\n--------------------------------\n\n* ``linkify()`` now understands port numbers. (#38)\n\n* Documented character encoding behavior. (#41)\n\n* Add an optional target argument to ``linkify()``.\n\n* Add ``delinkify()`` method. (#45)\n\n* Support subdomain whitelist for ``delinkify()``. (#47, #48)\n\n\nVersion 1.0.4 (September 2, 2011)\n---------------------------------\n\n* Switch to SemVer git tags.\n\n* Make ``linkify()`` smarter about trailing punctuation. (#30)\n\n* Pass ``exc_info`` to logger during rendering issues.\n\n* Add wildcard key for attributes. (#19)\n\n* Make ``linkify()`` use the ``HTMLSanitizer`` tokenizer. (#36)\n\n* Fix URLs wrapped in parentheses. (#23)\n\n* Make ``linkify()`` UTF-8 safe. (#33)\n\n\nVersion 1.0.3 (June 14, 2011)\n-----------------------------\n\n* ``linkify()`` works with 3rd level domains. (#24)\n\n* ``clean()`` supports vendor prefixes in style values. (#31, #32)\n\n* Fix ``linkify()`` email escaping.\n\n\nVersion 1.0.2 (June 6, 2011)\n----------------------------\n\n* ``linkify()`` supports email addresses.\n\n* ``clean()`` supports callables in attributes filter.\n\n\nVersion 1.0.1 (April 12, 2011)\n------------------------------\n\n* ``linkify()`` doesn't drop trailing slashes. (#21)\n* ``linkify()`` won't linkify 'libgl.so.1'. (#22)", - "release_date": "2021-08-25T14:58:31", - "parties": [ - { - "type": "person", - "role": "maintainer", - "name": "Will Kahn-Greene", - "email": "willkg@mozilla.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "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", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "https://github.com/mozilla/bleach", - "download_url": "https://files.pythonhosted.org/packages/6a/a3/217842324374fd3fb33db0eb4c2909ccf3ecc5a94f458088ac68581f8314/bleach-4.1.0.tar.gz", - "size": 195798, - "sha1": null, - "md5": "41e70ac58aa7bc5ff96c8fef24b9d659", - "sha256": "0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "Apache Software License", - "classifiers": [ - "License :: OSI Approved :: Apache Software License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/bleach/4.1.0/json", - "datasource_id": null, - "purl": "pkg:pypi/bleach@4.1.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "boolean-py", - "version": "4.0", + "name": "boolean-py", + "version": "4.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", @@ -2201,66 +1867,6 @@ "datasource_id": null, "purl": "pkg:pypi/boolean-py@4.0" }, - { - "type": "pypi", - "namespace": null, - "name": "boolean-py", - "version": "4.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Define boolean algebras, create and parse boolean expressions and create custom boolean DSL.\nThis library helps you deal with boolean expressions and algebra with variables\nand the boolean functions AND, OR, NOT.\n\nYou can parse expressions from strings and simplify and compare expressions.\nYou can also easily create your custom algreba and mini DSL and create custom\ntokenizers to handle custom expressions.\n\nFor extensive documentation look either into the docs directory or view it online, at\nhttps://booleanpy.readthedocs.org/en/latest/\n\nhttps://github.com/bastikr/boolean.py\n\nCopyright (c) 2009-2020 Sebastian Kraemer, basti.kr@gmail.com and others\nSPDX-License-Identifier: BSD-2-Clause", - "release_date": "2022-05-05T08:19:01", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Sebastian Kraemer", - "email": "basti.kr@gmail.com", - "url": null - } - ], - "keywords": [ - "boolean expression", - "boolean algebra", - "logic", - "expression parser", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Topic :: Scientific/Engineering :: Mathematics", - "Topic :: Software Development :: Compilers", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/bastikr/boolean.py", - "download_url": "https://files.pythonhosted.org/packages/a2/d9/b6e56a303d221fc0bdff2c775e4eef7fedd58194aa5a96fa89fb71634cc9/boolean.py-4.0.tar.gz", - "size": 34504, - "sha1": null, - "md5": "5a8b0eae254b0c37a1bdde38c6bd5b5d", - "sha256": "17b9a181630e43dde1851d42bef546d616d5d9b4480357514597e78b203d06e4", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-2-Clause" - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/boolean-py/4.0/json", - "datasource_id": null, - "purl": "pkg:pypi/boolean-py@4.0" - }, { "type": "pypi", "namespace": null, @@ -2321,66 +1927,6 @@ "datasource_id": null, "purl": "pkg:pypi/certifi@2022.5.18.1" }, - { - "type": "pypi", - "namespace": null, - "name": "certifi", - "version": "2022.5.18.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Python package for providing Mozilla's CA Bundle.\nCertifi: Python SSL Certificates\n================================\n\nCertifi provides Mozilla's carefully curated collection of Root Certificates for\nvalidating the trustworthiness of SSL certificates while verifying the identity\nof TLS hosts. It has been extracted from the `Requests`_ project.\n\nInstallation\n------------\n\n``certifi`` is available on PyPI. Simply install it with ``pip``::\n\n $ pip install certifi\n\nUsage\n-----\n\nTo reference the installed certificate authority (CA) bundle, you can use the\nbuilt-in function::\n\n >>> import certifi\n\n >>> certifi.where()\n '/usr/local/lib/python3.7/site-packages/certifi/cacert.pem'\n\nOr from the command line::\n\n $ python -m certifi\n /usr/local/lib/python3.7/site-packages/certifi/cacert.pem\n\nEnjoy!\n\n1024-bit Root Certificates\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nBrowsers and certificate authorities have concluded that 1024-bit keys are\nunacceptably weak for certificates, particularly root certificates. For this\nreason, Mozilla has removed any weak (i.e. 1024-bit key) certificate from its\nbundle, replacing it with an equivalent strong (i.e. 2048-bit or greater key)\ncertificate from the same CA. Because Mozilla removed these certificates from\nits bundle, ``certifi`` removed them as well.\n\nIn previous versions, ``certifi`` provided the ``certifi.old_where()`` function\nto intentionally re-add the 1024-bit roots back into your bundle. This was not\nrecommended in production and therefore was removed at the end of 2018.\n\n.. _`Requests`: https://requests.readthedocs.io/en/master/\n\nAddition/Removal of Certificates\n--------------------------------\n\nCertifi does not support any addition/removal or other modification of the\nCA trust store content. This project is intended to provide a reliable and\nhighly portable root of trust to python deployments. Look to upstream projects\nfor methods to use alternate trust.", - "release_date": "2022-05-19T19:21:31", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Kenneth Reitz", - "email": "me@kennethreitz.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Natural Language :: English", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9" - ], - "homepage_url": "https://github.com/certifi/python-certifi", - "download_url": "https://files.pythonhosted.org/packages/07/10/75277f313d13a2b74fc56e29239d5c840c2bf09f17bf25c02b35558812c6/certifi-2022.5.18.1.tar.gz", - "size": 156701, - "sha1": null, - "md5": "70f3688480b8fc4556c033f3ea655d36", - "sha256": "9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/certifi/python-certifi", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MPL-2.0", - "classifiers": [ - "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/certifi/2022.5.18.1/json", - "datasource_id": null, - "purl": "pkg:pypi/certifi@2022.5.18.1" - }, { "type": "pypi", "namespace": null, @@ -2442,67 +1988,6 @@ "datasource_id": null, "purl": "pkg:pypi/cffi@1.15.0" }, - { - "type": "pypi", - "namespace": null, - "name": "cffi", - "version": "1.15.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "CFFI\n====\n\nForeign Function Interface for Python calling C code.\nPlease see the `Documentation `_.\n\nContact\n-------\n\n`Mailing list `_", - "release_date": "2021-10-13T15:53:33", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Rigo, Maciej Fijalkowski", - "email": "python-cffi@googlegroups.com", - "url": null - } - ], - "keywords": [ - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy" - ], - "homepage_url": "http://cffi.readthedocs.org", - "download_url": "https://files.pythonhosted.org/packages/00/9e/92de7e1217ccc3d5f352ba21e52398372525765b2e0c4530e6eb2ba9282a/cffi-1.15.0.tar.gz", - "size": 484058, - "sha1": null, - "md5": "f3a3f26cd3335fc597479c9475da0a0b", - "sha256": "920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/cffi/1.15.0/json", - "datasource_id": null, - "purl": "pkg:pypi/cffi@1.15.0" - }, { "type": "pypi", "namespace": null, @@ -2581,106 +2066,31 @@ { "type": "pypi", "namespace": null, - "name": "charset-normalizer", - "version": "2.0.12", + "name": "click", + "version": "8.0.4", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet.\n

Charset Detection, for Everyone \ud83d\udc4b

\n\n

\n The Real First Universal Charset Detector
\n \n \n \n \n \n \n \n \"Download\n \n

\n\n> A library that helps you read text from an unknown charset encoding.
Motivated by `chardet`,\n> I'm trying to resolve the issue by taking a new approach.\n> All IANA character set names for which the Python core library provides codecs are supported.\n\n

\n >>>>> \ud83d\udc49 Try Me Online Now, Then Adopt Me \ud83d\udc48 <<<<<\n

\n\nThis project offers you an alternative to **Universal Charset Encoding Detector**, also known as **Chardet**.\n\n| Feature | [Chardet](https://github.com/chardet/chardet) | Charset Normalizer | [cChardet](https://github.com/PyYoshi/cChardet) |\n| ------------- | :-------------: | :------------------: | :------------------: |\n| `Fast` | \u274c
| \u2705
| \u2705
|\n| `Universal**` | \u274c | \u2705 | \u274c |\n| `Reliable` **without** distinguishable standards | \u274c | \u2705 | \u2705 |\n| `Reliable` **with** distinguishable standards | \u2705 | \u2705 | \u2705 |\n| `Free & Open` | \u2705 | \u2705 | \u2705 |\n| `License` | LGPL-2.1 | MIT | MPL-1.1\n| `Native Python` | \u2705 | \u2705 | \u274c |\n| `Detect spoken language` | \u274c | \u2705 | N/A |\n| `Supported Encoding` | 30 | :tada: [93](https://charset-normalizer.readthedocs.io/en/latest/user/support.html#supported-encodings) | 40\n\n

\n\"Reading\"Cat\n\n*\\*\\* : They are clearly using specific code for a specific encoding even if covering most of used one*
\nDid you got there because of the logs? See [https://charset-normalizer.readthedocs.io/en/latest/user/miscellaneous.html](https://charset-normalizer.readthedocs.io/en/latest/user/miscellaneous.html)\n\n## \u2b50 Your support\n\n*Fork, test-it, star-it, submit your ideas! We do listen.*\n \n## \u26a1 Performance\n\nThis package offer better performance than its counterpart Chardet. Here are some numbers.\n\n| Package | Accuracy | Mean per file (ms) | File per sec (est) |\n| ------------- | :-------------: | :------------------: | :------------------: |\n| [chardet](https://github.com/chardet/chardet) | 92 % | 220 ms | 5 file/sec |\n| charset-normalizer | **98 %** | **40 ms** | 25 file/sec |\n\n| Package | 99th percentile | 95th percentile | 50th percentile |\n| ------------- | :-------------: | :------------------: | :------------------: |\n| [chardet](https://github.com/chardet/chardet) | 1115 ms | 300 ms | 27 ms |\n| charset-normalizer | 460 ms | 240 ms | 18 ms |\n\nChardet's performance on larger file (1MB+) are very poor. Expect huge difference on large payload.\n\n> Stats are generated using 400+ files using default parameters. More details on used files, see GHA workflows.\n> And yes, these results might change at any time. The dataset can be updated to include more files.\n> The actual delays heavily depends on your CPU capabilities. The factors should remain the same.\n\n[cchardet](https://github.com/PyYoshi/cChardet) is a non-native (cpp binding) and unmaintained faster alternative with \na better accuracy than chardet but lower than this package. If speed is the most important factor, you should try it.\n\n## \u2728 Installation\n\nUsing PyPi for latest stable\n```sh\npip install charset-normalizer -U\n```\n\nIf you want a more up-to-date `unicodedata` than the one available in your Python setup.\n```sh\npip install charset-normalizer[unicode_backport] -U\n```\n\n## \ud83d\ude80 Basic Usage\n\n### CLI\nThis package comes with a CLI.\n\n```\nusage: normalizer [-h] [-v] [-a] [-n] [-m] [-r] [-f] [-t THRESHOLD]\n file [file ...]\n\nThe Real First Universal Charset Detector. Discover originating encoding used\non text file. Normalize text to unicode.\n\npositional arguments:\n files File(s) to be analysed\n\noptional arguments:\n -h, --help show this help message and exit\n -v, --verbose Display complementary information about file if any.\n Stdout will contain logs about the detection process.\n -a, --with-alternative\n Output complementary possibilities if any. Top-level\n JSON WILL be a list.\n -n, --normalize Permit to normalize input file. If not set, program\n does not write anything.\n -m, --minimal Only output the charset detected to STDOUT. Disabling\n JSON output.\n -r, --replace Replace file when trying to normalize it instead of\n creating a new one.\n -f, --force Replace file without asking if you are sure, use this\n flag with caution.\n -t THRESHOLD, --threshold THRESHOLD\n Define a custom maximum amount of chaos allowed in\n decoded content. 0. <= chaos <= 1.\n --version Show version information and exit.\n```\n\n```bash\nnormalizer ./data/sample.1.fr.srt\n```\n\n:tada: Since version 1.4.0 the CLI produce easily usable stdout result in JSON format.\n\n```json\n{\n \"path\": \"/home/default/projects/charset_normalizer/data/sample.1.fr.srt\",\n \"encoding\": \"cp1252\",\n \"encoding_aliases\": [\n \"1252\",\n \"windows_1252\"\n ],\n \"alternative_encodings\": [\n \"cp1254\",\n \"cp1256\",\n \"cp1258\",\n \"iso8859_14\",\n \"iso8859_15\",\n \"iso8859_16\",\n \"iso8859_3\",\n \"iso8859_9\",\n \"latin_1\",\n \"mbcs\"\n ],\n \"language\": \"French\",\n \"alphabets\": [\n \"Basic Latin\",\n \"Latin-1 Supplement\"\n ],\n \"has_sig_or_bom\": false,\n \"chaos\": 0.149,\n \"coherence\": 97.152,\n \"unicode_path\": null,\n \"is_preferred\": true\n}\n```\n\n### Python\n*Just print out normalized text*\n```python\nfrom charset_normalizer import from_path\n\nresults = from_path('./my_subtitle.srt')\n\nprint(str(results.best()))\n```\n\n*Normalize any text file*\n```python\nfrom charset_normalizer import normalize\ntry:\n normalize('./my_subtitle.srt') # should write to disk my_subtitle-***.srt\nexcept IOError as e:\n print('Sadly, we are unable to perform charset normalization.', str(e))\n```\n\n*Upgrade your code without effort*\n```python\nfrom charset_normalizer import detect\n```\n\nThe above code will behave the same as **chardet**. We ensure that we offer the best (reasonable) BC result possible.\n\nSee the docs for advanced usage : [readthedocs.io](https://charset-normalizer.readthedocs.io/en/latest/)\n\n## \ud83d\ude07 Why\n\nWhen I started using Chardet, I noticed that it was not suited to my expectations, and I wanted to propose a\nreliable alternative using a completely different method. Also! I never back down on a good challenge!\n\nI **don't care** about the **originating charset** encoding, because **two different tables** can\nproduce **two identical rendered string.**\nWhat I want is to get readable text, the best I can. \n\nIn a way, **I'm brute forcing text decoding.** How cool is that ? \ud83d\ude0e\n\nDon't confuse package **ftfy** with charset-normalizer or chardet. ftfy goal is to repair unicode string whereas charset-normalizer to convert raw file in unknown encoding to unicode.\n\n## \ud83c\udf70 How\n\n - Discard all charset encoding table that could not fit the binary content.\n - Measure chaos, or the mess once opened (by chunks) with a corresponding charset encoding.\n - Extract matches with the lowest mess detected.\n - Additionally, we measure coherence / probe for a language.\n\n**Wait a minute**, what is chaos/mess and coherence according to **YOU ?**\n\n*Chaos :* I opened hundred of text files, **written by humans**, with the wrong encoding table. **I observed**, then\n**I established** some ground rules about **what is obvious** when **it seems like** a mess.\n I know that my interpretation of what is chaotic is very subjective, feel free to contribute in order to\n improve or rewrite it.\n\n*Coherence :* For each language there is on earth, we have computed ranked letter appearance occurrences (the best we can). So I thought\nthat intel is worth something here. So I use those records against decoded text to check if I can detect intelligent design.\n\n## \u26a1 Known limitations\n\n - Language detection is unreliable when text contains two or more languages sharing identical letters. (eg. HTML (english tags) + Turkish content (Sharing Latin characters))\n - Every charset detector heavily depends on sufficient content. In common cases, do not bother run detection on very tiny content.\n\n## \ud83d\udc64 Contributing\n\nContributions, issues and feature requests are very much welcome.
\nFeel free to check [issues page](https://github.com/ousret/charset_normalizer/issues) if you want to contribute.\n\n## \ud83d\udcdd License\n\nCopyright \u00a9 2019 [Ahmed TAHRI @Ousret](https://github.com/Ousret).
\nThis project is [MIT](https://github.com/Ousret/charset_normalizer/blob/master/LICENSE) licensed.\n\nCharacters frequencies used in this project \u00a9 2012 [Denny Vrande\u010di\u0107](http://simia.net/letters/)", - "release_date": "2022-02-12T14:33:13", + "description": "Composable command line interface toolkit\n\\$ click\\_\n==========\n\nClick is a Python package for creating beautiful command line interfaces\nin a composable way with as little code as necessary. It's the \"Command\nLine Interface Creation Kit\". It's highly configurable but comes with\nsensible defaults out of the box.\n\nIt aims to make the process of writing command line tools quick and fun\nwhile also preventing any frustration caused by the inability to\nimplement an intended CLI API.\n\nClick in three points:\n\n- Arbitrary nesting of commands\n- Automatic help page generation\n- Supports lazy loading of subcommands at runtime\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U click\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n import click\n\n @click.command()\n @click.option(\"--count\", default=1, help=\"Number of greetings.\")\n @click.option(\"--name\", prompt=\"Your name\", help=\"The person to greet.\")\n def hello(count, name):\n \"\"\"Simple program that greets NAME for a total of COUNT times.\"\"\"\n for _ in range(count):\n click.echo(f\"Hello, {name}!\")\n\n if __name__ == '__main__':\n hello()\n\n.. code-block:: text\n\n $ python hello.py --count=3\n Your name: Click\n Hello, Click!\n Hello, Click!\n Hello, Click!\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Click and other popular\npackages. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://click.palletsprojects.com/\n- Changes: https://click.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/click/\n- Source Code: https://github.com/pallets/click\n- Issue Tracker: https://github.com/pallets/click/issues\n- Website: https://palletsprojects.com/p/click\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", + "release_date": "2022-02-18T20:31:27", "parties": [ { "type": "person", "role": "author", - "name": "Ahmed TAHRI @Ousret", - "email": "ahmed.tahri@cloudnursery.dev", + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "url": null + }, + { + "type": "person", + "role": "maintainer", + "name": "Pallets", + "email": "contact@palletsprojects.com", "url": null } ], "keywords": [ - "encoding", - "i18n", - "txt", - "text", - "charset", - "charset-detector", - "normalization", - "unicode", - "chardet", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Text Processing :: Linguistic", - "Topic :: Utilities", - "Typing :: Typed" - ], - "homepage_url": "https://github.com/ousret/charset_normalizer", - "download_url": "https://files.pythonhosted.org/packages/56/31/7bcaf657fafb3c6db8c787a865434290b726653c912085fbd371e9b92e1c/charset-normalizer-2.0.12.tar.gz", - "size": 79105, - "sha1": null, - "md5": "f6664e0e90dbb3cc9cfc154a980f9864", - "sha256": "2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/charset-normalizer/2.0.12/json", - "datasource_id": null, - "purl": "pkg:pypi/charset-normalizer@2.0.12" - }, - { - "type": "pypi", - "namespace": null, - "name": "click", - "version": "8.0.4", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Composable command line interface toolkit\n\\$ click\\_\n==========\n\nClick is a Python package for creating beautiful command line interfaces\nin a composable way with as little code as necessary. It's the \"Command\nLine Interface Creation Kit\". It's highly configurable but comes with\nsensible defaults out of the box.\n\nIt aims to make the process of writing command line tools quick and fun\nwhile also preventing any frustration caused by the inability to\nimplement an intended CLI API.\n\nClick in three points:\n\n- Arbitrary nesting of commands\n- Automatic help page generation\n- Supports lazy loading of subcommands at runtime\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U click\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n import click\n\n @click.command()\n @click.option(\"--count\", default=1, help=\"Number of greetings.\")\n @click.option(\"--name\", prompt=\"Your name\", help=\"The person to greet.\")\n def hello(count, name):\n \"\"\"Simple program that greets NAME for a total of COUNT times.\"\"\"\n for _ in range(count):\n click.echo(f\"Hello, {name}!\")\n\n if __name__ == '__main__':\n hello()\n\n.. code-block:: text\n\n $ python hello.py --count=3\n Your name: Click\n Hello, Click!\n Hello, Click!\n Hello, Click!\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Click and other popular\npackages. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://click.palletsprojects.com/\n- Changes: https://click.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/click/\n- Source Code: https://github.com/pallets/click\n- Issue Tracker: https://github.com/pallets/click/issues\n- Website: https://palletsprojects.com/p/click\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2022-02-18T20:31:27", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", + "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Operating System :: OS Independent", "Programming Language :: Python" @@ -2714,67 +2124,6 @@ "datasource_id": null, "purl": "pkg:pypi/click@8.0.4" }, - { - "type": "pypi", - "namespace": null, - "name": "click", - "version": "8.0.4", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Composable command line interface toolkit\n\\$ click\\_\n==========\n\nClick is a Python package for creating beautiful command line interfaces\nin a composable way with as little code as necessary. It's the \"Command\nLine Interface Creation Kit\". It's highly configurable but comes with\nsensible defaults out of the box.\n\nIt aims to make the process of writing command line tools quick and fun\nwhile also preventing any frustration caused by the inability to\nimplement an intended CLI API.\n\nClick in three points:\n\n- Arbitrary nesting of commands\n- Automatic help page generation\n- Supports lazy loading of subcommands at runtime\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U click\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n import click\n\n @click.command()\n @click.option(\"--count\", default=1, help=\"Number of greetings.\")\n @click.option(\"--name\", prompt=\"Your name\", help=\"The person to greet.\")\n def hello(count, name):\n \"\"\"Simple program that greets NAME for a total of COUNT times.\"\"\"\n for _ in range(count):\n click.echo(f\"Hello, {name}!\")\n\n if __name__ == '__main__':\n hello()\n\n.. code-block:: text\n\n $ python hello.py --count=3\n Your name: Click\n Hello, Click!\n Hello, Click!\n Hello, Click!\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Click and other popular\npackages. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://click.palletsprojects.com/\n- Changes: https://click.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/click/\n- Source Code: https://github.com/pallets/click\n- Issue Tracker: https://github.com/pallets/click/issues\n- Website: https://palletsprojects.com/p/click\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2022-02-18T20:31:30", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python" - ], - "homepage_url": "https://palletsprojects.com/p/click/", - "download_url": "https://files.pythonhosted.org/packages/dd/cf/706c1ad49ab26abed0b77a2f867984c1341ed7387b8030a6aa914e2942a0/click-8.0.4.tar.gz", - "size": 329520, - "sha1": null, - "md5": "c89efc98d1b36d52ba26a39c803df0cc", - "sha256": "8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/click/issues/", - "code_view_url": "https://github.com/pallets/click/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/click/8.0.4/json", - "datasource_id": null, - "purl": "pkg:pypi/click@8.0.4" - }, { "type": "pypi", "namespace": null, @@ -2848,79 +2197,6 @@ "datasource_id": null, "purl": "pkg:pypi/colorama@0.4.4" }, - { - "type": "pypi", - "namespace": null, - "name": "colorama", - "version": "0.4.4", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Cross-platform colored terminal text.\n.. image:: https://img.shields.io/pypi/v/colorama.svg\n :target: https://pypi.org/project/colorama/\n :alt: Latest Version\n\n.. image:: https://img.shields.io/pypi/pyversions/colorama.svg\n :target: https://pypi.org/project/colorama/\n :alt: Supported Python versions\n\n.. image:: https://travis-ci.org/tartley/colorama.svg?branch=master\n :target: https://travis-ci.org/tartley/colorama\n :alt: Build Status\n\nColorama\n========\n\nMakes ANSI escape character sequences (for producing colored terminal text and\ncursor positioning) work under MS Windows.\n\n.. |donate| image:: https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif\n :target: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2MZ9D2GMLYCUJ&item_name=Colorama¤cy_code=USD\n :alt: Donate with Paypal\n\n`PyPI for releases `_ \u00c2\u00b7\n`Github for source `_ \u00c2\u00b7\n`Colorama for enterprise on Tidelift `_\n\nIf you find Colorama useful, please |donate| to the authors. Thank you!\n\n\nInstallation\n------------\n\n.. code-block:: bash\n\n pip install colorama\n # or\n conda install -c anaconda colorama\n\n\nDescription\n-----------\n\nANSI escape character sequences have long been used to produce colored terminal\ntext and cursor positioning on Unix and Macs. Colorama makes this work on\nWindows, too, by wrapping ``stdout``, stripping ANSI sequences it finds (which\nwould appear as gobbledygook in the output), and converting them into the\nappropriate win32 calls to modify the state of the terminal. On other platforms,\nColorama does nothing.\n\nThis has the upshot of providing a simple cross-platform API for printing\ncolored terminal text from Python, and has the happy side-effect that existing\napplications or libraries which use ANSI sequences to produce colored output on\nLinux or Macs can now also work on Windows, simply by calling\n``colorama.init()``.\n\nAn alternative approach is to install ``ansi.sys`` on Windows machines, which\nprovides the same behaviour for all applications running in terminals. Colorama\nis intended for situations where that isn't easy (e.g., maybe your app doesn't\nhave an installer.)\n\nDemo scripts in the source code repository print some colored text using\nANSI sequences. Compare their output under Gnome-terminal's built in ANSI\nhandling, versus on Windows Command-Prompt using Colorama:\n\n.. image:: https://github.com/tartley/colorama/raw/master/screenshots/ubuntu-demo.png\n :width: 661\n :height: 357\n :alt: ANSI sequences on Ubuntu under gnome-terminal.\n\n.. image:: https://github.com/tartley/colorama/raw/master/screenshots/windows-demo.png\n :width: 668\n :height: 325\n :alt: Same ANSI sequences on Windows, using Colorama.\n\nThese screenshots show that, on Windows, Colorama does not support ANSI 'dim\ntext'; it looks the same as 'normal text'.\n\nUsage\n-----\n\nInitialisation\n..............\n\nApplications should initialise Colorama using:\n\n.. code-block:: python\n\n from colorama import init\n init()\n\nOn Windows, calling ``init()`` will filter ANSI escape sequences out of any\ntext sent to ``stdout`` or ``stderr``, and replace them with equivalent Win32\ncalls.\n\nOn other platforms, calling ``init()`` has no effect (unless you request other\noptional functionality; see \"Init Keyword Args\", below). By design, this permits\napplications to call ``init()`` unconditionally on all platforms, after which\nANSI output should just work.\n\nTo stop using Colorama before your program exits, simply call ``deinit()``.\nThis will restore ``stdout`` and ``stderr`` to their original values, so that\nColorama is disabled. To resume using Colorama again, call ``reinit()``; it is\ncheaper than calling ``init()`` again (but does the same thing).\n\n\nColored Output\n..............\n\nCross-platform printing of colored text can then be done using Colorama's\nconstant shorthand for ANSI escape sequences:\n\n.. code-block:: python\n\n from colorama import Fore, Back, Style\n print(Fore.RED + 'some red text')\n print(Back.GREEN + 'and with a green background')\n print(Style.DIM + 'and in dim text')\n print(Style.RESET_ALL)\n print('back to normal now')\n\n...or simply by manually printing ANSI sequences from your own code:\n\n.. code-block:: python\n\n print('\\033[31m' + 'some red text')\n print('\\033[39m') # and reset to default color\n\n...or, Colorama can be used in conjunction with existing ANSI libraries\nsuch as the venerable `Termcolor `_\nor the fabulous `Blessings `_.\nThis is highly recommended for anything more than trivial coloring:\n\n.. code-block:: python\n\n from colorama import init\n from termcolor import colored\n\n # use Colorama to make Termcolor work on Windows too\n init()\n\n # then use Termcolor for all colored text output\n print(colored('Hello, World!', 'green', 'on_red'))\n\nAvailable formatting constants are::\n\n Fore: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET.\n Back: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET.\n Style: DIM, NORMAL, BRIGHT, RESET_ALL\n\n``Style.RESET_ALL`` resets foreground, background, and brightness. Colorama will\nperform this reset automatically on program exit.\n\n\nCursor Positioning\n..................\n\nANSI codes to reposition the cursor are supported. See ``demos/demo06.py`` for\nan example of how to generate them.\n\n\nInit Keyword Args\n.................\n\n``init()`` accepts some ``**kwargs`` to override default behaviour.\n\ninit(autoreset=False):\n If you find yourself repeatedly sending reset sequences to turn off color\n changes at the end of every print, then ``init(autoreset=True)`` will\n automate that:\n\n .. code-block:: python\n\n from colorama import init\n init(autoreset=True)\n print(Fore.RED + 'some red text')\n print('automatically back to default color again')\n\ninit(strip=None):\n Pass ``True`` or ``False`` to override whether ANSI codes should be\n stripped from the output. The default behaviour is to strip if on Windows\n or if output is redirected (not a tty).\n\ninit(convert=None):\n Pass ``True`` or ``False`` to override whether to convert ANSI codes in the\n output into win32 calls. The default behaviour is to convert if on Windows\n and output is to a tty (terminal).\n\ninit(wrap=True):\n On Windows, Colorama works by replacing ``sys.stdout`` and ``sys.stderr``\n with proxy objects, which override the ``.write()`` method to do their work.\n If this wrapping causes you problems, then this can be disabled by passing\n ``init(wrap=False)``. The default behaviour is to wrap if ``autoreset`` or\n ``strip`` or ``convert`` are True.\n\n When wrapping is disabled, colored printing on non-Windows platforms will\n continue to work as normal. To do cross-platform colored output, you can\n use Colorama's ``AnsiToWin32`` proxy directly:\n\n .. code-block:: python\n\n import sys\n from colorama import init, AnsiToWin32\n init(wrap=False)\n stream = AnsiToWin32(sys.stderr).stream\n\n # Python 2\n print >>stream, Fore.BLUE + 'blue text on stderr'\n\n # Python 3\n print(Fore.BLUE + 'blue text on stderr', file=stream)\n\n\nRecognised ANSI Sequences\n.........................\n\nANSI sequences generally take the form::\n\n ESC [ ; ... \n\nWhere ```` is an integer, and ```` is a single letter. Zero or\nmore params are passed to a ````. If no params are passed, it is\ngenerally synonymous with passing a single zero. No spaces exist in the\nsequence; they have been inserted here simply to read more easily.\n\nThe only ANSI sequences that Colorama converts into win32 calls are::\n\n ESC [ 0 m # reset all (colors and brightness)\n ESC [ 1 m # bright\n ESC [ 2 m # dim (looks same as normal brightness)\n ESC [ 22 m # normal brightness\n\n # FOREGROUND:\n ESC [ 30 m # black\n ESC [ 31 m # red\n ESC [ 32 m # green\n ESC [ 33 m # yellow\n ESC [ 34 m # blue\n ESC [ 35 m # magenta\n ESC [ 36 m # cyan\n ESC [ 37 m # white\n ESC [ 39 m # reset\n\n # BACKGROUND\n ESC [ 40 m # black\n ESC [ 41 m # red\n ESC [ 42 m # green\n ESC [ 43 m # yellow\n ESC [ 44 m # blue\n ESC [ 45 m # magenta\n ESC [ 46 m # cyan\n ESC [ 47 m # white\n ESC [ 49 m # reset\n\n # cursor positioning\n ESC [ y;x H # position cursor at x across, y down\n ESC [ y;x f # position cursor at x across, y down\n ESC [ n A # move cursor n lines up\n ESC [ n B # move cursor n lines down\n ESC [ n C # move cursor n characters forward\n ESC [ n D # move cursor n characters backward\n\n # clear the screen\n ESC [ mode J # clear the screen\n\n # clear the line\n ESC [ mode K # clear the line\n\nMultiple numeric params to the ``'m'`` command can be combined into a single\nsequence::\n\n ESC [ 36 ; 45 ; 1 m # bright cyan text on magenta background\n\nAll other ANSI sequences of the form ``ESC [ ; ... ``\nare silently stripped from the output on Windows.\n\nAny other form of ANSI sequence, such as single-character codes or alternative\ninitial characters, are not recognised or stripped. It would be cool to add\nthem though. Let me know if it would be useful for you, via the Issues on\nGitHub.\n\n\nStatus & Known Problems\n-----------------------\n\nI've personally only tested it on Windows XP (CMD, Console2), Ubuntu\n(gnome-terminal, xterm), and OS X.\n\nSome presumably valid ANSI sequences aren't recognised (see details below),\nbut to my knowledge nobody has yet complained about this. Puzzling.\n\nSee outstanding issues and wish-list:\nhttps://github.com/tartley/colorama/issues\n\nIf anything doesn't work for you, or doesn't do what you expected or hoped for,\nI'd love to hear about it on that issues list, would be delighted by patches,\nand would be happy to grant commit access to anyone who submits a working patch\nor two.\n\n\nLicense\n-------\n\nCopyright Jonathan Hartley & Arnon Yaari, 2013-2020. BSD 3-Clause license; see\nLICENSE file.\n\n\nDevelopment\n-----------\n\nHelp and fixes welcome!\n\nTested on CPython 2.7, 3.5, 3.6, 3.7 and 3.8.\n\nNo requirements other than the standard library.\nDevelopment requirements are captured in requirements-dev.txt.\n\nTo create and populate a virtual environment::\n\n ./bootstrap.ps1 # Windows\n make bootstrap # Linux\n\nTo run tests::\n\n ./test.ps1 # Windows\n make test # Linux\n\nIf you use nose to run the tests, you must pass the ``-s`` flag; otherwise,\n``nosetests`` applies its own proxy to ``stdout``, which confuses the unit\ntests.\n\n\nProfessional support\n--------------------\n\n.. |tideliftlogo| image:: https://cdn2.hubspot.net/hubfs/4008838/website/logos/logos_for_download/Tidelift_primary-shorthand-logo.png\n :alt: Tidelift\n :target: https://tidelift.com/subscription/pkg/pypi-colorama?utm_source=pypi-colorama&utm_medium=referral&utm_campaign=readme\n\n.. list-table::\n :widths: 10 100\n\n * - |tideliftlogo|\n - Professional support for colorama is available as part of the\n `Tidelift Subscription`_.\n Tidelift gives software development teams a single source for purchasing\n and maintaining their software, with professional grade assurances from\n the experts who know it best, while seamlessly integrating with existing\n tools.\n\n.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-colorama?utm_source=pypi-colorama&utm_medium=referral&utm_campaign=readme\n\n\nThanks\n------\n\n* Marc Schlaich (schlamar) for a ``setup.py`` fix for Python2.5.\n* Marc Abramowitz, reported & fixed a crash on exit with closed ``stdout``,\n providing a solution to issue #7's setuptools/distutils debate,\n and other fixes.\n* User 'eryksun', for guidance on correctly instantiating ``ctypes.windll``.\n* Matthew McCormick for politely pointing out a longstanding crash on non-Win.\n* Ben Hoyt, for a magnificent fix under 64-bit Windows.\n* Jesse at Empty Square for submitting a fix for examples in the README.\n* User 'jamessp', an observant documentation fix for cursor positioning.\n* User 'vaal1239', Dave Mckee & Lackner Kristof for a tiny but much-needed Win7\n fix.\n* Julien Stuyck, for wisely suggesting Python3 compatible updates to README.\n* Daniel Griffith for multiple fabulous patches.\n* Oscar Lesta for a valuable fix to stop ANSI chars being sent to non-tty\n output.\n* Roger Binns, for many suggestions, valuable feedback, & bug reports.\n* Tim Golden for thought and much appreciated feedback on the initial idea.\n* User 'Zearin' for updates to the README file.\n* John Szakmeister for adding support for light colors\n* Charles Merriam for adding documentation to demos\n* Jurko for a fix on 64-bit Windows CPython2.5 w/o ctypes\n* Florian Bruhin for a fix when stdout or stderr are None\n* Thomas Weininger for fixing ValueError on Windows\n* Remi Rampin for better Github integration and fixes to the README file\n* Simeon Visser for closing a file handle using 'with' and updating classifiers\n to include Python 3.3 and 3.4\n* Andy Neff for fixing RESET of LIGHT_EX colors.\n* Jonathan Hartley for the initial idea and implementation.", - "release_date": "2020-10-15T18:36:33", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Jonathan Hartley", - "email": "tartley@tartley.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Arnon Yaari", - "email": null, - "url": null - } - ], - "keywords": [ - "color colour terminal text ansi windows crossplatform xplatform", - "Development Status :: 5 - Production/Stable", - "Environment :: Console", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "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", - "Topic :: Terminals" - ], - "homepage_url": "https://github.com/tartley/colorama", - "download_url": "https://files.pythonhosted.org/packages/1f/bb/5d3246097ab77fa083a61bd8d3d527b7ae063c7d8e8671b1cf8c4ec10cbe/colorama-0.4.4.tar.gz", - "size": 27813, - "sha1": null, - "md5": "57b22f2597f63df051b69906fbf310cc", - "sha256": "5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/colorama/0.4.4/json", - "datasource_id": null, - "purl": "pkg:pypi/colorama@0.4.4" - }, { "type": "pypi", "namespace": null, @@ -2976,61 +2252,6 @@ "datasource_id": null, "purl": "pkg:pypi/commoncode@30.2.0" }, - { - "type": "pypi", - "namespace": null, - "name": "commoncode", - "version": "30.2.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Set of common utilities, originally split from ScanCode\nCommonCode\n==========\n\n- license: Apache-2.0\n- copyright: copyright (c) nexB. Inc. and others\n- homepage_url: https://github.com/nexB/commoncode\n- keywords: utilities, scancode-toolkit, commoncode\n\nCommoncode provides a set of common functions and utilities for handling various things like paths,\ndates, files and hashes. It started as library in scancode-toolkit.\nVisit https://aboutcode.org and https://github.com/nexB/ for support and download.\n\n\nTo install this package use::\n\n pip install commoncode\n\n\nAlternatively, to set up a development environment::\n\n source configure --dev\n\nTo run unit tests::\n\n pytest -vvs -n 2\n\nTo clean up development environment::\n\n ./configure --clean", - "release_date": "2022-05-02T07:24:37", - "parties": [ - { - "type": "person", - "role": "author", - "name": "nexB. Inc. and others", - "email": "info@aboutcode.org", - "url": null - } - ], - "keywords": [ - "utilities", - "scancode-toolkit", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Topic :: Software Development", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/nexB/commoncode", - "download_url": "https://files.pythonhosted.org/packages/8b/65/99ad49681e8897ab851014f18bf51e8081a492efc1ef0b443209f7a83e0e/commoncode-30.2.0.tar.gz", - "size": 1690459, - "sha1": null, - "md5": "754bc02c505adcf65a8d1006b7894703", - "sha256": "ee470359fc3833b6e87b40013b8a1bd5df973b56314bddb89ad1844ef1e835fd", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "Apache-2.0" - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/commoncode/30.2.0/json", - "datasource_id": null, - "purl": "pkg:pypi/commoncode@30.2.0" - }, { "type": "pypi", "namespace": null, @@ -3104,89 +2325,19 @@ { "type": "pypi", "namespace": null, - "name": "cryptography", - "version": "37.0.2", + "name": "docutils", + "version": "0.18.1", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "cryptography is a package which provides cryptographic recipes and primitives to Python developers.\npyca/cryptography\n=================\n\n.. image:: https://img.shields.io/pypi/v/cryptography.svg\n :target: https://pypi.org/project/cryptography/\n :alt: Latest Version\n\n.. image:: https://readthedocs.org/projects/cryptography/badge/?version=latest\n :target: https://cryptography.io\n :alt: Latest Docs\n\n.. image:: https://github.com/pyca/cryptography/workflows/CI/badge.svg?branch=main\n :target: https://github.com/pyca/cryptography/actions?query=workflow%3ACI+branch%3Amain\n\n.. image:: https://codecov.io/github/pyca/cryptography/coverage.svg?branch=main\n :target: https://codecov.io/github/pyca/cryptography?branch=main\n\n\n``cryptography`` is a package which provides cryptographic recipes and\nprimitives to Python developers. Our goal is for it to be your \"cryptographic\nstandard library\". It supports Python 3.6+ and PyPy3 7.2+.\n\n``cryptography`` includes both high level recipes and low level interfaces to\ncommon cryptographic algorithms such as symmetric ciphers, message digests, and\nkey derivation functions. For example, to encrypt something with\n``cryptography``'s high level symmetric encryption recipe:\n\n.. code-block:: pycon\n\n >>> from cryptography.fernet import Fernet\n >>> # Put this somewhere safe!\n >>> key = Fernet.generate_key()\n >>> f = Fernet(key)\n >>> token = f.encrypt(b\"A really secret message. Not for prying eyes.\")\n >>> token\n '...'\n >>> f.decrypt(token)\n 'A really secret message. Not for prying eyes.'\n\nYou can find more information in the `documentation`_.\n\nYou can install ``cryptography`` with:\n\n.. code-block:: console\n\n $ pip install cryptography\n\nFor full details see `the installation documentation`_.\n\nDiscussion\n~~~~~~~~~~\n\nIf you run into bugs, you can file them in our `issue tracker`_.\n\nWe maintain a `cryptography-dev`_ mailing list for development discussion.\n\nYou can also join ``#pyca`` on ``irc.libera.chat`` to ask questions or get\ninvolved.\n\nSecurity\n~~~~~~~~\n\nNeed to report a security issue? Please consult our `security reporting`_\ndocumentation.\n\n\n.. _`documentation`: https://cryptography.io/\n.. _`the installation documentation`: https://cryptography.io/en/latest/installation/\n.. _`issue tracker`: https://github.com/pyca/cryptography/issues\n.. _`cryptography-dev`: https://mail.python.org/mailman/listinfo/cryptography-dev\n.. _`security reporting`: https://cryptography.io/en/latest/security/", - "release_date": "2022-05-04T00:44:58", + "description": "Docutils -- Python Documentation Utilities\nDocutils is a modular system for processing documentation\ninto useful formats, such as HTML, XML, and LaTeX. For\ninput Docutils supports reStructuredText, an easy-to-read,\nwhat-you-see-is-what-you-get plaintext markup syntax.", + "release_date": "2021-11-23T17:49:38", "parties": [ { "type": "person", "role": "author", - "name": "The Python Cryptographic Authority and individual contributors", - "email": "cryptography-dev@python.org", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Natural Language :: English", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Operating System :: POSIX :: BSD", - "Operating System :: POSIX :: Linux", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Security :: Cryptography" - ], - "homepage_url": "https://github.com/pyca/cryptography", - "download_url": "https://files.pythonhosted.org/packages/51/05/bb2b681f6a77276fc423d04187c39dafdb65b799c8d87b62ca82659f9ead/cryptography-37.0.2.tar.gz", - "size": 585433, - "sha1": null, - "md5": "7477bd10af69e78aed4c83accd401416", - "sha256": "f224ad253cc9cea7568f49077007d2263efa57396a2f2f78114066fd54b5c68e", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/pyca/cryptography/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause OR Apache-2.0", - "classifiers": [ - "License :: OSI Approved :: Apache Software License", - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/cryptography/37.0.2/json", - "datasource_id": null, - "purl": "pkg:pypi/cryptography@37.0.2" - }, - { - "type": "pypi", - "namespace": null, - "name": "docutils", - "version": "0.18.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Docutils -- Python Documentation Utilities\nDocutils is a modular system for processing documentation\ninto useful formats, such as HTML, XML, and LaTeX. For\ninput Docutils supports reStructuredText, an easy-to-read,\nwhat-you-see-is-what-you-get plaintext markup syntax.", - "release_date": "2021-11-23T17:49:38", - "parties": [ - { - "type": "person", - "role": "author", - "name": "David Goodger", - "email": "goodger@python.org", + "name": "David Goodger", + "email": "goodger@python.org", "url": null }, { @@ -3276,111 +2427,6 @@ "datasource_id": null, "purl": "pkg:pypi/docutils@0.18.1" }, - { - "type": "pypi", - "namespace": null, - "name": "docutils", - "version": "0.18.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Docutils -- Python Documentation Utilities\nDocutils is a modular system for processing documentation\ninto useful formats, such as HTML, XML, and LaTeX. For\ninput Docutils supports reStructuredText, an easy-to-read,\nwhat-you-see-is-what-you-get plaintext markup syntax.", - "release_date": "2021-11-23T17:49:42", - "parties": [ - { - "type": "person", - "role": "author", - "name": "David Goodger", - "email": "goodger@python.org", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "docutils-develop list", - "email": "docutils-develop@lists.sourceforge.net", - "url": null - } - ], - "keywords": [ - "Development Status :: 4 - Beta", - "Environment :: Console", - "Intended Audience :: Developers", - "Intended Audience :: End Users/Desktop", - "Intended Audience :: Other Audience", - "Intended Audience :: System Administrators", - "Natural Language :: Afrikaans", - "Natural Language :: Arabic", - "Natural Language :: Catalan", - "Natural Language :: Chinese (Simplified)", - "Natural Language :: Chinese (Traditional)", - "Natural Language :: Czech", - "Natural Language :: Danish", - "Natural Language :: Dutch", - "Natural Language :: English", - "Natural Language :: Esperanto", - "Natural Language :: Finnish", - "Natural Language :: French", - "Natural Language :: Galician", - "Natural Language :: German", - "Natural Language :: Hebrew", - "Natural Language :: Italian", - "Natural Language :: Japanese", - "Natural Language :: Korean", - "Natural Language :: Latvian", - "Natural Language :: Lithuanian", - "Natural Language :: Persian", - "Natural Language :: Polish", - "Natural Language :: Portuguese (Brazilian)", - "Natural Language :: Russian", - "Natural Language :: Slovak", - "Natural Language :: Spanish", - "Natural Language :: Swedish", - "Operating System :: OS Independent", - "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 :: 3.9", - "Topic :: Documentation", - "Topic :: Software Development :: Documentation", - "Topic :: Text Processing" - ], - "homepage_url": "http://docutils.sourceforge.net/", - "download_url": "https://files.pythonhosted.org/packages/57/b1/b880503681ea1b64df05106fc7e3c4e3801736cf63deffc6fa7fc5404cf5/docutils-0.18.1.tar.gz", - "size": 2043249, - "sha1": null, - "md5": "ca5827e2432fd58f4c8d74a6591135de", - "sha256": "679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "public domain, Python, 2-Clause BSD, GPL 3 (see COPYING.txt)", - "classifiers": [ - "License :: OSI Approved :: BSD License", - "License :: OSI Approved :: GNU General Public License (GPL)", - "License :: OSI Approved :: Python Software Foundation License", - "License :: Public Domain" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/docutils/0.18.1/json", - "datasource_id": null, - "purl": "pkg:pypi/docutils@0.18.1" - }, { "type": "pypi", "namespace": null, @@ -3441,66 +2487,6 @@ "datasource_id": null, "purl": "pkg:pypi/dparse2@0.6.1" }, - { - "type": "pypi", - "namespace": null, - "name": "dparse2", - "version": "0.6.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A parser for Python dependency files\n=================\nDependency Parser\n=================\n\n\nA parser for Python manifests and dependency files now at \nhttps://github.com/nexB/dparse2\n\nOriginally at https://github.com/pyupio/dparse\n\nThis is a maintained fork by some of the contributors since upstream stopped\nupdating this.\n\n\nSupported Files\n---------------\n\n+------------------+------------+\n| File | parse |\n+==================+============+\n| conda.yml | yes |\n+------------------+------------+\n| tox.ini | yes |\n+------------------+------------+\n| Pipfile | yes |\n+------------------+------------+\n| Pipfile.lock | yes |\n+------------------+------------+\n\n************\nInstallation\n************\n\nTo install dparse2, run:\n\n.. code-block:: console\n\n $ pip install dparse2\n\nIf you want to update Pipfiles, install the pipenv extra:\n\n.. code-block:: console\n\n $ pip install dparse2[pipenv]\n\n*****\nUsage\n*****\n\nTo use dparse2 in a Python project::\n\n from dparse2 import parse\n from dparse2 import filetypes\n\n content = \"\"\"\n South==1.0.1 --hash=sha256:abcdefghijklmno\n pycrypto>=2.6\n \"\"\"\n\n df = parse(content, file_type=filetypes.requirements_txt)\n\n print(df.json())\n\n\n {\n \"file_type\": \"requirements.txt\",\n \"content\": \"\\nSouth==1.0.1 --hash=sha256:abcdefghijklmno\\npycrypto>=2.6\\n\",\n \"path\": null,\n \"sha\": null,\n \"dependencies\": [\n {\n \"name\": \"South\",\n \"specs\": [\n [\n \"==\",\n \"1.0.1\"\n ]\n ],\n \"line\": \"South==1.0.1 --hash=sha256:abcdefghijklmno\",\n \"source\": \"pypi\",\n \"meta\": {},\n \"line_numbers\": null,\n \"index_server\": null,\n \"hashes\": [\n \"--hash=sha256:abcdefghijklmno\"\n ],\n \"dependency_type\": \"requirements.txt\",\n \"extras\": []\n },\n {\n \"name\": \"pycrypto\",\n \"specs\": [\n [\n \">=\",\n \"2.6\"\n ]\n ],\n \"line\": \"pycrypto>=2.6\",\n \"source\": \"pypi\",\n \"meta\": {},\n \"line_numbers\": null,\n \"index_server\": null,\n \"hashes\": [],\n \"dependency_type\": \"requirements.txt\",\n \"extras\": []\n }\n ]\n }\n\n\n\nThis tool supports Python 3.6 and up. Older version support older Python versions\n\n\n==========\nChangelog\n==========\n\n0.6.1 \n-------\n\n* Use non-deprecated ConfiParser method\n\n\n0.6.0 \n-------\n\n* Fork from upstream dparse that is unresponsive\n* Rename package to dparse2\n* Fix security issue for GHSL-2021-111https://github.com/pyupio/dparse/issues/50\n* Drop support for Python < 3.6 and add support for up to 3.10\n* Drop support for updating requirements files\n* format code with black, sort imports\n\n\n0.5.1 (2020-04-26)\n------------------\n\n* Fixed package metadata removing 2.7 support\n* Install pipenv only when asked for with extras\n\n0.5.0 (2020-03-14)\n------------------\n\nA bug with this package allows it to be installed on Python 2.7 environments,\neven though it should not work on such version. You should stick with version\n0.4.1 version instead for Python 2.7 support.\n\n* Dropped Python 2.7, 3.3, 3.4 support\n* Removed six package\n* Removed pinned dependencies of tests\n* Dropped setup.py tests support in favor of tox\n\n0.4.1 (2018-04-06)\n------------------\n\n* Fixed a packaging error.\n\n0.4.0 (2018-04-06)\n------------------\n\n* pipenv is now an optional dependency that's only used when updating a Pipfile. Install it with dparse[pipenv]\n* Added support for invalid toml Pipfiles (thanks @pombredanne)\n\n\n0.3.0 (2018-03-01)\n------------------\n\n* Added support for setup.cfg files (thanks @kexepal)\n* Dependencies from Pipfiles now include the section (thanks @paulortman)\n* Multiline requirements are now ignored if they are marked\n* Added experimental support for Pipfiles\n\n0.2.1 (2017-07-19)\n------------------\n\n* Internal refactoring\n\n0.2.0 (2017-07-19)\n------------------\n\n* Removed setuptools dependency\n\n\n0.1.1 (2017-07-14)\n------------------\n\n* Fixed a bug that was causing the parser to throw errors on invalid requirements.\n\n0.1.0 (2017-07-11)\n------------------\n\n* Initial, not much to see here.", - "release_date": "2022-05-07T16:35:37", - "parties": [ - { - "type": "person", - "role": "author", - "name": "originally from Jannis Gebauer, maintained by AboutCode.org", - "email": "info@nexb.com", - "url": null - } - ], - "keywords": [ - "dparse pypi dependencies tox conda pipfile setup.cfg", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Natural Language :: English", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9" - ], - "homepage_url": "https://github.com/nexB/dparse2", - "download_url": "https://files.pythonhosted.org/packages/2d/a3/49cd39abdf8b4832cba27d635a775b721388e50671bee7ea0d10afcf0cfd/dparse2-0.6.1.tar.gz", - "size": 10458, - "sha1": null, - "md5": "8d8c7be322b2211c5c5eea6150da2832", - "sha256": "fbafb839c3dc83040012af2602a00ca4e4b1693a9b1988492150466afa59dd26", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/dparse2/0.6.1/json", - "datasource_id": null, - "purl": "pkg:pypi/dparse2@0.6.1" - }, { "type": "pypi", "namespace": null, @@ -3563,39 +2549,48 @@ { "type": "pypi", "namespace": null, - "name": "et-xmlfile", - "version": "1.1.0", + "name": "execnet", + "version": "1.9.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "An implementation of lxml.xmlfile for the standard library\net_xmfile\n=========\n\net_xmlfile is a low memory library for creating large XML files.\n\nIt is based upon the `xmlfile module from lxml `_ with the aim of allowing code to be developed that will work with both libraries. It was developed initially for the openpyxl project but is now a standalone module.\n\nThe code was written by Elias Rabel as part of the `Python D\u00fcsseldorf `_ openpyxl sprint in September 2014.\n\n\nNote on performance\n-------------------\n\nThe code was not developed with performance in mind but turned out to be faster than the existing SAX-based implementation but is significantly slower than lxml's xmlfile. There is one area where an optimisation for lxml will negatively affect the performance of et_xmfile and that is when using the `.element()` method on an xmlfile context manager. It is, therefore, recommended not to use this, though the method is provided for code compatibility.", - "release_date": "2021-04-26T13:26:05", + "description": "execnet: rapid multi-Python deployment\nexecnet: distributed Python deployment and communication\n========================================================\n\nImportant\n---------\n\n**execnet currently is in maintenance-only mode, mostly because it is still the backend\nof the pytest-xdist plugin. Do not use in new projects.**\n\n.. image:: https://img.shields.io/pypi/v/execnet.svg\n :target: https://pypi.org/project/execnet/\n\n.. image:: https://anaconda.org/conda-forge/execnet/badges/version.svg\n :target: https://anaconda.org/conda-forge/execnet\n\n.. image:: https://img.shields.io/pypi/pyversions/execnet.svg\n :target: https://pypi.org/project/execnet/\n\n.. image:: https://github.com/pytest-dev/execnet/workflows/build/badge.svg\n :target: https://github.com/pytest-dev/execnet/actions?query=workflow%3Abuild\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/python/black\n\n.. _execnet: http://codespeak.net/execnet\n\nexecnet_ provides carefully tested means to ad-hoc interact with Python\ninterpreters across version, platform and network barriers. It provides\na minimal and fast API targetting the following uses:\n\n* distribute tasks to local or remote processes\n* write and deploy hybrid multi-process applications\n* write scripts to administer multiple hosts\n\nFeatures\n------------------\n\n* zero-install bootstrapping: no remote installation required!\n\n* flexible communication: send/receive as well as\n callback/queue mechanisms supported\n\n* simple serialization of python builtin types (no pickling)\n\n* grouped creation and robust termination of processes\n\n* interoperable between Windows and Unix-ish systems.\n\n* integrates with different threading models, including standard\n os threads, eventlet and gevent based systems.", + "release_date": "2021-06-13T13:47:18", "parties": [ { "type": "person", "role": "author", - "name": "See ATUHORS.txt", - "email": "charlie.clark@clark-consulting.eu", + "name": "holger krekel and others", + "email": null, "url": null } ], "keywords": [ "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", - "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 :: 3.9" + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Libraries", + "Topic :: System :: Distributed Computing", + "Topic :: System :: Networking" ], - "homepage_url": "https://foss.heptapod.net/openpyxl/et_xmlfile", - "download_url": "https://files.pythonhosted.org/packages/3d/5d/0413a31d184a20c763ad741cc7852a659bf15094c24840c5bdd1754765cd/et_xmlfile-1.1.0.tar.gz", - "size": 3218, + "homepage_url": "https://execnet.readthedocs.io/en/latest/", + "download_url": "https://files.pythonhosted.org/packages/81/c0/3072ecc23f4c5e0a1af35e3a222855cfd9c80a1a105ca67be3b6172637dd/execnet-1.9.0-py2.py3-none-any.whl", + "size": 39002, "sha1": null, - "md5": "8fbae9b969eac28c02f5073febefc445", - "sha256": "8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c", + "md5": "6d06f41bd3b5d800debf505d81d0cb37", + "sha256": "a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -3615,65 +2610,64 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/et-xmlfile/1.1.0/json", + "api_data_url": "https://pypi.org/pypi/execnet/1.9.0/json", "datasource_id": null, - "purl": "pkg:pypi/et-xmlfile@1.1.0" + "purl": "pkg:pypi/execnet@1.9.0" }, { "type": "pypi", "namespace": null, - "name": "execnet", - "version": "1.9.0", + "name": "flask", + "version": "2.1.2", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "execnet: rapid multi-Python deployment\nexecnet: distributed Python deployment and communication\n========================================================\n\nImportant\n---------\n\n**execnet currently is in maintenance-only mode, mostly because it is still the backend\nof the pytest-xdist plugin. Do not use in new projects.**\n\n.. image:: https://img.shields.io/pypi/v/execnet.svg\n :target: https://pypi.org/project/execnet/\n\n.. image:: https://anaconda.org/conda-forge/execnet/badges/version.svg\n :target: https://anaconda.org/conda-forge/execnet\n\n.. image:: https://img.shields.io/pypi/pyversions/execnet.svg\n :target: https://pypi.org/project/execnet/\n\n.. image:: https://github.com/pytest-dev/execnet/workflows/build/badge.svg\n :target: https://github.com/pytest-dev/execnet/actions?query=workflow%3Abuild\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/python/black\n\n.. _execnet: http://codespeak.net/execnet\n\nexecnet_ provides carefully tested means to ad-hoc interact with Python\ninterpreters across version, platform and network barriers. It provides\na minimal and fast API targetting the following uses:\n\n* distribute tasks to local or remote processes\n* write and deploy hybrid multi-process applications\n* write scripts to administer multiple hosts\n\nFeatures\n------------------\n\n* zero-install bootstrapping: no remote installation required!\n\n* flexible communication: send/receive as well as\n callback/queue mechanisms supported\n\n* simple serialization of python builtin types (no pickling)\n\n* grouped creation and robust termination of processes\n\n* interoperable between Windows and Unix-ish systems.\n\n* integrates with different threading models, including standard\n os threads, eventlet and gevent based systems.", - "release_date": "2021-06-13T13:47:18", - "parties": [ + "description": "A simple framework for building complex web applications.\nFlask\n=====\n\nFlask is a lightweight `WSGI`_ web application framework. It is designed\nto make getting started quick and easy, with the ability to scale up to\ncomplex applications. It began as a simple wrapper around `Werkzeug`_\nand `Jinja`_ and has become one of the most popular Python web\napplication frameworks.\n\nFlask offers suggestions, but doesn't enforce any dependencies or\nproject layout. It is up to the developer to choose the tools and\nlibraries they want to use. There are many extensions provided by the\ncommunity that make adding new functionality easy.\n\n.. _WSGI: https://wsgi.readthedocs.io/\n.. _Werkzeug: https://werkzeug.palletsprojects.com/\n.. _Jinja: https://jinja.palletsprojects.com/\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U Flask\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n # save this as app.py\n from flask import Flask\n\n app = Flask(__name__)\n\n @app.route(\"/\")\n def hello():\n return \"Hello, World!\"\n\n.. code-block:: text\n\n $ flask run\n * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)\n\n\nContributing\n------------\n\nFor guidance on setting up a development environment and how to make a\ncontribution to Flask, see the `contributing guidelines`_.\n\n.. _contributing guidelines: https://github.com/pallets/flask/blob/main/CONTRIBUTING.rst\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Flask and the libraries\nit uses. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://flask.palletsprojects.com/\n- Changes: https://flask.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/Flask/\n- Source Code: https://github.com/pallets/flask/\n- Issue Tracker: https://github.com/pallets/flask/issues/\n- Website: https://palletsprojects.com/p/flask/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", + "release_date": "2022-04-28T17:47:38", + "parties": [ { "type": "person", "role": "author", - "name": "holger krekel and others", - "email": null, + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "url": null + }, + { + "type": "person", + "role": "maintainer", + "name": "Pallets", + "email": "contact@palletsprojects.com", "url": null } ], "keywords": [ "Development Status :: 5 - Production/Stable", + "Environment :: Web Environment", + "Framework :: Flask", "Intended Audience :: Developers", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "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 :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries", - "Topic :: System :: Distributed Computing", - "Topic :: System :: Networking" + "Operating System :: OS Independent", + "Programming Language :: Python", + "Topic :: Internet :: WWW/HTTP :: Dynamic Content", + "Topic :: Internet :: WWW/HTTP :: WSGI", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + "Topic :: Software Development :: Libraries :: Application Frameworks" ], - "homepage_url": "https://execnet.readthedocs.io/en/latest/", - "download_url": "https://files.pythonhosted.org/packages/81/c0/3072ecc23f4c5e0a1af35e3a222855cfd9c80a1a105ca67be3b6172637dd/execnet-1.9.0-py2.py3-none-any.whl", - "size": 39002, + "homepage_url": "https://palletsprojects.com/p/flask", + "download_url": "https://files.pythonhosted.org/packages/ba/76/e9580e494eaf6f09710b0f3b9000c9c0363e44af5390be32bb0394165853/Flask-2.1.2-py3-none-any.whl", + "size": 95235, "sha1": null, - "md5": "6d06f41bd3b5d800debf505d81d0cb37", - "sha256": "a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142", + "md5": "07aede47b441c019aeebbeaed6a76215", + "sha256": "fad5b446feb0d6db6aec0c3184d16a8c1f6c3e464b511649c8918a9be100b4fe", "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, + "bug_tracking_url": "https://github.com/pallets/flask/issues/", + "code_view_url": "https://github.com/pallets/flask/", "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { - "license": "MIT", + "license": "BSD-3-Clause", "classifiers": [ - "License :: OSI Approved :: MIT License" + "License :: OSI Approved :: BSD License" ] }, "notice_text": null, @@ -3683,38 +2677,38 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/execnet/1.9.0/json", + "api_data_url": "https://pypi.org/pypi/flask/2.1.2/json", "datasource_id": null, - "purl": "pkg:pypi/execnet@1.9.0" + "purl": "pkg:pypi/flask@2.1.2" }, { "type": "pypi", "namespace": null, - "name": "execnet", - "version": "1.9.0", + "name": "idna", + "version": "3.3", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "execnet: rapid multi-Python deployment\nexecnet: distributed Python deployment and communication\n========================================================\n\nImportant\n---------\n\n**execnet currently is in maintenance-only mode, mostly because it is still the backend\nof the pytest-xdist plugin. Do not use in new projects.**\n\n.. image:: https://img.shields.io/pypi/v/execnet.svg\n :target: https://pypi.org/project/execnet/\n\n.. image:: https://anaconda.org/conda-forge/execnet/badges/version.svg\n :target: https://anaconda.org/conda-forge/execnet\n\n.. image:: https://img.shields.io/pypi/pyversions/execnet.svg\n :target: https://pypi.org/project/execnet/\n\n.. image:: https://github.com/pytest-dev/execnet/workflows/build/badge.svg\n :target: https://github.com/pytest-dev/execnet/actions?query=workflow%3Abuild\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/python/black\n\n.. _execnet: http://codespeak.net/execnet\n\nexecnet_ provides carefully tested means to ad-hoc interact with Python\ninterpreters across version, platform and network barriers. It provides\na minimal and fast API targetting the following uses:\n\n* distribute tasks to local or remote processes\n* write and deploy hybrid multi-process applications\n* write scripts to administer multiple hosts\n\nFeatures\n------------------\n\n* zero-install bootstrapping: no remote installation required!\n\n* flexible communication: send/receive as well as\n callback/queue mechanisms supported\n\n* simple serialization of python builtin types (no pickling)\n\n* grouped creation and robust termination of processes\n\n* interoperable between Windows and Unix-ish systems.\n\n* integrates with different threading models, including standard\n os threads, eventlet and gevent based systems.", - "release_date": "2021-06-13T13:47:19", + "description": "Internationalized Domain Names in Applications (IDNA)\n=====================================================\n\nSupport for the Internationalised Domain Names in Applications\n(IDNA) protocol as specified in `RFC 5891 `_.\nThis is the latest version of the protocol and is sometimes referred to as\n\u201cIDNA 2008\u201d.\n\nThis library also provides support for Unicode Technical Standard 46,\n`Unicode IDNA Compatibility Processing `_.\n\nThis acts as a suitable replacement for the \u201cencodings.idna\u201d module that\ncomes with the Python standard library, but which only supports the\nolder superseded IDNA specification (`RFC 3490 `_).\n\nBasic functions are simply executed:\n\n.. code-block:: pycon\n\n >>> import idna\n >>> idna.encode('\u30c9\u30e1\u30a4\u30f3.\u30c6\u30b9\u30c8')\n b'xn--eckwd4c7c.xn--zckzah'\n >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah'))\n \u30c9\u30e1\u30a4\u30f3.\u30c6\u30b9\u30c8\n\n\nInstallation\n------------\n\nTo install this library, you can use pip:\n\n.. code-block:: bash\n\n $ pip install idna\n\nAlternatively, you can install the package using the bundled setup script:\n\n.. code-block:: bash\n\n $ python setup.py install\n\n\nUsage\n-----\n\nFor typical usage, the ``encode`` and ``decode`` functions will take a domain\nname argument and perform a conversion to A-labels or U-labels respectively.\n\n.. code-block:: pycon\n\n >>> import idna\n >>> idna.encode('\u30c9\u30e1\u30a4\u30f3.\u30c6\u30b9\u30c8')\n b'xn--eckwd4c7c.xn--zckzah'\n >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah'))\n \u30c9\u30e1\u30a4\u30f3.\u30c6\u30b9\u30c8\n\nYou may use the codec encoding and decoding methods using the\n``idna.codec`` module:\n\n.. code-block:: pycon\n\n >>> import idna.codec\n >>> print('\u0434\u043e\u043c\u0435\u043d.\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435'.encode('idna'))\n b'xn--d1acufc.xn--80akhbyknj4f'\n >>> print(b'xn--d1acufc.xn--80akhbyknj4f'.decode('idna'))\n \u0434\u043e\u043c\u0435\u043d.\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435\n\nConversions can be applied at a per-label basis using the ``ulabel`` or ``alabel``\nfunctions if necessary:\n\n.. code-block:: pycon\n\n >>> idna.alabel('\u6d4b\u8bd5')\n b'xn--0zwm56d'\n\nCompatibility Mapping (UTS #46)\n+++++++++++++++++++++++++++++++\n\nAs described in `RFC 5895 `_, the IDNA\nspecification does not normalize input from different potential ways a user\nmay input a domain name. This functionality, known as a \u201cmapping\u201d, is \nconsidered by the specification to be a local user-interface issue distinct\nfrom IDNA conversion functionality.\n\nThis library provides one such mapping, that was developed by the Unicode\nConsortium. Known as `Unicode IDNA Compatibility Processing `_,\nit provides for both a regular mapping for typical applications, as well as\na transitional mapping to help migrate from older IDNA 2003 applications.\n\nFor example, \u201cK\u00f6nigsg\u00e4\u00dfchen\u201d is not a permissible label as *LATIN CAPITAL\nLETTER K* is not allowed (nor are capital letters in general). UTS 46 will\nconvert this into lower case prior to applying the IDNA conversion.\n\n.. code-block:: pycon\n\n >>> import idna\n >>> idna.encode('K\u00f6nigsg\u00e4\u00dfchen')\n ...\n idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'K\u00f6nigsg\u00e4\u00dfchen' not allowed\n >>> idna.encode('K\u00f6nigsg\u00e4\u00dfchen', uts46=True)\n b'xn--knigsgchen-b4a3dun'\n >>> print(idna.decode('xn--knigsgchen-b4a3dun'))\n k\u00f6nigsg\u00e4\u00dfchen\n\nTransitional processing provides conversions to help transition from the older\n2003 standard to the current standard. For example, in the original IDNA\nspecification, the *LATIN SMALL LETTER SHARP S* (\u00df) was converted into two\n*LATIN SMALL LETTER S* (ss), whereas in the current IDNA specification this\nconversion is not performed.\n\n.. code-block:: pycon\n\n >>> idna.encode('K\u00f6nigsg\u00e4\u00dfchen', uts46=True, transitional=True)\n 'xn--knigsgsschen-lcb0w'\n\nImplementors should use transitional processing with caution, only in rare\ncases where conversion from legacy labels to current labels must be performed\n(i.e. IDNA implementations that pre-date 2008). For typical applications\nthat just need to convert labels, transitional processing is unlikely to be\nbeneficial and could produce unexpected incompatible results.\n\n``encodings.idna`` Compatibility\n++++++++++++++++++++++++++++++++\n\nFunction calls from the Python built-in ``encodings.idna`` module are\nmapped to their IDNA 2008 equivalents using the ``idna.compat`` module.\nSimply substitute the ``import`` clause in your code to refer to the\nnew module name.\n\nExceptions\n----------\n\nAll errors raised during the conversion following the specification should\nraise an exception derived from the ``idna.IDNAError`` base class.\n\nMore specific exceptions that may be generated as ``idna.IDNABidiError``\nwhen the error reflects an illegal combination of left-to-right and\nright-to-left characters in a label; ``idna.InvalidCodepoint`` when\na specific codepoint is an illegal character in an IDN label (i.e.\nINVALID); and ``idna.InvalidCodepointContext`` when the codepoint is\nillegal based on its positional context (i.e. it is CONTEXTO or CONTEXTJ\nbut the contextual requirements are not satisfied.)\n\nBuilding and Diagnostics\n------------------------\n\nThe IDNA and UTS 46 functionality relies upon pre-calculated lookup\ntables for performance. These tables are derived from computing against\neligibility criteria in the respective standards. These tables are\ncomputed using the command-line script ``tools/idna-data``.\n\nThis tool will fetch relevant codepoint data from the Unicode repository \nand perform the required calculations to identify eligibility. There are \nthree main modes:\n\n* ``idna-data make-libdata``. Generates ``idnadata.py`` and ``uts46data.py``,\n the pre-calculated lookup tables using for IDNA and UTS 46 conversions. Implementors\n who wish to track this library against a different Unicode version may use this tool\n to manually generate a different version of the ``idnadata.py`` and ``uts46data.py``\n files.\n\n* ``idna-data make-table``. Generate a table of the IDNA disposition\n (e.g. PVALID, CONTEXTJ, CONTEXTO) in the format found in Appendix B.1 of RFC\n 5892 and the pre-computed tables published by `IANA `_.\n\n* ``idna-data U+0061``. Prints debugging output on the various properties\n associated with an individual Unicode codepoint (in this case, U+0061), that are\n used to assess the IDNA and UTS 46 status of a codepoint. This is helpful in debugging\n or analysis.\n\nThe tool accepts a number of arguments, described using ``idna-data -h``. Most notably,\nthe ``--version`` argument allows the specification of the version of Unicode to use\nin computing the table data. For example, ``idna-data --version 9.0.0 make-libdata``\nwill generate library data against Unicode 9.0.0.\n\n\nAdditional Notes\n----------------\n\n* **Packages**. The latest tagged release version is published in the\n `Python Package Index `_.\n\n* **Version support**. This library supports Python 3.5 and higher. As this library\n serves as a low-level toolkit for a variety of applications, many of which strive\n for broad compatibility with older Python versions, there is no rush to remove\n older intepreter support. Removing support for older versions should be well\n justified in that the maintenance burden has become too high.\n\n* **Python 2**. Python 2 is supported by version 2.x of this library. While active\n development of the version 2.x series has ended, notable issues being corrected\n may be backported to 2.x. Use \"idna<3\" in your requirements file if you need this\n library for a Python 2 application.\n\n* **Testing**. The library has a test suite based on each rule of the IDNA specification, as\n well as tests that are provided as part of the Unicode Technical Standard 46,\n `Unicode IDNA Compatibility Processing `_.\n\n* **Emoji**. It is an occasional request to support emoji domains in this library. Encoding\n of symbols like emoji is expressly prohibited by the technical standard IDNA 2008 and\n emoji domains are broadly phased out across the domain industry due to associated security\n risks. For now, applications that wish need to support these non-compliant labels may\n wish to consider trying the encode/decode operation in this library first, and then falling\n back to using `encodings.idna`. See `the Github project `_\n for more discussion.", + "release_date": "2021-10-12T23:33:38", "parties": [ { "type": "person", "role": "author", - "name": "holger krekel and others", - "email": null, + "name": "Kim Davies", + "email": "kim@cynosure.com.au", "url": null } ], "keywords": [ "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.7", + "Intended Audience :: System Administrators", + "Operating System :: OS Independent", + "Programming Language :: Python", "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", @@ -3722,16 +2716,16 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries", - "Topic :: System :: Distributed Computing", - "Topic :: System :: Networking" + "Topic :: Internet :: Name Service (DNS)", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Utilities" ], - "homepage_url": "https://execnet.readthedocs.io/en/latest/", - "download_url": "https://files.pythonhosted.org/packages/7a/3c/b5ac9fc61e1e559ced3e40bf5b518a4142536b34eb274aa50dff29cb89f5/execnet-1.9.0.tar.gz", - "size": 173884, + "homepage_url": "https://github.com/kjd/idna", + "download_url": "https://files.pythonhosted.org/packages/04/a2/d918dcd22354d8958fe113e1a3630137e0fc8b44859ade3063982eacd2a4/idna-3.3-py3-none-any.whl", + "size": 61160, "sha1": null, - "md5": "69f7f721586d5a02b66cac7cb388b7e3", - "sha256": "8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5", + "md5": "461e73a409996cb35e00116e5301bac6", + "sha256": "84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -3739,9 +2733,9 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "MIT", + "license": "BSD-3-Clause", "classifiers": [ - "License :: OSI Approved :: MIT License" + "License :: OSI Approved :: BSD License" ] }, "notice_text": null, @@ -3751,64 +2745,50 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/execnet/1.9.0/json", + "api_data_url": "https://pypi.org/pypi/idna/3.3/json", "datasource_id": null, - "purl": "pkg:pypi/execnet@1.9.0" + "purl": "pkg:pypi/idna@3.3" }, { "type": "pypi", "namespace": null, - "name": "flask", - "version": "2.1.2", + "name": "importlib-metadata", + "version": "4.8.3", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "A simple framework for building complex web applications.\nFlask\n=====\n\nFlask is a lightweight `WSGI`_ web application framework. It is designed\nto make getting started quick and easy, with the ability to scale up to\ncomplex applications. It began as a simple wrapper around `Werkzeug`_\nand `Jinja`_ and has become one of the most popular Python web\napplication frameworks.\n\nFlask offers suggestions, but doesn't enforce any dependencies or\nproject layout. It is up to the developer to choose the tools and\nlibraries they want to use. There are many extensions provided by the\ncommunity that make adding new functionality easy.\n\n.. _WSGI: https://wsgi.readthedocs.io/\n.. _Werkzeug: https://werkzeug.palletsprojects.com/\n.. _Jinja: https://jinja.palletsprojects.com/\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U Flask\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n # save this as app.py\n from flask import Flask\n\n app = Flask(__name__)\n\n @app.route(\"/\")\n def hello():\n return \"Hello, World!\"\n\n.. code-block:: text\n\n $ flask run\n * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)\n\n\nContributing\n------------\n\nFor guidance on setting up a development environment and how to make a\ncontribution to Flask, see the `contributing guidelines`_.\n\n.. _contributing guidelines: https://github.com/pallets/flask/blob/main/CONTRIBUTING.rst\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Flask and the libraries\nit uses. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://flask.palletsprojects.com/\n- Changes: https://flask.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/Flask/\n- Source Code: https://github.com/pallets/flask/\n- Issue Tracker: https://github.com/pallets/flask/issues/\n- Website: https://palletsprojects.com/p/flask/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2022-04-28T17:47:38", + "description": "Read metadata from Python packages\n.. image:: https://img.shields.io/pypi/v/importlib_metadata.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/importlib_metadata.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/importlib_metadata\n\n.. image:: https://github.com/python/importlib_metadata/workflows/tests/badge.svg\n :target: https://github.com/python/importlib_metadata/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. image:: https://readthedocs.org/projects/importlib-metadata/badge/?version=latest\n :target: https://importlib-metadata.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2021-informational\n :target: https://blog.jaraco.com/skeleton\n\n\nLibrary to access the metadata for a Python package.\n\nThis package supplies third-party access to the functionality of\n`importlib.metadata `_\nincluding improvements added to subsequent Python versions.\n\n\nCompatibility\n=============\n\nNew features are introduced in this third-party library and later merged\ninto CPython. The following table indicates which versions of this library\nwere contributed to different versions in the standard library:\n\n.. list-table::\n :header-rows: 1\n\n * - importlib_metadata\n - stdlib\n * - 4.4\n - 3.10\n * - 1.4\n - 3.8\n\n\nUsage\n=====\n\nSee the `online documentation `_\nfor usage details.\n\n`Finder authors\n`_ can\nalso add support for custom package installers. See the above documentation\nfor details.\n\n\nCaveats\n=======\n\nThis project primarily supports third-party packages installed by PyPA\ntools (or other conforming packages). It does not support:\n\n- Packages in the stdlib.\n- Packages installed without metadata.\n\nProject details\n===============\n\n * Project home: https://github.com/python/importlib_metadata\n * Report bugs at: https://github.com/python/importlib_metadata/issues\n * Code hosting: https://github.com/python/importlib_metadata\n * Documentation: https://importlib_metadata.readthedocs.io/", + "release_date": "2021-12-16T14:42:25", "parties": [ { "type": "person", "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", + "name": "Jason R. Coombs", + "email": "jaraco@jaraco.com", "url": null } ], "keywords": [ "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Framework :: Flask", "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Internet :: WWW/HTTP :: WSGI", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - "Topic :: Software Development :: Libraries :: Application Frameworks" + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only" ], - "homepage_url": "https://palletsprojects.com/p/flask", - "download_url": "https://files.pythonhosted.org/packages/ba/76/e9580e494eaf6f09710b0f3b9000c9c0363e44af5390be32bb0394165853/Flask-2.1.2-py3-none-any.whl", - "size": 95235, + "homepage_url": "https://github.com/python/importlib_metadata", + "download_url": "https://files.pythonhosted.org/packages/a0/a1/b153a0a4caf7a7e3f15c2cd56c7702e2cf3d89b1b359d1f1c5e59d68f4ce/importlib_metadata-4.8.3-py3-none-any.whl", + "size": 17978, "sha1": null, - "md5": "07aede47b441c019aeebbeaed6a76215", - "sha256": "fad5b446feb0d6db6aec0c3184d16a8c1f6c3e464b511649c8918a9be100b4fe", + "md5": "492a63a286daa402226ae8f36cff221d", + "sha256": "65a9576a5b2d58ca44d133c42a241905cc45e34d2c06fd5ba2bafa221e5d7b5e", "sha512": null, - "bug_tracking_url": "https://github.com/pallets/flask/issues/", - "code_view_url": "https://github.com/pallets/flask/", + "bug_tracking_url": null, + "code_view_url": null, "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { - "license": "BSD-3-Clause", "classifiers": [ - "License :: OSI Approved :: BSD License" + "License :: OSI Approved :: Apache Software License" ] }, "notice_text": null, @@ -3818,64 +2798,57 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/flask/2.1.2/json", + "api_data_url": "https://pypi.org/pypi/importlib-metadata/4.8.3/json", "datasource_id": null, - "purl": "pkg:pypi/flask@2.1.2" + "purl": "pkg:pypi/importlib-metadata@4.8.3" }, { "type": "pypi", "namespace": null, - "name": "flask", - "version": "2.1.2", + "name": "iniconfig", + "version": "1.1.1", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "A simple framework for building complex web applications.\nFlask\n=====\n\nFlask is a lightweight `WSGI`_ web application framework. It is designed\nto make getting started quick and easy, with the ability to scale up to\ncomplex applications. It began as a simple wrapper around `Werkzeug`_\nand `Jinja`_ and has become one of the most popular Python web\napplication frameworks.\n\nFlask offers suggestions, but doesn't enforce any dependencies or\nproject layout. It is up to the developer to choose the tools and\nlibraries they want to use. There are many extensions provided by the\ncommunity that make adding new functionality easy.\n\n.. _WSGI: https://wsgi.readthedocs.io/\n.. _Werkzeug: https://werkzeug.palletsprojects.com/\n.. _Jinja: https://jinja.palletsprojects.com/\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U Flask\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n # save this as app.py\n from flask import Flask\n\n app = Flask(__name__)\n\n @app.route(\"/\")\n def hello():\n return \"Hello, World!\"\n\n.. code-block:: text\n\n $ flask run\n * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)\n\n\nContributing\n------------\n\nFor guidance on setting up a development environment and how to make a\ncontribution to Flask, see the `contributing guidelines`_.\n\n.. _contributing guidelines: https://github.com/pallets/flask/blob/main/CONTRIBUTING.rst\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Flask and the libraries\nit uses. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://flask.palletsprojects.com/\n- Changes: https://flask.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/Flask/\n- Source Code: https://github.com/pallets/flask/\n- Issue Tracker: https://github.com/pallets/flask/issues/\n- Website: https://palletsprojects.com/p/flask/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2022-04-28T17:47:40", + "description": "iniconfig: brain-dead simple config-ini parsing\niniconfig: brain-dead simple parsing of ini files\n=======================================================\n\niniconfig is a small and simple INI-file parser module\nhaving a unique set of features:\n\n* tested against Python2.4 across to Python3.2, Jython, PyPy\n* maintains order of sections and entries\n* supports multi-line values with or without line-continuations\n* supports \"#\" comments everywhere\n* raises errors with proper line-numbers\n* no bells and whistles like automatic substitutions\n* iniconfig raises an Error if two sections have the same name.\n\nIf you encounter issues or have feature wishes please report them to:\n\n http://github.com/RonnyPfannschmidt/iniconfig/issues\n\nBasic Example\n===================================\n\nIf you have an ini file like this::\n\n # content of example.ini\n [section1] # comment\n name1=value1 # comment\n name1b=value1,value2 # comment\n\n [section2]\n name2=\n line1\n line2\n\nthen you can do::\n\n >>> import iniconfig\n >>> ini = iniconfig.IniConfig(\"example.ini\")\n >>> ini['section1']['name1'] # raises KeyError if not exists\n 'value1'\n >>> ini.get('section1', 'name1b', [], lambda x: x.split(\",\"))\n ['value1', 'value2']\n >>> ini.get('section1', 'notexist', [], lambda x: x.split(\",\"))\n []\n >>> [x.name for x in list(ini)]\n ['section1', 'section2']\n >>> list(list(ini)[0].items())\n [('name1', 'value1'), ('name1b', 'value1,value2')]\n >>> 'section1' in ini\n True\n >>> 'inexistendsection' in ini\n False", + "release_date": "2020-10-16T17:37:23", "parties": [ { "type": "person", "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", + "name": "Ronny Pfannschmidt, Holger Krekel", + "email": "opensource@ronnypfannschmidt.de, holger.krekel@gmail.com", "url": null } ], "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Framework :: Flask", + "Development Status :: 4 - Beta", "Intended Audience :: Developers", - "Operating System :: OS Independent", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", "Programming Language :: Python", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Internet :: WWW/HTTP :: WSGI", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - "Topic :: Software Development :: Libraries :: Application Frameworks" + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 3", + "Topic :: Software Development :: Libraries", + "Topic :: Utilities" ], - "homepage_url": "https://palletsprojects.com/p/flask", - "download_url": "https://files.pythonhosted.org/packages/d3/3c/94f38d4db919a9326a706ad56f05a7e6f0c8f7b7d93e2997cca54d3bc14b/Flask-2.1.2.tar.gz", - "size": 631846, + "homepage_url": "http://github.com/RonnyPfannschmidt/iniconfig", + "download_url": "https://files.pythonhosted.org/packages/9b/dd/b3c12c6d707058fa947864b67f0c4e0c39ef8610988d7baea9578f3c48f3/iniconfig-1.1.1-py2.py3-none-any.whl", + "size": 4990, "sha1": null, - "md5": "93f1832e5be704ef6ff2a4124579cd85", - "sha256": "315ded2ddf8a6281567edb27393010fe3406188bafbfe65a3339d5787d89e477", + "md5": "90f3e1bb7ced782f2b04eb5af266ecb7", + "sha256": "011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", "sha512": null, - "bug_tracking_url": "https://github.com/pallets/flask/issues/", - "code_view_url": "https://github.com/pallets/flask/", + "bug_tracking_url": null, + "code_view_url": null, "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { - "license": "BSD-3-Clause", + "license": "MIT License", "classifiers": [ - "License :: OSI Approved :: BSD License" + "License :: OSI Approved :: MIT License" ] }, "notice_text": null, @@ -3885,55 +2858,45 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/flask/2.1.2/json", + "api_data_url": "https://pypi.org/pypi/iniconfig/1.1.1/json", "datasource_id": null, - "purl": "pkg:pypi/flask@2.1.2" + "purl": "pkg:pypi/iniconfig@1.1.1" }, { "type": "pypi", "namespace": null, - "name": "idna", - "version": "3.3", + "name": "intbitset", + "version": "3.0.1", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Internationalized Domain Names in Applications (IDNA)\n=====================================================\n\nSupport for the Internationalised Domain Names in Applications\n(IDNA) protocol as specified in `RFC 5891 `_.\nThis is the latest version of the protocol and is sometimes referred to as\n\u201cIDNA 2008\u201d.\n\nThis library also provides support for Unicode Technical Standard 46,\n`Unicode IDNA Compatibility Processing `_.\n\nThis acts as a suitable replacement for the \u201cencodings.idna\u201d module that\ncomes with the Python standard library, but which only supports the\nolder superseded IDNA specification (`RFC 3490 `_).\n\nBasic functions are simply executed:\n\n.. code-block:: pycon\n\n >>> import idna\n >>> idna.encode('\u30c9\u30e1\u30a4\u30f3.\u30c6\u30b9\u30c8')\n b'xn--eckwd4c7c.xn--zckzah'\n >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah'))\n \u30c9\u30e1\u30a4\u30f3.\u30c6\u30b9\u30c8\n\n\nInstallation\n------------\n\nTo install this library, you can use pip:\n\n.. code-block:: bash\n\n $ pip install idna\n\nAlternatively, you can install the package using the bundled setup script:\n\n.. code-block:: bash\n\n $ python setup.py install\n\n\nUsage\n-----\n\nFor typical usage, the ``encode`` and ``decode`` functions will take a domain\nname argument and perform a conversion to A-labels or U-labels respectively.\n\n.. code-block:: pycon\n\n >>> import idna\n >>> idna.encode('\u30c9\u30e1\u30a4\u30f3.\u30c6\u30b9\u30c8')\n b'xn--eckwd4c7c.xn--zckzah'\n >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah'))\n \u30c9\u30e1\u30a4\u30f3.\u30c6\u30b9\u30c8\n\nYou may use the codec encoding and decoding methods using the\n``idna.codec`` module:\n\n.. code-block:: pycon\n\n >>> import idna.codec\n >>> print('\u0434\u043e\u043c\u0435\u043d.\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435'.encode('idna'))\n b'xn--d1acufc.xn--80akhbyknj4f'\n >>> print(b'xn--d1acufc.xn--80akhbyknj4f'.decode('idna'))\n \u0434\u043e\u043c\u0435\u043d.\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435\n\nConversions can be applied at a per-label basis using the ``ulabel`` or ``alabel``\nfunctions if necessary:\n\n.. code-block:: pycon\n\n >>> idna.alabel('\u6d4b\u8bd5')\n b'xn--0zwm56d'\n\nCompatibility Mapping (UTS #46)\n+++++++++++++++++++++++++++++++\n\nAs described in `RFC 5895 `_, the IDNA\nspecification does not normalize input from different potential ways a user\nmay input a domain name. This functionality, known as a \u201cmapping\u201d, is \nconsidered by the specification to be a local user-interface issue distinct\nfrom IDNA conversion functionality.\n\nThis library provides one such mapping, that was developed by the Unicode\nConsortium. Known as `Unicode IDNA Compatibility Processing `_,\nit provides for both a regular mapping for typical applications, as well as\na transitional mapping to help migrate from older IDNA 2003 applications.\n\nFor example, \u201cK\u00f6nigsg\u00e4\u00dfchen\u201d is not a permissible label as *LATIN CAPITAL\nLETTER K* is not allowed (nor are capital letters in general). UTS 46 will\nconvert this into lower case prior to applying the IDNA conversion.\n\n.. code-block:: pycon\n\n >>> import idna\n >>> idna.encode('K\u00f6nigsg\u00e4\u00dfchen')\n ...\n idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'K\u00f6nigsg\u00e4\u00dfchen' not allowed\n >>> idna.encode('K\u00f6nigsg\u00e4\u00dfchen', uts46=True)\n b'xn--knigsgchen-b4a3dun'\n >>> print(idna.decode('xn--knigsgchen-b4a3dun'))\n k\u00f6nigsg\u00e4\u00dfchen\n\nTransitional processing provides conversions to help transition from the older\n2003 standard to the current standard. For example, in the original IDNA\nspecification, the *LATIN SMALL LETTER SHARP S* (\u00df) was converted into two\n*LATIN SMALL LETTER S* (ss), whereas in the current IDNA specification this\nconversion is not performed.\n\n.. code-block:: pycon\n\n >>> idna.encode('K\u00f6nigsg\u00e4\u00dfchen', uts46=True, transitional=True)\n 'xn--knigsgsschen-lcb0w'\n\nImplementors should use transitional processing with caution, only in rare\ncases where conversion from legacy labels to current labels must be performed\n(i.e. IDNA implementations that pre-date 2008). For typical applications\nthat just need to convert labels, transitional processing is unlikely to be\nbeneficial and could produce unexpected incompatible results.\n\n``encodings.idna`` Compatibility\n++++++++++++++++++++++++++++++++\n\nFunction calls from the Python built-in ``encodings.idna`` module are\nmapped to their IDNA 2008 equivalents using the ``idna.compat`` module.\nSimply substitute the ``import`` clause in your code to refer to the\nnew module name.\n\nExceptions\n----------\n\nAll errors raised during the conversion following the specification should\nraise an exception derived from the ``idna.IDNAError`` base class.\n\nMore specific exceptions that may be generated as ``idna.IDNABidiError``\nwhen the error reflects an illegal combination of left-to-right and\nright-to-left characters in a label; ``idna.InvalidCodepoint`` when\na specific codepoint is an illegal character in an IDN label (i.e.\nINVALID); and ``idna.InvalidCodepointContext`` when the codepoint is\nillegal based on its positional context (i.e. it is CONTEXTO or CONTEXTJ\nbut the contextual requirements are not satisfied.)\n\nBuilding and Diagnostics\n------------------------\n\nThe IDNA and UTS 46 functionality relies upon pre-calculated lookup\ntables for performance. These tables are derived from computing against\neligibility criteria in the respective standards. These tables are\ncomputed using the command-line script ``tools/idna-data``.\n\nThis tool will fetch relevant codepoint data from the Unicode repository \nand perform the required calculations to identify eligibility. There are \nthree main modes:\n\n* ``idna-data make-libdata``. Generates ``idnadata.py`` and ``uts46data.py``,\n the pre-calculated lookup tables using for IDNA and UTS 46 conversions. Implementors\n who wish to track this library against a different Unicode version may use this tool\n to manually generate a different version of the ``idnadata.py`` and ``uts46data.py``\n files.\n\n* ``idna-data make-table``. Generate a table of the IDNA disposition\n (e.g. PVALID, CONTEXTJ, CONTEXTO) in the format found in Appendix B.1 of RFC\n 5892 and the pre-computed tables published by `IANA `_.\n\n* ``idna-data U+0061``. Prints debugging output on the various properties\n associated with an individual Unicode codepoint (in this case, U+0061), that are\n used to assess the IDNA and UTS 46 status of a codepoint. This is helpful in debugging\n or analysis.\n\nThe tool accepts a number of arguments, described using ``idna-data -h``. Most notably,\nthe ``--version`` argument allows the specification of the version of Unicode to use\nin computing the table data. For example, ``idna-data --version 9.0.0 make-libdata``\nwill generate library data against Unicode 9.0.0.\n\n\nAdditional Notes\n----------------\n\n* **Packages**. The latest tagged release version is published in the\n `Python Package Index `_.\n\n* **Version support**. This library supports Python 3.5 and higher. As this library\n serves as a low-level toolkit for a variety of applications, many of which strive\n for broad compatibility with older Python versions, there is no rush to remove\n older intepreter support. Removing support for older versions should be well\n justified in that the maintenance burden has become too high.\n\n* **Python 2**. Python 2 is supported by version 2.x of this library. While active\n development of the version 2.x series has ended, notable issues being corrected\n may be backported to 2.x. Use \"idna<3\" in your requirements file if you need this\n library for a Python 2 application.\n\n* **Testing**. The library has a test suite based on each rule of the IDNA specification, as\n well as tests that are provided as part of the Unicode Technical Standard 46,\n `Unicode IDNA Compatibility Processing `_.\n\n* **Emoji**. It is an occasional request to support emoji domains in this library. Encoding\n of symbols like emoji is expressly prohibited by the technical standard IDNA 2008 and\n emoji domains are broadly phased out across the domain industry due to associated security\n risks. For now, applications that wish need to support these non-compliant labels may\n wish to consider trying the encode/decode operation in this library first, and then falling\n back to using `encodings.idna`. See `the Github project `_\n for more discussion.", - "release_date": "2021-10-12T23:33:38", + "description": "C-based extension implementing fast integer bit sets.\n===========\n intbitset\n===========\n\n.. image:: https://img.shields.io/travis/inveniosoftware/intbitset.svg\n :target: https://travis-ci.org/inveniosoftware/intbitset\n\n.. image:: https://img.shields.io/github/tag/inveniosoftware/intbitset.svg\n :target: https://github.com/inveniosoftware/intbitset/releases\n\n.. image:: https://img.shields.io/pypi/dm/intbitset.svg\n :target: https://pypi.python.org/pypi/intbitset\n\n.. image:: https://img.shields.io/github/license/inveniosoftware/intbitset.svg\n :target: https://github.com/inveniosoftware/intbitset/blob/master/LICENSE\n\n\nInstallation\n============\n\nintbitset is on PyPI so all you need is a C compiler and pip: ::\n\n pip install intbitset\n\nDocumentation\n=============\n\nThe ``intbitset`` library provides a set implementation to store sorted\nunsigned integers either 32-bits integers (between ``0`` and\n``2**31 - 1`` or ``intbitset.__maxelem__``) or an infinite range\nwith fast set operations implemented via bit vectors in a *Python C\nextension* for speed and reduced memory usage.\n\nThe ``inbitset`` class emulates the Python built-in set class interface\nwith some additional specific methods such as its own fast dump and load\nmarshalling functions. ::\n\n >>> from intbitset import intbitset\n >>> x = intbitset([1,2,3])\n >>> y = intbitset([3,4,5])\n >>> x & y\n intbitset([3])\n >>> x | y\n intbitset([1, 2, 3, 4, 5])\n\n``intbitset`` additionally support the `pickle protocol\n`_, the `iterator protocol\n`_ and can\nbehave like a ``sequence`` that can be sliced. Because the intergers are\nalways stored sorted, the fist element of a non-empty set `[0]` is also\nthe `min()` integer and the last element `[-1]` is also the `max()` integer\nin the set.\n\nWhen compared to the standard library ``set`` class, ``intbitset`` set\noperations such as intersection, union and difference can be up to 5000\nfaster for dense integer sets.\n\nComplete documentation is available at or\ncan be built using Sphinx: ::\n\n pip install Sphinx\n python setup.py build_sphinx\n\nTesting\n=======\n\nRunning the tests are as simple as: ::\n\n pip install -e .[tests]\n pytest\n\nRunning the tests on multiple Python versions: ::\n\n pip install tox\n tox\n\n\nDevelopment\n===========\n\nTo regenerate the C code with Cython: ::\n\n pip install cython\n cython intbitset/intbitset.pyx\n\nThen commit the regenarted C source and update the CHANGE.rst\n\n\nLicense\n=======\n\nCopyright (C) CERN and others\n\nSPDX-License-Identifier: LGPL-3.0-or-later\n\nintbitset is free software; you can redistribute it and/or modify it under the\nterms of the GNU Lesser General Public License as published by the Free Software\nFoundation; either version 3 of the License, or (at your option) any later\nversion.\n\nintbitset is distributed in the hope that it will be useful, but WITHOUT ANY\nWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A\nPARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.\n\nYou should have received a copy of the GNU Lesser General Public License along with\nintbitset; if not, write to the Free Software Foundation, Inc., 59 Temple\nPlace, Suite 330, Boston, MA 02111-1307, USA.\n\nIn applying this licence, CERN does not waive the privileges and immunities\ngranted to it by virtue of its status as an Intergovernmental Organization or\nsubmit itself to any jurisdiction.", + "release_date": "2022-03-04T21:42:42", "parties": [ { "type": "person", "role": "author", - "name": "Kim Davies", - "email": "kim@cynosure.com.au", + "name": "Invenio collaboration, maintained by Philippe Ombredanne", + "email": "info@inveniosoftware.org", "url": null } ], "keywords": [ - "Development Status :: 5 - Production/Stable", + "Environment :: Console", "Intended Audience :: Developers", - "Intended Audience :: System Administrators", "Operating System :: OS Independent", + "Programming Language :: C", + "Programming Language :: Cython", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Internet :: Name Service (DNS)", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Utilities" + "Topic :: Software Development :: Libraries :: Python Modules" ], - "homepage_url": "https://github.com/kjd/idna", - "download_url": "https://files.pythonhosted.org/packages/04/a2/d918dcd22354d8958fe113e1a3630137e0fc8b44859ade3063982eacd2a4/idna-3.3-py3-none-any.whl", - "size": 61160, + "homepage_url": "http://github.com/inveniosoftware/intbitset/", + "download_url": "https://files.pythonhosted.org/packages/0e/54/1acf40a273b881e394d01a23bcc6e532b28d905d6077426f92dfb903dd27/intbitset-3.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", + "size": 351721, "sha1": null, - "md5": "461e73a409996cb35e00116e5301bac6", - "sha256": "84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", + "md5": "9b95a1546ef91d5946c33c082aaeb46a", + "sha256": "83501f7d77ebcfc2cc4226bf7acc32cf042d35bb742ac544ae6dc4a33f66a9b6", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -3941,9 +2904,9 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "BSD-3-Clause", + "license": "LGPL-3.0-or-later", "classifiers": [ - "License :: OSI Approved :: BSD License" + "License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)" ] }, "notice_text": null, @@ -3953,55 +2916,58 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/idna/3.3/json", + "api_data_url": "https://pypi.org/pypi/intbitset/3.0.1/json", "datasource_id": null, - "purl": "pkg:pypi/idna@3.3" + "purl": "pkg:pypi/intbitset@3.0.1" }, { "type": "pypi", "namespace": null, - "name": "idna", - "version": "3.3", + "name": "isort", + "version": "5.10.1", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Internationalized Domain Names in Applications (IDNA)\n=====================================================\n\nSupport for the Internationalised Domain Names in Applications\n(IDNA) protocol as specified in `RFC 5891 `_.\nThis is the latest version of the protocol and is sometimes referred to as\n\u201cIDNA 2008\u201d.\n\nThis library also provides support for Unicode Technical Standard 46,\n`Unicode IDNA Compatibility Processing `_.\n\nThis acts as a suitable replacement for the \u201cencodings.idna\u201d module that\ncomes with the Python standard library, but which only supports the\nolder superseded IDNA specification (`RFC 3490 `_).\n\nBasic functions are simply executed:\n\n.. code-block:: pycon\n\n >>> import idna\n >>> idna.encode('\u30c9\u30e1\u30a4\u30f3.\u30c6\u30b9\u30c8')\n b'xn--eckwd4c7c.xn--zckzah'\n >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah'))\n \u30c9\u30e1\u30a4\u30f3.\u30c6\u30b9\u30c8\n\n\nInstallation\n------------\n\nTo install this library, you can use pip:\n\n.. code-block:: bash\n\n $ pip install idna\n\nAlternatively, you can install the package using the bundled setup script:\n\n.. code-block:: bash\n\n $ python setup.py install\n\n\nUsage\n-----\n\nFor typical usage, the ``encode`` and ``decode`` functions will take a domain\nname argument and perform a conversion to A-labels or U-labels respectively.\n\n.. code-block:: pycon\n\n >>> import idna\n >>> idna.encode('\u30c9\u30e1\u30a4\u30f3.\u30c6\u30b9\u30c8')\n b'xn--eckwd4c7c.xn--zckzah'\n >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah'))\n \u30c9\u30e1\u30a4\u30f3.\u30c6\u30b9\u30c8\n\nYou may use the codec encoding and decoding methods using the\n``idna.codec`` module:\n\n.. code-block:: pycon\n\n >>> import idna.codec\n >>> print('\u0434\u043e\u043c\u0435\u043d.\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435'.encode('idna'))\n b'xn--d1acufc.xn--80akhbyknj4f'\n >>> print(b'xn--d1acufc.xn--80akhbyknj4f'.decode('idna'))\n \u0434\u043e\u043c\u0435\u043d.\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435\n\nConversions can be applied at a per-label basis using the ``ulabel`` or ``alabel``\nfunctions if necessary:\n\n.. code-block:: pycon\n\n >>> idna.alabel('\u6d4b\u8bd5')\n b'xn--0zwm56d'\n\nCompatibility Mapping (UTS #46)\n+++++++++++++++++++++++++++++++\n\nAs described in `RFC 5895 `_, the IDNA\nspecification does not normalize input from different potential ways a user\nmay input a domain name. This functionality, known as a \u201cmapping\u201d, is \nconsidered by the specification to be a local user-interface issue distinct\nfrom IDNA conversion functionality.\n\nThis library provides one such mapping, that was developed by the Unicode\nConsortium. Known as `Unicode IDNA Compatibility Processing `_,\nit provides for both a regular mapping for typical applications, as well as\na transitional mapping to help migrate from older IDNA 2003 applications.\n\nFor example, \u201cK\u00f6nigsg\u00e4\u00dfchen\u201d is not a permissible label as *LATIN CAPITAL\nLETTER K* is not allowed (nor are capital letters in general). UTS 46 will\nconvert this into lower case prior to applying the IDNA conversion.\n\n.. code-block:: pycon\n\n >>> import idna\n >>> idna.encode('K\u00f6nigsg\u00e4\u00dfchen')\n ...\n idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'K\u00f6nigsg\u00e4\u00dfchen' not allowed\n >>> idna.encode('K\u00f6nigsg\u00e4\u00dfchen', uts46=True)\n b'xn--knigsgchen-b4a3dun'\n >>> print(idna.decode('xn--knigsgchen-b4a3dun'))\n k\u00f6nigsg\u00e4\u00dfchen\n\nTransitional processing provides conversions to help transition from the older\n2003 standard to the current standard. For example, in the original IDNA\nspecification, the *LATIN SMALL LETTER SHARP S* (\u00df) was converted into two\n*LATIN SMALL LETTER S* (ss), whereas in the current IDNA specification this\nconversion is not performed.\n\n.. code-block:: pycon\n\n >>> idna.encode('K\u00f6nigsg\u00e4\u00dfchen', uts46=True, transitional=True)\n 'xn--knigsgsschen-lcb0w'\n\nImplementors should use transitional processing with caution, only in rare\ncases where conversion from legacy labels to current labels must be performed\n(i.e. IDNA implementations that pre-date 2008). For typical applications\nthat just need to convert labels, transitional processing is unlikely to be\nbeneficial and could produce unexpected incompatible results.\n\n``encodings.idna`` Compatibility\n++++++++++++++++++++++++++++++++\n\nFunction calls from the Python built-in ``encodings.idna`` module are\nmapped to their IDNA 2008 equivalents using the ``idna.compat`` module.\nSimply substitute the ``import`` clause in your code to refer to the\nnew module name.\n\nExceptions\n----------\n\nAll errors raised during the conversion following the specification should\nraise an exception derived from the ``idna.IDNAError`` base class.\n\nMore specific exceptions that may be generated as ``idna.IDNABidiError``\nwhen the error reflects an illegal combination of left-to-right and\nright-to-left characters in a label; ``idna.InvalidCodepoint`` when\na specific codepoint is an illegal character in an IDN label (i.e.\nINVALID); and ``idna.InvalidCodepointContext`` when the codepoint is\nillegal based on its positional context (i.e. it is CONTEXTO or CONTEXTJ\nbut the contextual requirements are not satisfied.)\n\nBuilding and Diagnostics\n------------------------\n\nThe IDNA and UTS 46 functionality relies upon pre-calculated lookup\ntables for performance. These tables are derived from computing against\neligibility criteria in the respective standards. These tables are\ncomputed using the command-line script ``tools/idna-data``.\n\nThis tool will fetch relevant codepoint data from the Unicode repository \nand perform the required calculations to identify eligibility. There are \nthree main modes:\n\n* ``idna-data make-libdata``. Generates ``idnadata.py`` and ``uts46data.py``,\n the pre-calculated lookup tables using for IDNA and UTS 46 conversions. Implementors\n who wish to track this library against a different Unicode version may use this tool\n to manually generate a different version of the ``idnadata.py`` and ``uts46data.py``\n files.\n\n* ``idna-data make-table``. Generate a table of the IDNA disposition\n (e.g. PVALID, CONTEXTJ, CONTEXTO) in the format found in Appendix B.1 of RFC\n 5892 and the pre-computed tables published by `IANA `_.\n\n* ``idna-data U+0061``. Prints debugging output on the various properties\n associated with an individual Unicode codepoint (in this case, U+0061), that are\n used to assess the IDNA and UTS 46 status of a codepoint. This is helpful in debugging\n or analysis.\n\nThe tool accepts a number of arguments, described using ``idna-data -h``. Most notably,\nthe ``--version`` argument allows the specification of the version of Unicode to use\nin computing the table data. For example, ``idna-data --version 9.0.0 make-libdata``\nwill generate library data against Unicode 9.0.0.\n\n\nAdditional Notes\n----------------\n\n* **Packages**. The latest tagged release version is published in the\n `Python Package Index `_.\n\n* **Version support**. This library supports Python 3.5 and higher. As this library\n serves as a low-level toolkit for a variety of applications, many of which strive\n for broad compatibility with older Python versions, there is no rush to remove\n older intepreter support. Removing support for older versions should be well\n justified in that the maintenance burden has become too high.\n\n* **Python 2**. Python 2 is supported by version 2.x of this library. While active\n development of the version 2.x series has ended, notable issues being corrected\n may be backported to 2.x. Use \"idna<3\" in your requirements file if you need this\n library for a Python 2 application.\n\n* **Testing**. The library has a test suite based on each rule of the IDNA specification, as\n well as tests that are provided as part of the Unicode Technical Standard 46,\n `Unicode IDNA Compatibility Processing `_.\n\n* **Emoji**. It is an occasional request to support emoji domains in this library. Encoding\n of symbols like emoji is expressly prohibited by the technical standard IDNA 2008 and\n emoji domains are broadly phased out across the domain industry due to associated security\n risks. For now, applications that wish need to support these non-compliant labels may\n wish to consider trying the encode/decode operation in this library first, and then falling\n back to using `encodings.idna`. See `the Github project `_\n for more discussion.", - "release_date": "2021-10-12T23:33:41", + "description": "A Python utility / library to sort Python imports.\n[![isort - isort your imports, so you don't have to.](https://raw.githubusercontent.com/pycqa/isort/main/art/logo_large.png)](https://pycqa.github.io/isort/)\n\n------------------------------------------------------------------------\n\n[![PyPI version](https://badge.fury.io/py/isort.svg)](https://badge.fury.io/py/isort)\n[![Test Status](https://github.com/pycqa/isort/workflows/Test/badge.svg?branch=develop)](https://github.com/pycqa/isort/actions?query=workflow%3ATest)\n[![Lint Status](https://github.com/pycqa/isort/workflows/Lint/badge.svg?branch=develop)](https://github.com/pycqa/isort/actions?query=workflow%3ALint)\n[![Code coverage Status](https://codecov.io/gh/pycqa/isort/branch/main/graph/badge.svg)](https://codecov.io/gh/pycqa/isort)\n[![License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://pypi.org/project/isort/)\n[![Join the chat at https://gitter.im/timothycrosley/isort](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/timothycrosley/isort?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n[![Downloads](https://pepy.tech/badge/isort)](https://pepy.tech/project/isort)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)\n[![DeepSource](https://static.deepsource.io/deepsource-badge-light-mini.svg)](https://deepsource.io/gh/pycqa/isort/?ref=repository-badge)\n_________________\n\n[Read Latest Documentation](https://pycqa.github.io/isort/) - [Browse GitHub Code Repository](https://github.com/pycqa/isort/)\n_________________\n\nisort your imports, so you don't have to.\n\nisort is a Python utility / library to sort imports alphabetically, and\nautomatically separated into sections and by type. It provides a command line\nutility, Python library and [plugins for various\neditors](https://github.com/pycqa/isort/wiki/isort-Plugins) to\nquickly sort all your imports. It requires Python 3.6+ to run but\nsupports formatting Python 2 code too.\n\n- [Try isort now from your browser!](https://pycqa.github.io/isort/docs/quick_start/0.-try.html)\n- [Using black? See the isort and black compatibility guide.](https://pycqa.github.io/isort/docs/configuration/black_compatibility.html)\n- [isort has official support for pre-commit!](https://pycqa.github.io/isort/docs/configuration/pre-commit.html)\n\n![Example Usage](https://raw.github.com/pycqa/isort/main/example.gif)\n\nBefore isort:\n\n```python\nfrom my_lib import Object\n\nimport os\n\nfrom my_lib import Object3\n\nfrom my_lib import Object2\n\nimport sys\n\nfrom third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14\n\nimport sys\n\nfrom __future__ import absolute_import\n\nfrom third_party import lib3\n\nprint(\"Hey\")\nprint(\"yo\")\n```\n\nAfter isort:\n\n```python\nfrom __future__ import absolute_import\n\nimport os\nimport sys\n\nfrom third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8,\n lib9, lib10, lib11, lib12, lib13, lib14, lib15)\n\nfrom my_lib import Object, Object2, Object3\n\nprint(\"Hey\")\nprint(\"yo\")\n```\n\n## Installing isort\n\nInstalling isort is as simple as:\n\n```bash\npip install isort\n```\n\nInstall isort with requirements.txt support:\n\n```bash\npip install isort[requirements_deprecated_finder]\n```\n\nInstall isort with Pipfile support:\n\n```bash\npip install isort[pipfile_deprecated_finder]\n```\n\nInstall isort with both formats support:\n\n```bash\npip install isort[requirements_deprecated_finder,pipfile_deprecated_finder]\n```\n\n## Using isort\n\n**From the command line**:\n\nTo run on specific files:\n\n```bash\nisort mypythonfile.py mypythonfile2.py\n```\n\nTo apply recursively:\n\n```bash\nisort .\n```\n\nIf [globstar](https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html)\nis enabled, `isort .` is equivalent to:\n\n```bash\nisort **/*.py\n```\n\nTo view proposed changes without applying them:\n\n```bash\nisort mypythonfile.py --diff\n```\n\nFinally, to atomically run isort against a project, only applying\nchanges if they don't introduce syntax errors:\n\n```bash\nisort --atomic .\n```\n\n(Note: this is disabled by default, as it prevents isort from\nrunning against code written using a different version of Python.)\n\n**From within Python**:\n\n```python\nimport isort\n\nisort.file(\"pythonfile.py\")\n```\n\nor:\n\n```python\nimport isort\n\nsorted_code = isort.code(\"import b\\nimport a\\n\")\n```\n\n## Installing isort's for your preferred text editor\n\nSeveral plugins have been written that enable to use isort from within a\nvariety of text-editors. You can find a full list of them [on the isort\nwiki](https://github.com/pycqa/isort/wiki/isort-Plugins).\nAdditionally, I will enthusiastically accept pull requests that include\nplugins for other text editors and add documentation for them as I am\nnotified.\n\n## Multi line output modes\n\nYou will notice above the \\\"multi\\_line\\_output\\\" setting. This setting\ndefines how from imports wrap when they extend past the line\\_length\nlimit and has [12 possible settings](https://pycqa.github.io/isort/docs/configuration/multi_line_output_modes.html).\n\n## Indentation\n\nTo change the how constant indents appear - simply change the\nindent property with the following accepted formats:\n\n- Number of spaces you would like. For example: 4 would cause standard\n 4 space indentation.\n- Tab\n- A verbatim string with quotes around it.\n\nFor example:\n\n```python\n\" \"\n```\n\nis equivalent to 4.\n\nFor the import styles that use parentheses, you can control whether or\nnot to include a trailing comma after the last import with the\n`include_trailing_comma` option (defaults to `False`).\n\n## Intelligently Balanced Multi-line Imports\n\nAs of isort 3.1.0 support for balanced multi-line imports has been\nadded. With this enabled isort will dynamically change the import length\nto the one that produces the most balanced grid, while staying below the\nmaximum import length defined.\n\nExample:\n\n```python\nfrom __future__ import (absolute_import, division,\n print_function, unicode_literals)\n```\n\nWill be produced instead of:\n\n```python\nfrom __future__ import (absolute_import, division, print_function,\n unicode_literals)\n```\n\nTo enable this set `balanced_wrapping` to `True` in your config or pass\nthe `-e` option into the command line utility.\n\n## Custom Sections and Ordering\n\nisort provides configuration options to change almost every aspect of how\nimports are organized, ordered, or grouped together in sections.\n\n[Click here](https://pycqa.github.io/isort/docs/configuration/custom_sections_and_ordering.html) for an overview of all these options.\n\n## Skip processing of imports (outside of configuration)\n\nTo make isort ignore a single import simply add a comment at the end of\nthe import line containing the text `isort:skip`:\n\n```python\nimport module # isort:skip\n```\n\nor:\n\n```python\nfrom xyz import (abc, # isort:skip\n yo,\n hey)\n```\n\nTo make isort skip an entire file simply add `isort:skip_file` to the\nmodule's doc string:\n\n```python\n\"\"\" my_module.py\n Best module ever\n\n isort:skip_file\n\"\"\"\n\nimport b\nimport a\n```\n\n## Adding or removing an import from multiple files\n\nisort can be ran or configured to add / remove imports automatically.\n\n[See a complete guide here.](https://pycqa.github.io/isort/docs/configuration/add_or_remove_imports.html)\n\n## Using isort to verify code\n\nThe `--check-only` option\n-------------------------\n\nisort can also be used to verify that code is correctly formatted\nby running it with `-c`. Any files that contain incorrectly sorted\nand/or formatted imports will be outputted to `stderr`.\n\n```bash\nisort **/*.py -c -v\n\nSUCCESS: /home/timothy/Projects/Open_Source/isort/isort_kate_plugin.py Everything Looks Good!\nERROR: /home/timothy/Projects/Open_Source/isort/isort/isort.py Imports are incorrectly sorted.\n```\n\nOne great place this can be used is with a pre-commit git hook, such as\nthis one by \\@acdha:\n\n\n\nThis can help to ensure a certain level of code quality throughout a\nproject.\n\n## Git hook\n\nisort provides a hook function that can be integrated into your Git\npre-commit script to check Python code before committing.\n\n[More info here.](https://pycqa.github.io/isort/docs/configuration/git_hook.html)\n\n## Setuptools integration\n\nUpon installation, isort enables a `setuptools` command that checks\nPython files declared by your project.\n\n[More info here.](https://pycqa.github.io/isort/docs/configuration/setuptools_integration.html)\n\n## Spread the word\n\n[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)\n\nPlace this badge at the top of your repository to let others know your project uses isort.\n\nFor README.md:\n\n```markdown\n[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)\n```\n\nOr README.rst:\n\n```rst\n.. image:: https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336\n :target: https://pycqa.github.io/isort/\n```\n\n## Security contact information\n\nTo report a security vulnerability, please use the [Tidelift security\ncontact](https://tidelift.com/security). Tidelift will coordinate the\nfix and disclosure.\n\n## Why isort?\n\nisort simply stands for import sort. It was originally called\n\"sortImports\" however I got tired of typing the extra characters and\ncame to the realization camelCase is not pythonic.\n\nI wrote isort because in an organization I used to work in the manager\ncame in one day and decided all code must have alphabetically sorted\nimports. The code base was huge - and he meant for us to do it by hand.\nHowever, being a programmer - I\\'m too lazy to spend 8 hours mindlessly\nperforming a function, but not too lazy to spend 16 hours automating it.\nI was given permission to open source sortImports and here we are :)\n\n------------------------------------------------------------------------\n\n[Get professionally supported isort with the Tidelift\nSubscription](https://tidelift.com/subscription/pkg/pypi-isort?utm_source=pypi-isort&utm_medium=referral&utm_campaign=readme)\n\nProfessional support for isort is available as part of the [Tidelift\nSubscription](https://tidelift.com/subscription/pkg/pypi-isort?utm_source=pypi-isort&utm_medium=referral&utm_campaign=readme).\nTidelift gives software development teams a single source for purchasing\nand maintaining their software, with professional grade assurances from\nthe experts who know it best, while seamlessly integrating with existing\ntools.\n\n------------------------------------------------------------------------\n\nThanks and I hope you find isort useful!\n\n~Timothy Crosley", + "release_date": "2021-11-09T05:42:44", "parties": [ { "type": "person", "role": "author", - "name": "Kim Davies", - "email": "kim@cynosure.com.au", + "name": "Timothy Crosley", + "email": "timothy.crosley@gmail.com", "url": null } ], "keywords": [ - "Development Status :: 5 - Production/Stable", + "Refactor", + "Lint", + "Imports", + "Sort", + "Clean", + "Development Status :: 6 - Mature", + "Environment :: Console", "Intended Audience :: Developers", - "Intended Audience :: System Administrators", - "Operating System :: OS Independent", + "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Internet :: Name Service (DNS)", - "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Software Development :: Libraries", "Topic :: Utilities" ], - "homepage_url": "https://github.com/kjd/idna", - "download_url": "https://files.pythonhosted.org/packages/62/08/e3fc7c8161090f742f504f40b1bccbfc544d4a4e09eb774bf40aafce5436/idna-3.3.tar.gz", - "size": 286689, + "homepage_url": "https://pycqa.github.io/isort/", + "download_url": "https://files.pythonhosted.org/packages/b8/5b/f18e227df38b94b4ee30d2502fd531bebac23946a2497e5595067a561274/isort-5.10.1-py3-none-any.whl", + "size": 103430, "sha1": null, - "md5": "5856306eac5f25db8249e37a4c6ee3e7", - "sha256": "9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d", + "md5": "da9d912dc0b12468db6f88a4e2a2f04e", + "sha256": "6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -4009,9 +2975,9 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "BSD-3-Clause", + "license": "MIT", "classifiers": [ - "License :: OSI Approved :: BSD License" + "License :: OSI Approved :: MIT License" ] }, "notice_text": null, @@ -4021,50 +2987,58 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/idna/3.3/json", + "api_data_url": "https://pypi.org/pypi/isort/5.10.1/json", "datasource_id": null, - "purl": "pkg:pypi/idna@3.3" + "purl": "pkg:pypi/isort@5.10.1" }, { "type": "pypi", "namespace": null, - "name": "importlib-metadata", - "version": "4.8.3", + "name": "itsdangerous", + "version": "2.1.2", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Read metadata from Python packages\n.. image:: https://img.shields.io/pypi/v/importlib_metadata.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/importlib_metadata.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/importlib_metadata\n\n.. image:: https://github.com/python/importlib_metadata/workflows/tests/badge.svg\n :target: https://github.com/python/importlib_metadata/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. image:: https://readthedocs.org/projects/importlib-metadata/badge/?version=latest\n :target: https://importlib-metadata.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2021-informational\n :target: https://blog.jaraco.com/skeleton\n\n\nLibrary to access the metadata for a Python package.\n\nThis package supplies third-party access to the functionality of\n`importlib.metadata `_\nincluding improvements added to subsequent Python versions.\n\n\nCompatibility\n=============\n\nNew features are introduced in this third-party library and later merged\ninto CPython. The following table indicates which versions of this library\nwere contributed to different versions in the standard library:\n\n.. list-table::\n :header-rows: 1\n\n * - importlib_metadata\n - stdlib\n * - 4.4\n - 3.10\n * - 1.4\n - 3.8\n\n\nUsage\n=====\n\nSee the `online documentation `_\nfor usage details.\n\n`Finder authors\n`_ can\nalso add support for custom package installers. See the above documentation\nfor details.\n\n\nCaveats\n=======\n\nThis project primarily supports third-party packages installed by PyPA\ntools (or other conforming packages). It does not support:\n\n- Packages in the stdlib.\n- Packages installed without metadata.\n\nProject details\n===============\n\n * Project home: https://github.com/python/importlib_metadata\n * Report bugs at: https://github.com/python/importlib_metadata/issues\n * Code hosting: https://github.com/python/importlib_metadata\n * Documentation: https://importlib_metadata.readthedocs.io/", - "release_date": "2021-12-16T14:42:25", + "description": "Safely pass data to untrusted environments and back.\nItsDangerous\n============\n\n... so better sign this\n\nVarious helpers to pass data to untrusted environments and to get it\nback safe and sound. Data is cryptographically signed to ensure that a\ntoken has not been tampered with.\n\nIt's possible to customize how data is serialized. Data is compressed as\nneeded. A timestamp can be added and verified automatically while\nloading a token.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U itsdangerous\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\nHere's how you could generate a token for transmitting a user's id and\nname between web requests.\n\n.. code-block:: python\n\n from itsdangerous import URLSafeSerializer\n auth_s = URLSafeSerializer(\"secret key\", \"auth\")\n token = auth_s.dumps({\"id\": 5, \"name\": \"itsdangerous\"})\n\n print(token)\n # eyJpZCI6NSwibmFtZSI6Iml0c2Rhbmdlcm91cyJ9.6YP6T0BaO67XP--9UzTrmurXSmg\n\n data = auth_s.loads(token)\n print(data[\"name\"])\n # itsdangerous\n\n\nDonate\n------\n\nThe Pallets organization develops and supports ItsDangerous and other\npopular packages. In order to grow the community of contributors and\nusers, and allow the maintainers to devote more time to the projects,\n`please donate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://itsdangerous.palletsprojects.com/\n- Changes: https://itsdangerous.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/ItsDangerous/\n- Source Code: https://github.com/pallets/itsdangerous/\n- Issue Tracker: https://github.com/pallets/itsdangerous/issues/\n- Website: https://palletsprojects.com/p/itsdangerous/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", + "release_date": "2022-03-24T15:12:13", "parties": [ { "type": "person", "role": "author", - "name": "Jason R. Coombs", - "email": "jaraco@jaraco.com", + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "url": null + }, + { + "type": "person", + "role": "maintainer", + "name": "Pallets", + "email": "contact@palletsprojects.com", "url": null } ], "keywords": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only" + "Operating System :: OS Independent", + "Programming Language :: Python" ], - "homepage_url": "https://github.com/python/importlib_metadata", - "download_url": "https://files.pythonhosted.org/packages/a0/a1/b153a0a4caf7a7e3f15c2cd56c7702e2cf3d89b1b359d1f1c5e59d68f4ce/importlib_metadata-4.8.3-py3-none-any.whl", - "size": 17978, + "homepage_url": "https://palletsprojects.com/p/itsdangerous/", + "download_url": "https://files.pythonhosted.org/packages/68/5f/447e04e828f47465eeab35b5d408b7ebaaaee207f48b7136c5a7267a30ae/itsdangerous-2.1.2-py3-none-any.whl", + "size": 15749, "sha1": null, - "md5": "492a63a286daa402226ae8f36cff221d", - "sha256": "65a9576a5b2d58ca44d133c42a241905cc45e34d2c06fd5ba2bafa221e5d7b5e", + "md5": "efb0813a44f2abd3b7b375cfcb8b95c2", + "sha256": "2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, + "bug_tracking_url": "https://github.com/pallets/itsdangerous/issues/", + "code_view_url": "https://github.com/pallets/itsdangerous/", "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { + "license": "BSD-3-Clause", "classifiers": [ - "License :: OSI Approved :: Apache Software License" + "License :: OSI Approved :: BSD License" ] }, "notice_text": null, @@ -4074,41 +3048,39 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/importlib-metadata/4.8.3/json", + "api_data_url": "https://pypi.org/pypi/itsdangerous/2.1.2/json", "datasource_id": null, - "purl": "pkg:pypi/importlib-metadata@4.8.3" + "purl": "pkg:pypi/itsdangerous@2.1.2" }, { "type": "pypi", "namespace": null, - "name": "importlib-metadata", - "version": "4.8.3", + "name": "jeepney", + "version": "0.7.1", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Read metadata from Python packages\n.. image:: https://img.shields.io/pypi/v/importlib_metadata.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/importlib_metadata.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/importlib_metadata\n\n.. image:: https://github.com/python/importlib_metadata/workflows/tests/badge.svg\n :target: https://github.com/python/importlib_metadata/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. image:: https://readthedocs.org/projects/importlib-metadata/badge/?version=latest\n :target: https://importlib-metadata.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2021-informational\n :target: https://blog.jaraco.com/skeleton\n\n\nLibrary to access the metadata for a Python package.\n\nThis package supplies third-party access to the functionality of\n`importlib.metadata `_\nincluding improvements added to subsequent Python versions.\n\n\nCompatibility\n=============\n\nNew features are introduced in this third-party library and later merged\ninto CPython. The following table indicates which versions of this library\nwere contributed to different versions in the standard library:\n\n.. list-table::\n :header-rows: 1\n\n * - importlib_metadata\n - stdlib\n * - 4.4\n - 3.10\n * - 1.4\n - 3.8\n\n\nUsage\n=====\n\nSee the `online documentation `_\nfor usage details.\n\n`Finder authors\n`_ can\nalso add support for custom package installers. See the above documentation\nfor details.\n\n\nCaveats\n=======\n\nThis project primarily supports third-party packages installed by PyPA\ntools (or other conforming packages). It does not support:\n\n- Packages in the stdlib.\n- Packages installed without metadata.\n\nProject details\n===============\n\n * Project home: https://github.com/python/importlib_metadata\n * Report bugs at: https://github.com/python/importlib_metadata/issues\n * Code hosting: https://github.com/python/importlib_metadata\n * Documentation: https://importlib_metadata.readthedocs.io/", - "release_date": "2021-12-16T14:42:26", + "description": "Low-level, pure Python DBus protocol wrapper.\nJeepney is a pure Python implementation of D-Bus messaging. It has an `I/O-free\n`__ core, and integration modules for different\nevent loops.\n\nD-Bus is an inter-process communication system, mainly used in Linux.\n\nTo install Jeepney::\n\n pip install jeepney\n\n`Jeepney docs on Readthedocs `__", + "release_date": "2021-07-28T18:17:20", "parties": [ { "type": "person", "role": "author", - "name": "Jason R. Coombs", - "email": "jaraco@jaraco.com", + "name": "Thomas Kluyver", + "email": "thomas@kluyver.me.uk", "url": null } ], "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only" + "Topic :: Desktop Environment" ], - "homepage_url": "https://github.com/python/importlib_metadata", - "download_url": "https://files.pythonhosted.org/packages/85/ed/e65128cc5cb1580f22ee3009d9187ecdfcc43ffb3b581fe854b24e87d8e7/importlib_metadata-4.8.3.tar.gz", - "size": 41979, + "homepage_url": "https://gitlab.com/takluyver/jeepney", + "download_url": "https://files.pythonhosted.org/packages/14/b8/bb3e34d71472140f9bfdf5d77cd063e2cc964b72b1bb0b70fe3c1e7db932/jeepney-0.7.1-py3-none-any.whl", + "size": 54082, "sha1": null, - "md5": "833c41fd427678c8b590c5a7818dd873", - "sha256": "766abffff765960fcc18003801f7044eb6755ffae4521c8e8ce8e83b9c9b0668", + "md5": "22e7c84e1eadffad5299f40cc31d1e21", + "sha256": "1b5a0ea5c0e7b166b2f5895b91a08c14de8915afda4407fb5022a195224958ac", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -4117,7 +3089,7 @@ "license_expression": null, "declared_license": { "classifiers": [ - "License :: OSI Approved :: Apache Software License" + "License :: OSI Approved :: MIT License" ] }, "notice_text": null, @@ -4127,57 +3099,61 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/importlib-metadata/4.8.3/json", + "api_data_url": "https://pypi.org/pypi/jeepney/0.7.1/json", "datasource_id": null, - "purl": "pkg:pypi/importlib-metadata@4.8.3" + "purl": "pkg:pypi/jeepney@0.7.1" }, { "type": "pypi", "namespace": null, - "name": "iniconfig", - "version": "1.1.1", + "name": "jinja2", + "version": "3.0.3", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "iniconfig: brain-dead simple config-ini parsing\niniconfig: brain-dead simple parsing of ini files\n=======================================================\n\niniconfig is a small and simple INI-file parser module\nhaving a unique set of features:\n\n* tested against Python2.4 across to Python3.2, Jython, PyPy\n* maintains order of sections and entries\n* supports multi-line values with or without line-continuations\n* supports \"#\" comments everywhere\n* raises errors with proper line-numbers\n* no bells and whistles like automatic substitutions\n* iniconfig raises an Error if two sections have the same name.\n\nIf you encounter issues or have feature wishes please report them to:\n\n http://github.com/RonnyPfannschmidt/iniconfig/issues\n\nBasic Example\n===================================\n\nIf you have an ini file like this::\n\n # content of example.ini\n [section1] # comment\n name1=value1 # comment\n name1b=value1,value2 # comment\n\n [section2]\n name2=\n line1\n line2\n\nthen you can do::\n\n >>> import iniconfig\n >>> ini = iniconfig.IniConfig(\"example.ini\")\n >>> ini['section1']['name1'] # raises KeyError if not exists\n 'value1'\n >>> ini.get('section1', 'name1b', [], lambda x: x.split(\",\"))\n ['value1', 'value2']\n >>> ini.get('section1', 'notexist', [], lambda x: x.split(\",\"))\n []\n >>> [x.name for x in list(ini)]\n ['section1', 'section2']\n >>> list(list(ini)[0].items())\n [('name1', 'value1'), ('name1b', 'value1,value2')]\n >>> 'section1' in ini\n True\n >>> 'inexistendsection' in ini\n False", - "release_date": "2020-10-16T17:37:23", + "description": "A very fast and expressive template engine.\nJinja\n=====\n\nJinja is a fast, expressive, extensible templating engine. Special\nplaceholders in the template allow writing code similar to Python\nsyntax. Then the template is passed data to render the final document.\n\nIt includes:\n\n- Template inheritance and inclusion.\n- Define and import macros within templates.\n- HTML templates can use autoescaping to prevent XSS from untrusted\n user input.\n- A sandboxed environment can safely render untrusted templates.\n- AsyncIO support for generating templates and calling async\n functions.\n- I18N support with Babel.\n- Templates are compiled to optimized Python code just-in-time and\n cached, or can be compiled ahead-of-time.\n- Exceptions point to the correct line in templates to make debugging\n easier.\n- Extensible filters, tests, functions, and even syntax.\n\nJinja's philosophy is that while application logic belongs in Python if\npossible, it shouldn't make the template designer's job difficult by\nrestricting functionality too much.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U Jinja2\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nIn A Nutshell\n-------------\n\n.. code-block:: jinja\n\n {% extends \"base.html\" %}\n {% block title %}Members{% endblock %}\n {% block content %}\n

\n {% endblock %}\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Jinja and other popular\npackages. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://jinja.palletsprojects.com/\n- Changes: https://jinja.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/Jinja2/\n- Source Code: https://github.com/pallets/jinja/\n- Issue Tracker: https://github.com/pallets/jinja/issues/\n- Website: https://palletsprojects.com/p/jinja/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", + "release_date": "2021-11-09T20:27:27", "parties": [ { "type": "person", "role": "author", - "name": "Ronny Pfannschmidt, Holger Krekel", - "email": "opensource@ronnypfannschmidt.de, holger.krekel@gmail.com", + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "url": null + }, + { + "type": "person", + "role": "maintainer", + "name": "Pallets", + "email": "contact@palletsprojects.com", "url": null } ], "keywords": [ - "Development Status :: 4 - Beta", + "Development Status :: 5 - Production/Stable", + "Environment :: Web Environment", "Intended Audience :: Developers", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", + "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities" + "Topic :: Internet :: WWW/HTTP :: Dynamic Content", + "Topic :: Text Processing :: Markup :: HTML" ], - "homepage_url": "http://github.com/RonnyPfannschmidt/iniconfig", - "download_url": "https://files.pythonhosted.org/packages/9b/dd/b3c12c6d707058fa947864b67f0c4e0c39ef8610988d7baea9578f3c48f3/iniconfig-1.1.1-py2.py3-none-any.whl", - "size": 4990, + "homepage_url": "https://palletsprojects.com/p/jinja/", + "download_url": "https://files.pythonhosted.org/packages/20/9a/e5d9ec41927401e41aea8af6d16e78b5e612bca4699d417f646a9610a076/Jinja2-3.0.3-py3-none-any.whl", + "size": 133630, "sha1": null, - "md5": "90f3e1bb7ced782f2b04eb5af266ecb7", - "sha256": "011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", + "md5": "31d7a56a843bbf4ef35e0076fea86767", + "sha256": "077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8", "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, + "bug_tracking_url": "https://github.com/pallets/jinja/issues/", + "code_view_url": "https://github.com/pallets/jinja/", "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { - "license": "MIT License", + "license": "BSD-3-Clause", "classifiers": [ - "License :: OSI Approved :: MIT License" + "License :: OSI Approved :: BSD License" ] }, "notice_text": null, @@ -4187,47 +3163,48 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/iniconfig/1.1.1/json", + "api_data_url": "https://pypi.org/pypi/jinja2/3.0.3/json", "datasource_id": null, - "purl": "pkg:pypi/iniconfig@1.1.1" + "purl": "pkg:pypi/jinja2@3.0.3" }, { "type": "pypi", "namespace": null, - "name": "iniconfig", - "version": "1.1.1", + "name": "keyring", + "version": "23.4.1", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "iniconfig: brain-dead simple config-ini parsing\niniconfig: brain-dead simple parsing of ini files\n=======================================================\n\niniconfig is a small and simple INI-file parser module\nhaving a unique set of features:\n\n* tested against Python2.4 across to Python3.2, Jython, PyPy\n* maintains order of sections and entries\n* supports multi-line values with or without line-continuations\n* supports \"#\" comments everywhere\n* raises errors with proper line-numbers\n* no bells and whistles like automatic substitutions\n* iniconfig raises an Error if two sections have the same name.\n\nIf you encounter issues or have feature wishes please report them to:\n\n http://github.com/RonnyPfannschmidt/iniconfig/issues\n\nBasic Example\n===================================\n\nIf you have an ini file like this::\n\n # content of example.ini\n [section1] # comment\n name1=value1 # comment\n name1b=value1,value2 # comment\n\n [section2]\n name2=\n line1\n line2\n\nthen you can do::\n\n >>> import iniconfig\n >>> ini = iniconfig.IniConfig(\"example.ini\")\n >>> ini['section1']['name1'] # raises KeyError if not exists\n 'value1'\n >>> ini.get('section1', 'name1b', [], lambda x: x.split(\",\"))\n ['value1', 'value2']\n >>> ini.get('section1', 'notexist', [], lambda x: x.split(\",\"))\n []\n >>> [x.name for x in list(ini)]\n ['section1', 'section2']\n >>> list(list(ini)[0].items())\n [('name1', 'value1'), ('name1b', 'value1,value2')]\n >>> 'section1' in ini\n True\n >>> 'inexistendsection' in ini\n False", - "release_date": "2020-10-14T10:20:18", + "description": "Store and access your passwords safely.\n.. image:: https://img.shields.io/pypi/v/keyring.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/keyring.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/keyring\n\n.. image:: https://github.com/jaraco/keyring/workflows/tests/badge.svg\n :target: https://github.com/jaraco/keyring/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. image:: https://readthedocs.org/projects/keyring/badge/?version=latest\n :target: https://keyring.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2021-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. image:: https://tidelift.com/badges/package/pypi/keyring\n :target: https://tidelift.com/subscription/pkg/pypi-keyring?utm_source=pypi-keyring&utm_medium=readme\n\n.. image:: https://badges.gitter.im/jaraco/keyring.svg\n :alt: Join the chat at https://gitter.im/jaraco/keyring\n :target: https://gitter.im/jaraco/keyring?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge\n\nThe Python keyring library provides an easy way to access the\nsystem keyring service from python. It can be used in any\napplication that needs safe password storage.\n\nThese recommended keyring backends are supported:\n\n* macOS `Keychain\n `_\n* Freedesktop `Secret Service\n `_ supports many DE including\n GNOME (requires `secretstorage `_)\n* KDE4 & KDE5 `KWallet `_\n (requires `dbus `_)\n* `Windows Credential Locker\n `_\n\nOther keyring implementations are available through `Third-Party Backends`_.\n\nInstallation - Linux\n====================\n\nOn Linux, the KWallet backend relies on dbus-python_, which does not always\ninstall correctly when using pip (compilation is needed). For best results,\ninstall dbus-python as a system package.\n\n.. _dbus-python: https://gitlab.freedesktop.org/dbus/dbus-python\n\nCompatibility - macOS\n=====================\n\nmacOS keychain support macOS 11 (Big Sur) and later requires Python 3.8.7\nor later with the \"universal2\" binary. See\n`#525 `_ for details.\n\nUsing Keyring\n=============\n\nThe basic usage of keyring is pretty simple: just call\n``keyring.set_password`` and ``keyring.get_password``::\n\n >>> import keyring\n >>> keyring.set_password(\"system\", \"username\", \"password\")\n >>> keyring.get_password(\"system\", \"username\")\n 'password'\n\nCommand-line Utility\n--------------------\n\nKeyring supplies a ``keyring`` command which is installed with the\npackage. After installing keyring in most environments, the\ncommand should be available for setting, getting, and deleting\npasswords. For more information on usage, invoke with no arguments\nor with ``--help`` as so::\n\n $ keyring --help\n $ keyring set system username\n Password for 'username' in 'system':\n $ keyring get system username\n password\n\nThe command-line functionality is also exposed as an executable\npackage, suitable for invoking from Python like so::\n\n $ python -m keyring --help\n $ python -m keyring set system username\n Password for 'username' in 'system':\n $ python -m keyring get system username\n password\n\nConfiguring\n===========\n\nThe python keyring lib contains implementations for several backends. The\nlibrary will attempt to\nautomatically choose the most suitable backend for the current\nenvironment. Users may also specify the preferred keyring in a\nconfig file or by calling the ``set_keyring()`` function.\n\nConfig file path\n----------------\n\nThe configuration is stored in a file named \"keyringrc.cfg\"\nfound in a platform-specific location. To determine\nwhere the config file is stored, run the following::\n\n python -c \"import keyring.util.platform_; print(keyring.util.platform_.config_root())\"\n\nSome keyrings also store the keyring data in the file system.\nTo determine where the data files are stored, run::\n\n python -c \"import keyring.util.platform_; print(keyring.util.platform_.data_root())\"\n\nConfig file content\n-------------------\n\nTo specify a keyring backend, set the **default-keyring** option to the\nfull path of the class for that backend, such as\n``keyring.backends.OS_X.Keyring``.\n\nIf **keyring-path** is indicated, keyring will add that path to the Python\nmodule search path before loading the backend.\n\nFor example, this config might be used to load the\n``SimpleKeyring`` from the ``simplekeyring`` module in\nthe ``./demo`` directory (not implemented)::\n\n [backend]\n default-keyring=simplekeyring.SimpleKeyring\n keyring-path=demo\n\nThird-Party Backends\n====================\n\nIn addition to the backends provided by the core keyring package for\nthe most common and secure use cases, there\nare additional keyring backend implementations available for other\nuse-cases. Simply install them to make them available:\n\n- `keyrings.cryptfile `_\n - Encrypted text file storage.\n- `keyring_jeepney `__ - a\n pure Python backend using the secret service DBus API for desktop\n Linux.\n- `keyrings.alt `_ - \"alternate\",\n possibly-insecure backends, originally part of the core package, but\n available for opt-in.\n- `gsheet-keyring `_\n - a backend that stores secrets in a Google Sheet. For use with\n `ipython-secrets `_.\n- `bitwarden-keyring `_\n - a backend that stores secrets in the `BitWarden `_\n password manager.\n- `sagecipher `_ - an encryption\n backend which uses the ssh agent protocol's signature operation to\n derive the cipher key.\n- `keyrings.osx_keychain_keys `_\n - OSX keychain key-management, for private, public and symmetric keys.\n\n\nWrite your own keyring backend\n==============================\n\nThe interface for the backend is defined by ``keyring.backend.KeyringBackend``.\nEvery backend should derive from that base class and define a ``priority``\nattribute and three functions: ``get_password()``, ``set_password()``, and\n``delete_password()``. The ``get_credential()`` function may be defined if\ndesired.\n\nSee the ``backend`` module for more detail on the interface of this class.\n\nKeyring employs entry points to allow any third-party package to implement\nbackends without any modification to the keyring itself. Those interested in\ncreating new backends are encouraged to create new, third-party packages\nin the ``keyrings`` namespace, in a manner modeled by the `keyrings.alt\npackage `_. See the\n``setup.cfg`` file\nin that project for a hints on how to create the requisite entry points.\nBackends that prove essential may be considered for inclusion in the core\nlibrary, although the ease of installing these third-party packages should\nmean that extensions may be readily available.\n\nTo create an extension for Keyring, please submit a pull request to\nhave your extension mentioned as an available extension.\n\nRuntime Configuration\n=====================\n\nKeyring additionally allows programmatic configuration of the\nbackend calling the api ``set_keyring()``. The indicated backend\nwill subsequently be used to store and retrieve passwords.\n\nTo invoke ``set_keyring``::\n\n # define a new keyring class which extends the KeyringBackend\n import keyring.backend\n\n class TestKeyring(keyring.backend.KeyringBackend):\n \"\"\"A test keyring which always outputs same password\n \"\"\"\n priority = 1\n\n def set_password(self, servicename, username, password):\n pass\n\n def get_password(self, servicename, username):\n return \"password from TestKeyring\"\n\n def delete_password(self, servicename, username):\n pass\n\n # set the keyring for keyring lib\n keyring.set_keyring(TestKeyring())\n\n # invoke the keyring lib\n try:\n keyring.set_password(\"demo-service\", \"tarek\", \"passexample\")\n print(\"password stored successfully\")\n except keyring.errors.PasswordSetError:\n print(\"failed to store password\")\n print(\"password\", keyring.get_password(\"demo-service\", \"tarek\"))\n\n\nDisabling Keyring\n=================\n\nIn many cases, uninstalling keyring will never be necessary.\nEspecially on Windows and macOS, the behavior of keyring is\nusually degenerate, meaning it will return empty values to\nthe caller, allowing the caller to fall back to some other\nbehavior.\n\nIn some cases, the default behavior of keyring is undesirable and\nit would be preferable to disable the keyring behavior altogether.\nThere are several mechanisms to disable keyring:\n\n- Uninstall keyring. Most applications are tolerant to keyring\n not being installed. Uninstalling keyring should cause those\n applications to fall back to the behavior without keyring.\n This approach affects that Python environment where keyring\n would otherwise have been installed.\n\n- Configure the Null keyring in the environment. Set\n ``PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring``\n in the environment, and the ``Null`` (degenerate) backend\n will be used. This approach affects all uses of Keyring where\n that variable is set.\n\n- Permanently configure the Null keyring for the user by running\n ``keyring --disable`` or ``python -m keyring --disable``.\n This approach affects all uses of keyring for that user.\n\n\nAltering Keyring Behavior\n=========================\n\nKeyring provides a mechanism to alter the keyring's behavior through\nenvironment variables. Each backend implements a\n``KeyringBackend.set_properties_from_env``, which\nwhen invoked will find all environment variables beginning with\n``KEYRING_PROPERTY_{NAME}`` and will set a property for each\n``{NAME.lower()}`` on the keyring. This method is invoked during\ninitialization for the default/configured keyring.\n\nThis mechanism may be used to set some useful values on various\nkeyrings, including:\n\n- keychain; macOS, path to an alternate keychain file\n- appid; Linux/SecretService, alternate ID for the application\n\n\nUsing Keyring on Ubuntu 16.04\n=============================\n\nThe following is a complete transcript for installing keyring in a\nvirtual environment on Ubuntu 16.04. No config file was used::\n\n $ sudo apt install python3-venv libdbus-glib-1-dev\n $ cd /tmp\n $ pyvenv py3\n $ source py3/bin/activate\n $ pip install -U pip\n $ pip install secretstorage dbus-python\n $ pip install keyring\n $ python\n >>> import keyring\n >>> keyring.get_keyring()\n \n >>> keyring.set_password(\"system\", \"username\", \"password\")\n >>> keyring.get_password(\"system\", \"username\")\n 'password'\n\n\nUsing Keyring on headless Linux systems\n=======================================\n\nIt is possible to use the SecretService backend on Linux systems without\nX11 server available (only D-Bus is required). In this case:\n\n* Install the `GNOME Keyring`_ daemon.\n* Start a D-Bus session, e.g. run ``dbus-run-session -- sh`` and run\n the following commands inside that shell.\n* Run ``gnome-keyring-daemon`` with ``--unlock`` option. The description of\n that option says:\n\n Read a password from stdin, and use it to unlock the login keyring\n or create it if the login keyring does not exist.\n\n When that command is started, enter a password into stdin and\n press Ctrl+D (end of data). After that, the daemon will fork into\n background (use ``--foreground`` option to block).\n* Now you can use the SecretService backend of Keyring. Remember to\n run your application in the same D-Bus session as the daemon.\n\n.. _GNOME Keyring: https://wiki.gnome.org/Projects/GnomeKeyring\n\nUsing Keyring on headless Linux systems in a Docker container\n=============================================================\n\nIt is possible to use keyring with the SecretService backend in Docker containers as well.\nAll you need to do is install the necessary dependencies and add the `--privileged` flag\nto avoid any `Operation not permitted` errors when attempting to unlock the system's keyring.\n\nThe following is a complete transcript for installing keyring on a Ubuntu 18:04 container::\n\n docker run -it -d --privileged ubuntu:18.04\n\n $ apt-get update\n $ apt install -y gnome-keyring python3-venv python3-dev\n $ python3 -m venv venv\n $ source venv/bin/activate # source a virtual environment to avoid polluting your system\n $ pip3 install --upgrade pip\n $ pip3 install keyring\n $ dbus-run-session -- sh # this will drop you into a new D-bus shell\n $ echo 'somecredstorepass' | gnome-keyring-daemon --unlock # unlock the system's keyring\n\n $ python\n >>> import keyring\n >>> keyring.get_keyring()\n \n >>> keyring.set_password(\"system\", \"username\", \"password\")\n >>> keyring.get_password(\"system\", \"username\")\n 'password'\n\nIntegration\n===========\n\nAPI\n---\n\nThe keyring lib has a few functions:\n\n* ``get_keyring()``: Return the currently-loaded keyring implementation.\n* ``get_password(service, username)``: Returns the password stored in the\n active keyring. If the password does not exist, it will return None.\n* ``get_credential(service, username)``: Return a credential object stored\n in the active keyring. This object contains at least ``username`` and\n ``password`` attributes for the specified service, where the returned\n ``username`` may be different from the argument.\n* ``set_password(service, username, password)``: Store the password in the\n keyring.\n* ``delete_password(service, username)``: Delete the password stored in\n keyring. If the password does not exist, it will raise an exception.\n\nIn all cases, the parameters (``service``, ``username``, ``password``)\nshould be Unicode text.\n\n\nExceptions\n----------\n\nThe keyring lib raises following exceptions:\n\n* ``keyring.errors.KeyringError``: Base Error class for all exceptions in keyring lib.\n* ``keyring.errors.InitError``: Raised when the keyring cannot be initialized.\n* ``keyring.errors.PasswordSetError``: Raised when password cannot be set in the keyring.\n* ``keyring.errors.PasswordDeleteError``: Raised when the password cannot be deleted in the keyring.\n\nGet Involved\n============\n\nPython keyring lib is an open community project and eagerly\nwelcomes contributors.\n\n* Repository: https://github.com/jaraco/keyring/\n* Bug Tracker: https://github.com/jaraco/keyring/issues/\n* Mailing list: http://groups.google.com/group/python-keyring\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nThis project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more `_.\n\nSecurity Contact\n================\n\nTo report a security vulnerability, please use the\n`Tidelift security contact `_.\nTidelift will coordinate the fix and disclosure.\n\nSecurity Considerations\n=======================\n\nEach builtin backend may have security considerations to understand\nbefore using this library. Authors of tools or libraries utilizing\n``keyring`` are encouraged to consider these concerns.\n\nAs with any list of known security concerns, this list is not exhaustive.\nAdditional issues can be added as needed.\n\n- macOS Keychain\n - Any Python script or application can access secrets created by\n ``keyring`` from that same Python executable without the operating\n system prompting the user for a password. To cause any specific\n secret to prompt for a password every time it is accessed, locate\n the credential using the ``Keychain Access`` application, and in\n the ``Access Control`` settings, remove ``Python`` from the list\n of allowed applications.\n\n- Freedesktop Secret Service\n - No analysis has been performed\n\n- KDE4 & KDE5 KWallet\n - No analysis has been performed\n\n- Windows Credential Locker\n - No analysis has been performed\n\nMaking Releases\n===============\n\nThis project makes use of automated releases continuous\nintegration. The\nsimple workflow is to tag a commit and push it to Github. If it\npasses tests in CI, it will be automatically deployed to PyPI.\n\nOther things to consider when making a release:\n\n- Check that the changelog is current for the intended release.\n\nRunning Tests\n=============\n\nTests are continuously run in Github Actions.\n\nTo run the tests locally, install and invoke\n`tox `_.\n\nBackground\n==========\n\nThe project was based on Tarek Ziade's idea in `this post`_. Kang Zhang\ninitially carried it out as a `Google Summer of Code`_ project, and Tarek\nmentored Kang on this project.\n\n.. _this post: http://tarekziade.wordpress.com/2009/03/27/pycon-hallway-session-1-a-keyring-library-for-python/\n.. _Google Summer of Code: http://socghop.appspot.com/", + "release_date": "2022-01-02T00:25:39", "parties": [ { "type": "person", "role": "author", - "name": "Ronny Pfannschmidt, Holger Krekel", - "email": "opensource@ronnypfannschmidt.de, holger.krekel@gmail.com", + "name": "Kang Zhang", + "email": "jobo.zh@gmail.com", + "url": null + }, + { + "type": "person", + "role": "maintainer", + "name": "Jason R. Coombs", + "email": "jaraco@jaraco.com", "url": null } ], "keywords": [ - "Development Status :: 4 - Beta", + "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Programming Language :: Python", - "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities" + "Programming Language :: Python :: 3 :: Only" ], - "homepage_url": "http://github.com/RonnyPfannschmidt/iniconfig", - "download_url": "https://files.pythonhosted.org/packages/23/a2/97899f6bd0e873fed3a7e67ae8d3a08b21799430fb4da15cfedf10d6e2c2/iniconfig-1.1.1.tar.gz", - "size": 8104, + "homepage_url": "https://github.com/jaraco/keyring", + "download_url": "https://files.pythonhosted.org/packages/a4/e9/104ec4bffcf971375c348146c2199d4e241294286cc04a428b12c02e5f81/keyring-23.4.1-py3-none-any.whl", + "size": 33765, "sha1": null, - "md5": "0b7f3be87481211c183eae095bcea6f1", - "sha256": "bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32", + "md5": "10200c5f0172f6709052a7f94e6b4215", + "sha256": "17e49fb0d6883c2b4445359434dba95aad84aabb29bbff044ad0ed7100232eca", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -4235,9 +3212,9 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "MIT License", "classifiers": [ - "License :: OSI Approved :: MIT License" + "License :: OSI Approved :: MIT License", + "License :: OSI Approved :: Python Software Foundation License" ] }, "notice_text": null, @@ -4247,45 +3224,52 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/iniconfig/1.1.1/json", + "api_data_url": "https://pypi.org/pypi/keyring/23.4.1/json", "datasource_id": null, - "purl": "pkg:pypi/iniconfig@1.1.1" + "purl": "pkg:pypi/keyring@23.4.1" }, { "type": "pypi", "namespace": null, - "name": "intbitset", - "version": "3.0.1", + "name": "license-expression", + "version": "30.0.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "C-based extension implementing fast integer bit sets.\n===========\n intbitset\n===========\n\n.. image:: https://img.shields.io/travis/inveniosoftware/intbitset.svg\n :target: https://travis-ci.org/inveniosoftware/intbitset\n\n.. image:: https://img.shields.io/github/tag/inveniosoftware/intbitset.svg\n :target: https://github.com/inveniosoftware/intbitset/releases\n\n.. image:: https://img.shields.io/pypi/dm/intbitset.svg\n :target: https://pypi.python.org/pypi/intbitset\n\n.. image:: https://img.shields.io/github/license/inveniosoftware/intbitset.svg\n :target: https://github.com/inveniosoftware/intbitset/blob/master/LICENSE\n\n\nInstallation\n============\n\nintbitset is on PyPI so all you need is a C compiler and pip: ::\n\n pip install intbitset\n\nDocumentation\n=============\n\nThe ``intbitset`` library provides a set implementation to store sorted\nunsigned integers either 32-bits integers (between ``0`` and\n``2**31 - 1`` or ``intbitset.__maxelem__``) or an infinite range\nwith fast set operations implemented via bit vectors in a *Python C\nextension* for speed and reduced memory usage.\n\nThe ``inbitset`` class emulates the Python built-in set class interface\nwith some additional specific methods such as its own fast dump and load\nmarshalling functions. ::\n\n >>> from intbitset import intbitset\n >>> x = intbitset([1,2,3])\n >>> y = intbitset([3,4,5])\n >>> x & y\n intbitset([3])\n >>> x | y\n intbitset([1, 2, 3, 4, 5])\n\n``intbitset`` additionally support the `pickle protocol\n`_, the `iterator protocol\n`_ and can\nbehave like a ``sequence`` that can be sliced. Because the intergers are\nalways stored sorted, the fist element of a non-empty set `[0]` is also\nthe `min()` integer and the last element `[-1]` is also the `max()` integer\nin the set.\n\nWhen compared to the standard library ``set`` class, ``intbitset`` set\noperations such as intersection, union and difference can be up to 5000\nfaster for dense integer sets.\n\nComplete documentation is available at or\ncan be built using Sphinx: ::\n\n pip install Sphinx\n python setup.py build_sphinx\n\nTesting\n=======\n\nRunning the tests are as simple as: ::\n\n pip install -e .[tests]\n pytest\n\nRunning the tests on multiple Python versions: ::\n\n pip install tox\n tox\n\n\nDevelopment\n===========\n\nTo regenerate the C code with Cython: ::\n\n pip install cython\n cython intbitset/intbitset.pyx\n\nThen commit the regenarted C source and update the CHANGE.rst\n\n\nLicense\n=======\n\nCopyright (C) CERN and others\n\nSPDX-License-Identifier: LGPL-3.0-or-later\n\nintbitset is free software; you can redistribute it and/or modify it under the\nterms of the GNU Lesser General Public License as published by the Free Software\nFoundation; either version 3 of the License, or (at your option) any later\nversion.\n\nintbitset is distributed in the hope that it will be useful, but WITHOUT ANY\nWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A\nPARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.\n\nYou should have received a copy of the GNU Lesser General Public License along with\nintbitset; if not, write to the Free Software Foundation, Inc., 59 Temple\nPlace, Suite 330, Boston, MA 02111-1307, USA.\n\nIn applying this licence, CERN does not waive the privileges and immunities\ngranted to it by virtue of its status as an Intergovernmental Organization or\nsubmit itself to any jurisdiction.", - "release_date": "2022-03-04T21:42:42", + "description": "license-expression is a comprehensive utility library to parse, compare, simplify and normalize license expressions (such as SPDX license expressions) using boolean logic.\n==================\nlicense-expression\n==================\n\n``license-expression`` is a comprehensive utility library to parse, compare,\nsimplify and normalize license expressions (such as SPDX license expressions)\nusing boolean logic.\n\n- License: Apache-2.0\n- Python: 3.6+\n- Homepage: https://github.com/nexB/license-expression/\n- Install: `pip install license-expression` also available in most Linux distro.\n\nSoftware project licenses are often a combination of several free and open\nsource software licenses. License expressions -- as specified by SPDX -- provide\na concise and human readable way to express these licenses without having to\nread long license texts, while still being machine-readable.\n\nLicense expressions are used by key FOSS projects such as Linux; several\npackages ecosystem use them to document package licensing metadata such as\nnpm and Rubygems; they are important when exchanging software data (such as with\nSPDX and SBOM in general) as a way to express licensing precisely.\n\n``license-expression`` is a comprehensive utility library to parse, compare,\nsimplify and normalize these license expressions (such as SPDX license expressions)\nusing boolean logic like in: `GPL-2.0 or later WITH Classpath Exception AND MIT`.\n\nIt includes the license keys from SPDX https://spdx.org/licenses/ (version 3.13)\nand ScanCode license DB (version 21.6.7) https://scancode-licensedb.aboutcode.org/\nto get started quickly.\n\n``license-expression`` is both powerful and simple to use and is a used as the\nlicense expression engine in several projects and products such as:\n\n- AboutCode-toolkit https://github.com/nexB/aboutcode-toolkit\n- AlekSIS (School Information System) https://github.com/AlekSIS-org/AlekSIS-Core\n- Barista https://github.com/Optum/barista\n- Conda forge tools https://github.com/conda-forge/conda-smithy\n- DejaCode https://dejacode.com\n- DeltaCode https://github.com/nexB/deltacode\n- FenixscanX https://github.com/SmartsYoung/FenixscanX\n- FetchCode https://github.com/nexB/fetchcode\n- Flict https://github.com/vinland-technology/flict and https://github.com/vinland-technology\n- license.sh https://github.com/webscopeio/license.sh\n- liferay_inbound_checker https://github.com/carmenbianca/liferay_inbound_checker\n- REUSE https://reuse.software/ and https://github.com/fsfe/reuse-tool\n- ScanCode-io https://github.com/nexB/scancode.io\n- ScanCode-toolkit https://github.com/nexB/scancode-toolkit\n\nSee also for details:\n- https://spdx.github.io/spdx-spec/appendix-IV-SPDX-license-expressions/\n\n``license-expression`` is also packaged for most Linux distributions. See below.\n\nAlternative:\n\nThere is no known alternative library for Python, but there are several similar\nlibraries in other languages (but not as powerful of course!):\n\n- JavaScript https://github.com/jslicense/spdx-expression-parse.js\n- Rust https://github.com/ehuss/license-exprs\n- Haskell https://github.com/phadej/spdx\n- Go https://github.com/kyoh86/go-spdx\n- Ada https://github.com/Fabien-Chouteau/spdx_ada\n- Java https://github.com/spdx/tools and https://github.com/aschet/spdx-license-expression-tools\n\nBuild and tests status\n======================\n\n+--------------------------+------------------------+----------------------------------+\n|**Linux & macOS (Travis)**| **Windows (AppVeyor)** |**Linux, Windows & macOS (Azure)**|\n+==========================+========================+==================================+\n| | | |\n| |travis-badge-icon| | |appveyor-badge-icon| | |azure-badge-icon| |\n| | | |\n+--------------------------+------------------------+----------------------------------+\n\nSource code and download\n========================\n\n- GitHub https://github.com/nexB/license-expression.git\n- PyPI https://pypi.python.org/pypi/license-expression\n\nAlso available in several Linux distros:\n\n- Arch Linux https://archlinux.org/packages/community/any/python-license-expression/\n- Debian https://packages.debian.org/unstable/source/license-expression\n- DragonFly BSD https://github.com/DragonFlyBSD/DPorts/tree/master/textproc/py-license-expression\n- Fedora https://src.fedoraproject.org/rpms/python-license-expression/\n- FreeBSD https://www.freshports.org/textproc/py-license-expression\n- NixOS https://github.com/NixOS/nixpkgs/blob/release-21.05/pkgs/development/python-modules/license-expression/default.nix\n- openSUSE https://build.opensuse.org/package/show/openSUSE:Factory/python-license-expression\n\n\nSupport\n=======\n\n- Submit bugs and questions at: https://github.com/nexB/license-expression/issues\n- Join the chat at: https://gitter.im/aboutcode-org/discuss\n\nDescription\n===========\n\nThis module defines a mini language to parse, validate, simplify, normalize and\ncompare license expressions using a boolean logic engine.\n\nThis supports SPDX license expressions and also accepts other license naming\nconventions and license identifiers aliases to resolve and normalize any license\nexpressions.\n\nUsing boolean logic, license expressions can be tested for equality, containment,\nequivalence and can be normalized or simplified.\n\nIt also bundles the SPDX License list (3.13 as of now) and the ScanCode license\nDB (based on ScanCode 21.6.7) to easily parse and validate expressions using\nthe license symbols.\n\n\nUsage examples\n==============\n\nThe main entry point is the ``Licensing`` object that you can use to parse,\nvalidate, compare, simplify and normalize license expressions.\n\nCreate an SPDX Licensing and parse expressions::\n\n\t>>> from license_expression import get_spdx_licensing\n\t>>> licensing = get_spdx_licensing()\n\t>>> expression = ' GPL-2.0 or LGPL-2.1 and mit '\n\t>>> parsed = licensing.parse(expression)\n\t>>> print(parsed.pretty())\n\tOR(\n\t LicenseSymbol('GPL-2.0-only'),\n\t AND(\n\t LicenseSymbol('LGPL-2.1-only'),\n\t LicenseSymbol('MIT')\n\t )\n\t)\n\n\t>>> str(parsed)\n\t'GPL-2.0-only OR (LGPL-2.1-only AND MIT)'\n\n\t>>> licensing.parse('unknwon with foo', validate=True, strict=True)\n\tlicense_expression.ExpressionParseError: A plain license symbol cannot be used\n\tas an exception in a \"WITH symbol\" statement. for token: \"foo\" at position: 13\n\n\t>>> licensing.parse('unknwon with foo', validate=True)\n\tlicense_expression.ExpressionError: Unknown license key(s): unknwon, foo\n\n\t>>> licensing.validate('foo and MIT and GPL-2.0+')\n\tExpressionInfo(\n\t original_expression='foo and MIT and GPL-2.0+',\n\t normalized_expression=None,\n\t errors=['Unknown license key(s): foo'],\n\t invalid_symbols=['foo']\n\t)\n\n\nCreate a simple Licensing and parse expressions::\n\n >>> from license_expression import Licensing, LicenseSymbol\n >>> licensing = Licensing()\n >>> expression = ' GPL-2.0 or LGPL-2.1 and mit '\n >>> parsed = licensing.parse(expression)\n >>> expression = ' GPL-2.0 or LGPL-2.1 and mit '\n >>> expected = 'GPL-2.0-only OR (LGPL-2.1-only AND mit)'\n >>> assert str(parsed) == expected\n >>> assert parsed.render('{symbol.key}') == expected\n\n\nCreate a Licensing with your own license symbols::\n\n >>> expected = [\n ... LicenseSymbol('GPL-2.0'),\n ... LicenseSymbol('LGPL-2.1'),\n ... LicenseSymbol('mit')\n ... ]\n >>> assert licensing.license_symbols(expression) == expected\n >>> assert licensing.license_symbols(parsed) == expected\n\n >>> symbols = ['GPL-2.0+', 'Classpath', 'BSD']\n >>> licensing = Licensing(symbols)\n >>> expression = 'GPL-2.0+ with Classpath or (bsd)'\n >>> parsed = licensing.parse(expression)\n >>> expected = 'GPL-2.0+ WITH Classpath OR BSD'\n >>> assert parsed.render('{symbol.key}') == expected\n\n >>> expected = [\n ... LicenseSymbol('GPL-2.0+'),\n ... LicenseSymbol('Classpath'),\n ... LicenseSymbol('BSD')\n ... ]\n >>> assert licensing.license_symbols(parsed) == expected\n >>> assert licensing.license_symbols(expression) == expected\n\nAnd expression can be deduplicated, to remove duplicate license subexpressions\nwithout changing the order and without consider license choices as simplifiable::\n\n >>> expression2 = ' GPL-2.0 or (mit and LGPL 2.1) or bsd Or GPL-2.0 or (mit and LGPL 2.1)'\n >>> parsed2 = licensing.parse(expression2)\n >>> str(parsed2)\n 'GPL-2.0 OR (mit AND LGPL 2.1) OR BSD OR GPL-2.0 OR (mit AND LGPL 2.1)'\n >>> assert str(parsed2.simplify()) == 'BSD OR GPL-2.0 OR (LGPL 2.1 AND mit)'\n\nExpression can be simplified, treating them as boolean expressions::\n\n >>> expression2 = ' GPL-2.0 or (mit and LGPL 2.1) or bsd Or GPL-2.0 or (mit and LGPL 2.1)'\n >>> parsed2 = licensing.parse(expression2)\n >>> str(parsed2)\n 'GPL-2.0 OR (mit AND LGPL 2.1) OR BSD OR GPL-2.0 OR (mit AND LGPL 2.1)'\n >>> assert str(parsed2.simplify()) == 'BSD OR GPL-2.0 OR (LGPL 2.1 AND mit)'\n\nTwo expressions can be compared for equivalence and containment:\n\n >>> expr1 = licensing.parse(' GPL-2.0 or (LGPL 2.1 and mit) ')\n >>> expr2 = licensing.parse(' (mit and LGPL 2.1) or GPL-2.0 ')\n >>> licensing.is_equivalent(expr1, expr2)\n True\n >>> licensing.is_equivalent(' GPL-2.0 or (LGPL 2.1 and mit) ',\n ... ' (mit and LGPL 2.1) or GPL-2.0 ')\n True\n >>> expr1.simplify() == expr2.simplify()\n True\n >>> expr3 = licensing.parse(' GPL-2.0 or mit or LGPL 2.1')\n >>> licensing.is_equivalent(expr2, expr3)\n False\n >>> expr4 = licensing.parse('mit and LGPL 2.1')\n >>> expr4.simplify() in expr2.simplify()\n True\n >>> licensing.contains(expr2, expr4)\n True\n\nDevelopment\n===========\n\n- Checkout a clone from https://github.com/nexB/license-expression.git\n\n- Then run ``./configure --dev`` and then ``source tmp/bin/activate`` on Linux and POSIX.\n This will install all dependencies in a local virtualenv, including\n development deps.\n\n- On Windows run ``configure.bat --dev`` and then ``Scripts\\bin\\activate`` instead.\n\n- To run the tests, run ``pytest -vvs``\n\n\n.. |travis-badge-icon| image:: https://api.travis-ci.org/nexB/license-expression.png?branch=master\n :target: https://travis-ci.org/nexB/license-expression\n :alt: Travis tests status\n :align: middle\n\n.. |appveyor-badge-icon| image:: https://ci.appveyor.com/api/projects/status/github/nexB/license-expression?svg=true\n :target: https://ci.appveyor.com/project/nexB/license-expression\n :alt: Appveyor tests status\n :align: middle\n\n.. |azure-badge-icon| image:: https://dev.azure.com/nexB/license-expression/_apis/build/status/nexB.license-expression?branchName=master\n :target: https://dev.azure.com/nexB/license-expression/_build/latest?definitionId=2&branchName=master\n :alt: Azure pipelines tests status\n :align: middle", + "release_date": "2022-05-10T14:40:02", "parties": [ { "type": "person", "role": "author", - "name": "Invenio collaboration, maintained by Philippe Ombredanne", - "email": "info@inveniosoftware.org", + "name": "nexB. Inc. and others", + "email": "info@aboutcode.org", "url": null } ], "keywords": [ - "Environment :: Console", + "open source", + "license expression", + "license", + "spdx", + "boolean", + "parse expression", + "normalize expression", + "compare expression", + "licence", + "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: C", - "Programming Language :: Cython", - "Programming Language :: Python", "Programming Language :: Python :: 3", - "Topic :: Software Development :: Libraries :: Python Modules" + "Programming Language :: Python :: 3 :: Only", + "Topic :: Software Development", + "Topic :: Utilities" ], - "homepage_url": "http://github.com/inveniosoftware/intbitset/", - "download_url": "https://files.pythonhosted.org/packages/0e/54/1acf40a273b881e394d01a23bcc6e532b28d905d6077426f92dfb903dd27/intbitset-3.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", - "size": 351721, + "homepage_url": "https://github.com/nexB/license-expression", + "download_url": "https://files.pythonhosted.org/packages/12/36/d973dc41ce58eb3e6c8833e75d9e50f8c8f6c9bc9ac7e4f5430294e88708/license_expression-30.0.0-py3-none-any.whl", + "size": 86432, "sha1": null, - "md5": "9b95a1546ef91d5946c33c082aaeb46a", - "sha256": "83501f7d77ebcfc2cc4226bf7acc32cf042d35bb742ac544ae6dc4a33f66a9b6", + "md5": "a5cca31826be66e7cbcb15a18cbd9044", + "sha256": "e95325110110eb2b7539ee7773b97a0724d5371ec563cc718c8cac0e38cc40cc", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -4293,10 +3277,7 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "LGPL-3.0-or-later", - "classifiers": [ - "License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)" - ] + "license": "Apache-2.0" }, "notice_text": null, "source_packages": [], @@ -4305,2774 +3286,59 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/intbitset/3.0.1/json", + "api_data_url": "https://pypi.org/pypi/license-expression/30.0.0/json", "datasource_id": null, - "purl": "pkg:pypi/intbitset@3.0.1" + "purl": "pkg:pypi/license-expression@30.0.0" }, { "type": "pypi", "namespace": null, - "name": "intbitset", - "version": "3.0.1", + "name": "markupsafe", + "version": "2.0.1", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "C-based extension implementing fast integer bit sets.\n===========\n intbitset\n===========\n\n.. image:: https://img.shields.io/travis/inveniosoftware/intbitset.svg\n :target: https://travis-ci.org/inveniosoftware/intbitset\n\n.. image:: https://img.shields.io/github/tag/inveniosoftware/intbitset.svg\n :target: https://github.com/inveniosoftware/intbitset/releases\n\n.. image:: https://img.shields.io/pypi/dm/intbitset.svg\n :target: https://pypi.python.org/pypi/intbitset\n\n.. image:: https://img.shields.io/github/license/inveniosoftware/intbitset.svg\n :target: https://github.com/inveniosoftware/intbitset/blob/master/LICENSE\n\n\nInstallation\n============\n\nintbitset is on PyPI so all you need is a C compiler and pip: ::\n\n pip install intbitset\n\nDocumentation\n=============\n\nThe ``intbitset`` library provides a set implementation to store sorted\nunsigned integers either 32-bits integers (between ``0`` and\n``2**31 - 1`` or ``intbitset.__maxelem__``) or an infinite range\nwith fast set operations implemented via bit vectors in a *Python C\nextension* for speed and reduced memory usage.\n\nThe ``inbitset`` class emulates the Python built-in set class interface\nwith some additional specific methods such as its own fast dump and load\nmarshalling functions. ::\n\n >>> from intbitset import intbitset\n >>> x = intbitset([1,2,3])\n >>> y = intbitset([3,4,5])\n >>> x & y\n intbitset([3])\n >>> x | y\n intbitset([1, 2, 3, 4, 5])\n\n``intbitset`` additionally support the `pickle protocol\n`_, the `iterator protocol\n`_ and can\nbehave like a ``sequence`` that can be sliced. Because the intergers are\nalways stored sorted, the fist element of a non-empty set `[0]` is also\nthe `min()` integer and the last element `[-1]` is also the `max()` integer\nin the set.\n\nWhen compared to the standard library ``set`` class, ``intbitset`` set\noperations such as intersection, union and difference can be up to 5000\nfaster for dense integer sets.\n\nComplete documentation is available at or\ncan be built using Sphinx: ::\n\n pip install Sphinx\n python setup.py build_sphinx\n\nTesting\n=======\n\nRunning the tests are as simple as: ::\n\n pip install -e .[tests]\n pytest\n\nRunning the tests on multiple Python versions: ::\n\n pip install tox\n tox\n\n\nDevelopment\n===========\n\nTo regenerate the C code with Cython: ::\n\n pip install cython\n cython intbitset/intbitset.pyx\n\nThen commit the regenarted C source and update the CHANGE.rst\n\n\nLicense\n=======\n\nCopyright (C) CERN and others\n\nSPDX-License-Identifier: LGPL-3.0-or-later\n\nintbitset is free software; you can redistribute it and/or modify it under the\nterms of the GNU Lesser General Public License as published by the Free Software\nFoundation; either version 3 of the License, or (at your option) any later\nversion.\n\nintbitset is distributed in the hope that it will be useful, but WITHOUT ANY\nWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A\nPARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.\n\nYou should have received a copy of the GNU Lesser General Public License along with\nintbitset; if not, write to the Free Software Foundation, Inc., 59 Temple\nPlace, Suite 330, Boston, MA 02111-1307, USA.\n\nIn applying this licence, CERN does not waive the privileges and immunities\ngranted to it by virtue of its status as an Intergovernmental Organization or\nsubmit itself to any jurisdiction.", - "release_date": "2022-03-04T21:43:52", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Invenio collaboration, maintained by Philippe Ombredanne", - "email": "info@inveniosoftware.org", - "url": null - } - ], - "keywords": [ - "Environment :: Console", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: C", - "Programming Language :: Cython", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "http://github.com/inveniosoftware/intbitset/", - "download_url": "https://files.pythonhosted.org/packages/f8/80/81bf8129a2cc012a225ea0dc39cd6e11531a61d115616b1eead33b157164/intbitset-3.0.1.tar.gz", - "size": 151831, - "sha1": null, - "md5": "8f417e4ec5879841fde7aa873320ffdc", - "sha256": "f1e6d03c6729922a223c51849df65b9e916e625aefb911784e7f9acd4c207d53", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "LGPL-3.0-or-later", - "classifiers": [ - "License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/intbitset/3.0.1/json", - "datasource_id": null, - "purl": "pkg:pypi/intbitset@3.0.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "isort", - "version": "5.10.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A Python utility / library to sort Python imports.\n[![isort - isort your imports, so you don't have to.](https://raw.githubusercontent.com/pycqa/isort/main/art/logo_large.png)](https://pycqa.github.io/isort/)\n\n------------------------------------------------------------------------\n\n[![PyPI version](https://badge.fury.io/py/isort.svg)](https://badge.fury.io/py/isort)\n[![Test Status](https://github.com/pycqa/isort/workflows/Test/badge.svg?branch=develop)](https://github.com/pycqa/isort/actions?query=workflow%3ATest)\n[![Lint Status](https://github.com/pycqa/isort/workflows/Lint/badge.svg?branch=develop)](https://github.com/pycqa/isort/actions?query=workflow%3ALint)\n[![Code coverage Status](https://codecov.io/gh/pycqa/isort/branch/main/graph/badge.svg)](https://codecov.io/gh/pycqa/isort)\n[![License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://pypi.org/project/isort/)\n[![Join the chat at https://gitter.im/timothycrosley/isort](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/timothycrosley/isort?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n[![Downloads](https://pepy.tech/badge/isort)](https://pepy.tech/project/isort)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)\n[![DeepSource](https://static.deepsource.io/deepsource-badge-light-mini.svg)](https://deepsource.io/gh/pycqa/isort/?ref=repository-badge)\n_________________\n\n[Read Latest Documentation](https://pycqa.github.io/isort/) - [Browse GitHub Code Repository](https://github.com/pycqa/isort/)\n_________________\n\nisort your imports, so you don't have to.\n\nisort is a Python utility / library to sort imports alphabetically, and\nautomatically separated into sections and by type. It provides a command line\nutility, Python library and [plugins for various\neditors](https://github.com/pycqa/isort/wiki/isort-Plugins) to\nquickly sort all your imports. It requires Python 3.6+ to run but\nsupports formatting Python 2 code too.\n\n- [Try isort now from your browser!](https://pycqa.github.io/isort/docs/quick_start/0.-try.html)\n- [Using black? See the isort and black compatibility guide.](https://pycqa.github.io/isort/docs/configuration/black_compatibility.html)\n- [isort has official support for pre-commit!](https://pycqa.github.io/isort/docs/configuration/pre-commit.html)\n\n![Example Usage](https://raw.github.com/pycqa/isort/main/example.gif)\n\nBefore isort:\n\n```python\nfrom my_lib import Object\n\nimport os\n\nfrom my_lib import Object3\n\nfrom my_lib import Object2\n\nimport sys\n\nfrom third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14\n\nimport sys\n\nfrom __future__ import absolute_import\n\nfrom third_party import lib3\n\nprint(\"Hey\")\nprint(\"yo\")\n```\n\nAfter isort:\n\n```python\nfrom __future__ import absolute_import\n\nimport os\nimport sys\n\nfrom third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8,\n lib9, lib10, lib11, lib12, lib13, lib14, lib15)\n\nfrom my_lib import Object, Object2, Object3\n\nprint(\"Hey\")\nprint(\"yo\")\n```\n\n## Installing isort\n\nInstalling isort is as simple as:\n\n```bash\npip install isort\n```\n\nInstall isort with requirements.txt support:\n\n```bash\npip install isort[requirements_deprecated_finder]\n```\n\nInstall isort with Pipfile support:\n\n```bash\npip install isort[pipfile_deprecated_finder]\n```\n\nInstall isort with both formats support:\n\n```bash\npip install isort[requirements_deprecated_finder,pipfile_deprecated_finder]\n```\n\n## Using isort\n\n**From the command line**:\n\nTo run on specific files:\n\n```bash\nisort mypythonfile.py mypythonfile2.py\n```\n\nTo apply recursively:\n\n```bash\nisort .\n```\n\nIf [globstar](https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html)\nis enabled, `isort .` is equivalent to:\n\n```bash\nisort **/*.py\n```\n\nTo view proposed changes without applying them:\n\n```bash\nisort mypythonfile.py --diff\n```\n\nFinally, to atomically run isort against a project, only applying\nchanges if they don't introduce syntax errors:\n\n```bash\nisort --atomic .\n```\n\n(Note: this is disabled by default, as it prevents isort from\nrunning against code written using a different version of Python.)\n\n**From within Python**:\n\n```python\nimport isort\n\nisort.file(\"pythonfile.py\")\n```\n\nor:\n\n```python\nimport isort\n\nsorted_code = isort.code(\"import b\\nimport a\\n\")\n```\n\n## Installing isort's for your preferred text editor\n\nSeveral plugins have been written that enable to use isort from within a\nvariety of text-editors. You can find a full list of them [on the isort\nwiki](https://github.com/pycqa/isort/wiki/isort-Plugins).\nAdditionally, I will enthusiastically accept pull requests that include\nplugins for other text editors and add documentation for them as I am\nnotified.\n\n## Multi line output modes\n\nYou will notice above the \\\"multi\\_line\\_output\\\" setting. This setting\ndefines how from imports wrap when they extend past the line\\_length\nlimit and has [12 possible settings](https://pycqa.github.io/isort/docs/configuration/multi_line_output_modes.html).\n\n## Indentation\n\nTo change the how constant indents appear - simply change the\nindent property with the following accepted formats:\n\n- Number of spaces you would like. For example: 4 would cause standard\n 4 space indentation.\n- Tab\n- A verbatim string with quotes around it.\n\nFor example:\n\n```python\n\" \"\n```\n\nis equivalent to 4.\n\nFor the import styles that use parentheses, you can control whether or\nnot to include a trailing comma after the last import with the\n`include_trailing_comma` option (defaults to `False`).\n\n## Intelligently Balanced Multi-line Imports\n\nAs of isort 3.1.0 support for balanced multi-line imports has been\nadded. With this enabled isort will dynamically change the import length\nto the one that produces the most balanced grid, while staying below the\nmaximum import length defined.\n\nExample:\n\n```python\nfrom __future__ import (absolute_import, division,\n print_function, unicode_literals)\n```\n\nWill be produced instead of:\n\n```python\nfrom __future__ import (absolute_import, division, print_function,\n unicode_literals)\n```\n\nTo enable this set `balanced_wrapping` to `True` in your config or pass\nthe `-e` option into the command line utility.\n\n## Custom Sections and Ordering\n\nisort provides configuration options to change almost every aspect of how\nimports are organized, ordered, or grouped together in sections.\n\n[Click here](https://pycqa.github.io/isort/docs/configuration/custom_sections_and_ordering.html) for an overview of all these options.\n\n## Skip processing of imports (outside of configuration)\n\nTo make isort ignore a single import simply add a comment at the end of\nthe import line containing the text `isort:skip`:\n\n```python\nimport module # isort:skip\n```\n\nor:\n\n```python\nfrom xyz import (abc, # isort:skip\n yo,\n hey)\n```\n\nTo make isort skip an entire file simply add `isort:skip_file` to the\nmodule's doc string:\n\n```python\n\"\"\" my_module.py\n Best module ever\n\n isort:skip_file\n\"\"\"\n\nimport b\nimport a\n```\n\n## Adding or removing an import from multiple files\n\nisort can be ran or configured to add / remove imports automatically.\n\n[See a complete guide here.](https://pycqa.github.io/isort/docs/configuration/add_or_remove_imports.html)\n\n## Using isort to verify code\n\nThe `--check-only` option\n-------------------------\n\nisort can also be used to verify that code is correctly formatted\nby running it with `-c`. Any files that contain incorrectly sorted\nand/or formatted imports will be outputted to `stderr`.\n\n```bash\nisort **/*.py -c -v\n\nSUCCESS: /home/timothy/Projects/Open_Source/isort/isort_kate_plugin.py Everything Looks Good!\nERROR: /home/timothy/Projects/Open_Source/isort/isort/isort.py Imports are incorrectly sorted.\n```\n\nOne great place this can be used is with a pre-commit git hook, such as\nthis one by \\@acdha:\n\n\n\nThis can help to ensure a certain level of code quality throughout a\nproject.\n\n## Git hook\n\nisort provides a hook function that can be integrated into your Git\npre-commit script to check Python code before committing.\n\n[More info here.](https://pycqa.github.io/isort/docs/configuration/git_hook.html)\n\n## Setuptools integration\n\nUpon installation, isort enables a `setuptools` command that checks\nPython files declared by your project.\n\n[More info here.](https://pycqa.github.io/isort/docs/configuration/setuptools_integration.html)\n\n## Spread the word\n\n[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)\n\nPlace this badge at the top of your repository to let others know your project uses isort.\n\nFor README.md:\n\n```markdown\n[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)\n```\n\nOr README.rst:\n\n```rst\n.. image:: https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336\n :target: https://pycqa.github.io/isort/\n```\n\n## Security contact information\n\nTo report a security vulnerability, please use the [Tidelift security\ncontact](https://tidelift.com/security). Tidelift will coordinate the\nfix and disclosure.\n\n## Why isort?\n\nisort simply stands for import sort. It was originally called\n\"sortImports\" however I got tired of typing the extra characters and\ncame to the realization camelCase is not pythonic.\n\nI wrote isort because in an organization I used to work in the manager\ncame in one day and decided all code must have alphabetically sorted\nimports. The code base was huge - and he meant for us to do it by hand.\nHowever, being a programmer - I\\'m too lazy to spend 8 hours mindlessly\nperforming a function, but not too lazy to spend 16 hours automating it.\nI was given permission to open source sortImports and here we are :)\n\n------------------------------------------------------------------------\n\n[Get professionally supported isort with the Tidelift\nSubscription](https://tidelift.com/subscription/pkg/pypi-isort?utm_source=pypi-isort&utm_medium=referral&utm_campaign=readme)\n\nProfessional support for isort is available as part of the [Tidelift\nSubscription](https://tidelift.com/subscription/pkg/pypi-isort?utm_source=pypi-isort&utm_medium=referral&utm_campaign=readme).\nTidelift gives software development teams a single source for purchasing\nand maintaining their software, with professional grade assurances from\nthe experts who know it best, while seamlessly integrating with existing\ntools.\n\n------------------------------------------------------------------------\n\nThanks and I hope you find isort useful!\n\n~Timothy Crosley", - "release_date": "2021-11-09T05:42:44", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Timothy Crosley", - "email": "timothy.crosley@gmail.com", - "url": null - } - ], - "keywords": [ - "Refactor", - "Lint", - "Imports", - "Sort", - "Clean", - "Development Status :: 6 - Mature", - "Environment :: Console", - "Intended Audience :: Developers", - "Natural Language :: English", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities" - ], - "homepage_url": "https://pycqa.github.io/isort/", - "download_url": "https://files.pythonhosted.org/packages/b8/5b/f18e227df38b94b4ee30d2502fd531bebac23946a2497e5595067a561274/isort-5.10.1-py3-none-any.whl", - "size": 103430, - "sha1": null, - "md5": "da9d912dc0b12468db6f88a4e2a2f04e", - "sha256": "6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/isort/5.10.1/json", - "datasource_id": null, - "purl": "pkg:pypi/isort@5.10.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "isort", - "version": "5.10.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A Python utility / library to sort Python imports.\n[![isort - isort your imports, so you don't have to.](https://raw.githubusercontent.com/pycqa/isort/main/art/logo_large.png)](https://pycqa.github.io/isort/)\n\n------------------------------------------------------------------------\n\n[![PyPI version](https://badge.fury.io/py/isort.svg)](https://badge.fury.io/py/isort)\n[![Test Status](https://github.com/pycqa/isort/workflows/Test/badge.svg?branch=develop)](https://github.com/pycqa/isort/actions?query=workflow%3ATest)\n[![Lint Status](https://github.com/pycqa/isort/workflows/Lint/badge.svg?branch=develop)](https://github.com/pycqa/isort/actions?query=workflow%3ALint)\n[![Code coverage Status](https://codecov.io/gh/pycqa/isort/branch/main/graph/badge.svg)](https://codecov.io/gh/pycqa/isort)\n[![License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://pypi.org/project/isort/)\n[![Join the chat at https://gitter.im/timothycrosley/isort](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/timothycrosley/isort?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n[![Downloads](https://pepy.tech/badge/isort)](https://pepy.tech/project/isort)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)\n[![DeepSource](https://static.deepsource.io/deepsource-badge-light-mini.svg)](https://deepsource.io/gh/pycqa/isort/?ref=repository-badge)\n_________________\n\n[Read Latest Documentation](https://pycqa.github.io/isort/) - [Browse GitHub Code Repository](https://github.com/pycqa/isort/)\n_________________\n\nisort your imports, so you don't have to.\n\nisort is a Python utility / library to sort imports alphabetically, and\nautomatically separated into sections and by type. It provides a command line\nutility, Python library and [plugins for various\neditors](https://github.com/pycqa/isort/wiki/isort-Plugins) to\nquickly sort all your imports. It requires Python 3.6+ to run but\nsupports formatting Python 2 code too.\n\n- [Try isort now from your browser!](https://pycqa.github.io/isort/docs/quick_start/0.-try.html)\n- [Using black? See the isort and black compatibility guide.](https://pycqa.github.io/isort/docs/configuration/black_compatibility.html)\n- [isort has official support for pre-commit!](https://pycqa.github.io/isort/docs/configuration/pre-commit.html)\n\n![Example Usage](https://raw.github.com/pycqa/isort/main/example.gif)\n\nBefore isort:\n\n```python\nfrom my_lib import Object\n\nimport os\n\nfrom my_lib import Object3\n\nfrom my_lib import Object2\n\nimport sys\n\nfrom third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14\n\nimport sys\n\nfrom __future__ import absolute_import\n\nfrom third_party import lib3\n\nprint(\"Hey\")\nprint(\"yo\")\n```\n\nAfter isort:\n\n```python\nfrom __future__ import absolute_import\n\nimport os\nimport sys\n\nfrom third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8,\n lib9, lib10, lib11, lib12, lib13, lib14, lib15)\n\nfrom my_lib import Object, Object2, Object3\n\nprint(\"Hey\")\nprint(\"yo\")\n```\n\n## Installing isort\n\nInstalling isort is as simple as:\n\n```bash\npip install isort\n```\n\nInstall isort with requirements.txt support:\n\n```bash\npip install isort[requirements_deprecated_finder]\n```\n\nInstall isort with Pipfile support:\n\n```bash\npip install isort[pipfile_deprecated_finder]\n```\n\nInstall isort with both formats support:\n\n```bash\npip install isort[requirements_deprecated_finder,pipfile_deprecated_finder]\n```\n\n## Using isort\n\n**From the command line**:\n\nTo run on specific files:\n\n```bash\nisort mypythonfile.py mypythonfile2.py\n```\n\nTo apply recursively:\n\n```bash\nisort .\n```\n\nIf [globstar](https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html)\nis enabled, `isort .` is equivalent to:\n\n```bash\nisort **/*.py\n```\n\nTo view proposed changes without applying them:\n\n```bash\nisort mypythonfile.py --diff\n```\n\nFinally, to atomically run isort against a project, only applying\nchanges if they don't introduce syntax errors:\n\n```bash\nisort --atomic .\n```\n\n(Note: this is disabled by default, as it prevents isort from\nrunning against code written using a different version of Python.)\n\n**From within Python**:\n\n```python\nimport isort\n\nisort.file(\"pythonfile.py\")\n```\n\nor:\n\n```python\nimport isort\n\nsorted_code = isort.code(\"import b\\nimport a\\n\")\n```\n\n## Installing isort's for your preferred text editor\n\nSeveral plugins have been written that enable to use isort from within a\nvariety of text-editors. You can find a full list of them [on the isort\nwiki](https://github.com/pycqa/isort/wiki/isort-Plugins).\nAdditionally, I will enthusiastically accept pull requests that include\nplugins for other text editors and add documentation for them as I am\nnotified.\n\n## Multi line output modes\n\nYou will notice above the \\\"multi\\_line\\_output\\\" setting. This setting\ndefines how from imports wrap when they extend past the line\\_length\nlimit and has [12 possible settings](https://pycqa.github.io/isort/docs/configuration/multi_line_output_modes.html).\n\n## Indentation\n\nTo change the how constant indents appear - simply change the\nindent property with the following accepted formats:\n\n- Number of spaces you would like. For example: 4 would cause standard\n 4 space indentation.\n- Tab\n- A verbatim string with quotes around it.\n\nFor example:\n\n```python\n\" \"\n```\n\nis equivalent to 4.\n\nFor the import styles that use parentheses, you can control whether or\nnot to include a trailing comma after the last import with the\n`include_trailing_comma` option (defaults to `False`).\n\n## Intelligently Balanced Multi-line Imports\n\nAs of isort 3.1.0 support for balanced multi-line imports has been\nadded. With this enabled isort will dynamically change the import length\nto the one that produces the most balanced grid, while staying below the\nmaximum import length defined.\n\nExample:\n\n```python\nfrom __future__ import (absolute_import, division,\n print_function, unicode_literals)\n```\n\nWill be produced instead of:\n\n```python\nfrom __future__ import (absolute_import, division, print_function,\n unicode_literals)\n```\n\nTo enable this set `balanced_wrapping` to `True` in your config or pass\nthe `-e` option into the command line utility.\n\n## Custom Sections and Ordering\n\nisort provides configuration options to change almost every aspect of how\nimports are organized, ordered, or grouped together in sections.\n\n[Click here](https://pycqa.github.io/isort/docs/configuration/custom_sections_and_ordering.html) for an overview of all these options.\n\n## Skip processing of imports (outside of configuration)\n\nTo make isort ignore a single import simply add a comment at the end of\nthe import line containing the text `isort:skip`:\n\n```python\nimport module # isort:skip\n```\n\nor:\n\n```python\nfrom xyz import (abc, # isort:skip\n yo,\n hey)\n```\n\nTo make isort skip an entire file simply add `isort:skip_file` to the\nmodule's doc string:\n\n```python\n\"\"\" my_module.py\n Best module ever\n\n isort:skip_file\n\"\"\"\n\nimport b\nimport a\n```\n\n## Adding or removing an import from multiple files\n\nisort can be ran or configured to add / remove imports automatically.\n\n[See a complete guide here.](https://pycqa.github.io/isort/docs/configuration/add_or_remove_imports.html)\n\n## Using isort to verify code\n\nThe `--check-only` option\n-------------------------\n\nisort can also be used to verify that code is correctly formatted\nby running it with `-c`. Any files that contain incorrectly sorted\nand/or formatted imports will be outputted to `stderr`.\n\n```bash\nisort **/*.py -c -v\n\nSUCCESS: /home/timothy/Projects/Open_Source/isort/isort_kate_plugin.py Everything Looks Good!\nERROR: /home/timothy/Projects/Open_Source/isort/isort/isort.py Imports are incorrectly sorted.\n```\n\nOne great place this can be used is with a pre-commit git hook, such as\nthis one by \\@acdha:\n\n\n\nThis can help to ensure a certain level of code quality throughout a\nproject.\n\n## Git hook\n\nisort provides a hook function that can be integrated into your Git\npre-commit script to check Python code before committing.\n\n[More info here.](https://pycqa.github.io/isort/docs/configuration/git_hook.html)\n\n## Setuptools integration\n\nUpon installation, isort enables a `setuptools` command that checks\nPython files declared by your project.\n\n[More info here.](https://pycqa.github.io/isort/docs/configuration/setuptools_integration.html)\n\n## Spread the word\n\n[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)\n\nPlace this badge at the top of your repository to let others know your project uses isort.\n\nFor README.md:\n\n```markdown\n[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)\n```\n\nOr README.rst:\n\n```rst\n.. image:: https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336\n :target: https://pycqa.github.io/isort/\n```\n\n## Security contact information\n\nTo report a security vulnerability, please use the [Tidelift security\ncontact](https://tidelift.com/security). Tidelift will coordinate the\nfix and disclosure.\n\n## Why isort?\n\nisort simply stands for import sort. It was originally called\n\"sortImports\" however I got tired of typing the extra characters and\ncame to the realization camelCase is not pythonic.\n\nI wrote isort because in an organization I used to work in the manager\ncame in one day and decided all code must have alphabetically sorted\nimports. The code base was huge - and he meant for us to do it by hand.\nHowever, being a programmer - I\\'m too lazy to spend 8 hours mindlessly\nperforming a function, but not too lazy to spend 16 hours automating it.\nI was given permission to open source sortImports and here we are :)\n\n------------------------------------------------------------------------\n\n[Get professionally supported isort with the Tidelift\nSubscription](https://tidelift.com/subscription/pkg/pypi-isort?utm_source=pypi-isort&utm_medium=referral&utm_campaign=readme)\n\nProfessional support for isort is available as part of the [Tidelift\nSubscription](https://tidelift.com/subscription/pkg/pypi-isort?utm_source=pypi-isort&utm_medium=referral&utm_campaign=readme).\nTidelift gives software development teams a single source for purchasing\nand maintaining their software, with professional grade assurances from\nthe experts who know it best, while seamlessly integrating with existing\ntools.\n\n------------------------------------------------------------------------\n\nThanks and I hope you find isort useful!\n\n~Timothy Crosley", - "release_date": "2021-11-09T05:42:46", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Timothy Crosley", - "email": "timothy.crosley@gmail.com", - "url": null - } - ], - "keywords": [ - "Refactor", - "Lint", - "Imports", - "Sort", - "Clean", - "Development Status :: 6 - Mature", - "Environment :: Console", - "Intended Audience :: Developers", - "Natural Language :: English", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities" - ], - "homepage_url": "https://pycqa.github.io/isort/", - "download_url": "https://files.pythonhosted.org/packages/ab/e9/964cb0b2eedd80c92f5172f1f8ae0443781a9d461c1372a3ce5762489593/isort-5.10.1.tar.gz", - "size": 174062, - "sha1": null, - "md5": "717294d0a9017b27bd46b1c946b39bd0", - "sha256": "e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/isort/5.10.1/json", - "datasource_id": null, - "purl": "pkg:pypi/isort@5.10.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "itsdangerous", - "version": "2.1.2", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Safely pass data to untrusted environments and back.\nItsDangerous\n============\n\n... so better sign this\n\nVarious helpers to pass data to untrusted environments and to get it\nback safe and sound. Data is cryptographically signed to ensure that a\ntoken has not been tampered with.\n\nIt's possible to customize how data is serialized. Data is compressed as\nneeded. A timestamp can be added and verified automatically while\nloading a token.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U itsdangerous\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\nHere's how you could generate a token for transmitting a user's id and\nname between web requests.\n\n.. code-block:: python\n\n from itsdangerous import URLSafeSerializer\n auth_s = URLSafeSerializer(\"secret key\", \"auth\")\n token = auth_s.dumps({\"id\": 5, \"name\": \"itsdangerous\"})\n\n print(token)\n # eyJpZCI6NSwibmFtZSI6Iml0c2Rhbmdlcm91cyJ9.6YP6T0BaO67XP--9UzTrmurXSmg\n\n data = auth_s.loads(token)\n print(data[\"name\"])\n # itsdangerous\n\n\nDonate\n------\n\nThe Pallets organization develops and supports ItsDangerous and other\npopular packages. In order to grow the community of contributors and\nusers, and allow the maintainers to devote more time to the projects,\n`please donate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://itsdangerous.palletsprojects.com/\n- Changes: https://itsdangerous.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/ItsDangerous/\n- Source Code: https://github.com/pallets/itsdangerous/\n- Issue Tracker: https://github.com/pallets/itsdangerous/issues/\n- Website: https://palletsprojects.com/p/itsdangerous/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2022-03-24T15:12:13", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python" - ], - "homepage_url": "https://palletsprojects.com/p/itsdangerous/", - "download_url": "https://files.pythonhosted.org/packages/68/5f/447e04e828f47465eeab35b5d408b7ebaaaee207f48b7136c5a7267a30ae/itsdangerous-2.1.2-py3-none-any.whl", - "size": 15749, - "sha1": null, - "md5": "efb0813a44f2abd3b7b375cfcb8b95c2", - "sha256": "2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/itsdangerous/issues/", - "code_view_url": "https://github.com/pallets/itsdangerous/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/itsdangerous/2.1.2/json", - "datasource_id": null, - "purl": "pkg:pypi/itsdangerous@2.1.2" - }, - { - "type": "pypi", - "namespace": null, - "name": "itsdangerous", - "version": "2.1.2", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Safely pass data to untrusted environments and back.\nItsDangerous\n============\n\n... so better sign this\n\nVarious helpers to pass data to untrusted environments and to get it\nback safe and sound. Data is cryptographically signed to ensure that a\ntoken has not been tampered with.\n\nIt's possible to customize how data is serialized. Data is compressed as\nneeded. A timestamp can be added and verified automatically while\nloading a token.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U itsdangerous\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\nHere's how you could generate a token for transmitting a user's id and\nname between web requests.\n\n.. code-block:: python\n\n from itsdangerous import URLSafeSerializer\n auth_s = URLSafeSerializer(\"secret key\", \"auth\")\n token = auth_s.dumps({\"id\": 5, \"name\": \"itsdangerous\"})\n\n print(token)\n # eyJpZCI6NSwibmFtZSI6Iml0c2Rhbmdlcm91cyJ9.6YP6T0BaO67XP--9UzTrmurXSmg\n\n data = auth_s.loads(token)\n print(data[\"name\"])\n # itsdangerous\n\n\nDonate\n------\n\nThe Pallets organization develops and supports ItsDangerous and other\npopular packages. In order to grow the community of contributors and\nusers, and allow the maintainers to devote more time to the projects,\n`please donate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://itsdangerous.palletsprojects.com/\n- Changes: https://itsdangerous.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/ItsDangerous/\n- Source Code: https://github.com/pallets/itsdangerous/\n- Issue Tracker: https://github.com/pallets/itsdangerous/issues/\n- Website: https://palletsprojects.com/p/itsdangerous/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2022-03-24T15:12:15", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python" - ], - "homepage_url": "https://palletsprojects.com/p/itsdangerous/", - "download_url": "https://files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", - "size": 56143, - "sha1": null, - "md5": "c1bc730ddf53b8374eaa823f24eb6438", - "sha256": "5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/itsdangerous/issues/", - "code_view_url": "https://github.com/pallets/itsdangerous/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/itsdangerous/2.1.2/json", - "datasource_id": null, - "purl": "pkg:pypi/itsdangerous@2.1.2" - }, - { - "type": "pypi", - "namespace": null, - "name": "jeepney", - "version": "0.7.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Low-level, pure Python DBus protocol wrapper.\nJeepney is a pure Python implementation of D-Bus messaging. It has an `I/O-free\n`__ core, and integration modules for different\nevent loops.\n\nD-Bus is an inter-process communication system, mainly used in Linux.\n\nTo install Jeepney::\n\n pip install jeepney\n\n`Jeepney docs on Readthedocs `__", - "release_date": "2021-07-28T18:17:20", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Thomas Kluyver", - "email": "thomas@kluyver.me.uk", - "url": null - } - ], - "keywords": [ - "Programming Language :: Python :: 3", - "Topic :: Desktop Environment" - ], - "homepage_url": "https://gitlab.com/takluyver/jeepney", - "download_url": "https://files.pythonhosted.org/packages/14/b8/bb3e34d71472140f9bfdf5d77cd063e2cc964b72b1bb0b70fe3c1e7db932/jeepney-0.7.1-py3-none-any.whl", - "size": 54082, - "sha1": null, - "md5": "22e7c84e1eadffad5299f40cc31d1e21", - "sha256": "1b5a0ea5c0e7b166b2f5895b91a08c14de8915afda4407fb5022a195224958ac", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/jeepney/0.7.1/json", - "datasource_id": null, - "purl": "pkg:pypi/jeepney@0.7.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "jeepney", - "version": "0.7.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Low-level, pure Python DBus protocol wrapper.\nJeepney is a pure Python implementation of D-Bus messaging. It has an `I/O-free\n`__ core, and integration modules for different\nevent loops.\n\nD-Bus is an inter-process communication system, mainly used in Linux.\n\nTo install Jeepney::\n\n pip install jeepney\n\n`Jeepney docs on Readthedocs `__", - "release_date": "2021-07-28T18:17:22", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Thomas Kluyver", - "email": "thomas@kluyver.me.uk", - "url": null - } - ], - "keywords": [ - "Programming Language :: Python :: 3", - "Topic :: Desktop Environment" - ], - "homepage_url": "https://gitlab.com/takluyver/jeepney", - "download_url": "https://files.pythonhosted.org/packages/09/0d/81744e179cf3aede2d117c20c6d5b97a62ffe16b2ca5d856e068e81c7a68/jeepney-0.7.1.tar.gz", - "size": 61833, - "sha1": null, - "md5": "d804ad938b27d9b761f2c44f8d33fef6", - "sha256": "fa9e232dfa0c498bd0b8a3a73b8d8a31978304dcef0515adc859d4e096f96f4f", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/jeepney/0.7.1/json", - "datasource_id": null, - "purl": "pkg:pypi/jeepney@0.7.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "jinja2", - "version": "3.0.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A very fast and expressive template engine.\nJinja\n=====\n\nJinja is a fast, expressive, extensible templating engine. Special\nplaceholders in the template allow writing code similar to Python\nsyntax. Then the template is passed data to render the final document.\n\nIt includes:\n\n- Template inheritance and inclusion.\n- Define and import macros within templates.\n- HTML templates can use autoescaping to prevent XSS from untrusted\n user input.\n- A sandboxed environment can safely render untrusted templates.\n- AsyncIO support for generating templates and calling async\n functions.\n- I18N support with Babel.\n- Templates are compiled to optimized Python code just-in-time and\n cached, or can be compiled ahead-of-time.\n- Exceptions point to the correct line in templates to make debugging\n easier.\n- Extensible filters, tests, functions, and even syntax.\n\nJinja's philosophy is that while application logic belongs in Python if\npossible, it shouldn't make the template designer's job difficult by\nrestricting functionality too much.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U Jinja2\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nIn A Nutshell\n-------------\n\n.. code-block:: jinja\n\n {% extends \"base.html\" %}\n {% block title %}Members{% endblock %}\n {% block content %}\n \n {% endblock %}\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Jinja and other popular\npackages. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://jinja.palletsprojects.com/\n- Changes: https://jinja.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/Jinja2/\n- Source Code: https://github.com/pallets/jinja/\n- Issue Tracker: https://github.com/pallets/jinja/issues/\n- Website: https://palletsprojects.com/p/jinja/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2021-11-09T20:27:27", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Text Processing :: Markup :: HTML" - ], - "homepage_url": "https://palletsprojects.com/p/jinja/", - "download_url": "https://files.pythonhosted.org/packages/20/9a/e5d9ec41927401e41aea8af6d16e78b5e612bca4699d417f646a9610a076/Jinja2-3.0.3-py3-none-any.whl", - "size": 133630, - "sha1": null, - "md5": "31d7a56a843bbf4ef35e0076fea86767", - "sha256": "077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/jinja/issues/", - "code_view_url": "https://github.com/pallets/jinja/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/jinja2/3.0.3/json", - "datasource_id": null, - "purl": "pkg:pypi/jinja2@3.0.3" - }, - { - "type": "pypi", - "namespace": null, - "name": "jinja2", - "version": "3.0.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A very fast and expressive template engine.\nJinja\n=====\n\nJinja is a fast, expressive, extensible templating engine. Special\nplaceholders in the template allow writing code similar to Python\nsyntax. Then the template is passed data to render the final document.\n\nIt includes:\n\n- Template inheritance and inclusion.\n- Define and import macros within templates.\n- HTML templates can use autoescaping to prevent XSS from untrusted\n user input.\n- A sandboxed environment can safely render untrusted templates.\n- AsyncIO support for generating templates and calling async\n functions.\n- I18N support with Babel.\n- Templates are compiled to optimized Python code just-in-time and\n cached, or can be compiled ahead-of-time.\n- Exceptions point to the correct line in templates to make debugging\n easier.\n- Extensible filters, tests, functions, and even syntax.\n\nJinja's philosophy is that while application logic belongs in Python if\npossible, it shouldn't make the template designer's job difficult by\nrestricting functionality too much.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U Jinja2\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nIn A Nutshell\n-------------\n\n.. code-block:: jinja\n\n {% extends \"base.html\" %}\n {% block title %}Members{% endblock %}\n {% block content %}\n \n {% endblock %}\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Jinja and other popular\npackages. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://jinja.palletsprojects.com/\n- Changes: https://jinja.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/Jinja2/\n- Source Code: https://github.com/pallets/jinja/\n- Issue Tracker: https://github.com/pallets/jinja/issues/\n- Website: https://palletsprojects.com/p/jinja/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2021-11-09T20:27:29", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Text Processing :: Markup :: HTML" - ], - "homepage_url": "https://palletsprojects.com/p/jinja/", - "download_url": "https://files.pythonhosted.org/packages/91/a5/429efc6246119e1e3fbf562c00187d04e83e54619249eb732bb423efa6c6/Jinja2-3.0.3.tar.gz", - "size": 269196, - "sha1": null, - "md5": "b76ae2f0647abebc81e7c03f5fb7b00f", - "sha256": "611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/jinja/issues/", - "code_view_url": "https://github.com/pallets/jinja/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/jinja2/3.0.3/json", - "datasource_id": null, - "purl": "pkg:pypi/jinja2@3.0.3" - }, - { - "type": "pypi", - "namespace": null, - "name": "keyring", - "version": "23.4.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Store and access your passwords safely.\n.. image:: https://img.shields.io/pypi/v/keyring.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/keyring.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/keyring\n\n.. image:: https://github.com/jaraco/keyring/workflows/tests/badge.svg\n :target: https://github.com/jaraco/keyring/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. image:: https://readthedocs.org/projects/keyring/badge/?version=latest\n :target: https://keyring.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2021-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. image:: https://tidelift.com/badges/package/pypi/keyring\n :target: https://tidelift.com/subscription/pkg/pypi-keyring?utm_source=pypi-keyring&utm_medium=readme\n\n.. image:: https://badges.gitter.im/jaraco/keyring.svg\n :alt: Join the chat at https://gitter.im/jaraco/keyring\n :target: https://gitter.im/jaraco/keyring?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge\n\nThe Python keyring library provides an easy way to access the\nsystem keyring service from python. It can be used in any\napplication that needs safe password storage.\n\nThese recommended keyring backends are supported:\n\n* macOS `Keychain\n `_\n* Freedesktop `Secret Service\n `_ supports many DE including\n GNOME (requires `secretstorage `_)\n* KDE4 & KDE5 `KWallet `_\n (requires `dbus `_)\n* `Windows Credential Locker\n `_\n\nOther keyring implementations are available through `Third-Party Backends`_.\n\nInstallation - Linux\n====================\n\nOn Linux, the KWallet backend relies on dbus-python_, which does not always\ninstall correctly when using pip (compilation is needed). For best results,\ninstall dbus-python as a system package.\n\n.. _dbus-python: https://gitlab.freedesktop.org/dbus/dbus-python\n\nCompatibility - macOS\n=====================\n\nmacOS keychain support macOS 11 (Big Sur) and later requires Python 3.8.7\nor later with the \"universal2\" binary. See\n`#525 `_ for details.\n\nUsing Keyring\n=============\n\nThe basic usage of keyring is pretty simple: just call\n``keyring.set_password`` and ``keyring.get_password``::\n\n >>> import keyring\n >>> keyring.set_password(\"system\", \"username\", \"password\")\n >>> keyring.get_password(\"system\", \"username\")\n 'password'\n\nCommand-line Utility\n--------------------\n\nKeyring supplies a ``keyring`` command which is installed with the\npackage. After installing keyring in most environments, the\ncommand should be available for setting, getting, and deleting\npasswords. For more information on usage, invoke with no arguments\nor with ``--help`` as so::\n\n $ keyring --help\n $ keyring set system username\n Password for 'username' in 'system':\n $ keyring get system username\n password\n\nThe command-line functionality is also exposed as an executable\npackage, suitable for invoking from Python like so::\n\n $ python -m keyring --help\n $ python -m keyring set system username\n Password for 'username' in 'system':\n $ python -m keyring get system username\n password\n\nConfiguring\n===========\n\nThe python keyring lib contains implementations for several backends. The\nlibrary will attempt to\nautomatically choose the most suitable backend for the current\nenvironment. Users may also specify the preferred keyring in a\nconfig file or by calling the ``set_keyring()`` function.\n\nConfig file path\n----------------\n\nThe configuration is stored in a file named \"keyringrc.cfg\"\nfound in a platform-specific location. To determine\nwhere the config file is stored, run the following::\n\n python -c \"import keyring.util.platform_; print(keyring.util.platform_.config_root())\"\n\nSome keyrings also store the keyring data in the file system.\nTo determine where the data files are stored, run::\n\n python -c \"import keyring.util.platform_; print(keyring.util.platform_.data_root())\"\n\nConfig file content\n-------------------\n\nTo specify a keyring backend, set the **default-keyring** option to the\nfull path of the class for that backend, such as\n``keyring.backends.OS_X.Keyring``.\n\nIf **keyring-path** is indicated, keyring will add that path to the Python\nmodule search path before loading the backend.\n\nFor example, this config might be used to load the\n``SimpleKeyring`` from the ``simplekeyring`` module in\nthe ``./demo`` directory (not implemented)::\n\n [backend]\n default-keyring=simplekeyring.SimpleKeyring\n keyring-path=demo\n\nThird-Party Backends\n====================\n\nIn addition to the backends provided by the core keyring package for\nthe most common and secure use cases, there\nare additional keyring backend implementations available for other\nuse-cases. Simply install them to make them available:\n\n- `keyrings.cryptfile `_\n - Encrypted text file storage.\n- `keyring_jeepney `__ - a\n pure Python backend using the secret service DBus API for desktop\n Linux.\n- `keyrings.alt `_ - \"alternate\",\n possibly-insecure backends, originally part of the core package, but\n available for opt-in.\n- `gsheet-keyring `_\n - a backend that stores secrets in a Google Sheet. For use with\n `ipython-secrets `_.\n- `bitwarden-keyring `_\n - a backend that stores secrets in the `BitWarden `_\n password manager.\n- `sagecipher `_ - an encryption\n backend which uses the ssh agent protocol's signature operation to\n derive the cipher key.\n- `keyrings.osx_keychain_keys `_\n - OSX keychain key-management, for private, public and symmetric keys.\n\n\nWrite your own keyring backend\n==============================\n\nThe interface for the backend is defined by ``keyring.backend.KeyringBackend``.\nEvery backend should derive from that base class and define a ``priority``\nattribute and three functions: ``get_password()``, ``set_password()``, and\n``delete_password()``. The ``get_credential()`` function may be defined if\ndesired.\n\nSee the ``backend`` module for more detail on the interface of this class.\n\nKeyring employs entry points to allow any third-party package to implement\nbackends without any modification to the keyring itself. Those interested in\ncreating new backends are encouraged to create new, third-party packages\nin the ``keyrings`` namespace, in a manner modeled by the `keyrings.alt\npackage `_. See the\n``setup.cfg`` file\nin that project for a hints on how to create the requisite entry points.\nBackends that prove essential may be considered for inclusion in the core\nlibrary, although the ease of installing these third-party packages should\nmean that extensions may be readily available.\n\nTo create an extension for Keyring, please submit a pull request to\nhave your extension mentioned as an available extension.\n\nRuntime Configuration\n=====================\n\nKeyring additionally allows programmatic configuration of the\nbackend calling the api ``set_keyring()``. The indicated backend\nwill subsequently be used to store and retrieve passwords.\n\nTo invoke ``set_keyring``::\n\n # define a new keyring class which extends the KeyringBackend\n import keyring.backend\n\n class TestKeyring(keyring.backend.KeyringBackend):\n \"\"\"A test keyring which always outputs same password\n \"\"\"\n priority = 1\n\n def set_password(self, servicename, username, password):\n pass\n\n def get_password(self, servicename, username):\n return \"password from TestKeyring\"\n\n def delete_password(self, servicename, username):\n pass\n\n # set the keyring for keyring lib\n keyring.set_keyring(TestKeyring())\n\n # invoke the keyring lib\n try:\n keyring.set_password(\"demo-service\", \"tarek\", \"passexample\")\n print(\"password stored successfully\")\n except keyring.errors.PasswordSetError:\n print(\"failed to store password\")\n print(\"password\", keyring.get_password(\"demo-service\", \"tarek\"))\n\n\nDisabling Keyring\n=================\n\nIn many cases, uninstalling keyring will never be necessary.\nEspecially on Windows and macOS, the behavior of keyring is\nusually degenerate, meaning it will return empty values to\nthe caller, allowing the caller to fall back to some other\nbehavior.\n\nIn some cases, the default behavior of keyring is undesirable and\nit would be preferable to disable the keyring behavior altogether.\nThere are several mechanisms to disable keyring:\n\n- Uninstall keyring. Most applications are tolerant to keyring\n not being installed. Uninstalling keyring should cause those\n applications to fall back to the behavior without keyring.\n This approach affects that Python environment where keyring\n would otherwise have been installed.\n\n- Configure the Null keyring in the environment. Set\n ``PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring``\n in the environment, and the ``Null`` (degenerate) backend\n will be used. This approach affects all uses of Keyring where\n that variable is set.\n\n- Permanently configure the Null keyring for the user by running\n ``keyring --disable`` or ``python -m keyring --disable``.\n This approach affects all uses of keyring for that user.\n\n\nAltering Keyring Behavior\n=========================\n\nKeyring provides a mechanism to alter the keyring's behavior through\nenvironment variables. Each backend implements a\n``KeyringBackend.set_properties_from_env``, which\nwhen invoked will find all environment variables beginning with\n``KEYRING_PROPERTY_{NAME}`` and will set a property for each\n``{NAME.lower()}`` on the keyring. This method is invoked during\ninitialization for the default/configured keyring.\n\nThis mechanism may be used to set some useful values on various\nkeyrings, including:\n\n- keychain; macOS, path to an alternate keychain file\n- appid; Linux/SecretService, alternate ID for the application\n\n\nUsing Keyring on Ubuntu 16.04\n=============================\n\nThe following is a complete transcript for installing keyring in a\nvirtual environment on Ubuntu 16.04. No config file was used::\n\n $ sudo apt install python3-venv libdbus-glib-1-dev\n $ cd /tmp\n $ pyvenv py3\n $ source py3/bin/activate\n $ pip install -U pip\n $ pip install secretstorage dbus-python\n $ pip install keyring\n $ python\n >>> import keyring\n >>> keyring.get_keyring()\n \n >>> keyring.set_password(\"system\", \"username\", \"password\")\n >>> keyring.get_password(\"system\", \"username\")\n 'password'\n\n\nUsing Keyring on headless Linux systems\n=======================================\n\nIt is possible to use the SecretService backend on Linux systems without\nX11 server available (only D-Bus is required). In this case:\n\n* Install the `GNOME Keyring`_ daemon.\n* Start a D-Bus session, e.g. run ``dbus-run-session -- sh`` and run\n the following commands inside that shell.\n* Run ``gnome-keyring-daemon`` with ``--unlock`` option. The description of\n that option says:\n\n Read a password from stdin, and use it to unlock the login keyring\n or create it if the login keyring does not exist.\n\n When that command is started, enter a password into stdin and\n press Ctrl+D (end of data). After that, the daemon will fork into\n background (use ``--foreground`` option to block).\n* Now you can use the SecretService backend of Keyring. Remember to\n run your application in the same D-Bus session as the daemon.\n\n.. _GNOME Keyring: https://wiki.gnome.org/Projects/GnomeKeyring\n\nUsing Keyring on headless Linux systems in a Docker container\n=============================================================\n\nIt is possible to use keyring with the SecretService backend in Docker containers as well.\nAll you need to do is install the necessary dependencies and add the `--privileged` flag\nto avoid any `Operation not permitted` errors when attempting to unlock the system's keyring.\n\nThe following is a complete transcript for installing keyring on a Ubuntu 18:04 container::\n\n docker run -it -d --privileged ubuntu:18.04\n\n $ apt-get update\n $ apt install -y gnome-keyring python3-venv python3-dev\n $ python3 -m venv venv\n $ source venv/bin/activate # source a virtual environment to avoid polluting your system\n $ pip3 install --upgrade pip\n $ pip3 install keyring\n $ dbus-run-session -- sh # this will drop you into a new D-bus shell\n $ echo 'somecredstorepass' | gnome-keyring-daemon --unlock # unlock the system's keyring\n\n $ python\n >>> import keyring\n >>> keyring.get_keyring()\n \n >>> keyring.set_password(\"system\", \"username\", \"password\")\n >>> keyring.get_password(\"system\", \"username\")\n 'password'\n\nIntegration\n===========\n\nAPI\n---\n\nThe keyring lib has a few functions:\n\n* ``get_keyring()``: Return the currently-loaded keyring implementation.\n* ``get_password(service, username)``: Returns the password stored in the\n active keyring. If the password does not exist, it will return None.\n* ``get_credential(service, username)``: Return a credential object stored\n in the active keyring. This object contains at least ``username`` and\n ``password`` attributes for the specified service, where the returned\n ``username`` may be different from the argument.\n* ``set_password(service, username, password)``: Store the password in the\n keyring.\n* ``delete_password(service, username)``: Delete the password stored in\n keyring. If the password does not exist, it will raise an exception.\n\nIn all cases, the parameters (``service``, ``username``, ``password``)\nshould be Unicode text.\n\n\nExceptions\n----------\n\nThe keyring lib raises following exceptions:\n\n* ``keyring.errors.KeyringError``: Base Error class for all exceptions in keyring lib.\n* ``keyring.errors.InitError``: Raised when the keyring cannot be initialized.\n* ``keyring.errors.PasswordSetError``: Raised when password cannot be set in the keyring.\n* ``keyring.errors.PasswordDeleteError``: Raised when the password cannot be deleted in the keyring.\n\nGet Involved\n============\n\nPython keyring lib is an open community project and eagerly\nwelcomes contributors.\n\n* Repository: https://github.com/jaraco/keyring/\n* Bug Tracker: https://github.com/jaraco/keyring/issues/\n* Mailing list: http://groups.google.com/group/python-keyring\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nThis project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more `_.\n\nSecurity Contact\n================\n\nTo report a security vulnerability, please use the\n`Tidelift security contact `_.\nTidelift will coordinate the fix and disclosure.\n\nSecurity Considerations\n=======================\n\nEach builtin backend may have security considerations to understand\nbefore using this library. Authors of tools or libraries utilizing\n``keyring`` are encouraged to consider these concerns.\n\nAs with any list of known security concerns, this list is not exhaustive.\nAdditional issues can be added as needed.\n\n- macOS Keychain\n - Any Python script or application can access secrets created by\n ``keyring`` from that same Python executable without the operating\n system prompting the user for a password. To cause any specific\n secret to prompt for a password every time it is accessed, locate\n the credential using the ``Keychain Access`` application, and in\n the ``Access Control`` settings, remove ``Python`` from the list\n of allowed applications.\n\n- Freedesktop Secret Service\n - No analysis has been performed\n\n- KDE4 & KDE5 KWallet\n - No analysis has been performed\n\n- Windows Credential Locker\n - No analysis has been performed\n\nMaking Releases\n===============\n\nThis project makes use of automated releases continuous\nintegration. The\nsimple workflow is to tag a commit and push it to Github. If it\npasses tests in CI, it will be automatically deployed to PyPI.\n\nOther things to consider when making a release:\n\n- Check that the changelog is current for the intended release.\n\nRunning Tests\n=============\n\nTests are continuously run in Github Actions.\n\nTo run the tests locally, install and invoke\n`tox `_.\n\nBackground\n==========\n\nThe project was based on Tarek Ziade's idea in `this post`_. Kang Zhang\ninitially carried it out as a `Google Summer of Code`_ project, and Tarek\nmentored Kang on this project.\n\n.. _this post: http://tarekziade.wordpress.com/2009/03/27/pycon-hallway-session-1-a-keyring-library-for-python/\n.. _Google Summer of Code: http://socghop.appspot.com/", - "release_date": "2022-01-02T00:25:39", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Kang Zhang", - "email": "jobo.zh@gmail.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Jason R. Coombs", - "email": "jaraco@jaraco.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only" - ], - "homepage_url": "https://github.com/jaraco/keyring", - "download_url": "https://files.pythonhosted.org/packages/a4/e9/104ec4bffcf971375c348146c2199d4e241294286cc04a428b12c02e5f81/keyring-23.4.1-py3-none-any.whl", - "size": 33765, - "sha1": null, - "md5": "10200c5f0172f6709052a7f94e6b4215", - "sha256": "17e49fb0d6883c2b4445359434dba95aad84aabb29bbff044ad0ed7100232eca", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "classifiers": [ - "License :: OSI Approved :: MIT License", - "License :: OSI Approved :: Python Software Foundation License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/keyring/23.4.1/json", - "datasource_id": null, - "purl": "pkg:pypi/keyring@23.4.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "keyring", - "version": "23.4.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Store and access your passwords safely.\n.. image:: https://img.shields.io/pypi/v/keyring.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/keyring.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/keyring\n\n.. image:: https://github.com/jaraco/keyring/workflows/tests/badge.svg\n :target: https://github.com/jaraco/keyring/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. image:: https://readthedocs.org/projects/keyring/badge/?version=latest\n :target: https://keyring.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2021-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. image:: https://tidelift.com/badges/package/pypi/keyring\n :target: https://tidelift.com/subscription/pkg/pypi-keyring?utm_source=pypi-keyring&utm_medium=readme\n\n.. image:: https://badges.gitter.im/jaraco/keyring.svg\n :alt: Join the chat at https://gitter.im/jaraco/keyring\n :target: https://gitter.im/jaraco/keyring?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge\n\nThe Python keyring library provides an easy way to access the\nsystem keyring service from python. It can be used in any\napplication that needs safe password storage.\n\nThese recommended keyring backends are supported:\n\n* macOS `Keychain\n `_\n* Freedesktop `Secret Service\n `_ supports many DE including\n GNOME (requires `secretstorage `_)\n* KDE4 & KDE5 `KWallet `_\n (requires `dbus `_)\n* `Windows Credential Locker\n `_\n\nOther keyring implementations are available through `Third-Party Backends`_.\n\nInstallation - Linux\n====================\n\nOn Linux, the KWallet backend relies on dbus-python_, which does not always\ninstall correctly when using pip (compilation is needed). For best results,\ninstall dbus-python as a system package.\n\n.. _dbus-python: https://gitlab.freedesktop.org/dbus/dbus-python\n\nCompatibility - macOS\n=====================\n\nmacOS keychain support macOS 11 (Big Sur) and later requires Python 3.8.7\nor later with the \"universal2\" binary. See\n`#525 `_ for details.\n\nUsing Keyring\n=============\n\nThe basic usage of keyring is pretty simple: just call\n``keyring.set_password`` and ``keyring.get_password``::\n\n >>> import keyring\n >>> keyring.set_password(\"system\", \"username\", \"password\")\n >>> keyring.get_password(\"system\", \"username\")\n 'password'\n\nCommand-line Utility\n--------------------\n\nKeyring supplies a ``keyring`` command which is installed with the\npackage. After installing keyring in most environments, the\ncommand should be available for setting, getting, and deleting\npasswords. For more information on usage, invoke with no arguments\nor with ``--help`` as so::\n\n $ keyring --help\n $ keyring set system username\n Password for 'username' in 'system':\n $ keyring get system username\n password\n\nThe command-line functionality is also exposed as an executable\npackage, suitable for invoking from Python like so::\n\n $ python -m keyring --help\n $ python -m keyring set system username\n Password for 'username' in 'system':\n $ python -m keyring get system username\n password\n\nConfiguring\n===========\n\nThe python keyring lib contains implementations for several backends. The\nlibrary will attempt to\nautomatically choose the most suitable backend for the current\nenvironment. Users may also specify the preferred keyring in a\nconfig file or by calling the ``set_keyring()`` function.\n\nConfig file path\n----------------\n\nThe configuration is stored in a file named \"keyringrc.cfg\"\nfound in a platform-specific location. To determine\nwhere the config file is stored, run the following::\n\n python -c \"import keyring.util.platform_; print(keyring.util.platform_.config_root())\"\n\nSome keyrings also store the keyring data in the file system.\nTo determine where the data files are stored, run::\n\n python -c \"import keyring.util.platform_; print(keyring.util.platform_.data_root())\"\n\nConfig file content\n-------------------\n\nTo specify a keyring backend, set the **default-keyring** option to the\nfull path of the class for that backend, such as\n``keyring.backends.OS_X.Keyring``.\n\nIf **keyring-path** is indicated, keyring will add that path to the Python\nmodule search path before loading the backend.\n\nFor example, this config might be used to load the\n``SimpleKeyring`` from the ``simplekeyring`` module in\nthe ``./demo`` directory (not implemented)::\n\n [backend]\n default-keyring=simplekeyring.SimpleKeyring\n keyring-path=demo\n\nThird-Party Backends\n====================\n\nIn addition to the backends provided by the core keyring package for\nthe most common and secure use cases, there\nare additional keyring backend implementations available for other\nuse-cases. Simply install them to make them available:\n\n- `keyrings.cryptfile `_\n - Encrypted text file storage.\n- `keyring_jeepney `__ - a\n pure Python backend using the secret service DBus API for desktop\n Linux.\n- `keyrings.alt `_ - \"alternate\",\n possibly-insecure backends, originally part of the core package, but\n available for opt-in.\n- `gsheet-keyring `_\n - a backend that stores secrets in a Google Sheet. For use with\n `ipython-secrets `_.\n- `bitwarden-keyring `_\n - a backend that stores secrets in the `BitWarden `_\n password manager.\n- `sagecipher `_ - an encryption\n backend which uses the ssh agent protocol's signature operation to\n derive the cipher key.\n- `keyrings.osx_keychain_keys `_\n - OSX keychain key-management, for private, public and symmetric keys.\n\n\nWrite your own keyring backend\n==============================\n\nThe interface for the backend is defined by ``keyring.backend.KeyringBackend``.\nEvery backend should derive from that base class and define a ``priority``\nattribute and three functions: ``get_password()``, ``set_password()``, and\n``delete_password()``. The ``get_credential()`` function may be defined if\ndesired.\n\nSee the ``backend`` module for more detail on the interface of this class.\n\nKeyring employs entry points to allow any third-party package to implement\nbackends without any modification to the keyring itself. Those interested in\ncreating new backends are encouraged to create new, third-party packages\nin the ``keyrings`` namespace, in a manner modeled by the `keyrings.alt\npackage `_. See the\n``setup.cfg`` file\nin that project for a hints on how to create the requisite entry points.\nBackends that prove essential may be considered for inclusion in the core\nlibrary, although the ease of installing these third-party packages should\nmean that extensions may be readily available.\n\nTo create an extension for Keyring, please submit a pull request to\nhave your extension mentioned as an available extension.\n\nRuntime Configuration\n=====================\n\nKeyring additionally allows programmatic configuration of the\nbackend calling the api ``set_keyring()``. The indicated backend\nwill subsequently be used to store and retrieve passwords.\n\nTo invoke ``set_keyring``::\n\n # define a new keyring class which extends the KeyringBackend\n import keyring.backend\n\n class TestKeyring(keyring.backend.KeyringBackend):\n \"\"\"A test keyring which always outputs same password\n \"\"\"\n priority = 1\n\n def set_password(self, servicename, username, password):\n pass\n\n def get_password(self, servicename, username):\n return \"password from TestKeyring\"\n\n def delete_password(self, servicename, username):\n pass\n\n # set the keyring for keyring lib\n keyring.set_keyring(TestKeyring())\n\n # invoke the keyring lib\n try:\n keyring.set_password(\"demo-service\", \"tarek\", \"passexample\")\n print(\"password stored successfully\")\n except keyring.errors.PasswordSetError:\n print(\"failed to store password\")\n print(\"password\", keyring.get_password(\"demo-service\", \"tarek\"))\n\n\nDisabling Keyring\n=================\n\nIn many cases, uninstalling keyring will never be necessary.\nEspecially on Windows and macOS, the behavior of keyring is\nusually degenerate, meaning it will return empty values to\nthe caller, allowing the caller to fall back to some other\nbehavior.\n\nIn some cases, the default behavior of keyring is undesirable and\nit would be preferable to disable the keyring behavior altogether.\nThere are several mechanisms to disable keyring:\n\n- Uninstall keyring. Most applications are tolerant to keyring\n not being installed. Uninstalling keyring should cause those\n applications to fall back to the behavior without keyring.\n This approach affects that Python environment where keyring\n would otherwise have been installed.\n\n- Configure the Null keyring in the environment. Set\n ``PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring``\n in the environment, and the ``Null`` (degenerate) backend\n will be used. This approach affects all uses of Keyring where\n that variable is set.\n\n- Permanently configure the Null keyring for the user by running\n ``keyring --disable`` or ``python -m keyring --disable``.\n This approach affects all uses of keyring for that user.\n\n\nAltering Keyring Behavior\n=========================\n\nKeyring provides a mechanism to alter the keyring's behavior through\nenvironment variables. Each backend implements a\n``KeyringBackend.set_properties_from_env``, which\nwhen invoked will find all environment variables beginning with\n``KEYRING_PROPERTY_{NAME}`` and will set a property for each\n``{NAME.lower()}`` on the keyring. This method is invoked during\ninitialization for the default/configured keyring.\n\nThis mechanism may be used to set some useful values on various\nkeyrings, including:\n\n- keychain; macOS, path to an alternate keychain file\n- appid; Linux/SecretService, alternate ID for the application\n\n\nUsing Keyring on Ubuntu 16.04\n=============================\n\nThe following is a complete transcript for installing keyring in a\nvirtual environment on Ubuntu 16.04. No config file was used::\n\n $ sudo apt install python3-venv libdbus-glib-1-dev\n $ cd /tmp\n $ pyvenv py3\n $ source py3/bin/activate\n $ pip install -U pip\n $ pip install secretstorage dbus-python\n $ pip install keyring\n $ python\n >>> import keyring\n >>> keyring.get_keyring()\n \n >>> keyring.set_password(\"system\", \"username\", \"password\")\n >>> keyring.get_password(\"system\", \"username\")\n 'password'\n\n\nUsing Keyring on headless Linux systems\n=======================================\n\nIt is possible to use the SecretService backend on Linux systems without\nX11 server available (only D-Bus is required). In this case:\n\n* Install the `GNOME Keyring`_ daemon.\n* Start a D-Bus session, e.g. run ``dbus-run-session -- sh`` and run\n the following commands inside that shell.\n* Run ``gnome-keyring-daemon`` with ``--unlock`` option. The description of\n that option says:\n\n Read a password from stdin, and use it to unlock the login keyring\n or create it if the login keyring does not exist.\n\n When that command is started, enter a password into stdin and\n press Ctrl+D (end of data). After that, the daemon will fork into\n background (use ``--foreground`` option to block).\n* Now you can use the SecretService backend of Keyring. Remember to\n run your application in the same D-Bus session as the daemon.\n\n.. _GNOME Keyring: https://wiki.gnome.org/Projects/GnomeKeyring\n\nUsing Keyring on headless Linux systems in a Docker container\n=============================================================\n\nIt is possible to use keyring with the SecretService backend in Docker containers as well.\nAll you need to do is install the necessary dependencies and add the `--privileged` flag\nto avoid any `Operation not permitted` errors when attempting to unlock the system's keyring.\n\nThe following is a complete transcript for installing keyring on a Ubuntu 18:04 container::\n\n docker run -it -d --privileged ubuntu:18.04\n\n $ apt-get update\n $ apt install -y gnome-keyring python3-venv python3-dev\n $ python3 -m venv venv\n $ source venv/bin/activate # source a virtual environment to avoid polluting your system\n $ pip3 install --upgrade pip\n $ pip3 install keyring\n $ dbus-run-session -- sh # this will drop you into a new D-bus shell\n $ echo 'somecredstorepass' | gnome-keyring-daemon --unlock # unlock the system's keyring\n\n $ python\n >>> import keyring\n >>> keyring.get_keyring()\n \n >>> keyring.set_password(\"system\", \"username\", \"password\")\n >>> keyring.get_password(\"system\", \"username\")\n 'password'\n\nIntegration\n===========\n\nAPI\n---\n\nThe keyring lib has a few functions:\n\n* ``get_keyring()``: Return the currently-loaded keyring implementation.\n* ``get_password(service, username)``: Returns the password stored in the\n active keyring. If the password does not exist, it will return None.\n* ``get_credential(service, username)``: Return a credential object stored\n in the active keyring. This object contains at least ``username`` and\n ``password`` attributes for the specified service, where the returned\n ``username`` may be different from the argument.\n* ``set_password(service, username, password)``: Store the password in the\n keyring.\n* ``delete_password(service, username)``: Delete the password stored in\n keyring. If the password does not exist, it will raise an exception.\n\nIn all cases, the parameters (``service``, ``username``, ``password``)\nshould be Unicode text.\n\n\nExceptions\n----------\n\nThe keyring lib raises following exceptions:\n\n* ``keyring.errors.KeyringError``: Base Error class for all exceptions in keyring lib.\n* ``keyring.errors.InitError``: Raised when the keyring cannot be initialized.\n* ``keyring.errors.PasswordSetError``: Raised when password cannot be set in the keyring.\n* ``keyring.errors.PasswordDeleteError``: Raised when the password cannot be deleted in the keyring.\n\nGet Involved\n============\n\nPython keyring lib is an open community project and eagerly\nwelcomes contributors.\n\n* Repository: https://github.com/jaraco/keyring/\n* Bug Tracker: https://github.com/jaraco/keyring/issues/\n* Mailing list: http://groups.google.com/group/python-keyring\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nThis project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more `_.\n\nSecurity Contact\n================\n\nTo report a security vulnerability, please use the\n`Tidelift security contact `_.\nTidelift will coordinate the fix and disclosure.\n\nSecurity Considerations\n=======================\n\nEach builtin backend may have security considerations to understand\nbefore using this library. Authors of tools or libraries utilizing\n``keyring`` are encouraged to consider these concerns.\n\nAs with any list of known security concerns, this list is not exhaustive.\nAdditional issues can be added as needed.\n\n- macOS Keychain\n - Any Python script or application can access secrets created by\n ``keyring`` from that same Python executable without the operating\n system prompting the user for a password. To cause any specific\n secret to prompt for a password every time it is accessed, locate\n the credential using the ``Keychain Access`` application, and in\n the ``Access Control`` settings, remove ``Python`` from the list\n of allowed applications.\n\n- Freedesktop Secret Service\n - No analysis has been performed\n\n- KDE4 & KDE5 KWallet\n - No analysis has been performed\n\n- Windows Credential Locker\n - No analysis has been performed\n\nMaking Releases\n===============\n\nThis project makes use of automated releases continuous\nintegration. The\nsimple workflow is to tag a commit and push it to Github. If it\npasses tests in CI, it will be automatically deployed to PyPI.\n\nOther things to consider when making a release:\n\n- Check that the changelog is current for the intended release.\n\nRunning Tests\n=============\n\nTests are continuously run in Github Actions.\n\nTo run the tests locally, install and invoke\n`tox `_.\n\nBackground\n==========\n\nThe project was based on Tarek Ziade's idea in `this post`_. Kang Zhang\ninitially carried it out as a `Google Summer of Code`_ project, and Tarek\nmentored Kang on this project.\n\n.. _this post: http://tarekziade.wordpress.com/2009/03/27/pycon-hallway-session-1-a-keyring-library-for-python/\n.. _Google Summer of Code: http://socghop.appspot.com/", - "release_date": "2022-01-02T00:25:41", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Kang Zhang", - "email": "jobo.zh@gmail.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Jason R. Coombs", - "email": "jaraco@jaraco.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only" - ], - "homepage_url": "https://github.com/jaraco/keyring", - "download_url": "https://files.pythonhosted.org/packages/6f/23/143b4adec7d6957d35c0fc90c095203046da04eb5eade7fef8b00fe421fc/keyring-23.4.1.tar.gz", - "size": 54135, - "sha1": null, - "md5": "e1d85ffb9b2ba1032068c361e2431b3c", - "sha256": "89cbd74d4683ed164c8082fb38619341097741323b3786905c6dac04d6915a55", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "classifiers": [ - "License :: OSI Approved :: MIT License", - "License :: OSI Approved :: Python Software Foundation License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/keyring/23.4.1/json", - "datasource_id": null, - "purl": "pkg:pypi/keyring@23.4.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "license-expression", - "version": "30.0.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "license-expression is a comprehensive utility library to parse, compare, simplify and normalize license expressions (such as SPDX license expressions) using boolean logic.\n==================\nlicense-expression\n==================\n\n``license-expression`` is a comprehensive utility library to parse, compare,\nsimplify and normalize license expressions (such as SPDX license expressions)\nusing boolean logic.\n\n- License: Apache-2.0\n- Python: 3.6+\n- Homepage: https://github.com/nexB/license-expression/\n- Install: `pip install license-expression` also available in most Linux distro.\n\nSoftware project licenses are often a combination of several free and open\nsource software licenses. License expressions -- as specified by SPDX -- provide\na concise and human readable way to express these licenses without having to\nread long license texts, while still being machine-readable.\n\nLicense expressions are used by key FOSS projects such as Linux; several\npackages ecosystem use them to document package licensing metadata such as\nnpm and Rubygems; they are important when exchanging software data (such as with\nSPDX and SBOM in general) as a way to express licensing precisely.\n\n``license-expression`` is a comprehensive utility library to parse, compare,\nsimplify and normalize these license expressions (such as SPDX license expressions)\nusing boolean logic like in: `GPL-2.0 or later WITH Classpath Exception AND MIT`.\n\nIt includes the license keys from SPDX https://spdx.org/licenses/ (version 3.13)\nand ScanCode license DB (version 21.6.7) https://scancode-licensedb.aboutcode.org/\nto get started quickly.\n\n``license-expression`` is both powerful and simple to use and is a used as the\nlicense expression engine in several projects and products such as:\n\n- AboutCode-toolkit https://github.com/nexB/aboutcode-toolkit\n- AlekSIS (School Information System) https://github.com/AlekSIS-org/AlekSIS-Core\n- Barista https://github.com/Optum/barista\n- Conda forge tools https://github.com/conda-forge/conda-smithy\n- DejaCode https://dejacode.com\n- DeltaCode https://github.com/nexB/deltacode\n- FenixscanX https://github.com/SmartsYoung/FenixscanX\n- FetchCode https://github.com/nexB/fetchcode\n- Flict https://github.com/vinland-technology/flict and https://github.com/vinland-technology\n- license.sh https://github.com/webscopeio/license.sh\n- liferay_inbound_checker https://github.com/carmenbianca/liferay_inbound_checker\n- REUSE https://reuse.software/ and https://github.com/fsfe/reuse-tool\n- ScanCode-io https://github.com/nexB/scancode.io\n- ScanCode-toolkit https://github.com/nexB/scancode-toolkit\n\nSee also for details:\n- https://spdx.github.io/spdx-spec/appendix-IV-SPDX-license-expressions/\n\n``license-expression`` is also packaged for most Linux distributions. See below.\n\nAlternative:\n\nThere is no known alternative library for Python, but there are several similar\nlibraries in other languages (but not as powerful of course!):\n\n- JavaScript https://github.com/jslicense/spdx-expression-parse.js\n- Rust https://github.com/ehuss/license-exprs\n- Haskell https://github.com/phadej/spdx\n- Go https://github.com/kyoh86/go-spdx\n- Ada https://github.com/Fabien-Chouteau/spdx_ada\n- Java https://github.com/spdx/tools and https://github.com/aschet/spdx-license-expression-tools\n\nBuild and tests status\n======================\n\n+--------------------------+------------------------+----------------------------------+\n|**Linux & macOS (Travis)**| **Windows (AppVeyor)** |**Linux, Windows & macOS (Azure)**|\n+==========================+========================+==================================+\n| | | |\n| |travis-badge-icon| | |appveyor-badge-icon| | |azure-badge-icon| |\n| | | |\n+--------------------------+------------------------+----------------------------------+\n\nSource code and download\n========================\n\n- GitHub https://github.com/nexB/license-expression.git\n- PyPI https://pypi.python.org/pypi/license-expression\n\nAlso available in several Linux distros:\n\n- Arch Linux https://archlinux.org/packages/community/any/python-license-expression/\n- Debian https://packages.debian.org/unstable/source/license-expression\n- DragonFly BSD https://github.com/DragonFlyBSD/DPorts/tree/master/textproc/py-license-expression\n- Fedora https://src.fedoraproject.org/rpms/python-license-expression/\n- FreeBSD https://www.freshports.org/textproc/py-license-expression\n- NixOS https://github.com/NixOS/nixpkgs/blob/release-21.05/pkgs/development/python-modules/license-expression/default.nix\n- openSUSE https://build.opensuse.org/package/show/openSUSE:Factory/python-license-expression\n\n\nSupport\n=======\n\n- Submit bugs and questions at: https://github.com/nexB/license-expression/issues\n- Join the chat at: https://gitter.im/aboutcode-org/discuss\n\nDescription\n===========\n\nThis module defines a mini language to parse, validate, simplify, normalize and\ncompare license expressions using a boolean logic engine.\n\nThis supports SPDX license expressions and also accepts other license naming\nconventions and license identifiers aliases to resolve and normalize any license\nexpressions.\n\nUsing boolean logic, license expressions can be tested for equality, containment,\nequivalence and can be normalized or simplified.\n\nIt also bundles the SPDX License list (3.13 as of now) and the ScanCode license\nDB (based on ScanCode 21.6.7) to easily parse and validate expressions using\nthe license symbols.\n\n\nUsage examples\n==============\n\nThe main entry point is the ``Licensing`` object that you can use to parse,\nvalidate, compare, simplify and normalize license expressions.\n\nCreate an SPDX Licensing and parse expressions::\n\n\t>>> from license_expression import get_spdx_licensing\n\t>>> licensing = get_spdx_licensing()\n\t>>> expression = ' GPL-2.0 or LGPL-2.1 and mit '\n\t>>> parsed = licensing.parse(expression)\n\t>>> print(parsed.pretty())\n\tOR(\n\t LicenseSymbol('GPL-2.0-only'),\n\t AND(\n\t LicenseSymbol('LGPL-2.1-only'),\n\t LicenseSymbol('MIT')\n\t )\n\t)\n\n\t>>> str(parsed)\n\t'GPL-2.0-only OR (LGPL-2.1-only AND MIT)'\n\n\t>>> licensing.parse('unknwon with foo', validate=True, strict=True)\n\tlicense_expression.ExpressionParseError: A plain license symbol cannot be used\n\tas an exception in a \"WITH symbol\" statement. for token: \"foo\" at position: 13\n\n\t>>> licensing.parse('unknwon with foo', validate=True)\n\tlicense_expression.ExpressionError: Unknown license key(s): unknwon, foo\n\n\t>>> licensing.validate('foo and MIT and GPL-2.0+')\n\tExpressionInfo(\n\t original_expression='foo and MIT and GPL-2.0+',\n\t normalized_expression=None,\n\t errors=['Unknown license key(s): foo'],\n\t invalid_symbols=['foo']\n\t)\n\n\nCreate a simple Licensing and parse expressions::\n\n >>> from license_expression import Licensing, LicenseSymbol\n >>> licensing = Licensing()\n >>> expression = ' GPL-2.0 or LGPL-2.1 and mit '\n >>> parsed = licensing.parse(expression)\n >>> expression = ' GPL-2.0 or LGPL-2.1 and mit '\n >>> expected = 'GPL-2.0-only OR (LGPL-2.1-only AND mit)'\n >>> assert str(parsed) == expected\n >>> assert parsed.render('{symbol.key}') == expected\n\n\nCreate a Licensing with your own license symbols::\n\n >>> expected = [\n ... LicenseSymbol('GPL-2.0'),\n ... LicenseSymbol('LGPL-2.1'),\n ... LicenseSymbol('mit')\n ... ]\n >>> assert licensing.license_symbols(expression) == expected\n >>> assert licensing.license_symbols(parsed) == expected\n\n >>> symbols = ['GPL-2.0+', 'Classpath', 'BSD']\n >>> licensing = Licensing(symbols)\n >>> expression = 'GPL-2.0+ with Classpath or (bsd)'\n >>> parsed = licensing.parse(expression)\n >>> expected = 'GPL-2.0+ WITH Classpath OR BSD'\n >>> assert parsed.render('{symbol.key}') == expected\n\n >>> expected = [\n ... LicenseSymbol('GPL-2.0+'),\n ... LicenseSymbol('Classpath'),\n ... LicenseSymbol('BSD')\n ... ]\n >>> assert licensing.license_symbols(parsed) == expected\n >>> assert licensing.license_symbols(expression) == expected\n\nAnd expression can be deduplicated, to remove duplicate license subexpressions\nwithout changing the order and without consider license choices as simplifiable::\n\n >>> expression2 = ' GPL-2.0 or (mit and LGPL 2.1) or bsd Or GPL-2.0 or (mit and LGPL 2.1)'\n >>> parsed2 = licensing.parse(expression2)\n >>> str(parsed2)\n 'GPL-2.0 OR (mit AND LGPL 2.1) OR BSD OR GPL-2.0 OR (mit AND LGPL 2.1)'\n >>> assert str(parsed2.simplify()) == 'BSD OR GPL-2.0 OR (LGPL 2.1 AND mit)'\n\nExpression can be simplified, treating them as boolean expressions::\n\n >>> expression2 = ' GPL-2.0 or (mit and LGPL 2.1) or bsd Or GPL-2.0 or (mit and LGPL 2.1)'\n >>> parsed2 = licensing.parse(expression2)\n >>> str(parsed2)\n 'GPL-2.0 OR (mit AND LGPL 2.1) OR BSD OR GPL-2.0 OR (mit AND LGPL 2.1)'\n >>> assert str(parsed2.simplify()) == 'BSD OR GPL-2.0 OR (LGPL 2.1 AND mit)'\n\nTwo expressions can be compared for equivalence and containment:\n\n >>> expr1 = licensing.parse(' GPL-2.0 or (LGPL 2.1 and mit) ')\n >>> expr2 = licensing.parse(' (mit and LGPL 2.1) or GPL-2.0 ')\n >>> licensing.is_equivalent(expr1, expr2)\n True\n >>> licensing.is_equivalent(' GPL-2.0 or (LGPL 2.1 and mit) ',\n ... ' (mit and LGPL 2.1) or GPL-2.0 ')\n True\n >>> expr1.simplify() == expr2.simplify()\n True\n >>> expr3 = licensing.parse(' GPL-2.0 or mit or LGPL 2.1')\n >>> licensing.is_equivalent(expr2, expr3)\n False\n >>> expr4 = licensing.parse('mit and LGPL 2.1')\n >>> expr4.simplify() in expr2.simplify()\n True\n >>> licensing.contains(expr2, expr4)\n True\n\nDevelopment\n===========\n\n- Checkout a clone from https://github.com/nexB/license-expression.git\n\n- Then run ``./configure --dev`` and then ``source tmp/bin/activate`` on Linux and POSIX.\n This will install all dependencies in a local virtualenv, including\n development deps.\n\n- On Windows run ``configure.bat --dev`` and then ``Scripts\\bin\\activate`` instead.\n\n- To run the tests, run ``pytest -vvs``\n\n\n.. |travis-badge-icon| image:: https://api.travis-ci.org/nexB/license-expression.png?branch=master\n :target: https://travis-ci.org/nexB/license-expression\n :alt: Travis tests status\n :align: middle\n\n.. |appveyor-badge-icon| image:: https://ci.appveyor.com/api/projects/status/github/nexB/license-expression?svg=true\n :target: https://ci.appveyor.com/project/nexB/license-expression\n :alt: Appveyor tests status\n :align: middle\n\n.. |azure-badge-icon| image:: https://dev.azure.com/nexB/license-expression/_apis/build/status/nexB.license-expression?branchName=master\n :target: https://dev.azure.com/nexB/license-expression/_build/latest?definitionId=2&branchName=master\n :alt: Azure pipelines tests status\n :align: middle", - "release_date": "2022-05-10T14:40:02", - "parties": [ - { - "type": "person", - "role": "author", - "name": "nexB. Inc. and others", - "email": "info@aboutcode.org", - "url": null - } - ], - "keywords": [ - "open source", - "license expression", - "license", - "spdx", - "boolean", - "parse expression", - "normalize expression", - "compare expression", - "licence", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Topic :: Software Development", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/nexB/license-expression", - "download_url": "https://files.pythonhosted.org/packages/12/36/d973dc41ce58eb3e6c8833e75d9e50f8c8f6c9bc9ac7e4f5430294e88708/license_expression-30.0.0-py3-none-any.whl", - "size": 86432, - "sha1": null, - "md5": "a5cca31826be66e7cbcb15a18cbd9044", - "sha256": "e95325110110eb2b7539ee7773b97a0724d5371ec563cc718c8cac0e38cc40cc", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "Apache-2.0" - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/license-expression/30.0.0/json", - "datasource_id": null, - "purl": "pkg:pypi/license-expression@30.0.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "license-expression", - "version": "30.0.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "license-expression is a comprehensive utility library to parse, compare, simplify and normalize license expressions (such as SPDX license expressions) using boolean logic.\n==================\nlicense-expression\n==================\n\n``license-expression`` is a comprehensive utility library to parse, compare,\nsimplify and normalize license expressions (such as SPDX license expressions)\nusing boolean logic.\n\n- License: Apache-2.0\n- Python: 3.6+\n- Homepage: https://github.com/nexB/license-expression/\n- Install: `pip install license-expression` also available in most Linux distro.\n\nSoftware project licenses are often a combination of several free and open\nsource software licenses. License expressions -- as specified by SPDX -- provide\na concise and human readable way to express these licenses without having to\nread long license texts, while still being machine-readable.\n\nLicense expressions are used by key FOSS projects such as Linux; several\npackages ecosystem use them to document package licensing metadata such as\nnpm and Rubygems; they are important when exchanging software data (such as with\nSPDX and SBOM in general) as a way to express licensing precisely.\n\n``license-expression`` is a comprehensive utility library to parse, compare,\nsimplify and normalize these license expressions (such as SPDX license expressions)\nusing boolean logic like in: `GPL-2.0 or later WITH Classpath Exception AND MIT`.\n\nIt includes the license keys from SPDX https://spdx.org/licenses/ (version 3.13)\nand ScanCode license DB (version 21.6.7) https://scancode-licensedb.aboutcode.org/\nto get started quickly.\n\n``license-expression`` is both powerful and simple to use and is a used as the\nlicense expression engine in several projects and products such as:\n\n- AboutCode-toolkit https://github.com/nexB/aboutcode-toolkit\n- AlekSIS (School Information System) https://github.com/AlekSIS-org/AlekSIS-Core\n- Barista https://github.com/Optum/barista\n- Conda forge tools https://github.com/conda-forge/conda-smithy\n- DejaCode https://dejacode.com\n- DeltaCode https://github.com/nexB/deltacode\n- FenixscanX https://github.com/SmartsYoung/FenixscanX\n- FetchCode https://github.com/nexB/fetchcode\n- Flict https://github.com/vinland-technology/flict and https://github.com/vinland-technology\n- license.sh https://github.com/webscopeio/license.sh\n- liferay_inbound_checker https://github.com/carmenbianca/liferay_inbound_checker\n- REUSE https://reuse.software/ and https://github.com/fsfe/reuse-tool\n- ScanCode-io https://github.com/nexB/scancode.io\n- ScanCode-toolkit https://github.com/nexB/scancode-toolkit\n\nSee also for details:\n- https://spdx.github.io/spdx-spec/appendix-IV-SPDX-license-expressions/\n\n``license-expression`` is also packaged for most Linux distributions. See below.\n\nAlternative:\n\nThere is no known alternative library for Python, but there are several similar\nlibraries in other languages (but not as powerful of course!):\n\n- JavaScript https://github.com/jslicense/spdx-expression-parse.js\n- Rust https://github.com/ehuss/license-exprs\n- Haskell https://github.com/phadej/spdx\n- Go https://github.com/kyoh86/go-spdx\n- Ada https://github.com/Fabien-Chouteau/spdx_ada\n- Java https://github.com/spdx/tools and https://github.com/aschet/spdx-license-expression-tools\n\nBuild and tests status\n======================\n\n+--------------------------+------------------------+----------------------------------+\n|**Linux & macOS (Travis)**| **Windows (AppVeyor)** |**Linux, Windows & macOS (Azure)**|\n+==========================+========================+==================================+\n| | | |\n| |travis-badge-icon| | |appveyor-badge-icon| | |azure-badge-icon| |\n| | | |\n+--------------------------+------------------------+----------------------------------+\n\nSource code and download\n========================\n\n- GitHub https://github.com/nexB/license-expression.git\n- PyPI https://pypi.python.org/pypi/license-expression\n\nAlso available in several Linux distros:\n\n- Arch Linux https://archlinux.org/packages/community/any/python-license-expression/\n- Debian https://packages.debian.org/unstable/source/license-expression\n- DragonFly BSD https://github.com/DragonFlyBSD/DPorts/tree/master/textproc/py-license-expression\n- Fedora https://src.fedoraproject.org/rpms/python-license-expression/\n- FreeBSD https://www.freshports.org/textproc/py-license-expression\n- NixOS https://github.com/NixOS/nixpkgs/blob/release-21.05/pkgs/development/python-modules/license-expression/default.nix\n- openSUSE https://build.opensuse.org/package/show/openSUSE:Factory/python-license-expression\n\n\nSupport\n=======\n\n- Submit bugs and questions at: https://github.com/nexB/license-expression/issues\n- Join the chat at: https://gitter.im/aboutcode-org/discuss\n\nDescription\n===========\n\nThis module defines a mini language to parse, validate, simplify, normalize and\ncompare license expressions using a boolean logic engine.\n\nThis supports SPDX license expressions and also accepts other license naming\nconventions and license identifiers aliases to resolve and normalize any license\nexpressions.\n\nUsing boolean logic, license expressions can be tested for equality, containment,\nequivalence and can be normalized or simplified.\n\nIt also bundles the SPDX License list (3.13 as of now) and the ScanCode license\nDB (based on ScanCode 21.6.7) to easily parse and validate expressions using\nthe license symbols.\n\n\nUsage examples\n==============\n\nThe main entry point is the ``Licensing`` object that you can use to parse,\nvalidate, compare, simplify and normalize license expressions.\n\nCreate an SPDX Licensing and parse expressions::\n\n\t>>> from license_expression import get_spdx_licensing\n\t>>> licensing = get_spdx_licensing()\n\t>>> expression = ' GPL-2.0 or LGPL-2.1 and mit '\n\t>>> parsed = licensing.parse(expression)\n\t>>> print(parsed.pretty())\n\tOR(\n\t LicenseSymbol('GPL-2.0-only'),\n\t AND(\n\t LicenseSymbol('LGPL-2.1-only'),\n\t LicenseSymbol('MIT')\n\t )\n\t)\n\n\t>>> str(parsed)\n\t'GPL-2.0-only OR (LGPL-2.1-only AND MIT)'\n\n\t>>> licensing.parse('unknwon with foo', validate=True, strict=True)\n\tlicense_expression.ExpressionParseError: A plain license symbol cannot be used\n\tas an exception in a \"WITH symbol\" statement. for token: \"foo\" at position: 13\n\n\t>>> licensing.parse('unknwon with foo', validate=True)\n\tlicense_expression.ExpressionError: Unknown license key(s): unknwon, foo\n\n\t>>> licensing.validate('foo and MIT and GPL-2.0+')\n\tExpressionInfo(\n\t original_expression='foo and MIT and GPL-2.0+',\n\t normalized_expression=None,\n\t errors=['Unknown license key(s): foo'],\n\t invalid_symbols=['foo']\n\t)\n\n\nCreate a simple Licensing and parse expressions::\n\n >>> from license_expression import Licensing, LicenseSymbol\n >>> licensing = Licensing()\n >>> expression = ' GPL-2.0 or LGPL-2.1 and mit '\n >>> parsed = licensing.parse(expression)\n >>> expression = ' GPL-2.0 or LGPL-2.1 and mit '\n >>> expected = 'GPL-2.0-only OR (LGPL-2.1-only AND mit)'\n >>> assert str(parsed) == expected\n >>> assert parsed.render('{symbol.key}') == expected\n\n\nCreate a Licensing with your own license symbols::\n\n >>> expected = [\n ... LicenseSymbol('GPL-2.0'),\n ... LicenseSymbol('LGPL-2.1'),\n ... LicenseSymbol('mit')\n ... ]\n >>> assert licensing.license_symbols(expression) == expected\n >>> assert licensing.license_symbols(parsed) == expected\n\n >>> symbols = ['GPL-2.0+', 'Classpath', 'BSD']\n >>> licensing = Licensing(symbols)\n >>> expression = 'GPL-2.0+ with Classpath or (bsd)'\n >>> parsed = licensing.parse(expression)\n >>> expected = 'GPL-2.0+ WITH Classpath OR BSD'\n >>> assert parsed.render('{symbol.key}') == expected\n\n >>> expected = [\n ... LicenseSymbol('GPL-2.0+'),\n ... LicenseSymbol('Classpath'),\n ... LicenseSymbol('BSD')\n ... ]\n >>> assert licensing.license_symbols(parsed) == expected\n >>> assert licensing.license_symbols(expression) == expected\n\nAnd expression can be deduplicated, to remove duplicate license subexpressions\nwithout changing the order and without consider license choices as simplifiable::\n\n >>> expression2 = ' GPL-2.0 or (mit and LGPL 2.1) or bsd Or GPL-2.0 or (mit and LGPL 2.1)'\n >>> parsed2 = licensing.parse(expression2)\n >>> str(parsed2)\n 'GPL-2.0 OR (mit AND LGPL 2.1) OR BSD OR GPL-2.0 OR (mit AND LGPL 2.1)'\n >>> assert str(parsed2.simplify()) == 'BSD OR GPL-2.0 OR (LGPL 2.1 AND mit)'\n\nExpression can be simplified, treating them as boolean expressions::\n\n >>> expression2 = ' GPL-2.0 or (mit and LGPL 2.1) or bsd Or GPL-2.0 or (mit and LGPL 2.1)'\n >>> parsed2 = licensing.parse(expression2)\n >>> str(parsed2)\n 'GPL-2.0 OR (mit AND LGPL 2.1) OR BSD OR GPL-2.0 OR (mit AND LGPL 2.1)'\n >>> assert str(parsed2.simplify()) == 'BSD OR GPL-2.0 OR (LGPL 2.1 AND mit)'\n\nTwo expressions can be compared for equivalence and containment:\n\n >>> expr1 = licensing.parse(' GPL-2.0 or (LGPL 2.1 and mit) ')\n >>> expr2 = licensing.parse(' (mit and LGPL 2.1) or GPL-2.0 ')\n >>> licensing.is_equivalent(expr1, expr2)\n True\n >>> licensing.is_equivalent(' GPL-2.0 or (LGPL 2.1 and mit) ',\n ... ' (mit and LGPL 2.1) or GPL-2.0 ')\n True\n >>> expr1.simplify() == expr2.simplify()\n True\n >>> expr3 = licensing.parse(' GPL-2.0 or mit or LGPL 2.1')\n >>> licensing.is_equivalent(expr2, expr3)\n False\n >>> expr4 = licensing.parse('mit and LGPL 2.1')\n >>> expr4.simplify() in expr2.simplify()\n True\n >>> licensing.contains(expr2, expr4)\n True\n\nDevelopment\n===========\n\n- Checkout a clone from https://github.com/nexB/license-expression.git\n\n- Then run ``./configure --dev`` and then ``source tmp/bin/activate`` on Linux and POSIX.\n This will install all dependencies in a local virtualenv, including\n development deps.\n\n- On Windows run ``configure.bat --dev`` and then ``Scripts\\bin\\activate`` instead.\n\n- To run the tests, run ``pytest -vvs``\n\n\n.. |travis-badge-icon| image:: https://api.travis-ci.org/nexB/license-expression.png?branch=master\n :target: https://travis-ci.org/nexB/license-expression\n :alt: Travis tests status\n :align: middle\n\n.. |appveyor-badge-icon| image:: https://ci.appveyor.com/api/projects/status/github/nexB/license-expression?svg=true\n :target: https://ci.appveyor.com/project/nexB/license-expression\n :alt: Appveyor tests status\n :align: middle\n\n.. |azure-badge-icon| image:: https://dev.azure.com/nexB/license-expression/_apis/build/status/nexB.license-expression?branchName=master\n :target: https://dev.azure.com/nexB/license-expression/_build/latest?definitionId=2&branchName=master\n :alt: Azure pipelines tests status\n :align: middle", - "release_date": "2022-05-10T14:40:04", - "parties": [ - { - "type": "person", - "role": "author", - "name": "nexB. Inc. and others", - "email": "info@aboutcode.org", - "url": null - } - ], - "keywords": [ - "open source", - "license expression", - "license", - "spdx", - "boolean", - "parse expression", - "normalize expression", - "compare expression", - "licence", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Topic :: Software Development", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/nexB/license-expression", - "download_url": "https://files.pythonhosted.org/packages/80/ad/9b3614c4630f3a1c0d5d7e5f6cfa8e90850186864e1181e86a65150d983f/license-expression-30.0.0.tar.gz", - "size": 158232, - "sha1": null, - "md5": "253c39f105199625d9ac35f0a50976e2", - "sha256": "ad638292aa8493f84354909b517922cb823582c2ce2c4d880e42544a86bea8dd", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "Apache-2.0" - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/license-expression/30.0.0/json", - "datasource_id": null, - "purl": "pkg:pypi/license-expression@30.0.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "markupsafe", - "version": "2.0.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Safely add untrusted strings to HTML/XML markup.\nMarkupSafe\n==========\n\nMarkupSafe implements a text object that escapes characters so it is\nsafe to use in HTML and XML. Characters that have special meanings are\nreplaced so that they display as the actual characters. This mitigates\ninjection attacks, meaning untrusted user input can safely be displayed\non a page.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U MarkupSafe\n\n.. _pip: https://pip.pypa.io/en/stable/quickstart/\n\n\nExamples\n--------\n\n.. code-block:: pycon\n\n >>> from markupsafe import Markup, escape\n\n >>> # escape replaces special characters and wraps in Markup\n >>> escape(\"\")\n Markup('<script>alert(document.cookie);</script>')\n\n >>> # wrap in Markup to mark text \"safe\" and prevent escaping\n >>> Markup(\"Hello\")\n Markup('hello')\n\n >>> escape(Markup(\"Hello\"))\n Markup('hello')\n\n >>> # Markup is a str subclass\n >>> # methods and operators escape their arguments\n >>> template = Markup(\"Hello {name}\")\n >>> template.format(name='\"World\"')\n Markup('Hello "World"')\n\n\nDonate\n------\n\nThe Pallets organization develops and supports MarkupSafe and other\npopular packages. In order to grow the community of contributors and\nusers, and allow the maintainers to devote more time to the projects,\n`please donate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://markupsafe.palletsprojects.com/\n- Changes: https://markupsafe.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/MarkupSafe/\n- Source Code: https://github.com/pallets/markupsafe/\n- Issue Tracker: https://github.com/pallets/markupsafe/issues/\n- Website: https://palletsprojects.com/p/markupsafe/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2021-08-11T18:10:44", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Text Processing :: Markup :: HTML" - ], - "homepage_url": "https://palletsprojects.com/p/markupsafe/", - "download_url": "https://files.pythonhosted.org/packages/53/e8/601efa63c4058311a8bda7984a2fe554b9da574044967d7aee253661ee46/MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", - "size": 30770, - "sha1": null, - "md5": "fc893cdd7d045234e0120e6e325fe190", - "sha256": "168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/markupsafe/issues/", - "code_view_url": "https://github.com/pallets/markupsafe/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/markupsafe/2.0.1/json", - "datasource_id": null, - "purl": "pkg:pypi/markupsafe@2.0.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "markupsafe", - "version": "2.0.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Safely add untrusted strings to HTML/XML markup.\nMarkupSafe\n==========\n\nMarkupSafe implements a text object that escapes characters so it is\nsafe to use in HTML and XML. Characters that have special meanings are\nreplaced so that they display as the actual characters. This mitigates\ninjection attacks, meaning untrusted user input can safely be displayed\non a page.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U MarkupSafe\n\n.. _pip: https://pip.pypa.io/en/stable/quickstart/\n\n\nExamples\n--------\n\n.. code-block:: pycon\n\n >>> from markupsafe import Markup, escape\n\n >>> # escape replaces special characters and wraps in Markup\n >>> escape(\"\")\n Markup('<script>alert(document.cookie);</script>')\n\n >>> # wrap in Markup to mark text \"safe\" and prevent escaping\n >>> Markup(\"Hello\")\n Markup('hello')\n\n >>> escape(Markup(\"Hello\"))\n Markup('hello')\n\n >>> # Markup is a str subclass\n >>> # methods and operators escape their arguments\n >>> template = Markup(\"Hello {name}\")\n >>> template.format(name='\"World\"')\n Markup('Hello "World"')\n\n\nDonate\n------\n\nThe Pallets organization develops and supports MarkupSafe and other\npopular packages. In order to grow the community of contributors and\nusers, and allow the maintainers to devote more time to the projects,\n`please donate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://markupsafe.palletsprojects.com/\n- Changes: https://markupsafe.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/MarkupSafe/\n- Source Code: https://github.com/pallets/markupsafe/\n- Issue Tracker: https://github.com/pallets/markupsafe/issues/\n- Website: https://palletsprojects.com/p/markupsafe/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2021-05-18T17:18:22", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Text Processing :: Markup :: HTML" - ], - "homepage_url": "https://palletsprojects.com/p/markupsafe/", - "download_url": "https://files.pythonhosted.org/packages/bf/10/ff66fea6d1788c458663a84d88787bae15d45daa16f6b3ef33322a51fc7e/MarkupSafe-2.0.1.tar.gz", - "size": 18596, - "sha1": null, - "md5": "892e0fefa3c488387e5cc0cad2daa523", - "sha256": "594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/markupsafe/issues/", - "code_view_url": "https://github.com/pallets/markupsafe/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/markupsafe/2.0.1/json", - "datasource_id": null, - "purl": "pkg:pypi/markupsafe@2.0.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "mypy-extensions", - "version": "0.4.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Experimental type system extensions for programs checked with the mypy typechecker.\nMypy Extensions\n===============\n\nThe \"mypy_extensions\" module defines experimental extensions to the\nstandard \"typing\" module that are supported by the mypy typechecker.", - "release_date": "2019-10-17T22:38:56", - "parties": [ - { - "type": "person", - "role": "author", - "name": "The mypy developers", - "email": "jukka.lehtosalo@iki.fi", - "url": null - } - ], - "keywords": [ - "Development Status :: 2 - Pre-Alpha", - "Environment :: Console", - "Intended Audience :: Developers", - "Programming Language :: Python :: 2", - "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 :: 3.7", - "Programming Language :: Python :: 3.8", - "Topic :: Software Development" - ], - "homepage_url": "https://github.com/python/mypy_extensions", - "download_url": "https://files.pythonhosted.org/packages/5c/eb/975c7c080f3223a5cdaff09612f3a5221e4ba534f7039db34c35d95fa6a5/mypy_extensions-0.4.3-py2.py3-none-any.whl", - "size": 4470, - "sha1": null, - "md5": "b9c790261bc8932c80b5938c69e5b65f", - "sha256": "090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT License", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/mypy-extensions/0.4.3/json", - "datasource_id": null, - "purl": "pkg:pypi/mypy-extensions@0.4.3" - }, - { - "type": "pypi", - "namespace": null, - "name": "mypy-extensions", - "version": "0.4.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Experimental type system extensions for programs checked with the mypy typechecker.\nMypy Extensions\n===============\n\nThe \"mypy_extensions\" module defines experimental extensions to the\nstandard \"typing\" module that are supported by the mypy typechecker.", - "release_date": "2019-10-17T22:38:58", - "parties": [ - { - "type": "person", - "role": "author", - "name": "The mypy developers", - "email": "jukka.lehtosalo@iki.fi", - "url": null - } - ], - "keywords": [ - "Development Status :: 2 - Pre-Alpha", - "Environment :: Console", - "Intended Audience :: Developers", - "Programming Language :: Python :: 2", - "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 :: 3.7", - "Programming Language :: Python :: 3.8", - "Topic :: Software Development" - ], - "homepage_url": "https://github.com/python/mypy_extensions", - "download_url": "https://files.pythonhosted.org/packages/63/60/0582ce2eaced55f65a4406fc97beba256de4b7a95a0034c6576458c6519f/mypy_extensions-0.4.3.tar.gz", - "size": 4252, - "sha1": null, - "md5": "4163ff73d0db8631c0a78bb55b551c84", - "sha256": "2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT License", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/mypy-extensions/0.4.3/json", - "datasource_id": null, - "purl": "pkg:pypi/mypy-extensions@0.4.3" - }, - { - "type": "pypi", - "namespace": null, - "name": "openpyxl", - "version": "3.0.10", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A Python library to read/write Excel 2010 xlsx/xlsm files\n.. image:: https://coveralls.io/repos/bitbucket/openpyxl/openpyxl/badge.svg?branch=default\n :target: https://coveralls.io/bitbucket/openpyxl/openpyxl?branch=default\n :alt: coverage status\n\nIntroduction\n------------\n\nopenpyxl is a Python library to read/write Excel 2010 xlsx/xlsm/xltx/xltm files.\n\nIt was born from lack of existing library to read/write natively from Python\nthe Office Open XML format.\n\nAll kudos to the PHPExcel team as openpyxl was initially based on PHPExcel.\n\n\nSecurity\n--------\n\nBy default openpyxl does not guard against quadratic blowup or billion laughs\nxml attacks. To guard against these attacks install defusedxml.\n\nMailing List\n------------\n\nThe user list can be found on http://groups.google.com/group/openpyxl-users\n\n\nSample code::\n\n from openpyxl import Workbook\n wb = Workbook()\n\n # grab the active worksheet\n ws = wb.active\n\n # Data can be assigned directly to cells\n ws['A1'] = 42\n\n # Rows can also be appended\n ws.append([1, 2, 3])\n\n # Python types will automatically be converted\n import datetime\n ws['A2'] = datetime.datetime.now()\n\n # Save the file\n wb.save(\"sample.xlsx\")\n\n\nDocumentation\n-------------\n\nThe documentation is at: https://openpyxl.readthedocs.io\n\n* installation methods\n* code examples\n* instructions for contributing\n\nRelease notes: https://openpyxl.readthedocs.io/en/stable/changes.html", - "release_date": "2022-05-19T15:43:03", - "parties": [ - { - "type": "person", - "role": "author", - "name": "See AUTHORS", - "email": "charlie.clark@clark-consulting.eu", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Programming Language :: Python", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9" - ], - "homepage_url": "https://openpyxl.readthedocs.io", - "download_url": "https://files.pythonhosted.org/packages/7b/60/9afac4fd6feee0ac09339de4101ee452ea643d26e9ce44c7708a0023f503/openpyxl-3.0.10-py2.py3-none-any.whl", - "size": 242144, - "sha1": null, - "md5": "8c57b36e745fe4c437d190272e50debb", - "sha256": "0ab6d25d01799f97a9464630abacbb34aafecdcaa0ef3cba6d6b3499867d0355", - "sha512": null, - "bug_tracking_url": "https://foss.heptapod.net/openpyxl/openpyxl/-/issues", - "code_view_url": "https://foss.heptapod.net/openpyxl/openpyxl", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/openpyxl/3.0.10/json", - "datasource_id": null, - "purl": "pkg:pypi/openpyxl@3.0.10" - }, - { - "type": "pypi", - "namespace": null, - "name": "openpyxl", - "version": "3.0.10", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A Python library to read/write Excel 2010 xlsx/xlsm files\n.. image:: https://coveralls.io/repos/bitbucket/openpyxl/openpyxl/badge.svg?branch=default\n :target: https://coveralls.io/bitbucket/openpyxl/openpyxl?branch=default\n :alt: coverage status\n\nIntroduction\n------------\n\nopenpyxl is a Python library to read/write Excel 2010 xlsx/xlsm/xltx/xltm files.\n\nIt was born from lack of existing library to read/write natively from Python\nthe Office Open XML format.\n\nAll kudos to the PHPExcel team as openpyxl was initially based on PHPExcel.\n\n\nSecurity\n--------\n\nBy default openpyxl does not guard against quadratic blowup or billion laughs\nxml attacks. To guard against these attacks install defusedxml.\n\nMailing List\n------------\n\nThe user list can be found on http://groups.google.com/group/openpyxl-users\n\n\nSample code::\n\n from openpyxl import Workbook\n wb = Workbook()\n\n # grab the active worksheet\n ws = wb.active\n\n # Data can be assigned directly to cells\n ws['A1'] = 42\n\n # Rows can also be appended\n ws.append([1, 2, 3])\n\n # Python types will automatically be converted\n import datetime\n ws['A2'] = datetime.datetime.now()\n\n # Save the file\n wb.save(\"sample.xlsx\")\n\n\nDocumentation\n-------------\n\nThe documentation is at: https://openpyxl.readthedocs.io\n\n* installation methods\n* code examples\n* instructions for contributing\n\nRelease notes: https://openpyxl.readthedocs.io/en/stable/changes.html", - "release_date": "2022-05-19T15:43:05", - "parties": [ - { - "type": "person", - "role": "author", - "name": "See AUTHORS", - "email": "charlie.clark@clark-consulting.eu", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Programming Language :: Python", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9" - ], - "homepage_url": "https://openpyxl.readthedocs.io", - "download_url": "https://files.pythonhosted.org/packages/2c/b8/ff77a718173fd73e49f883b4fda88f11af1fc51edb9252af3785b0cad987/openpyxl-3.0.10.tar.gz", - "size": 179688, - "sha1": null, - "md5": "ebcc3a30768a45163d5143f1f7bf0224", - "sha256": "e47805627aebcf860edb4edf7987b1309c1b3632f3750538ed962bbcc3bd7449", - "sha512": null, - "bug_tracking_url": "https://foss.heptapod.net/openpyxl/openpyxl/-/issues", - "code_view_url": "https://foss.heptapod.net/openpyxl/openpyxl", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/openpyxl/3.0.10/json", - "datasource_id": null, - "purl": "pkg:pypi/openpyxl@3.0.10" - }, - { - "type": "pypi", - "namespace": null, - "name": "packageurl-python", - "version": "0.9.9", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A purl aka. Package URL parser and builder\n# packageurl-python\n\nPython library to parse and build \"purl\" aka. Package URLs.\nSee https://github.com/package-url/purl-spec for details.\n\nJoin the discussion at https://gitter.im/package-url/Lobby or enter a ticket for support.\n\nLicense: MIT\n\n\nBuild and tests status\n======================\n\n+------------------------------------------------------------------------------------+\n| **Linux (Travis) on Python 2 and 3** |\n+====================================================================================+\n|.. image:: https://api.travis-ci.com/package-url/packageurl-python.png?branch=master|\n| :target: https://travis-ci.com/package-url/packageurl-python |\n| :alt: Linux Master branch tests status |\n+------------------------------------------------------------------------------------+\n\n\nUsage\n=====\n\n::\n\n >>> from packageurl import PackageURL\n >>> purl = PackageURL.from_string(\"pkg:maven/org.apache.commons/io@1.3.4\")\n >>> print(purl.to_dict())\n {'type': 'maven', 'namespace': 'org.apache.commons', 'name': 'io', 'version': '1.3.4', 'qualifiers': None, 'subpath': None}\n >>> print(purl.to_string())\n pkg:maven/org.apache.commons/io@1.3.4\n >>> print(str(purl))\n pkg:maven/org.apache.commons/io@1.3.4\n >>> print(repr(purl))\n PackageURL(type='maven', namespace='org.apache.commons', name='io', version='1.3.4', qualifiers={}, subpath=None)\n\n\nOther utilities:\n\n- packageurl.contrib.django_models.PackageURLMixin is a Django abstract model mixin to use Package URLs in Django.\n- packageurl.contrib.purl2url.get_url(purl) returns the download URL inferred from a Package URL.\n- packageurl.contrib.url2purl.get_purl(url) returns a Package URL inferred from URL.\n\n\nInstall\n=======\n::\n\n pip install packageurl-python\n\nRun tests\n=========\n\ninstall::\n\n python3 thirdparty/virtualenv.pyz --never-download --no-periodic-update .\n bin/pip install -e .\"[test]\"\n\nrun tests::\n\n bin/py.test tests\n\nMake a new release\n==================\n\n- start a new release branch\n- update the CHANGELOG.rst and AUTHORS.rst\n- update README.rst if needed\n- bump version in setup.cfg\n- run all tests\n- install restview and validate that all .rst docs are correct\n- commit and push this branch\n- tag and push that tag\n- make a PR to merge branch\n- once merged, run::\n\n bin/pip install --upgrade pip wheel twine setuptools\n\n- delete the \"dist\" and \"build\" directories::\n\n rm -rf dist/ build/\n\n- create a source distribution and wheel with::\n\n bin/python setup.py sdist bdist_wheel\n\n- finally, upload to PyPI::\n\n bin/twine upload dist/*", - "release_date": "2022-02-15T19:21:48", - "parties": [ - { - "type": "person", - "role": "author", - "name": "the purl authors", - "email": null, - "url": null - } - ], - "keywords": [ - "package", - "url", - "package manager", - "package url", - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "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 :: Software Development :: Libraries", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/package-url/packageurl-python", - "download_url": "https://files.pythonhosted.org/packages/59/48/e9962fd0a4b982e1ed41a64cb38366e680f8d5e501248c0b520a667ccf87/packageurl_python-0.9.9-py3-none-any.whl", - "size": 24764, - "sha1": null, - "md5": "510182ba2248cca64795b988219cef26", - "sha256": "07aa852d1c48b0e86e625f6a32d83f96427739806b269d0f8142788ee807114b", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/packageurl-python/0.9.9/json", - "datasource_id": null, - "purl": "pkg:pypi/packageurl-python@0.9.9" - }, - { - "type": "pypi", - "namespace": null, - "name": "packageurl-python", - "version": "0.9.9", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A purl aka. Package URL parser and builder\n# packageurl-python\n\nPython library to parse and build \"purl\" aka. Package URLs.\nSee https://github.com/package-url/purl-spec for details.\n\nJoin the discussion at https://gitter.im/package-url/Lobby or enter a ticket for support.\n\nLicense: MIT\n\n\nBuild and tests status\n======================\n\n+------------------------------------------------------------------------------------+\n| **Linux (Travis) on Python 2 and 3** |\n+====================================================================================+\n|.. image:: https://api.travis-ci.com/package-url/packageurl-python.png?branch=master|\n| :target: https://travis-ci.com/package-url/packageurl-python |\n| :alt: Linux Master branch tests status |\n+------------------------------------------------------------------------------------+\n\n\nUsage\n=====\n\n::\n\n >>> from packageurl import PackageURL\n >>> purl = PackageURL.from_string(\"pkg:maven/org.apache.commons/io@1.3.4\")\n >>> print(purl.to_dict())\n {'type': 'maven', 'namespace': 'org.apache.commons', 'name': 'io', 'version': '1.3.4', 'qualifiers': None, 'subpath': None}\n >>> print(purl.to_string())\n pkg:maven/org.apache.commons/io@1.3.4\n >>> print(str(purl))\n pkg:maven/org.apache.commons/io@1.3.4\n >>> print(repr(purl))\n PackageURL(type='maven', namespace='org.apache.commons', name='io', version='1.3.4', qualifiers={}, subpath=None)\n\n\nOther utilities:\n\n- packageurl.contrib.django_models.PackageURLMixin is a Django abstract model mixin to use Package URLs in Django.\n- packageurl.contrib.purl2url.get_url(purl) returns the download URL inferred from a Package URL.\n- packageurl.contrib.url2purl.get_purl(url) returns a Package URL inferred from URL.\n\n\nInstall\n=======\n::\n\n pip install packageurl-python\n\nRun tests\n=========\n\ninstall::\n\n python3 thirdparty/virtualenv.pyz --never-download --no-periodic-update .\n bin/pip install -e .\"[test]\"\n\nrun tests::\n\n bin/py.test tests\n\nMake a new release\n==================\n\n- start a new release branch\n- update the CHANGELOG.rst and AUTHORS.rst\n- update README.rst if needed\n- bump version in setup.cfg\n- run all tests\n- install restview and validate that all .rst docs are correct\n- commit and push this branch\n- tag and push that tag\n- make a PR to merge branch\n- once merged, run::\n\n bin/pip install --upgrade pip wheel twine setuptools\n\n- delete the \"dist\" and \"build\" directories::\n\n rm -rf dist/ build/\n\n- create a source distribution and wheel with::\n\n bin/python setup.py sdist bdist_wheel\n\n- finally, upload to PyPI::\n\n bin/twine upload dist/*", - "release_date": "2022-02-15T19:21:50", - "parties": [ - { - "type": "person", - "role": "author", - "name": "the purl authors", - "email": null, - "url": null - } - ], - "keywords": [ - "package", - "url", - "package manager", - "package url", - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "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 :: Software Development :: Libraries", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/package-url/packageurl-python", - "download_url": "https://files.pythonhosted.org/packages/6e/ee/8d89d660da6e44d77f547de9949b380dc93b08b758ee361bc237bcc8b179/packageurl-python-0.9.9.tar.gz", - "size": 30107, - "sha1": null, - "md5": "35651efef038a54f5083197038d358c0", - "sha256": "872a0434b9a448b3fa97571711f69dd2a3fb72345ad66c90b17d827afea82f09", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/packageurl-python/0.9.9/json", - "datasource_id": null, - "purl": "pkg:pypi/packageurl-python@0.9.9" - }, - { - "type": "pypi", - "namespace": null, - "name": "packaging", - "version": "21.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Core utilities for Python packages\npackaging\n=========\n\n.. start-intro\n\nReusable core utilities for various Python Packaging\n`interoperability specifications `_.\n\nThis library provides utilities that implement the interoperability\nspecifications which have clearly one correct behaviour (eg: :pep:`440`)\nor benefit greatly from having a single shared implementation (eg: :pep:`425`).\n\n.. end-intro\n\nThe ``packaging`` project includes the following: version handling, specifiers,\nmarkers, requirements, tags, utilities.\n\nDocumentation\n-------------\n\nThe `documentation`_ provides information and the API for the following:\n\n- Version Handling\n- Specifiers\n- Markers\n- Requirements\n- Tags\n- Utilities\n\nInstallation\n------------\n\nUse ``pip`` to install these utilities::\n\n pip install packaging\n\nDiscussion\n----------\n\nIf you run into bugs, you can file them in our `issue tracker`_.\n\nYou can also join ``#pypa`` on Freenode to ask questions or get involved.\n\n\n.. _`documentation`: https://packaging.pypa.io/\n.. _`issue tracker`: https://github.com/pypa/packaging/issues\n\n\nCode of Conduct\n---------------\n\nEveryone interacting in the packaging project's codebases, issue trackers, chat\nrooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.\n\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md\n\nContributing\n------------\n\nThe ``CONTRIBUTING.rst`` file outlines how to contribute to this project as\nwell as how to report a potential security issue. The documentation for this\nproject also covers information about `project development`_ and `security`_.\n\n.. _`project development`: https://packaging.pypa.io/en/latest/development/\n.. _`security`: https://packaging.pypa.io/en/latest/security/\n\nProject History\n---------------\n\nPlease review the ``CHANGELOG.rst`` file or the `Changelog documentation`_ for\nrecent changes and project history.\n\n.. _`Changelog documentation`: https://packaging.pypa.io/en/latest/changelog/\n\nChangelog\n---------\n\n21.3 - 2021-11-17\n~~~~~~~~~~~~~~~~~\n\n* Add a ``pp3-none-any`` tag (`#311 `__)\n* Replace the blank pyparsing 3 exclusion with a 3.0.5 exclusion (`#481 `__, `#486 `__)\n* Fix a spelling mistake (`#479 `__)\n\n21.2 - 2021-10-29\n~~~~~~~~~~~~~~~~~\n\n* Update documentation entry for 21.1.\n\n21.1 - 2021-10-29\n~~~~~~~~~~~~~~~~~\n\n* Update pin to pyparsing to exclude 3.0.0.\n\n21.0 - 2021-07-03\n~~~~~~~~~~~~~~~~~\n\n* PEP 656: musllinux support (`#411 `__)\n* Drop support for Python 2.7, Python 3.4 and Python 3.5.\n* Replace distutils usage with sysconfig (`#396 `__)\n* Add support for zip files in ``parse_sdist_filename`` (`#429 `__)\n* Use cached ``_hash`` attribute to short-circuit tag equality comparisons (`#417 `__)\n* Specify the default value for the ``specifier`` argument to ``SpecifierSet`` (`#437 `__)\n* Proper keyword-only \"warn\" argument in packaging.tags (`#403 `__)\n* Correctly remove prerelease suffixes from ~= check (`#366 `__)\n* Fix type hints for ``Version.post`` and ``Version.dev`` (`#393 `__)\n* Use typing alias ``UnparsedVersion`` (`#398 `__)\n* Improve type inference for ``packaging.specifiers.filter()`` (`#430 `__)\n* Tighten the return type of ``canonicalize_version()`` (`#402 `__)\n\n20.9 - 2021-01-29\n~~~~~~~~~~~~~~~~~\n\n* Run `isort `_ over the code base (`#377 `__)\n* Add support for the ``macosx_10_*_universal2`` platform tags (`#379 `__)\n* Introduce ``packaging.utils.parse_wheel_filename()`` and ``parse_sdist_filename()``\n (`#387 `__ and `#389 `__)\n\n20.8 - 2020-12-11\n~~~~~~~~~~~~~~~~~\n\n* Revert back to setuptools for compatibility purposes for some Linux distros (`#363 `__)\n* Do not insert an underscore in wheel tags when the interpreter version number\n is more than 2 digits (`#372 `__)\n\n20.7 - 2020-11-28\n~~~~~~~~~~~~~~~~~\n\nNo unreleased changes.\n\n20.6 - 2020-11-28\n~~~~~~~~~~~~~~~~~\n\n.. note:: This release was subsequently yanked, and these changes were included in 20.7.\n\n* Fix flit configuration, to include LICENSE files (`#357 `__)\n* Make `intel` a recognized CPU architecture for the `universal` macOS platform tag (`#361 `__)\n* Add some missing type hints to `packaging.requirements` (issue:`350`)\n\n20.5 - 2020-11-27\n~~~~~~~~~~~~~~~~~\n\n* Officially support Python 3.9 (`#343 `__)\n* Deprecate the ``LegacyVersion`` and ``LegacySpecifier`` classes (`#321 `__)\n* Handle ``OSError`` on non-dynamic executables when attempting to resolve\n the glibc version string.\n\n20.4 - 2020-05-19\n~~~~~~~~~~~~~~~~~\n\n* Canonicalize version before comparing specifiers. (`#282 `__)\n* Change type hint for ``canonicalize_name`` to return\n ``packaging.utils.NormalizedName``.\n This enables the use of static typing tools (like mypy) to detect mixing of\n normalized and un-normalized names.\n\n20.3 - 2020-03-05\n~~~~~~~~~~~~~~~~~\n\n* Fix changelog for 20.2.\n\n20.2 - 2020-03-05\n~~~~~~~~~~~~~~~~~\n\n* Fix a bug that caused a 32-bit OS that runs on a 64-bit ARM CPU (e.g. ARM-v8,\n aarch64), to report the wrong bitness.\n\n20.1 - 2020-01-24\n~~~~~~~~~~~~~~~~~~~\n\n* Fix a bug caused by reuse of an exhausted iterator. (`#257 `__)\n\n20.0 - 2020-01-06\n~~~~~~~~~~~~~~~~~\n\n* Add type hints (`#191 `__)\n\n* Add proper trove classifiers for PyPy support (`#198 `__)\n\n* Scale back depending on ``ctypes`` for manylinux support detection (`#171 `__)\n\n* Use ``sys.implementation.name`` where appropriate for ``packaging.tags`` (`#193 `__)\n\n* Expand upon the API provided by ``packaging.tags``: ``interpreter_name()``, ``mac_platforms()``, ``compatible_tags()``, ``cpython_tags()``, ``generic_tags()`` (`#187 `__)\n\n* Officially support Python 3.8 (`#232 `__)\n\n* Add ``major``, ``minor``, and ``micro`` aliases to ``packaging.version.Version`` (`#226 `__)\n\n* Properly mark ``packaging`` has being fully typed by adding a `py.typed` file (`#226 `__)\n\n19.2 - 2019-09-18\n~~~~~~~~~~~~~~~~~\n\n* Remove dependency on ``attrs`` (`#178 `__, `#179 `__)\n\n* Use appropriate fallbacks for CPython ABI tag (`#181 `__, `#185 `__)\n\n* Add manylinux2014 support (`#186 `__)\n\n* Improve ABI detection (`#181 `__)\n\n* Properly handle debug wheels for Python 3.8 (`#172 `__)\n\n* Improve detection of debug builds on Windows (`#194 `__)\n\n19.1 - 2019-07-30\n~~~~~~~~~~~~~~~~~\n\n* Add the ``packaging.tags`` module. (`#156 `__)\n\n* Correctly handle two-digit versions in ``python_version`` (`#119 `__)\n\n\n19.0 - 2019-01-20\n~~~~~~~~~~~~~~~~~\n\n* Fix string representation of PEP 508 direct URL requirements with markers.\n\n* Better handling of file URLs\n\n This allows for using ``file:///absolute/path``, which was previously\n prevented due to the missing ``netloc``.\n\n This allows for all file URLs that ``urlunparse`` turns back into the\n original URL to be valid.\n\n\n18.0 - 2018-09-26\n~~~~~~~~~~~~~~~~~\n\n* Improve error messages when invalid requirements are given. (`#129 `__)\n\n\n17.1 - 2017-02-28\n~~~~~~~~~~~~~~~~~\n\n* Fix ``utils.canonicalize_version`` when supplying non PEP 440 versions.\n\n\n17.0 - 2017-02-28\n~~~~~~~~~~~~~~~~~\n\n* Drop support for python 2.6, 3.2, and 3.3.\n\n* Define minimal pyparsing version to 2.0.2 (`#91 `__).\n\n* Add ``epoch``, ``release``, ``pre``, ``dev``, and ``post`` attributes to\n ``Version`` and ``LegacyVersion`` (`#34 `__).\n\n* Add ``Version().is_devrelease`` and ``LegacyVersion().is_devrelease`` to\n make it easy to determine if a release is a development release.\n\n* Add ``utils.canonicalize_version`` to canonicalize version strings or\n ``Version`` instances (`#121 `__).\n\n\n16.8 - 2016-10-29\n~~~~~~~~~~~~~~~~~\n\n* Fix markers that utilize ``in`` so that they render correctly.\n\n* Fix an erroneous test on Python RC releases.\n\n\n16.7 - 2016-04-23\n~~~~~~~~~~~~~~~~~\n\n* Add support for the deprecated ``python_implementation`` marker which was\n an undocumented setuptools marker in addition to the newer markers.\n\n\n16.6 - 2016-03-29\n~~~~~~~~~~~~~~~~~\n\n* Add support for the deprecated, PEP 345 environment markers in addition to\n the newer markers.\n\n\n16.5 - 2016-02-26\n~~~~~~~~~~~~~~~~~\n\n* Fix a regression in parsing requirements with whitespaces between the comma\n separators.\n\n\n16.4 - 2016-02-22\n~~~~~~~~~~~~~~~~~\n\n* Fix a regression in parsing requirements like ``foo (==4)``.\n\n\n16.3 - 2016-02-21\n~~~~~~~~~~~~~~~~~\n\n* Fix a bug where ``packaging.requirements:Requirement`` was overly strict when\n matching legacy requirements.\n\n\n16.2 - 2016-02-09\n~~~~~~~~~~~~~~~~~\n\n* Add a function that implements the name canonicalization from PEP 503.\n\n\n16.1 - 2016-02-07\n~~~~~~~~~~~~~~~~~\n\n* Implement requirement specifiers from PEP 508.\n\n\n16.0 - 2016-01-19\n~~~~~~~~~~~~~~~~~\n\n* Relicense so that packaging is available under *either* the Apache License,\n Version 2.0 or a 2 Clause BSD license.\n\n* Support installation of packaging when only distutils is available.\n\n* Fix ``==`` comparison when there is a prefix and a local version in play.\n (`#41 `__).\n\n* Implement environment markers from PEP 508.\n\n\n15.3 - 2015-08-01\n~~~~~~~~~~~~~~~~~\n\n* Normalize post-release spellings for rev/r prefixes. `#35 `__\n\n\n15.2 - 2015-05-13\n~~~~~~~~~~~~~~~~~\n\n* Fix an error where the arbitrary specifier (``===``) was not correctly\n allowing pre-releases when it was being used.\n\n* Expose the specifier and version parts through properties on the\n ``Specifier`` classes.\n\n* Allow iterating over the ``SpecifierSet`` to get access to all of the\n ``Specifier`` instances.\n\n* Allow testing if a version is contained within a specifier via the ``in``\n operator.\n\n\n15.1 - 2015-04-13\n~~~~~~~~~~~~~~~~~\n\n* Fix a logic error that was causing inconsistent answers about whether or not\n a pre-release was contained within a ``SpecifierSet`` or not.\n\n\n15.0 - 2015-01-02\n~~~~~~~~~~~~~~~~~\n\n* Add ``Version().is_postrelease`` and ``LegacyVersion().is_postrelease`` to\n make it easy to determine if a release is a post release.\n\n* Add ``Version().base_version`` and ``LegacyVersion().base_version`` to make\n it easy to get the public version without any pre or post release markers.\n\n* Support the update to PEP 440 which removed the implied ``!=V.*`` when using\n either ``>V`` or ``V`` or ````) operator.\n\n\n14.3 - 2014-11-19\n~~~~~~~~~~~~~~~~~\n\n* **BACKWARDS INCOMPATIBLE** Refactor specifier support so that it can sanely\n handle legacy specifiers as well as PEP 440 specifiers.\n\n* **BACKWARDS INCOMPATIBLE** Move the specifier support out of\n ``packaging.version`` into ``packaging.specifiers``.\n\n\n14.2 - 2014-09-10\n~~~~~~~~~~~~~~~~~\n\n* Add prerelease support to ``Specifier``.\n* Remove the ability to do ``item in Specifier()`` and replace it with\n ``Specifier().contains(item)`` in order to allow flags that signal if a\n prerelease should be accepted or not.\n* Add a method ``Specifier().filter()`` which will take an iterable and returns\n an iterable with items that do not match the specifier filtered out.\n\n\n14.1 - 2014-09-08\n~~~~~~~~~~~~~~~~~\n\n* Allow ``LegacyVersion`` and ``Version`` to be sorted together.\n* Add ``packaging.version.parse()`` to enable easily parsing a version string\n as either a ``Version`` or a ``LegacyVersion`` depending on it's PEP 440\n validity.\n\n\n14.0 - 2014-09-05\n~~~~~~~~~~~~~~~~~\n\n* Initial release.\n\n\n.. _`master`: https://github.com/pypa/packaging/", - "release_date": "2021-11-18T00:39:10", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Donald Stufft and individual contributors", - "email": "donald@stufft.io", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy" - ], - "homepage_url": "https://github.com/pypa/packaging", - "download_url": "https://files.pythonhosted.org/packages/05/8e/8de486cbd03baba4deef4142bd643a3e7bbe954a784dc1bb17142572d127/packaging-21.3-py3-none-any.whl", - "size": 40750, - "sha1": null, - "md5": "670a7057642064a747bd8274b24eb3f9", - "sha256": "ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-2-Clause or Apache-2.0", - "classifiers": [ - "License :: OSI Approved :: Apache Software License", - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/packaging/21.3/json", - "datasource_id": null, - "purl": "pkg:pypi/packaging@21.3" - }, - { - "type": "pypi", - "namespace": null, - "name": "packaging", - "version": "21.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Core utilities for Python packages\npackaging\n=========\n\n.. start-intro\n\nReusable core utilities for various Python Packaging\n`interoperability specifications `_.\n\nThis library provides utilities that implement the interoperability\nspecifications which have clearly one correct behaviour (eg: :pep:`440`)\nor benefit greatly from having a single shared implementation (eg: :pep:`425`).\n\n.. end-intro\n\nThe ``packaging`` project includes the following: version handling, specifiers,\nmarkers, requirements, tags, utilities.\n\nDocumentation\n-------------\n\nThe `documentation`_ provides information and the API for the following:\n\n- Version Handling\n- Specifiers\n- Markers\n- Requirements\n- Tags\n- Utilities\n\nInstallation\n------------\n\nUse ``pip`` to install these utilities::\n\n pip install packaging\n\nDiscussion\n----------\n\nIf you run into bugs, you can file them in our `issue tracker`_.\n\nYou can also join ``#pypa`` on Freenode to ask questions or get involved.\n\n\n.. _`documentation`: https://packaging.pypa.io/\n.. _`issue tracker`: https://github.com/pypa/packaging/issues\n\n\nCode of Conduct\n---------------\n\nEveryone interacting in the packaging project's codebases, issue trackers, chat\nrooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.\n\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md\n\nContributing\n------------\n\nThe ``CONTRIBUTING.rst`` file outlines how to contribute to this project as\nwell as how to report a potential security issue. The documentation for this\nproject also covers information about `project development`_ and `security`_.\n\n.. _`project development`: https://packaging.pypa.io/en/latest/development/\n.. _`security`: https://packaging.pypa.io/en/latest/security/\n\nProject History\n---------------\n\nPlease review the ``CHANGELOG.rst`` file or the `Changelog documentation`_ for\nrecent changes and project history.\n\n.. _`Changelog documentation`: https://packaging.pypa.io/en/latest/changelog/\n\nChangelog\n---------\n\n21.3 - 2021-11-17\n~~~~~~~~~~~~~~~~~\n\n* Add a ``pp3-none-any`` tag (`#311 `__)\n* Replace the blank pyparsing 3 exclusion with a 3.0.5 exclusion (`#481 `__, `#486 `__)\n* Fix a spelling mistake (`#479 `__)\n\n21.2 - 2021-10-29\n~~~~~~~~~~~~~~~~~\n\n* Update documentation entry for 21.1.\n\n21.1 - 2021-10-29\n~~~~~~~~~~~~~~~~~\n\n* Update pin to pyparsing to exclude 3.0.0.\n\n21.0 - 2021-07-03\n~~~~~~~~~~~~~~~~~\n\n* PEP 656: musllinux support (`#411 `__)\n* Drop support for Python 2.7, Python 3.4 and Python 3.5.\n* Replace distutils usage with sysconfig (`#396 `__)\n* Add support for zip files in ``parse_sdist_filename`` (`#429 `__)\n* Use cached ``_hash`` attribute to short-circuit tag equality comparisons (`#417 `__)\n* Specify the default value for the ``specifier`` argument to ``SpecifierSet`` (`#437 `__)\n* Proper keyword-only \"warn\" argument in packaging.tags (`#403 `__)\n* Correctly remove prerelease suffixes from ~= check (`#366 `__)\n* Fix type hints for ``Version.post`` and ``Version.dev`` (`#393 `__)\n* Use typing alias ``UnparsedVersion`` (`#398 `__)\n* Improve type inference for ``packaging.specifiers.filter()`` (`#430 `__)\n* Tighten the return type of ``canonicalize_version()`` (`#402 `__)\n\n20.9 - 2021-01-29\n~~~~~~~~~~~~~~~~~\n\n* Run `isort `_ over the code base (`#377 `__)\n* Add support for the ``macosx_10_*_universal2`` platform tags (`#379 `__)\n* Introduce ``packaging.utils.parse_wheel_filename()`` and ``parse_sdist_filename()``\n (`#387 `__ and `#389 `__)\n\n20.8 - 2020-12-11\n~~~~~~~~~~~~~~~~~\n\n* Revert back to setuptools for compatibility purposes for some Linux distros (`#363 `__)\n* Do not insert an underscore in wheel tags when the interpreter version number\n is more than 2 digits (`#372 `__)\n\n20.7 - 2020-11-28\n~~~~~~~~~~~~~~~~~\n\nNo unreleased changes.\n\n20.6 - 2020-11-28\n~~~~~~~~~~~~~~~~~\n\n.. note:: This release was subsequently yanked, and these changes were included in 20.7.\n\n* Fix flit configuration, to include LICENSE files (`#357 `__)\n* Make `intel` a recognized CPU architecture for the `universal` macOS platform tag (`#361 `__)\n* Add some missing type hints to `packaging.requirements` (issue:`350`)\n\n20.5 - 2020-11-27\n~~~~~~~~~~~~~~~~~\n\n* Officially support Python 3.9 (`#343 `__)\n* Deprecate the ``LegacyVersion`` and ``LegacySpecifier`` classes (`#321 `__)\n* Handle ``OSError`` on non-dynamic executables when attempting to resolve\n the glibc version string.\n\n20.4 - 2020-05-19\n~~~~~~~~~~~~~~~~~\n\n* Canonicalize version before comparing specifiers. (`#282 `__)\n* Change type hint for ``canonicalize_name`` to return\n ``packaging.utils.NormalizedName``.\n This enables the use of static typing tools (like mypy) to detect mixing of\n normalized and un-normalized names.\n\n20.3 - 2020-03-05\n~~~~~~~~~~~~~~~~~\n\n* Fix changelog for 20.2.\n\n20.2 - 2020-03-05\n~~~~~~~~~~~~~~~~~\n\n* Fix a bug that caused a 32-bit OS that runs on a 64-bit ARM CPU (e.g. ARM-v8,\n aarch64), to report the wrong bitness.\n\n20.1 - 2020-01-24\n~~~~~~~~~~~~~~~~~~~\n\n* Fix a bug caused by reuse of an exhausted iterator. (`#257 `__)\n\n20.0 - 2020-01-06\n~~~~~~~~~~~~~~~~~\n\n* Add type hints (`#191 `__)\n\n* Add proper trove classifiers for PyPy support (`#198 `__)\n\n* Scale back depending on ``ctypes`` for manylinux support detection (`#171 `__)\n\n* Use ``sys.implementation.name`` where appropriate for ``packaging.tags`` (`#193 `__)\n\n* Expand upon the API provided by ``packaging.tags``: ``interpreter_name()``, ``mac_platforms()``, ``compatible_tags()``, ``cpython_tags()``, ``generic_tags()`` (`#187 `__)\n\n* Officially support Python 3.8 (`#232 `__)\n\n* Add ``major``, ``minor``, and ``micro`` aliases to ``packaging.version.Version`` (`#226 `__)\n\n* Properly mark ``packaging`` has being fully typed by adding a `py.typed` file (`#226 `__)\n\n19.2 - 2019-09-18\n~~~~~~~~~~~~~~~~~\n\n* Remove dependency on ``attrs`` (`#178 `__, `#179 `__)\n\n* Use appropriate fallbacks for CPython ABI tag (`#181 `__, `#185 `__)\n\n* Add manylinux2014 support (`#186 `__)\n\n* Improve ABI detection (`#181 `__)\n\n* Properly handle debug wheels for Python 3.8 (`#172 `__)\n\n* Improve detection of debug builds on Windows (`#194 `__)\n\n19.1 - 2019-07-30\n~~~~~~~~~~~~~~~~~\n\n* Add the ``packaging.tags`` module. (`#156 `__)\n\n* Correctly handle two-digit versions in ``python_version`` (`#119 `__)\n\n\n19.0 - 2019-01-20\n~~~~~~~~~~~~~~~~~\n\n* Fix string representation of PEP 508 direct URL requirements with markers.\n\n* Better handling of file URLs\n\n This allows for using ``file:///absolute/path``, which was previously\n prevented due to the missing ``netloc``.\n\n This allows for all file URLs that ``urlunparse`` turns back into the\n original URL to be valid.\n\n\n18.0 - 2018-09-26\n~~~~~~~~~~~~~~~~~\n\n* Improve error messages when invalid requirements are given. (`#129 `__)\n\n\n17.1 - 2017-02-28\n~~~~~~~~~~~~~~~~~\n\n* Fix ``utils.canonicalize_version`` when supplying non PEP 440 versions.\n\n\n17.0 - 2017-02-28\n~~~~~~~~~~~~~~~~~\n\n* Drop support for python 2.6, 3.2, and 3.3.\n\n* Define minimal pyparsing version to 2.0.2 (`#91 `__).\n\n* Add ``epoch``, ``release``, ``pre``, ``dev``, and ``post`` attributes to\n ``Version`` and ``LegacyVersion`` (`#34 `__).\n\n* Add ``Version().is_devrelease`` and ``LegacyVersion().is_devrelease`` to\n make it easy to determine if a release is a development release.\n\n* Add ``utils.canonicalize_version`` to canonicalize version strings or\n ``Version`` instances (`#121 `__).\n\n\n16.8 - 2016-10-29\n~~~~~~~~~~~~~~~~~\n\n* Fix markers that utilize ``in`` so that they render correctly.\n\n* Fix an erroneous test on Python RC releases.\n\n\n16.7 - 2016-04-23\n~~~~~~~~~~~~~~~~~\n\n* Add support for the deprecated ``python_implementation`` marker which was\n an undocumented setuptools marker in addition to the newer markers.\n\n\n16.6 - 2016-03-29\n~~~~~~~~~~~~~~~~~\n\n* Add support for the deprecated, PEP 345 environment markers in addition to\n the newer markers.\n\n\n16.5 - 2016-02-26\n~~~~~~~~~~~~~~~~~\n\n* Fix a regression in parsing requirements with whitespaces between the comma\n separators.\n\n\n16.4 - 2016-02-22\n~~~~~~~~~~~~~~~~~\n\n* Fix a regression in parsing requirements like ``foo (==4)``.\n\n\n16.3 - 2016-02-21\n~~~~~~~~~~~~~~~~~\n\n* Fix a bug where ``packaging.requirements:Requirement`` was overly strict when\n matching legacy requirements.\n\n\n16.2 - 2016-02-09\n~~~~~~~~~~~~~~~~~\n\n* Add a function that implements the name canonicalization from PEP 503.\n\n\n16.1 - 2016-02-07\n~~~~~~~~~~~~~~~~~\n\n* Implement requirement specifiers from PEP 508.\n\n\n16.0 - 2016-01-19\n~~~~~~~~~~~~~~~~~\n\n* Relicense so that packaging is available under *either* the Apache License,\n Version 2.0 or a 2 Clause BSD license.\n\n* Support installation of packaging when only distutils is available.\n\n* Fix ``==`` comparison when there is a prefix and a local version in play.\n (`#41 `__).\n\n* Implement environment markers from PEP 508.\n\n\n15.3 - 2015-08-01\n~~~~~~~~~~~~~~~~~\n\n* Normalize post-release spellings for rev/r prefixes. `#35 `__\n\n\n15.2 - 2015-05-13\n~~~~~~~~~~~~~~~~~\n\n* Fix an error where the arbitrary specifier (``===``) was not correctly\n allowing pre-releases when it was being used.\n\n* Expose the specifier and version parts through properties on the\n ``Specifier`` classes.\n\n* Allow iterating over the ``SpecifierSet`` to get access to all of the\n ``Specifier`` instances.\n\n* Allow testing if a version is contained within a specifier via the ``in``\n operator.\n\n\n15.1 - 2015-04-13\n~~~~~~~~~~~~~~~~~\n\n* Fix a logic error that was causing inconsistent answers about whether or not\n a pre-release was contained within a ``SpecifierSet`` or not.\n\n\n15.0 - 2015-01-02\n~~~~~~~~~~~~~~~~~\n\n* Add ``Version().is_postrelease`` and ``LegacyVersion().is_postrelease`` to\n make it easy to determine if a release is a post release.\n\n* Add ``Version().base_version`` and ``LegacyVersion().base_version`` to make\n it easy to get the public version without any pre or post release markers.\n\n* Support the update to PEP 440 which removed the implied ``!=V.*`` when using\n either ``>V`` or ``V`` or ````) operator.\n\n\n14.3 - 2014-11-19\n~~~~~~~~~~~~~~~~~\n\n* **BACKWARDS INCOMPATIBLE** Refactor specifier support so that it can sanely\n handle legacy specifiers as well as PEP 440 specifiers.\n\n* **BACKWARDS INCOMPATIBLE** Move the specifier support out of\n ``packaging.version`` into ``packaging.specifiers``.\n\n\n14.2 - 2014-09-10\n~~~~~~~~~~~~~~~~~\n\n* Add prerelease support to ``Specifier``.\n* Remove the ability to do ``item in Specifier()`` and replace it with\n ``Specifier().contains(item)`` in order to allow flags that signal if a\n prerelease should be accepted or not.\n* Add a method ``Specifier().filter()`` which will take an iterable and returns\n an iterable with items that do not match the specifier filtered out.\n\n\n14.1 - 2014-09-08\n~~~~~~~~~~~~~~~~~\n\n* Allow ``LegacyVersion`` and ``Version`` to be sorted together.\n* Add ``packaging.version.parse()`` to enable easily parsing a version string\n as either a ``Version`` or a ``LegacyVersion`` depending on it's PEP 440\n validity.\n\n\n14.0 - 2014-09-05\n~~~~~~~~~~~~~~~~~\n\n* Initial release.\n\n\n.. _`master`: https://github.com/pypa/packaging/", - "release_date": "2021-11-18T00:39:13", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Donald Stufft and individual contributors", - "email": "donald@stufft.io", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy" - ], - "homepage_url": "https://github.com/pypa/packaging", - "download_url": "https://files.pythonhosted.org/packages/df/9e/d1a7217f69310c1db8fdf8ab396229f55a699ce34a203691794c5d1cad0c/packaging-21.3.tar.gz", - "size": 84848, - "sha1": null, - "md5": "e713c1939f294fd729af4a7be40dd141", - "sha256": "dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-2-Clause or Apache-2.0", - "classifiers": [ - "License :: OSI Approved :: Apache Software License", - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/packaging/21.3/json", - "datasource_id": null, - "purl": "pkg:pypi/packaging@21.3" - }, - { - "type": "pypi", - "namespace": null, - "name": "pathspec", - "version": "0.9.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Utility library for gitignore style pattern matching of file paths.\n*pathspec*: Path Specification\n==============================\n\n*pathspec* is a utility library for pattern matching of file paths. So\nfar this only includes Git's wildmatch pattern matching which itself is\nderived from Rsync's wildmatch. Git uses wildmatch for its `gitignore`_\nfiles.\n\n.. _`gitignore`: http://git-scm.com/docs/gitignore\n\n\nTutorial\n--------\n\nSay you have a \"Projects\" directory and you want to back it up, but only\ncertain files, and ignore others depending on certain conditions::\n\n\t>>> import pathspec\n\t>>> # The gitignore-style patterns for files to select, but we're including\n\t>>> # instead of ignoring.\n\t>>> spec = \"\"\"\n\t...\n\t... # This is a comment because the line begins with a hash: \"#\"\n\t...\n\t... # Include several project directories (and all descendants) relative to\n\t... # the current directory. To reference a directory you must end with a\n\t... # slash: \"/\"\n\t... /project-a/\n\t... /project-b/\n\t... /project-c/\n\t...\n\t... # Patterns can be negated by prefixing with exclamation mark: \"!\"\n\t...\n\t... # Ignore temporary files beginning or ending with \"~\" and ending with\n\t... # \".swp\".\n\t... !~*\n\t... !*~\n\t... !*.swp\n\t...\n\t... # These are python projects so ignore compiled python files from\n\t... # testing.\n\t... !*.pyc\n\t...\n\t... # Ignore the build directories but only directly under the project\n\t... # directories.\n\t... !/*/build/\n\t...\n\t... \"\"\"\n\nWe want to use the ``GitWildMatchPattern`` class to compile our patterns. The\n``PathSpec`` class provides an interface around pattern implementations::\n\n\t>>> spec = pathspec.PathSpec.from_lines(pathspec.patterns.GitWildMatchPattern, spec.splitlines())\n\nThat may be a mouthful but it allows for additional patterns to be implemented\nin the future without them having to deal with anything but matching the paths\nsent to them. ``GitWildMatchPattern`` is the implementation of the actual\npattern which internally gets converted into a regular expression.\n``PathSpec`` is a simple wrapper around a list of compiled patterns.\n\nTo make things simpler, we can use the registered name for a pattern class\ninstead of always having to provide a reference to the class itself. The\n``GitWildMatchPattern`` class is registered as **gitwildmatch**::\n\n\t>>> spec = pathspec.PathSpec.from_lines('gitwildmatch', spec.splitlines())\n\nIf we wanted to manually compile the patterns we can just do the following::\n\n\t>>> patterns = map(pathspec.patterns.GitWildMatchPattern, spec.splitlines())\n\t>>> spec = PathSpec(patterns)\n\n``PathSpec.from_lines()`` is simply a class method which does just that.\n\nIf you want to load the patterns from file, you can pass the file instance\ndirectly as well::\n\n\t>>> with open('patterns.list', 'r') as fh:\n\t>>> spec = pathspec.PathSpec.from_lines('gitwildmatch', fh)\n\nYou can perform matching on a whole directory tree with::\n\n\t>>> matches = spec.match_tree('path/to/directory')\n\nOr you can perform matching on a specific set of file paths with::\n\n\t>>> matches = spec.match_files(file_paths)\n\nOr check to see if an individual file matches::\n\n\t>>> is_matched = spec.match_file(file_path)\n\n\nLicense\n-------\n\n*pathspec* is licensed under the `Mozilla Public License Version 2.0`_. See\n`LICENSE`_ or the `FAQ`_ for more information.\n\nIn summary, you may use *pathspec* with any closed or open source project\nwithout affecting the license of the larger work so long as you:\n\n- give credit where credit is due,\n\n- and release any custom changes made to *pathspec*.\n\n.. _`Mozilla Public License Version 2.0`: http://www.mozilla.org/MPL/2.0\n.. _`LICENSE`: LICENSE\n.. _`FAQ`: http://www.mozilla.org/MPL/2.0/FAQ.html\n\n\nSource\n------\n\nThe source code for *pathspec* is available from the GitHub repo\n`cpburnz/python-path-specification`_.\n\n.. _`cpburnz/python-path-specification`: https://github.com/cpburnz/python-path-specification\n\n\nInstallation\n------------\n\n*pathspec* requires the following packages:\n\n- `setuptools`_\n\n*pathspec* can be installed from source with::\n\n\tpython setup.py install\n\n*pathspec* is also available for install through `PyPI`_::\n\n\tpip install pathspec\n\n.. _`setuptools`: https://pypi.python.org/pypi/setuptools\n.. _`PyPI`: http://pypi.python.org/pypi/pathspec\n\n\nDocumentation\n-------------\n\nDocumentation for *pathspec* is available on `Read the Docs`_.\n\n.. _`Read the Docs`: http://python-path-specification.readthedocs.io\n\n\nOther Languages\n---------------\n\n*pathspec* is also available as a `Ruby gem`_.\n\n.. _`Ruby gem`: https://github.com/highb/pathspec-ruby\n\n\nChange History\n==============\n\n0.9.0 (2021-07-17)\n------------------\n\n- `Issue #44`_/`Issue #50`_: Raise `GitWildMatchPatternError` for invalid git patterns.\n- `Issue #45`_: Fix for duplicate leading double-asterisk, and edge cases.\n- `Issue #46`_: Fix matching absolute paths.\n- API change: `util.normalize_files()` now returns a `Dict[str, List[pathlike]]` instead of a `Dict[str, pathlike]`.\n- Added type hinting.\n\n.. _`Issue #44`: https://github.com/cpburnz/python-path-specification/issues/44\n.. _`Issue #45`: https://github.com/cpburnz/python-path-specification/pull/45\n.. _`Issue #46`: https://github.com/cpburnz/python-path-specification/issues/46\n.. _`Issue #50`: https://github.com/cpburnz/python-path-specification/pull/50\n\n\n0.8.1 (2020-11-07)\n------------------\n\n- `Issue #43`_: Add support for addition operator.\n\n.. _`Issue #43`: https://github.com/cpburnz/python-path-specification/pull/43\n\n\n0.8.0 (2020-04-09)\n------------------\n\n- `Issue #30`_: Expose what patterns matched paths. Added `util.detailed_match_files()`.\n- `Issue #31`_: `match_tree()` doesn't return symlinks.\n- `Issue #34`_: Support `pathlib.Path`\\ s.\n- Add `PathSpec.match_tree_entries` and `util.iter_tree_entries()` to support directories and symlinks.\n- API change: `match_tree()` has been renamed to `match_tree_files()`. The old name `match_tree()` is still available as an alias.\n- API change: `match_tree_files()` now returns symlinks. This is a bug fix but it will change the returned results.\n\n.. _`Issue #30`: https://github.com/cpburnz/python-path-specification/issues/30\n.. _`Issue #31`: https://github.com/cpburnz/python-path-specification/issues/31\n.. _`Issue #34`: https://github.com/cpburnz/python-path-specification/issues/34\n\n\n0.7.0 (2019-12-27)\n------------------\n\n- `Issue #28`_: Add support for Python 3.8, and drop Python 3.4.\n- `Issue #29`_: Publish bdist wheel.\n\n.. _`Issue #28`: https://github.com/cpburnz/python-path-specification/pull/28\n.. _`Issue #29`: https://github.com/cpburnz/python-path-specification/pull/29\n\n\n0.6.0 (2019-10-03)\n------------------\n\n- `Issue #24`_: Drop support for Python 2.6, 3.2, and 3.3.\n- `Issue #25`_: Update README.rst.\n- `Issue #26`_: Method to escape gitwildmatch.\n\n.. _`Issue #24`: https://github.com/cpburnz/python-path-specification/pull/24\n.. _`Issue #25`: https://github.com/cpburnz/python-path-specification/pull/25\n.. _`Issue #26`: https://github.com/cpburnz/python-path-specification/pull/26\n\n\n0.5.9 (2018-09-15)\n------------------\n\n- Fixed file system error handling.\n\n\n0.5.8 (2018-09-15)\n------------------\n\n- Improved type checking.\n- Created scripts to test Python 2.6 because Tox removed support for it.\n- Improved byte string handling in Python 3.\n- `Issue #22`_: Handle dangling symlinks.\n\n.. _`Issue #22`: https://github.com/cpburnz/python-path-specification/issues/22\n\n\n0.5.7 (2018-08-14)\n------------------\n\n- `Issue #21`_: Fix collections deprecation warning.\n\n.. _`Issue #21`: https://github.com/cpburnz/python-path-specification/issues/21\n\n\n0.5.6 (2018-04-06)\n------------------\n\n- Improved unit tests.\n- Improved type checking.\n- `Issue #20`_: Support current directory prefix.\n\n.. _`Issue #20`: https://github.com/cpburnz/python-path-specification/issues/20\n\n\n0.5.5 (2017-09-09)\n------------------\n\n- Add documentation link to README.\n\n\n0.5.4 (2017-09-09)\n------------------\n\n- `Issue #17`_: Add link to Ruby implementation of *pathspec*.\n- Add sphinx documentation.\n\n.. _`Issue #17`: https://github.com/cpburnz/python-path-specification/pull/17\n\n\n0.5.3 (2017-07-01)\n------------------\n\n- `Issue #14`_: Fix byte strings for Python 3.\n- `Issue #15`_: Include \"LICENSE\" in source package.\n- `Issue #16`_: Support Python 2.6.\n\n.. _`Issue #14`: https://github.com/cpburnz/python-path-specification/issues/14\n.. _`Issue #15`: https://github.com/cpburnz/python-path-specification/pull/15\n.. _`Issue #16`: https://github.com/cpburnz/python-path-specification/issues/16\n\n\n0.5.2 (2017-04-04)\n------------------\n\n- Fixed change log.\n\n\n0.5.1 (2017-04-04)\n------------------\n\n- `Issue #13`_: Add equality methods to `PathSpec` and `RegexPattern`.\n\n.. _`Issue #13`: https://github.com/cpburnz/python-path-specification/pull/13\n\n\n0.5.0 (2016-08-22)\n------------------\n\n- `Issue #12`_: Add `PathSpec.match_file()`.\n- Renamed `gitignore.GitIgnorePattern` to `patterns.gitwildmatch.GitWildMatchPattern`.\n- Deprecated `gitignore.GitIgnorePattern`.\n\n.. _`Issue #12`: https://github.com/cpburnz/python-path-specification/issues/12\n\n\n0.4.0 (2016-07-15)\n------------------\n\n- `Issue #11`_: Support converting patterns into regular expressions without compiling them.\n- API change: Subclasses of `RegexPattern` should implement `pattern_to_regex()`.\n\n.. _`Issue #11`: https://github.com/cpburnz/python-path-specification/issues/11\n\n\n0.3.4 (2015-08-24)\n------------------\n\n- `Issue #7`_: Fixed non-recursive links.\n- `Issue #8`_: Fixed edge cases in gitignore patterns.\n- `Issue #9`_: Fixed minor usage documentation.\n- Fixed recursion detection.\n- Fixed trivial incompatibility with Python 3.2.\n\n.. _`Issue #7`: https://github.com/cpburnz/python-path-specification/pull/7\n.. _`Issue #8`: https://github.com/cpburnz/python-path-specification/pull/8\n.. _`Issue #9`: https://github.com/cpburnz/python-path-specification/pull/9\n\n\n0.3.3 (2014-11-21)\n------------------\n\n- Improved documentation.\n\n\n0.3.2 (2014-11-08)\n------------------\n\n- `Issue #5`_: Use tox for testing.\n- `Issue #6`_: Fixed matching Windows paths.\n- Improved documentation.\n- API change: `spec.match_tree()` and `spec.match_files()` now return iterators instead of sets.\n\n.. _`Issue #5`: https://github.com/cpburnz/python-path-specification/pull/5\n.. _`Issue #6`: https://github.com/cpburnz/python-path-specification/issues/6\n\n\n0.3.1 (2014-09-17)\n------------------\n\n- Updated README.\n\n\n0.3.0 (2014-09-17)\n------------------\n\n- `Issue #3`_: Fixed trailing slash in gitignore patterns.\n- `Issue #4`_: Fixed test for trailing slash in gitignore patterns.\n- Added registered patterns.\n\n.. _`Issue #3`: https://github.com/cpburnz/python-path-specification/pull/3\n.. _`Issue #4`: https://github.com/cpburnz/python-path-specification/pull/4\n\n\n0.2.2 (2013-12-17)\n------------------\n\n- Fixed setup.py.\n\n\n0.2.1 (2013-12-17)\n------------------\n\n- Added tests.\n- Fixed comment gitignore patterns.\n- Fixed relative path gitignore patterns.\n\n\n0.2.0 (2013-12-07)\n------------------\n\n- Initial release.", - "release_date": "2021-07-18T00:27:58", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Caleb P. Burns", - "email": "cpburnz@gmail.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "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 :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/cpburnz/python-path-specification", - "download_url": "https://files.pythonhosted.org/packages/42/ba/a9d64c7bcbc7e3e8e5f93a52721b377e994c22d16196e2b0f1236774353a/pathspec-0.9.0-py2.py3-none-any.whl", - "size": 31165, - "sha1": null, - "md5": "ffa2e0227d4eef53c5329af611e26c32", - "sha256": "7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MPL 2.0", - "classifiers": [ - "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pathspec/0.9.0/json", - "datasource_id": null, - "purl": "pkg:pypi/pathspec@0.9.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "pathspec", - "version": "0.9.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Utility library for gitignore style pattern matching of file paths.\n*pathspec*: Path Specification\n==============================\n\n*pathspec* is a utility library for pattern matching of file paths. So\nfar this only includes Git's wildmatch pattern matching which itself is\nderived from Rsync's wildmatch. Git uses wildmatch for its `gitignore`_\nfiles.\n\n.. _`gitignore`: http://git-scm.com/docs/gitignore\n\n\nTutorial\n--------\n\nSay you have a \"Projects\" directory and you want to back it up, but only\ncertain files, and ignore others depending on certain conditions::\n\n\t>>> import pathspec\n\t>>> # The gitignore-style patterns for files to select, but we're including\n\t>>> # instead of ignoring.\n\t>>> spec = \"\"\"\n\t...\n\t... # This is a comment because the line begins with a hash: \"#\"\n\t...\n\t... # Include several project directories (and all descendants) relative to\n\t... # the current directory. To reference a directory you must end with a\n\t... # slash: \"/\"\n\t... /project-a/\n\t... /project-b/\n\t... /project-c/\n\t...\n\t... # Patterns can be negated by prefixing with exclamation mark: \"!\"\n\t...\n\t... # Ignore temporary files beginning or ending with \"~\" and ending with\n\t... # \".swp\".\n\t... !~*\n\t... !*~\n\t... !*.swp\n\t...\n\t... # These are python projects so ignore compiled python files from\n\t... # testing.\n\t... !*.pyc\n\t...\n\t... # Ignore the build directories but only directly under the project\n\t... # directories.\n\t... !/*/build/\n\t...\n\t... \"\"\"\n\nWe want to use the ``GitWildMatchPattern`` class to compile our patterns. The\n``PathSpec`` class provides an interface around pattern implementations::\n\n\t>>> spec = pathspec.PathSpec.from_lines(pathspec.patterns.GitWildMatchPattern, spec.splitlines())\n\nThat may be a mouthful but it allows for additional patterns to be implemented\nin the future without them having to deal with anything but matching the paths\nsent to them. ``GitWildMatchPattern`` is the implementation of the actual\npattern which internally gets converted into a regular expression.\n``PathSpec`` is a simple wrapper around a list of compiled patterns.\n\nTo make things simpler, we can use the registered name for a pattern class\ninstead of always having to provide a reference to the class itself. The\n``GitWildMatchPattern`` class is registered as **gitwildmatch**::\n\n\t>>> spec = pathspec.PathSpec.from_lines('gitwildmatch', spec.splitlines())\n\nIf we wanted to manually compile the patterns we can just do the following::\n\n\t>>> patterns = map(pathspec.patterns.GitWildMatchPattern, spec.splitlines())\n\t>>> spec = PathSpec(patterns)\n\n``PathSpec.from_lines()`` is simply a class method which does just that.\n\nIf you want to load the patterns from file, you can pass the file instance\ndirectly as well::\n\n\t>>> with open('patterns.list', 'r') as fh:\n\t>>> spec = pathspec.PathSpec.from_lines('gitwildmatch', fh)\n\nYou can perform matching on a whole directory tree with::\n\n\t>>> matches = spec.match_tree('path/to/directory')\n\nOr you can perform matching on a specific set of file paths with::\n\n\t>>> matches = spec.match_files(file_paths)\n\nOr check to see if an individual file matches::\n\n\t>>> is_matched = spec.match_file(file_path)\n\n\nLicense\n-------\n\n*pathspec* is licensed under the `Mozilla Public License Version 2.0`_. See\n`LICENSE`_ or the `FAQ`_ for more information.\n\nIn summary, you may use *pathspec* with any closed or open source project\nwithout affecting the license of the larger work so long as you:\n\n- give credit where credit is due,\n\n- and release any custom changes made to *pathspec*.\n\n.. _`Mozilla Public License Version 2.0`: http://www.mozilla.org/MPL/2.0\n.. _`LICENSE`: LICENSE\n.. _`FAQ`: http://www.mozilla.org/MPL/2.0/FAQ.html\n\n\nSource\n------\n\nThe source code for *pathspec* is available from the GitHub repo\n`cpburnz/python-path-specification`_.\n\n.. _`cpburnz/python-path-specification`: https://github.com/cpburnz/python-path-specification\n\n\nInstallation\n------------\n\n*pathspec* requires the following packages:\n\n- `setuptools`_\n\n*pathspec* can be installed from source with::\n\n\tpython setup.py install\n\n*pathspec* is also available for install through `PyPI`_::\n\n\tpip install pathspec\n\n.. _`setuptools`: https://pypi.python.org/pypi/setuptools\n.. _`PyPI`: http://pypi.python.org/pypi/pathspec\n\n\nDocumentation\n-------------\n\nDocumentation for *pathspec* is available on `Read the Docs`_.\n\n.. _`Read the Docs`: http://python-path-specification.readthedocs.io\n\n\nOther Languages\n---------------\n\n*pathspec* is also available as a `Ruby gem`_.\n\n.. _`Ruby gem`: https://github.com/highb/pathspec-ruby\n\n\nChange History\n==============\n\n0.9.0 (2021-07-17)\n------------------\n\n- `Issue #44`_/`Issue #50`_: Raise `GitWildMatchPatternError` for invalid git patterns.\n- `Issue #45`_: Fix for duplicate leading double-asterisk, and edge cases.\n- `Issue #46`_: Fix matching absolute paths.\n- API change: `util.normalize_files()` now returns a `Dict[str, List[pathlike]]` instead of a `Dict[str, pathlike]`.\n- Added type hinting.\n\n.. _`Issue #44`: https://github.com/cpburnz/python-path-specification/issues/44\n.. _`Issue #45`: https://github.com/cpburnz/python-path-specification/pull/45\n.. _`Issue #46`: https://github.com/cpburnz/python-path-specification/issues/46\n.. _`Issue #50`: https://github.com/cpburnz/python-path-specification/pull/50\n\n\n0.8.1 (2020-11-07)\n------------------\n\n- `Issue #43`_: Add support for addition operator.\n\n.. _`Issue #43`: https://github.com/cpburnz/python-path-specification/pull/43\n\n\n0.8.0 (2020-04-09)\n------------------\n\n- `Issue #30`_: Expose what patterns matched paths. Added `util.detailed_match_files()`.\n- `Issue #31`_: `match_tree()` doesn't return symlinks.\n- `Issue #34`_: Support `pathlib.Path`\\ s.\n- Add `PathSpec.match_tree_entries` and `util.iter_tree_entries()` to support directories and symlinks.\n- API change: `match_tree()` has been renamed to `match_tree_files()`. The old name `match_tree()` is still available as an alias.\n- API change: `match_tree_files()` now returns symlinks. This is a bug fix but it will change the returned results.\n\n.. _`Issue #30`: https://github.com/cpburnz/python-path-specification/issues/30\n.. _`Issue #31`: https://github.com/cpburnz/python-path-specification/issues/31\n.. _`Issue #34`: https://github.com/cpburnz/python-path-specification/issues/34\n\n\n0.7.0 (2019-12-27)\n------------------\n\n- `Issue #28`_: Add support for Python 3.8, and drop Python 3.4.\n- `Issue #29`_: Publish bdist wheel.\n\n.. _`Issue #28`: https://github.com/cpburnz/python-path-specification/pull/28\n.. _`Issue #29`: https://github.com/cpburnz/python-path-specification/pull/29\n\n\n0.6.0 (2019-10-03)\n------------------\n\n- `Issue #24`_: Drop support for Python 2.6, 3.2, and 3.3.\n- `Issue #25`_: Update README.rst.\n- `Issue #26`_: Method to escape gitwildmatch.\n\n.. _`Issue #24`: https://github.com/cpburnz/python-path-specification/pull/24\n.. _`Issue #25`: https://github.com/cpburnz/python-path-specification/pull/25\n.. _`Issue #26`: https://github.com/cpburnz/python-path-specification/pull/26\n\n\n0.5.9 (2018-09-15)\n------------------\n\n- Fixed file system error handling.\n\n\n0.5.8 (2018-09-15)\n------------------\n\n- Improved type checking.\n- Created scripts to test Python 2.6 because Tox removed support for it.\n- Improved byte string handling in Python 3.\n- `Issue #22`_: Handle dangling symlinks.\n\n.. _`Issue #22`: https://github.com/cpburnz/python-path-specification/issues/22\n\n\n0.5.7 (2018-08-14)\n------------------\n\n- `Issue #21`_: Fix collections deprecation warning.\n\n.. _`Issue #21`: https://github.com/cpburnz/python-path-specification/issues/21\n\n\n0.5.6 (2018-04-06)\n------------------\n\n- Improved unit tests.\n- Improved type checking.\n- `Issue #20`_: Support current directory prefix.\n\n.. _`Issue #20`: https://github.com/cpburnz/python-path-specification/issues/20\n\n\n0.5.5 (2017-09-09)\n------------------\n\n- Add documentation link to README.\n\n\n0.5.4 (2017-09-09)\n------------------\n\n- `Issue #17`_: Add link to Ruby implementation of *pathspec*.\n- Add sphinx documentation.\n\n.. _`Issue #17`: https://github.com/cpburnz/python-path-specification/pull/17\n\n\n0.5.3 (2017-07-01)\n------------------\n\n- `Issue #14`_: Fix byte strings for Python 3.\n- `Issue #15`_: Include \"LICENSE\" in source package.\n- `Issue #16`_: Support Python 2.6.\n\n.. _`Issue #14`: https://github.com/cpburnz/python-path-specification/issues/14\n.. _`Issue #15`: https://github.com/cpburnz/python-path-specification/pull/15\n.. _`Issue #16`: https://github.com/cpburnz/python-path-specification/issues/16\n\n\n0.5.2 (2017-04-04)\n------------------\n\n- Fixed change log.\n\n\n0.5.1 (2017-04-04)\n------------------\n\n- `Issue #13`_: Add equality methods to `PathSpec` and `RegexPattern`.\n\n.. _`Issue #13`: https://github.com/cpburnz/python-path-specification/pull/13\n\n\n0.5.0 (2016-08-22)\n------------------\n\n- `Issue #12`_: Add `PathSpec.match_file()`.\n- Renamed `gitignore.GitIgnorePattern` to `patterns.gitwildmatch.GitWildMatchPattern`.\n- Deprecated `gitignore.GitIgnorePattern`.\n\n.. _`Issue #12`: https://github.com/cpburnz/python-path-specification/issues/12\n\n\n0.4.0 (2016-07-15)\n------------------\n\n- `Issue #11`_: Support converting patterns into regular expressions without compiling them.\n- API change: Subclasses of `RegexPattern` should implement `pattern_to_regex()`.\n\n.. _`Issue #11`: https://github.com/cpburnz/python-path-specification/issues/11\n\n\n0.3.4 (2015-08-24)\n------------------\n\n- `Issue #7`_: Fixed non-recursive links.\n- `Issue #8`_: Fixed edge cases in gitignore patterns.\n- `Issue #9`_: Fixed minor usage documentation.\n- Fixed recursion detection.\n- Fixed trivial incompatibility with Python 3.2.\n\n.. _`Issue #7`: https://github.com/cpburnz/python-path-specification/pull/7\n.. _`Issue #8`: https://github.com/cpburnz/python-path-specification/pull/8\n.. _`Issue #9`: https://github.com/cpburnz/python-path-specification/pull/9\n\n\n0.3.3 (2014-11-21)\n------------------\n\n- Improved documentation.\n\n\n0.3.2 (2014-11-08)\n------------------\n\n- `Issue #5`_: Use tox for testing.\n- `Issue #6`_: Fixed matching Windows paths.\n- Improved documentation.\n- API change: `spec.match_tree()` and `spec.match_files()` now return iterators instead of sets.\n\n.. _`Issue #5`: https://github.com/cpburnz/python-path-specification/pull/5\n.. _`Issue #6`: https://github.com/cpburnz/python-path-specification/issues/6\n\n\n0.3.1 (2014-09-17)\n------------------\n\n- Updated README.\n\n\n0.3.0 (2014-09-17)\n------------------\n\n- `Issue #3`_: Fixed trailing slash in gitignore patterns.\n- `Issue #4`_: Fixed test for trailing slash in gitignore patterns.\n- Added registered patterns.\n\n.. _`Issue #3`: https://github.com/cpburnz/python-path-specification/pull/3\n.. _`Issue #4`: https://github.com/cpburnz/python-path-specification/pull/4\n\n\n0.2.2 (2013-12-17)\n------------------\n\n- Fixed setup.py.\n\n\n0.2.1 (2013-12-17)\n------------------\n\n- Added tests.\n- Fixed comment gitignore patterns.\n- Fixed relative path gitignore patterns.\n\n\n0.2.0 (2013-12-07)\n------------------\n\n- Initial release.", - "release_date": "2021-07-18T00:27:56", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Caleb P. Burns", - "email": "cpburnz@gmail.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "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 :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/cpburnz/python-path-specification", - "download_url": "https://files.pythonhosted.org/packages/f6/33/436c5cb94e9f8902e59d1d544eb298b83c84b9ec37b5b769c5a0ad6edb19/pathspec-0.9.0.tar.gz", - "size": 29483, - "sha1": null, - "md5": "9b6b70fa5ffc31e6f5700522880140c0", - "sha256": "e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MPL 2.0", - "classifiers": [ - "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pathspec/0.9.0/json", - "datasource_id": null, - "purl": "pkg:pypi/pathspec@0.9.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "pip-requirements-parser", - "version": "31.2.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "pip requirements parser - a mostly correct pip requirements parsing library because it uses pip's own code.\npip-requirements-parser - a mostly correct pip requirements parsing library\n================================================================================\n\nCopyright (c) nexB Inc. and others.\nCopyright (c) The pip developers (see AUTHORS.rst file)\nSPDX-License-Identifier: MIT\nHomepage: https://github.com/nexB/pip-requirements and https://www.aboutcode.org/\n\n\n``pip-requirements-parser`` is a mostly correct pip requirements parsing\nlibrary ... because it uses pip's own code!\n\npip is the ``package installer`` for Python that is using \"requirements\" text\nfiles listing the packages to install.\n\nPer https://pip.pypa.io/en/stable/reference/requirements-file-format/ :\n\n \"The requirements file format is closely tied to a number of internal\n details of pip (e.g., pip\u2019s command line options). The basic format is\n relatively stable and portable but the full syntax, as described here,\n is only intended for consumption by pip, and other tools should take\n that into account before using it for their own purposes.\"\n\nAnd per https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program :\n\n \"[..] pip is a command line program. While it is implemented in Python, and\n so is available from your Python code via import pip, you must not use pip\u2019s\n internal APIs in this way.\"\n \n \"What this means in practice is that everything inside of pip is considered\n an implementation detail. Even the fact that the import name is pip is\n subject to change without notice. While we do try not to break things as\n much as possible, all the internal APIs can change at any time, for any\n reason. It also means that we generally won\u2019t fix issues that are a result\n of using pip in an unsupported way.\"\n\n\nBecause of all this, pip requirements are notoriously difficult to parse right\nin all their diversity because:\n\n- pip does not have a public API and therefore cannot be reliably used as a\n stable library. Some libraries attempt to do this though. (See Alternative)\n\n- The pip requirements file syntax is closely aligned with pip's command line\n interface and command line options. In some ways a pip requirements file is a\n list of pip command line options and arguments. Therefore, it is hard to parse\n these short of reproducing the pip command line options parsing. At least one\n other library is using a command line option parser to parse options correctly.\n\n\nThis ``pip-requirements-parser`` Python library is yet another pip requirements\nfiles parser, but this time doing it hopefully correctly and doing as well as\npip does it, because this is using pip's own code.\n\n\nThe ``pip-requirements-parser`` library offers these key advantages:\n\n- Other requirements parsers typically do not work in all the cases that ``pip``\n supports: parsing any requirement as seen in the wild will fail parsing some\n valid pip requirements. Since the ``pip-requirements-parser`` library is based\n on pip's own code, it works **exactly** like pip and will parse all the\n requirements files that pip can parse.\n\n- The ``pip-requirements-parser`` library offers a simple and stable code API\n that will not change without notice.\n\n- The ``pip-requirements-parser`` library is designed to work offline without\n making any external network call, while the original pip code needs network\n access.\n\n- The ``pip-requirements-parser`` library is a single file that can easily be\n copied around as needed for easy vendoring. This is useful as requirements\n parsing is often needed to bootstrap in a constrained environment.\n\n- The ``pip-requirements-parser`` library has only one external dependency on\n the common \"packaging\" package. Otherwise it uses only the standard library.\n The benefits are the same as being a single file: fewer moving parts helps with\n using it in more cases.\n\n- The ``pip-requirements-parser`` library reuses and passes the full subset of\n the pip test suite that deals with requirements. This is a not really\n surprising since this is pip's own code. The suite suite has been carefully\n ported and adjusted to work with the updated code subset.\n\n- The standard pip requirements parser depends on the ``requests`` HTTP library\n and makes network connection to PyPI and other referenced repositories when\n parsing. The ``pip-requirements-parser`` library works entirely offline and the\n requests dependency and calling has been entirely removed.\n\n- The ``pip-requirements-parser`` library has preserved the complete pip git\n history for the subset of the code we kept. The original pip code was merged\n from multiple modules keeping all the git history at the line/blame level using\n some git fu and git filter repo. The benefit is that we will be able to more\n easily track and merge future pip updates.\n\n- The ``pip-requirements-parser`` library has an extensive test suite made of:\n\n - pip's own tests\n - new unit tests\n - new requirements test files (over 40 new test files)\n - the tests suite of some of the main other requirement parsers including:\n\n - http://github.com/di/pip-api\n - https://github.com/pyupio/dparse\n - https://github.com/landscapeio/requirements-detector\n - https://github.com/madpah/requirements-parser\n\nAs a result, it has likely the most comprehensive requiremente parsing test\nsuite around.\n\n\nUsage\n~~~~~~~~~~\n\nThe entry point is the ``RequirementsFile`` object::\n\n >>> from pip_requirements_parser import RequirementsFile\n >>> rf = RequirementsFile.from_file(\"requirements.txt\")\n\nFrom there, you can dump to a dict::\n >>> rf.to_dict()\n\nOr access the requirements (either InstallRequirement or EditableRequirement\nobjects)::\n\n >>> for req in rf.requirements:\n ... print(req.to_dict())\n ... print(req.dumps())\n\nAnd the various other parsed elements such as options, commenst and invalid lines\nthat have a parsing error::\n\n >>> rf.options\n >>> rf.comment_lines\n >>> rf.invalid_lines\n\nEach of these and the ``requirements`` hahve a \"requirement_line\" attribute\nwith the original text.\n\nFinally you can get a requirements file back as a string::\n\n >>> rf.dumps()\n\n\nAlternative\n------------------\n\nThere are several other parsers that either:\n\n- Implement their own parsing and can therefore miss some subtle differences\n- Or wrap and import pip as a library, working around the lack of pip API\n\nNone of these use the approach of reusing and forking the subset of pip that is\nneeded to parse requirements. The ones that wrap pip require network access\nlike pip does. They potentially need updating each time there is a new pip\nrelease. The ones that reimplement pip parsing may not support all pip\nspecifics.\n\n\nImplement a new pip parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n- pip-api https://github.com/di/pip-api does not support hashes and certain pip options.\n It does however use argparse for parsing options and is therefore correctly\n handling most options. The parser is a single script that only depends on\n packaging (that is vendored). It is not designed to be used as a single script\n though and ``pip`` is a dependency.\n\n- requirements-parser https://github.com/madpah/requirements-parse does not\n support hashes and certain pip options\n\n- dparse https://github.com/pyupio/dparse\n\n- https://github.com/GoogleCloudPlatform/django-cloud-deploy/blob/d316b1e45357761e2b124143e6e12ce34ef6f975/django_cloud_deploy/skeleton/requirements_parser.py\n\n\nReuse and wrap pip's own parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n- requirementslib https://github.com/sarugaku/requirementslib uses pip-shim\n https://github.com/sarugaku/pip-shims which is a set of \"shims\" around each\n pip versions in an attempt to offer an API to pip. Comes with 20+ dependencies,\n\n- micropipenv https://github.com/thoth-station/micropipenv/blob/d0c37c1bf0aadf5149aebe2df0bf1cb12ded4c40/micropipenv.py#L53\n\n- pip-tools https://github.com/jazzband/pip-tools/blob/9e1be05375104c56e07cdb0904e1b50b86f8b550/piptools/_compat/pip_compat.py", - "release_date": "2022-01-28T13:21:39", - "parties": [ - { - "type": "person", - "role": "author", - "name": "The pip authors, nexB. Inc. and others", - "email": "info@aboutcode.org", - "url": null - } - ], - "keywords": [ - "utilities pip requirements parser dependencies pypi", - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Topic :: Software Development", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/nexB/pip-requirements-parser", - "download_url": "https://files.pythonhosted.org/packages/67/2e/94750665759e54b39c9c49eff98d9db1385896c7331b2e44e7c69eec3630/pip_requirements_parser-31.2.0-py3-none-any.whl", - "size": 33025, - "sha1": null, - "md5": "1bfb708322e90b0be35a848e63b67dd1", - "sha256": "22fa213a987913385b2484d5698ecfa1d9cf4154978cdf929085548af55355b0", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT" - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pip-requirements-parser/31.2.0/json", - "datasource_id": null, - "purl": "pkg:pypi/pip-requirements-parser@31.2.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "pip-requirements-parser", - "version": "31.2.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "pip requirements parser - a mostly correct pip requirements parsing library because it uses pip's own code.\npip-requirements-parser - a mostly correct pip requirements parsing library\n================================================================================\n\nCopyright (c) nexB Inc. and others.\nCopyright (c) The pip developers (see AUTHORS.rst file)\nSPDX-License-Identifier: MIT\nHomepage: https://github.com/nexB/pip-requirements and https://www.aboutcode.org/\n\n\n``pip-requirements-parser`` is a mostly correct pip requirements parsing\nlibrary ... because it uses pip's own code!\n\npip is the ``package installer`` for Python that is using \"requirements\" text\nfiles listing the packages to install.\n\nPer https://pip.pypa.io/en/stable/reference/requirements-file-format/ :\n\n \"The requirements file format is closely tied to a number of internal\n details of pip (e.g., pip\u2019s command line options). The basic format is\n relatively stable and portable but the full syntax, as described here,\n is only intended for consumption by pip, and other tools should take\n that into account before using it for their own purposes.\"\n\nAnd per https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program :\n\n \"[..] pip is a command line program. While it is implemented in Python, and\n so is available from your Python code via import pip, you must not use pip\u2019s\n internal APIs in this way.\"\n \n \"What this means in practice is that everything inside of pip is considered\n an implementation detail. Even the fact that the import name is pip is\n subject to change without notice. While we do try not to break things as\n much as possible, all the internal APIs can change at any time, for any\n reason. It also means that we generally won\u2019t fix issues that are a result\n of using pip in an unsupported way.\"\n\n\nBecause of all this, pip requirements are notoriously difficult to parse right\nin all their diversity because:\n\n- pip does not have a public API and therefore cannot be reliably used as a\n stable library. Some libraries attempt to do this though. (See Alternative)\n\n- The pip requirements file syntax is closely aligned with pip's command line\n interface and command line options. In some ways a pip requirements file is a\n list of pip command line options and arguments. Therefore, it is hard to parse\n these short of reproducing the pip command line options parsing. At least one\n other library is using a command line option parser to parse options correctly.\n\n\nThis ``pip-requirements-parser`` Python library is yet another pip requirements\nfiles parser, but this time doing it hopefully correctly and doing as well as\npip does it, because this is using pip's own code.\n\n\nThe ``pip-requirements-parser`` library offers these key advantages:\n\n- Other requirements parsers typically do not work in all the cases that ``pip``\n supports: parsing any requirement as seen in the wild will fail parsing some\n valid pip requirements. Since the ``pip-requirements-parser`` library is based\n on pip's own code, it works **exactly** like pip and will parse all the\n requirements files that pip can parse.\n\n- The ``pip-requirements-parser`` library offers a simple and stable code API\n that will not change without notice.\n\n- The ``pip-requirements-parser`` library is designed to work offline without\n making any external network call, while the original pip code needs network\n access.\n\n- The ``pip-requirements-parser`` library is a single file that can easily be\n copied around as needed for easy vendoring. This is useful as requirements\n parsing is often needed to bootstrap in a constrained environment.\n\n- The ``pip-requirements-parser`` library has only one external dependency on\n the common \"packaging\" package. Otherwise it uses only the standard library.\n The benefits are the same as being a single file: fewer moving parts helps with\n using it in more cases.\n\n- The ``pip-requirements-parser`` library reuses and passes the full subset of\n the pip test suite that deals with requirements. This is a not really\n surprising since this is pip's own code. The suite suite has been carefully\n ported and adjusted to work with the updated code subset.\n\n- The standard pip requirements parser depends on the ``requests`` HTTP library\n and makes network connection to PyPI and other referenced repositories when\n parsing. The ``pip-requirements-parser`` library works entirely offline and the\n requests dependency and calling has been entirely removed.\n\n- The ``pip-requirements-parser`` library has preserved the complete pip git\n history for the subset of the code we kept. The original pip code was merged\n from multiple modules keeping all the git history at the line/blame level using\n some git fu and git filter repo. The benefit is that we will be able to more\n easily track and merge future pip updates.\n\n- The ``pip-requirements-parser`` library has an extensive test suite made of:\n\n - pip's own tests\n - new unit tests\n - new requirements test files (over 40 new test files)\n - the tests suite of some of the main other requirement parsers including:\n\n - http://github.com/di/pip-api\n - https://github.com/pyupio/dparse\n - https://github.com/landscapeio/requirements-detector\n - https://github.com/madpah/requirements-parser\n\nAs a result, it has likely the most comprehensive requiremente parsing test\nsuite around.\n\n\nUsage\n~~~~~~~~~~\n\nThe entry point is the ``RequirementsFile`` object::\n\n >>> from pip_requirements_parser import RequirementsFile\n >>> rf = RequirementsFile.from_file(\"requirements.txt\")\n\nFrom there, you can dump to a dict::\n >>> rf.to_dict()\n\nOr access the requirements (either InstallRequirement or EditableRequirement\nobjects)::\n\n >>> for req in rf.requirements:\n ... print(req.to_dict())\n ... print(req.dumps())\n\nAnd the various other parsed elements such as options, commenst and invalid lines\nthat have a parsing error::\n\n >>> rf.options\n >>> rf.comment_lines\n >>> rf.invalid_lines\n\nEach of these and the ``requirements`` hahve a \"requirement_line\" attribute\nwith the original text.\n\nFinally you can get a requirements file back as a string::\n\n >>> rf.dumps()\n\n\nAlternative\n------------------\n\nThere are several other parsers that either:\n\n- Implement their own parsing and can therefore miss some subtle differences\n- Or wrap and import pip as a library, working around the lack of pip API\n\nNone of these use the approach of reusing and forking the subset of pip that is\nneeded to parse requirements. The ones that wrap pip require network access\nlike pip does. They potentially need updating each time there is a new pip\nrelease. The ones that reimplement pip parsing may not support all pip\nspecifics.\n\n\nImplement a new pip parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n- pip-api https://github.com/di/pip-api does not support hashes and certain pip options.\n It does however use argparse for parsing options and is therefore correctly\n handling most options. The parser is a single script that only depends on\n packaging (that is vendored). It is not designed to be used as a single script\n though and ``pip`` is a dependency.\n\n- requirements-parser https://github.com/madpah/requirements-parse does not\n support hashes and certain pip options\n\n- dparse https://github.com/pyupio/dparse\n\n- https://github.com/GoogleCloudPlatform/django-cloud-deploy/blob/d316b1e45357761e2b124143e6e12ce34ef6f975/django_cloud_deploy/skeleton/requirements_parser.py\n\n\nReuse and wrap pip's own parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n- requirementslib https://github.com/sarugaku/requirementslib uses pip-shim\n https://github.com/sarugaku/pip-shims which is a set of \"shims\" around each\n pip versions in an attempt to offer an API to pip. Comes with 20+ dependencies,\n\n- micropipenv https://github.com/thoth-station/micropipenv/blob/d0c37c1bf0aadf5149aebe2df0bf1cb12ded4c40/micropipenv.py#L53\n\n- pip-tools https://github.com/jazzband/pip-tools/blob/9e1be05375104c56e07cdb0904e1b50b86f8b550/piptools/_compat/pip_compat.py", - "release_date": "2022-01-28T13:21:42", - "parties": [ - { - "type": "person", - "role": "author", - "name": "The pip authors, nexB. Inc. and others", - "email": "info@aboutcode.org", - "url": null - } - ], - "keywords": [ - "utilities pip requirements parser dependencies pypi", - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Topic :: Software Development", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/nexB/pip-requirements-parser", - "download_url": "https://files.pythonhosted.org/packages/fc/aa/4fbc8040db7afae616eda6329ddc8ef73afc8bcb611bf9126937970bca83/pip-requirements-parser-31.2.0.tar.gz", - "size": 209659, - "sha1": null, - "md5": "a202d8dda5f2840181b80d4c81fa63d0", - "sha256": "8c2a6f8e091ac2693824a5ef4e3b250226e34f74a20a91a87b9ab0714b47788f", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT" - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pip-requirements-parser/31.2.0/json", - "datasource_id": null, - "purl": "pkg:pypi/pip-requirements-parser@31.2.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "pip", - "version": "24.0", - "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 :alt: PyPI\n\n.. image:: https://img.shields.io/pypi/pyversions/pip\n :target: https://pypi.org/project/pip\n :alt: PyPI - Python Version\n\n.. image:: https://readthedocs.org/projects/pip/badge/?version=latest\n :target: https://pip.pypa.io/en/latest\n :alt: Documentation\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\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 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 `PSF 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/installation/\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.. _Issue tracking: https://github.com/pypa/pip/issues\n.. _Discourse channel: https://discuss.python.org/c/packaging\n.. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa\n.. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md", - "release_date": "2024-02-03T09:53:09", - "parties": [ - { - "type": "person", - "role": "author", - "name": null, - "email": "The pip developers ", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Build Tools" - ], - "homepage_url": "", - "download_url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", - "size": 2110226, - "sha1": null, - "md5": "74e3c5e4082113b1239ca0e9abfd1e82", - "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/pypa/pip", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pip/24.0/json", - "datasource_id": null, - "purl": "pkg:pypi/pip@24.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "pip", - "version": "24.0", - "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 :alt: PyPI\n\n.. image:: https://img.shields.io/pypi/pyversions/pip\n :target: https://pypi.org/project/pip\n :alt: PyPI - Python Version\n\n.. image:: https://readthedocs.org/projects/pip/badge/?version=latest\n :target: https://pip.pypa.io/en/latest\n :alt: Documentation\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\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 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 `PSF 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/installation/\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.. _Issue tracking: https://github.com/pypa/pip/issues\n.. _Discourse channel: https://discuss.python.org/c/packaging\n.. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa\n.. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md", - "release_date": "2024-02-03T09:53:18", - "parties": [ - { - "type": "person", - "role": "author", - "name": null, - "email": "The pip developers ", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Build Tools" - ], - "homepage_url": "", - "download_url": "https://files.pythonhosted.org/packages/94/59/6638090c25e9bc4ce0c42817b5a234e183872a1129735a9330c472cc2056/pip-24.0.tar.gz", - "size": 2132709, - "sha1": null, - "md5": "1331aabb4d1a2677f493effeebda3605", - "sha256": "ea9bd1a847e8c5774a5777bb398c19e80bcd4e2aa16a4b301b718fe6f593aba2", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/pypa/pip", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pip/24.0/json", - "datasource_id": null, - "purl": "pkg:pypi/pip@24.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "pipdeptree", - "version": "2.2.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Command line utility to show dependency tree of packages\npipdeptree\n==========\n\n.. image:: https://github.com/naiquevin/pipdeptree/workflows/check/badge.svg\n :target: https://github.com/naiquevin/pipdeptree/actions\n\n\n``pipdeptree`` is a command line utility for displaying the installed\npython packages in form of a dependency tree. It works for packages\ninstalled globally on a machine as well as in a virtualenv. Since\n``pip freeze`` shows all dependencies as a flat list, finding out\nwhich are the top level packages and which packages do they depend on\nrequires some effort. It's also tedious to resolve conflicting\ndependencies that could have been installed because older version of\n``pip`` didn't have true dependency resolution [1]_. ``pipdeptree``\ncan help here by identifying conflicting dependencies installed in the\nenvironment.\n\nTo some extent, ``pipdeptree`` is inspired by the ``lein deps :tree``\ncommand of `Leiningen `_.\n\n\nInstallation\n------------\n\n.. code-block:: bash\n\n $ pip install pipdeptree\n\npipdeptree has been tested with Python versions ``2.7``, ``3.5``,\n``3.6``, ``3.7``, ``3.8``, ``3.9`` as well as ``pypy2`` and ``pypy3``.\n\nPython ``2.6`` is way past it's end of life but if you ever find\nyourself stuck on a legacy environment, version ``0.9.0`` *might*\nwork.\n\n\nRunning in virtualenvs\n----------------------\n\n`New in ver. 2.0.0`\n\nIf you want to run pipdeptree in the context of a particular\nvirtualenv, you can specify the ``--python`` option. Note that this\ncapability has been recently added in version ``2.0.0``.\n\nAlternately, you may also install pipdeptree inside the virtualenv and\nthen run it from there.\n\n\nUsage and examples\n------------------\n\nTo give you a brief idea, here is the output of ``pipdeptree``\ncompared with ``pip freeze``:\n\n.. code-block:: bash\n\n $ pip freeze\n Flask==0.10.1\n itsdangerous==0.24\n Jinja2==2.11.2\n -e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy\n MarkupSafe==0.22\n pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl\n Werkzeug==0.11.2\n\nAnd now see what ``pipdeptree`` outputs,\n\n.. code-block:: bash\n\n $ pipdeptree\n Warning!!! Possibly conflicting dependencies found:\n * Jinja2==2.11.2\n - MarkupSafe [required: >=0.23, installed: 0.22]\n ------------------------------------------------------------------------\n Flask==0.10.1\n - itsdangerous [required: >=0.21, installed: 0.24]\n - Jinja2 [required: >=2.4, installed: 2.11.2]\n - MarkupSafe [required: >=0.23, installed: 0.22]\n - Werkzeug [required: >=0.7, installed: 0.11.2]\n Lookupy==0.1\n pipdeptree==2.0.0b1\n - pip [required: >=6.0.0, installed: 20.1.1]\n setuptools==47.1.1\n wheel==0.34.2\n\n\nIs it possible to find out why a particular package is installed?\n-----------------------------------------------------------------\n\n`New in ver. 0.5.0`\n\nYes, there's a ``--reverse`` (or simply ``-r``) flag for this. To find\nout which packages depend on a particular package(s), it can be\ncombined with ``--packages`` option as follows:\n\n.. code-block:: bash\n\n $ pipdeptree --reverse --packages itsdangerous,MarkupSafe\n Warning!!! Possibly conflicting dependencies found:\n * Jinja2==2.11.2\n - MarkupSafe [required: >=0.23, installed: 0.22]\n ------------------------------------------------------------------------\n itsdangerous==0.24\n - Flask==0.10.1 [requires: itsdangerous>=0.21]\n MarkupSafe==0.22\n - Jinja2==2.11.2 [requires: MarkupSafe>=0.23]\n - Flask==0.10.1 [requires: Jinja2>=2.4]\n\n\nWhat's with the warning about conflicting dependencies?\n-------------------------------------------------------\n\nAs seen in the above output, ``pipdeptree`` by default warns about\npossible conflicting dependencies. Any package that's specified as a\ndependency of multiple packages with different versions is considered\nas a conflicting dependency. Conflicting dependencies are possible if\nolder version of pip<=20.2 (`without the new resolver\n`_ [1]_) was ever used to\ninstall dependencies at some point. The warning is printed to stderr\ninstead of stdout and it can be completely silenced by specifying the\n``-w silence`` or ``--warn silence`` option. On the other hand, it can\nbe made mode strict with ``--warn fail``, in which case the command\nwill not only print the warnings to stderr but also exit with a\nnon-zero status code. This is useful if you want to fit this tool into\nyour CI pipeline.\n\n**Note**: The ``--warn`` option is added in version ``0.6.0``. If you\nare using an older version, use ``--nowarn`` flag to silence the\nwarnings.\n\n\nWarnings about circular dependencies\n------------------------------------\n\nIn case any of the packages have circular dependencies (eg. package A\ndepends on package B and package B depends on package A), then\n``pipdeptree`` will print warnings about that as well.\n\n.. code-block:: bash\n\n $ pipdeptree --exclude pip,pipdeptree,setuptools,wheel\n Warning!!! Cyclic dependencies found:\n - CircularDependencyA => CircularDependencyB => CircularDependencyA\n - CircularDependencyB => CircularDependencyA => CircularDependencyB\n ------------------------------------------------------------------------\n wsgiref==0.1.2\n argparse==1.2.1\n\nSimilar to the warnings about conflicting dependencies, these too are\nprinted to stderr and can be controlled using the ``--warn`` option.\n\nIn the above example, you can also see ``--exclude`` option which is\nthe opposite of ``--packages`` ie. these packages will be excluded\nfrom the output.\n\n\nUsing pipdeptree to write requirements.txt file\n-----------------------------------------------\n\nIf you wish to track only top level packages in your\n``requirements.txt`` file, it's possible by grep-ing [2]_. only the\ntop-level lines from the output,\n\n.. code-block:: bash\n\n $ pipdeptree --warn silence | grep -E '^\\w+'\n Flask==0.10.1\n gnureadline==8.0.0\n Lookupy==0.1\n pipdeptree==2.0.0b1\n setuptools==47.1.1\n wheel==0.34.2\n\nThere is a problem here though - The output doesn't mention anything\nabout ``Lookupy`` being installed as an *editable* package (refer to\nthe output of ``pip freeze`` above) and information about its source\nis lost. To fix this, ``pipdeptree`` must be run with a ``-f`` or\n``--freeze`` flag.\n\n.. code-block:: bash\n\n $ pipdeptree -f --warn silence | grep -E '^[a-zA-Z0-9\\-]+'\n Flask==0.10.1\n gnureadline==8.0.0\n -e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy\n pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl\n setuptools==47.1.1\n wheel==0.34.2\n\n $ pipdeptree -f --warn silence | grep -E '^[a-zA-Z0-9\\-]+' > requirements.txt\n\nThe freeze flag will not prefix child dependencies with hyphens, so\nyou could dump the entire output of ``pipdeptree -f`` to the\nrequirements.txt file thus making it human-friendly (due to\nindentations) as well as pip-friendly.\n\n.. code-block:: bash\n\n $ pipdeptree -f | tee locked-requirements.txt\n Flask==0.10.1\n itsdangerous==0.24\n Jinja2==2.11.2\n MarkupSafe==0.23\n Werkzeug==0.11.2\n gnureadline==8.0.0\n -e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy\n pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl\n pip==20.1.1\n setuptools==47.1.1\n wheel==0.34.2\n\nOn confirming that there are no conflicting dependencies, you can even\ntreat this as a \"lock file\" where all packages, including the\ntransient dependencies will be pinned to their currently installed\nversions. Note that the ``locked-requirements.txt`` file could end up\nwith duplicate entries. Although ``pip install`` wouldn't complain\nabout that, you can avoid duplicate lines (at the cost of losing\nindentation) as follows,\n\n.. code-block:: bash\n\n $ pipdeptree -f | sed 's/ //g' | sort -u > locked-requirements.txt\n\n\nUsing pipdeptree with external tools\n------------------------------------\n\n`New in ver. 0.5.0`\n\nIt's also possible to have ``pipdeptree`` output json representation\nof the dependency tree so that it may be used as input to other\nexternal tools.\n\n.. code-block:: bash\n\n $ pipdeptree --json\n\nNote that ``--json`` will output a flat list of all packages with\ntheir immediate dependencies. This is not very useful in itself. To\nobtain nested json, use ``--json-tree``\n\n`New in ver. 0.11.0`\n\n.. code-block:: bash\n\n $ pipdeptree --json-tree\n\n\nVisualizing the dependency graph\n--------------------------------\n\n.. image:: https://raw.githubusercontent.com/naiquevin/pipdeptree/master/docs/twine-pdt.png\n\nThe dependency graph can also be visualized using `GraphViz\n`_:\n\n.. code-block:: bash\n\n $ pipdeptree --graph-output dot > dependencies.dot\n $ pipdeptree --graph-output pdf > dependencies.pdf\n $ pipdeptree --graph-output png > dependencies.png\n $ pipdeptree --graph-output svg > dependencies.svg\n\nNote that ``graphviz`` is an optional dependency ie. required only if\nyou want to use ``--graph-output``. If the version of ``graphviz``\ninstalled in the env is older than 0.18.1, then a warning will be\ndisplayed about upgrading ``graphviz``. Support for older versions of\ngraphviz will be dropped soon.\n\nSince version ``2.0.0b1``, ``--package`` and ``--reverse`` flags are\nsupported for all output formats ie. text, json, json-tree and graph.\n\nIn earlier versions, ``--json``, ``--json-tree`` and\n``--graph-output`` options override ``--package`` and ``--reverse``.\n\n\nUsage\n-----\n\n.. code-block:: bash\n\n usage: pipdeptree.py [-h] [-v] [-f] [--python PYTHON] [-a] [-l] [-u]\n [-w [{silence,suppress,fail}]] [-r] [-p PACKAGES]\n [-e PACKAGES] [-j] [--json-tree]\n [--graph-output OUTPUT_FORMAT]\n\n Dependency tree of the installed python packages\n\n optional arguments:\n -h, --help show this help message and exit\n -v, --version show program's version number and exit\n -f, --freeze Print names so as to write freeze files\n --python PYTHON Python to use to look for packages in it (default:\n where installed)\n -a, --all list all deps at top level\n -l, --local-only If in a virtualenv that has global access do not show\n globally installed packages\n -u, --user-only Only show installations in the user site dir\n -w [{silence,suppress,fail}], --warn [{silence,suppress,fail}]\n Warning control. \"suppress\" will show warnings but\n return 0 whether or not they are present. \"silence\"\n will not show warnings at all and always return 0.\n \"fail\" will show warnings and return 1 if any are\n present. The default is \"suppress\".\n -r, --reverse Shows the dependency tree in the reverse fashion ie.\n the sub-dependencies are listed with the list of\n packages that need them under them.\n -p PACKAGES, --packages PACKAGES\n Comma separated list of select packages to show in the\n output. If set, --all will be ignored.\n -e PACKAGES, --exclude PACKAGES\n Comma separated list of select packages to exclude\n from the output. If set, --all will be ignored.\n -j, --json Display dependency tree as json. This will yield \"raw\"\n output that may be used by external tools. This option\n overrides all other options.\n --json-tree Display dependency tree as json which is nested the\n same way as the plain text output printed by default.\n This option overrides all other options (except\n --json).\n --graph-output OUTPUT_FORMAT\n Print a dependency graph in the specified output\n format. Available are all formats supported by\n GraphViz, e.g.: dot, jpeg, pdf, png, svg\n\nKnown issues\n------------\n\n1. ``pipdeptree`` relies on the internal API of ``pip``. I fully\n understand that it's a bad idea but it mostly works! On rare\n occasions, it breaks when a new version of ``pip`` is out with\n backward incompatible changes in internal API. So beware if you are\n using this tool in environments in which ``pip`` version is\n unpinned, specially automation or CD/CI pipelines.\n\n\nLimitations & Alternatives\n--------------------------\n\n``pipdeptree`` merely looks at the installed packages in the current\nenvironment using pip, constructs the tree, then outputs it in the\nspecified format. If you want to generate the dependency tree without\ninstalling the packages, then you need a dependency resolver. You\nmight want to check alternatives such as `pipgrip\n`_ or `poetry\n`_.\n\n\nRuning Tests (for contributors)\n-------------------------------\n\nThere are 2 test suites in this repo:\n\n1. Unit tests that use mock objects. These are configured to run on\n every push to the repo and on every PR thanks to Github Actions.\n\n2. End-to-end tests that are run against actual packages installed in\n virtualenvs\n\nUnit tests can be run against all version of python using `tox\n`_ as follows:\n\n.. code-block:: bash\n\n $ make test-tox-all\n\nThis assumes that you have python versions specified in the\n``tox.ini`` file.\n\nIf you don't want to install all the versions of python but want to\nrun tests quickly against ``Python3.6`` only:\n\n.. code-block:: bash\n\n $ make test\n\nUnit tests are written using ``pytest`` and you can also run the tests\nwith code coverage as follows,\n\n.. code-block:: bash\n\n $ make test-cov\n\nOn the other hand, end-to-end tests actually create virtualenvs,\ninstall packages and then run tests against them. These tests are more\nreliable in the sense that they also test ``pipdeptree`` with the\nlatest version of ``pip`` and ``setuptools``.\n\nThe downside is that when new versions of ``pip`` or ``setuptools``\nare released, these need to be updated. At present the process is\nmanual but I have plans to setup nightly builds for these for faster\nfeedback.\n\nThe end-to-end tests can be run as follows,\n\n.. code-block:: bash\n\n $ make test-e2e # starts with a clean virtualenvs\n\n $ # or\n\n $ make test-e2e-quick # reuses existing virtualenvs\n\nBy default the e2e tests uses python executable ``python3.6``. To use\nan alternate version set the environment var ``E2E_PYTHON_EXE``.\n\n.. code-block:: bash\n\n $ E2E_PYTHON_EXE=python2.7 make test-e2e\n\n\nRelease checklist\n-----------------\n\n#. Make sure that tests pass on Github Actions.\n#. Create a commit with following changes and push it to github\n#. Update the `__version__` in the `pipdeptree.py` file.\n\n #. Add Changelog in `CHANGES.md` file.\n #. Also update `README.md` if required.\n#. Create an annotated tag on the above commit and push the tag to\n github\n#. Upload new version to PyPI.\n\n\nLicense\n-------\n\nMIT (See `LICENSE <./LICENSE>`_)\n\nFootnotes\n---------\n\n.. [1] pip version 20.3 has been released in Nov 2020 with the\n dependency resolver\n _\n\n.. [2] If you are on windows (powershell) you can run\n ``pipdeptree --warn silence | Select-String -Pattern '^\\w+'``\n instead of grep", - "release_date": "2022-01-09T06:14:38", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Vineet Naik", - "email": "naikvin@gmail.com", - "url": null - } - ], - "keywords": [ - "Environment :: Console", - "Intended Audience :: Developers", - "Programming Language :: Python", - "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 :: 3.9" - ], - "homepage_url": "https://github.com/naiquevin/pipdeptree", - "download_url": "https://files.pythonhosted.org/packages/e8/aa/e494d9f1027d2ef599c25ec03ec7e2e15d9e37748ebfded013fc3696d939/pipdeptree-2.2.1-py3-none-any.whl", - "size": 21915, - "sha1": null, - "md5": "2fb740f7fb0720fb3c2567d78d409051", - "sha256": "e20655a38d6e363d8e86d6a85e8a648680a3f4b6d039d6ee3ab0f539da1ad6ce", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT License", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pipdeptree/2.2.1/json", - "datasource_id": null, - "purl": "pkg:pypi/pipdeptree@2.2.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "pipdeptree", - "version": "2.2.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Command line utility to show dependency tree of packages\npipdeptree\n==========\n\n.. image:: https://github.com/naiquevin/pipdeptree/workflows/check/badge.svg\n :target: https://github.com/naiquevin/pipdeptree/actions\n\n\n``pipdeptree`` is a command line utility for displaying the installed\npython packages in form of a dependency tree. It works for packages\ninstalled globally on a machine as well as in a virtualenv. Since\n``pip freeze`` shows all dependencies as a flat list, finding out\nwhich are the top level packages and which packages do they depend on\nrequires some effort. It's also tedious to resolve conflicting\ndependencies that could have been installed because older version of\n``pip`` didn't have true dependency resolution [1]_. ``pipdeptree``\ncan help here by identifying conflicting dependencies installed in the\nenvironment.\n\nTo some extent, ``pipdeptree`` is inspired by the ``lein deps :tree``\ncommand of `Leiningen `_.\n\n\nInstallation\n------------\n\n.. code-block:: bash\n\n $ pip install pipdeptree\n\npipdeptree has been tested with Python versions ``2.7``, ``3.5``,\n``3.6``, ``3.7``, ``3.8``, ``3.9`` as well as ``pypy2`` and ``pypy3``.\n\nPython ``2.6`` is way past it's end of life but if you ever find\nyourself stuck on a legacy environment, version ``0.9.0`` *might*\nwork.\n\n\nRunning in virtualenvs\n----------------------\n\n`New in ver. 2.0.0`\n\nIf you want to run pipdeptree in the context of a particular\nvirtualenv, you can specify the ``--python`` option. Note that this\ncapability has been recently added in version ``2.0.0``.\n\nAlternately, you may also install pipdeptree inside the virtualenv and\nthen run it from there.\n\n\nUsage and examples\n------------------\n\nTo give you a brief idea, here is the output of ``pipdeptree``\ncompared with ``pip freeze``:\n\n.. code-block:: bash\n\n $ pip freeze\n Flask==0.10.1\n itsdangerous==0.24\n Jinja2==2.11.2\n -e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy\n MarkupSafe==0.22\n pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl\n Werkzeug==0.11.2\n\nAnd now see what ``pipdeptree`` outputs,\n\n.. code-block:: bash\n\n $ pipdeptree\n Warning!!! Possibly conflicting dependencies found:\n * Jinja2==2.11.2\n - MarkupSafe [required: >=0.23, installed: 0.22]\n ------------------------------------------------------------------------\n Flask==0.10.1\n - itsdangerous [required: >=0.21, installed: 0.24]\n - Jinja2 [required: >=2.4, installed: 2.11.2]\n - MarkupSafe [required: >=0.23, installed: 0.22]\n - Werkzeug [required: >=0.7, installed: 0.11.2]\n Lookupy==0.1\n pipdeptree==2.0.0b1\n - pip [required: >=6.0.0, installed: 20.1.1]\n setuptools==47.1.1\n wheel==0.34.2\n\n\nIs it possible to find out why a particular package is installed?\n-----------------------------------------------------------------\n\n`New in ver. 0.5.0`\n\nYes, there's a ``--reverse`` (or simply ``-r``) flag for this. To find\nout which packages depend on a particular package(s), it can be\ncombined with ``--packages`` option as follows:\n\n.. code-block:: bash\n\n $ pipdeptree --reverse --packages itsdangerous,MarkupSafe\n Warning!!! Possibly conflicting dependencies found:\n * Jinja2==2.11.2\n - MarkupSafe [required: >=0.23, installed: 0.22]\n ------------------------------------------------------------------------\n itsdangerous==0.24\n - Flask==0.10.1 [requires: itsdangerous>=0.21]\n MarkupSafe==0.22\n - Jinja2==2.11.2 [requires: MarkupSafe>=0.23]\n - Flask==0.10.1 [requires: Jinja2>=2.4]\n\n\nWhat's with the warning about conflicting dependencies?\n-------------------------------------------------------\n\nAs seen in the above output, ``pipdeptree`` by default warns about\npossible conflicting dependencies. Any package that's specified as a\ndependency of multiple packages with different versions is considered\nas a conflicting dependency. Conflicting dependencies are possible if\nolder version of pip<=20.2 (`without the new resolver\n`_ [1]_) was ever used to\ninstall dependencies at some point. The warning is printed to stderr\ninstead of stdout and it can be completely silenced by specifying the\n``-w silence`` or ``--warn silence`` option. On the other hand, it can\nbe made mode strict with ``--warn fail``, in which case the command\nwill not only print the warnings to stderr but also exit with a\nnon-zero status code. This is useful if you want to fit this tool into\nyour CI pipeline.\n\n**Note**: The ``--warn`` option is added in version ``0.6.0``. If you\nare using an older version, use ``--nowarn`` flag to silence the\nwarnings.\n\n\nWarnings about circular dependencies\n------------------------------------\n\nIn case any of the packages have circular dependencies (eg. package A\ndepends on package B and package B depends on package A), then\n``pipdeptree`` will print warnings about that as well.\n\n.. code-block:: bash\n\n $ pipdeptree --exclude pip,pipdeptree,setuptools,wheel\n Warning!!! Cyclic dependencies found:\n - CircularDependencyA => CircularDependencyB => CircularDependencyA\n - CircularDependencyB => CircularDependencyA => CircularDependencyB\n ------------------------------------------------------------------------\n wsgiref==0.1.2\n argparse==1.2.1\n\nSimilar to the warnings about conflicting dependencies, these too are\nprinted to stderr and can be controlled using the ``--warn`` option.\n\nIn the above example, you can also see ``--exclude`` option which is\nthe opposite of ``--packages`` ie. these packages will be excluded\nfrom the output.\n\n\nUsing pipdeptree to write requirements.txt file\n-----------------------------------------------\n\nIf you wish to track only top level packages in your\n``requirements.txt`` file, it's possible by grep-ing [2]_. only the\ntop-level lines from the output,\n\n.. code-block:: bash\n\n $ pipdeptree --warn silence | grep -E '^\\w+'\n Flask==0.10.1\n gnureadline==8.0.0\n Lookupy==0.1\n pipdeptree==2.0.0b1\n setuptools==47.1.1\n wheel==0.34.2\n\nThere is a problem here though - The output doesn't mention anything\nabout ``Lookupy`` being installed as an *editable* package (refer to\nthe output of ``pip freeze`` above) and information about its source\nis lost. To fix this, ``pipdeptree`` must be run with a ``-f`` or\n``--freeze`` flag.\n\n.. code-block:: bash\n\n $ pipdeptree -f --warn silence | grep -E '^[a-zA-Z0-9\\-]+'\n Flask==0.10.1\n gnureadline==8.0.0\n -e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy\n pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl\n setuptools==47.1.1\n wheel==0.34.2\n\n $ pipdeptree -f --warn silence | grep -E '^[a-zA-Z0-9\\-]+' > requirements.txt\n\nThe freeze flag will not prefix child dependencies with hyphens, so\nyou could dump the entire output of ``pipdeptree -f`` to the\nrequirements.txt file thus making it human-friendly (due to\nindentations) as well as pip-friendly.\n\n.. code-block:: bash\n\n $ pipdeptree -f | tee locked-requirements.txt\n Flask==0.10.1\n itsdangerous==0.24\n Jinja2==2.11.2\n MarkupSafe==0.23\n Werkzeug==0.11.2\n gnureadline==8.0.0\n -e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy\n pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl\n pip==20.1.1\n setuptools==47.1.1\n wheel==0.34.2\n\nOn confirming that there are no conflicting dependencies, you can even\ntreat this as a \"lock file\" where all packages, including the\ntransient dependencies will be pinned to their currently installed\nversions. Note that the ``locked-requirements.txt`` file could end up\nwith duplicate entries. Although ``pip install`` wouldn't complain\nabout that, you can avoid duplicate lines (at the cost of losing\nindentation) as follows,\n\n.. code-block:: bash\n\n $ pipdeptree -f | sed 's/ //g' | sort -u > locked-requirements.txt\n\n\nUsing pipdeptree with external tools\n------------------------------------\n\n`New in ver. 0.5.0`\n\nIt's also possible to have ``pipdeptree`` output json representation\nof the dependency tree so that it may be used as input to other\nexternal tools.\n\n.. code-block:: bash\n\n $ pipdeptree --json\n\nNote that ``--json`` will output a flat list of all packages with\ntheir immediate dependencies. This is not very useful in itself. To\nobtain nested json, use ``--json-tree``\n\n`New in ver. 0.11.0`\n\n.. code-block:: bash\n\n $ pipdeptree --json-tree\n\n\nVisualizing the dependency graph\n--------------------------------\n\n.. image:: https://raw.githubusercontent.com/naiquevin/pipdeptree/master/docs/twine-pdt.png\n\nThe dependency graph can also be visualized using `GraphViz\n`_:\n\n.. code-block:: bash\n\n $ pipdeptree --graph-output dot > dependencies.dot\n $ pipdeptree --graph-output pdf > dependencies.pdf\n $ pipdeptree --graph-output png > dependencies.png\n $ pipdeptree --graph-output svg > dependencies.svg\n\nNote that ``graphviz`` is an optional dependency ie. required only if\nyou want to use ``--graph-output``. If the version of ``graphviz``\ninstalled in the env is older than 0.18.1, then a warning will be\ndisplayed about upgrading ``graphviz``. Support for older versions of\ngraphviz will be dropped soon.\n\nSince version ``2.0.0b1``, ``--package`` and ``--reverse`` flags are\nsupported for all output formats ie. text, json, json-tree and graph.\n\nIn earlier versions, ``--json``, ``--json-tree`` and\n``--graph-output`` options override ``--package`` and ``--reverse``.\n\n\nUsage\n-----\n\n.. code-block:: bash\n\n usage: pipdeptree.py [-h] [-v] [-f] [--python PYTHON] [-a] [-l] [-u]\n [-w [{silence,suppress,fail}]] [-r] [-p PACKAGES]\n [-e PACKAGES] [-j] [--json-tree]\n [--graph-output OUTPUT_FORMAT]\n\n Dependency tree of the installed python packages\n\n optional arguments:\n -h, --help show this help message and exit\n -v, --version show program's version number and exit\n -f, --freeze Print names so as to write freeze files\n --python PYTHON Python to use to look for packages in it (default:\n where installed)\n -a, --all list all deps at top level\n -l, --local-only If in a virtualenv that has global access do not show\n globally installed packages\n -u, --user-only Only show installations in the user site dir\n -w [{silence,suppress,fail}], --warn [{silence,suppress,fail}]\n Warning control. \"suppress\" will show warnings but\n return 0 whether or not they are present. \"silence\"\n will not show warnings at all and always return 0.\n \"fail\" will show warnings and return 1 if any are\n present. The default is \"suppress\".\n -r, --reverse Shows the dependency tree in the reverse fashion ie.\n the sub-dependencies are listed with the list of\n packages that need them under them.\n -p PACKAGES, --packages PACKAGES\n Comma separated list of select packages to show in the\n output. If set, --all will be ignored.\n -e PACKAGES, --exclude PACKAGES\n Comma separated list of select packages to exclude\n from the output. If set, --all will be ignored.\n -j, --json Display dependency tree as json. This will yield \"raw\"\n output that may be used by external tools. This option\n overrides all other options.\n --json-tree Display dependency tree as json which is nested the\n same way as the plain text output printed by default.\n This option overrides all other options (except\n --json).\n --graph-output OUTPUT_FORMAT\n Print a dependency graph in the specified output\n format. Available are all formats supported by\n GraphViz, e.g.: dot, jpeg, pdf, png, svg\n\nKnown issues\n------------\n\n1. ``pipdeptree`` relies on the internal API of ``pip``. I fully\n understand that it's a bad idea but it mostly works! On rare\n occasions, it breaks when a new version of ``pip`` is out with\n backward incompatible changes in internal API. So beware if you are\n using this tool in environments in which ``pip`` version is\n unpinned, specially automation or CD/CI pipelines.\n\n\nLimitations & Alternatives\n--------------------------\n\n``pipdeptree`` merely looks at the installed packages in the current\nenvironment using pip, constructs the tree, then outputs it in the\nspecified format. If you want to generate the dependency tree without\ninstalling the packages, then you need a dependency resolver. You\nmight want to check alternatives such as `pipgrip\n`_ or `poetry\n`_.\n\n\nRuning Tests (for contributors)\n-------------------------------\n\nThere are 2 test suites in this repo:\n\n1. Unit tests that use mock objects. These are configured to run on\n every push to the repo and on every PR thanks to Github Actions.\n\n2. End-to-end tests that are run against actual packages installed in\n virtualenvs\n\nUnit tests can be run against all version of python using `tox\n`_ as follows:\n\n.. code-block:: bash\n\n $ make test-tox-all\n\nThis assumes that you have python versions specified in the\n``tox.ini`` file.\n\nIf you don't want to install all the versions of python but want to\nrun tests quickly against ``Python3.6`` only:\n\n.. code-block:: bash\n\n $ make test\n\nUnit tests are written using ``pytest`` and you can also run the tests\nwith code coverage as follows,\n\n.. code-block:: bash\n\n $ make test-cov\n\nOn the other hand, end-to-end tests actually create virtualenvs,\ninstall packages and then run tests against them. These tests are more\nreliable in the sense that they also test ``pipdeptree`` with the\nlatest version of ``pip`` and ``setuptools``.\n\nThe downside is that when new versions of ``pip`` or ``setuptools``\nare released, these need to be updated. At present the process is\nmanual but I have plans to setup nightly builds for these for faster\nfeedback.\n\nThe end-to-end tests can be run as follows,\n\n.. code-block:: bash\n\n $ make test-e2e # starts with a clean virtualenvs\n\n $ # or\n\n $ make test-e2e-quick # reuses existing virtualenvs\n\nBy default the e2e tests uses python executable ``python3.6``. To use\nan alternate version set the environment var ``E2E_PYTHON_EXE``.\n\n.. code-block:: bash\n\n $ E2E_PYTHON_EXE=python2.7 make test-e2e\n\n\nRelease checklist\n-----------------\n\n#. Make sure that tests pass on Github Actions.\n#. Create a commit with following changes and push it to github\n#. Update the `__version__` in the `pipdeptree.py` file.\n\n #. Add Changelog in `CHANGES.md` file.\n #. Also update `README.md` if required.\n#. Create an annotated tag on the above commit and push the tag to\n github\n#. Upload new version to PyPI.\n\n\nLicense\n-------\n\nMIT (See `LICENSE <./LICENSE>`_)\n\nFootnotes\n---------\n\n.. [1] pip version 20.3 has been released in Nov 2020 with the\n dependency resolver\n _\n\n.. [2] If you are on windows (powershell) you can run\n ``pipdeptree --warn silence | Select-String -Pattern '^\\w+'``\n instead of grep", - "release_date": "2022-01-09T06:14:41", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Vineet Naik", - "email": "naikvin@gmail.com", - "url": null - } - ], - "keywords": [ - "Environment :: Console", - "Intended Audience :: Developers", - "Programming Language :: Python", - "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 :: 3.9" - ], - "homepage_url": "https://github.com/naiquevin/pipdeptree", - "download_url": "https://files.pythonhosted.org/packages/9e/c0/2ca9cb24d8045a1c84bdeca2b2646fcf438266a930301a7672c4cb8d0ff9/pipdeptree-2.2.1.tar.gz", - "size": 22430, - "sha1": null, - "md5": "05cab13fbae0ebb7015a6ce6757000e7", - "sha256": "2b97d80c64d229e01ad242f14229a899263c6e8645c588ec5b054c1b81f3065d", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT License", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pipdeptree/2.2.1/json", - "datasource_id": null, - "purl": "pkg:pypi/pipdeptree@2.2.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "pkginfo2", - "version": "30.0.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Query metadatdata from sdists / bdists / installed packages. Safer fork of pkginfo to avoid doing arbitrary imports and eval()\n``pkginfo2`` README\n=====================\n\nHomepage URL: https://github.com/nexB/pkginfo2\nSPDX-License-Identifier: MIT\n\nThis package provides an API for querying the distutils metadata written in\nthe ``PKG-INFO`` file inside a source distriubtion (an ``sdist``) or a\nbinary distribution or a wheel (e.g., created by running ``bdist_egg``). It can\nalso query the ``EGG-INFO`` directory of an installed distribution, and\nthe ``*.egg-info`` stored in a \"development checkout\"\n(e.g, created by running ``setup.py develop``), or the ``*.dist-info`` from\nan as-installed package.\n\nThis is a fork of http://bazaar.launchpad.net/~tseaver/pkginfo removing the\nability to import and eval arbitrary code and work with modules known to the\ncurrent interpreter. Use importlib_metadata for this if you need it.\n\n\nPlease see the `pkginfo2 repo at `_\nfor more documentation.\n\n\n``pkginfo2`` Changelog\n=======================\n\n30.0.0 (2022-01-28)\n--------------------\n\n- Forked and rename to pkginfo2. Removed ability to import or eval packages\n or modules.\n- Move the bzr history to git\n\n1.8.2 (2021-12-01)\n------------------\n\n- Add fix for installed distributions with '__package__' set to an empty\n string. LP #1952946.\n\n1.8.1 (2021-11-19)\n------------------\n\n- Add 'MANIFEST.in' to ensure example files used by tests are included\n in source distributions. LP #1951553.\n\n1.8.0 (2021-11-18)\n------------------\n\n- Support new standard metadata location for installed dists. LP #1865286.\n\n- Don't overwrite header-based 'description' with empty payload. LP #1885458.\n\n- Add support for Metadata-Version 2.2. LP #1928729.\n\n- Add support for uncompressed tarballs for sdists. LP #1951457.\n\n- Add support for Python 3.10.\n\n1.7.1 (2021-07-09)\n------------------\n\n- Use Python3 to build docs, and fix doctest examples to use Python3-\n compatible syntax. LP #1933322.\n\n1.7.0 (2021-01-16)\n------------------\n\n- Add support for Python 3.9.\n\n- Drop support for Python 3.5.\n\n1.6.1 (2020-10-26)\n------------------\n\n- Adjust test classifiers to match supported Python versions. LP #1901127.\n\n1.6.0 (2020-10-20)\n------------------\n\n- Add support for Python 3.8.\n LP #1869854.\n\n- Drop support for Python 3.4.\n\n- Update tests to match setuptools' change, no longer reporting metadata\n version for installed packages w/o explicit metadata. LP #1870197.\n\n1.5.0.1 (2019-01-08)\n--------------------\n\n- Fix broken 'sdist'. LP #1639585.\n\n1.5.0 (2019-01-07)\n------------------\n\n- Fix 'console_scripts' entry point syntax. LP #1810734.\n\n- Add support for JSON output from the CLI. LP #1700580.\n\n- Add support for installed wheels. E.g., 'dist-info/' dirs. LP #1700200.\n\n- Harden metadata extraction against unexpected encodings. LP #1780454.\n\n- Update tests to match pip/setuptools' use of new metadata version.\n LP #1772274.\n\n- Add support for Python 3.6 and 3.7.\n\n- Drop support for Python 3.3.\n\n1.4.2 (2018-03-14)\n------------------\n\n- Use relative imports in pkginfo modules. Supports vendoring of the\n package into setuptools.\n\n- Add support for ``Provides-Extra`` and ``Description-Content-Type`` fields.\n Per https://packaging.python.org/specifications/. See: PEP 566.\n\n- Remove support for old setuptools leaving ``PKG-INFO`` in the root of\n the project directory.\n\n1.4.1 (2016-11-07)\n------------------\n\n- Packaging only change (invalid sdist built for 1.4.0).\n\n1.4.0 (2016-11-04)\n------------------\n\n- Relicense under MIT license: the PSF license is not suitable for\n third-party libraries.\n\n1.3.2 (2016-05-24)\n------------------\n\n- Packaging-only change (automate fix for wheel built for 1.3.1).\n\n1.3.1 (2016-05-24)\n------------------\n\n- Packaging-only change (invalid wheel built for 1.3.0).\n\n1.3.0 (2016-05-23)\n------------------\n\n- Update homepage URL to point to Launchpad, rather than PyPI.\n\n- Add support for building wheels.\n\n- Add support for Python 3.5.\n\n- Drop support for Python 2.6 and 3.2.\n\n1.2.1 (2014-01-02)\n------------------\n\n- Add overlooked Trove classifier for Python 3.4.\n\n1.2 (2014-01-02)\n----------------\n\n- Add support for Python 3.4, PyPy3.\n\n- Add 100% coverage for ``pkginfo.commandline`` module.\n\n1.2b1 (2013-12-05)\n------------------\n\n- Add support for the \"wheel\" distribution format, along with minimal\n metadata 2.0 support (not including new PEP 426 JSON properties).\n Code (re-)borrowed from Donald Stuft's ``twine`` package.\n\n1.1 (2013-10-09)\n----------------\n\n- Fix tests to pass with current PyPy releases.\n\n1.1b1 (2013-05-05)\n------------------\n\n- Support \"develop\" packages which keep their ``*.egg-info`` in a subdirectory.\n See https://bugs.launchpad.net/pkginfo/+bug/919147.\n\n- Add support for \"unpacked SDists\" (thanks to Mike Lundy for the patch).\n\n1.0 (2013-05-05)\n----------------\n\n- No changes from 1.0b2.\n\n1.0b2 (2012-12-28)\n------------------\n\n- Suppress resource warning leaks reported against clients.\n\n- Fix 'commandline' module under Py3k.\n\n1.0b1 (2012-12-28)\n------------------\n\n- Add support for Python 3.2 and 3.3, including testing them under ``tox``.\n\n- Add support for PyPy, including testing it under ``tox``.\n\n- Test supported Python versions under ``tox``.\n\n- Drop support for Python 2.5.\n\n- Add a ``setup.py dev`` alias: runs ``setup.py develop`` and installs\n testing extras (``nose`` and ``coverage``).\n\n0.9.1 (2012-10-22)\n------------------\n\n- Fix test failure under Python >= 2.7, which is enforcing\n 'metadata_version == 1.1' because we have classifiers.\n\n\n0.9 (2012-04-25)\n----------------\n\n- Fix introspection of installed namespace packages.\n They may be installed as eggs or via dist-installed 'egg-info' files.\n https://bugs.launchpad.net/pkginfo/+bug/934311\n\n- Avoid a regression in 0.8 under Python 2.6 / 2.7 when parsing unicode.\n https://bugs.launchpad.net/pkginfo/+bug/733827/comments/3\n\n\n0.8 (2011-03-12)\n----------------\n\n- Work around Python 2.7's breakage of StringIO. Fixes\n https://bugs.launchpad.net/pkginfo/+bug/733827\n\n- Fix bug in introspection of installed packages missing the\n ``__package__`` attribute.\n \n\n0.7 (2010-11-04)\n----------------\n\n- Preserve newlines in the ``description`` field. Thanks to Sridhar\n Ratnakumar for the patch.\n\n- 100% test coverage.\n\n\n0.6 (2010-06-01)\n----------------\n\n- Replace use of ``StringIO.StringIO`` with ``io.StringIO``, where available\n (Python >= 2.6).\n\n- Replace use of ``rfc822`` stdlib module with ``email.parser``, when\n available (Python >= 2.5). Ensured that distributions \"unfold\" wrapped\n continuation lines, stripping any leading / trailing whitespace, no matter\n which module was used for parsing.\n\n- Remove bogus testing dependency on ``zope.testing``.\n\n- Add tests that the \"environment markers\" spelled out in the approved\n PEP 345 are captured.\n\n- Add ``Project-URL`` for ``1.2`` PKG-INFO metdata (defined in the accepted\n version of PEP 345).\n\n\n0.5 (2009-09-11)\n----------------\n\n- Marked package as non-zip-safe.\n\n- Fix Trove metadata misspelling.\n\n- Restore compatibility with Python 2.4.\n\n- Note that the introspection of installed packages / modules works only\n in Python 2.6 or later.\n\n- Add ``Index`` class as an abstraction over a collection of distributions.\n\n- Add ``download_url_prefix`` argument to ``pkginfo`` script. If passed,\n the script will use the prefix to synthesize a ``download_url`` for\n distributions which do not supply that value directly.\n\n\n0.4.1 (2009-05-07)\n------------------\n\n- Fix bugs in handling of installed packages which lack ``__file__``\n or ``PKG-INFO``.\n\n\n0.4 (2009-05-07)\n----------------\n\n- Extend the console script to allow output as CSV or INI. Also, added\n arguments to specify the metadata version and other parsing / output\n policies.\n\n- Add support for the different metadata versions specified in PEPs\n 241, 314, and 345. Distributions now parse and expose only the attributes\n corresponding to their metadata version, which defaults to the version\n parsed from the ``PKG-INFO`` file. The programmer can override that version\n when creating the distribution object.\n\n\n0.3 (2009-05-07)\n----------------\n\n- Add support for introspection of \"development eggs\" (checkouts with\n ``PKG-INFO``, perhaps created via ``setup.py develop``).\n\n- Add a console script, ``pkginfo``, which takes one or more paths\n on the command line and writes out the associated information. Thanks\n to ``runeh`` for the patch!\n\n- Add ``get_metadata`` helper function, which dispatches a given path or\n module across the available distribution types, and returns a distribution\n object. Thanks to ``runeh`` for the patch!\n\n- Make distribution objects support iteration over the metadata fields.\n Thanks to ``runeh`` for the patch!\n\n- Make ``Distribution`` and subclasses new-style classes. Thanks to ``runeh``\n for the patch!\n\n\n0.2 (2009-04-14)\n----------------\n\n- Add support for introspection of ``bdist_egg`` binary distributions.\n\n\n0.1.1 (2009-04-10)\n------------------\n\n- Fix packaging errors.\n\n\n0.1 (2009-04-10)\n----------------\n\n- Initial release.", - "release_date": "2022-01-27T23:56:11", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Maintained by nexB, Inc. Authored by Tres Seaver, Agendaless Consulting", - "email": "tseaver@agendaless.com", - "url": null - } - ], - "keywords": [ - "distribution sdist installed metadata", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: System :: Software Distribution" - ], - "homepage_url": "https://github.com/nexB/pkginfo2", - "download_url": "https://files.pythonhosted.org/packages/49/01/4e506c68c9ea09c702b1eac87e6d2cda6d6633e6ed42ec1f43662e246769/pkginfo2-30.0.0-py3-none-any.whl", - "size": 25701, - "sha1": null, - "md5": "08f225691729a9b3441cb955c82abce9", - "sha256": "f1558f3ff71c99e8f362b6d079c15ef334dfce8ab2bc623a992341baeb1e7248", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pkginfo2/30.0.0/json", - "datasource_id": null, - "purl": "pkg:pypi/pkginfo2@30.0.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "pkginfo2", - "version": "30.0.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Query metadatdata from sdists / bdists / installed packages. Safer fork of pkginfo to avoid doing arbitrary imports and eval()\n``pkginfo2`` README\n=====================\n\nHomepage URL: https://github.com/nexB/pkginfo2\nSPDX-License-Identifier: MIT\n\nThis package provides an API for querying the distutils metadata written in\nthe ``PKG-INFO`` file inside a source distriubtion (an ``sdist``) or a\nbinary distribution or a wheel (e.g., created by running ``bdist_egg``). It can\nalso query the ``EGG-INFO`` directory of an installed distribution, and\nthe ``*.egg-info`` stored in a \"development checkout\"\n(e.g, created by running ``setup.py develop``), or the ``*.dist-info`` from\nan as-installed package.\n\nThis is a fork of http://bazaar.launchpad.net/~tseaver/pkginfo removing the\nability to import and eval arbitrary code and work with modules known to the\ncurrent interpreter. Use importlib_metadata for this if you need it.\n\n\nPlease see the `pkginfo2 repo at `_\nfor more documentation.\n\n\n``pkginfo2`` Changelog\n=======================\n\n30.0.0 (2022-01-28)\n--------------------\n\n- Forked and rename to pkginfo2. Removed ability to import or eval packages\n or modules.\n- Move the bzr history to git\n\n1.8.2 (2021-12-01)\n------------------\n\n- Add fix for installed distributions with '__package__' set to an empty\n string. LP #1952946.\n\n1.8.1 (2021-11-19)\n------------------\n\n- Add 'MANIFEST.in' to ensure example files used by tests are included\n in source distributions. LP #1951553.\n\n1.8.0 (2021-11-18)\n------------------\n\n- Support new standard metadata location for installed dists. LP #1865286.\n\n- Don't overwrite header-based 'description' with empty payload. LP #1885458.\n\n- Add support for Metadata-Version 2.2. LP #1928729.\n\n- Add support for uncompressed tarballs for sdists. LP #1951457.\n\n- Add support for Python 3.10.\n\n1.7.1 (2021-07-09)\n------------------\n\n- Use Python3 to build docs, and fix doctest examples to use Python3-\n compatible syntax. LP #1933322.\n\n1.7.0 (2021-01-16)\n------------------\n\n- Add support for Python 3.9.\n\n- Drop support for Python 3.5.\n\n1.6.1 (2020-10-26)\n------------------\n\n- Adjust test classifiers to match supported Python versions. LP #1901127.\n\n1.6.0 (2020-10-20)\n------------------\n\n- Add support for Python 3.8.\n LP #1869854.\n\n- Drop support for Python 3.4.\n\n- Update tests to match setuptools' change, no longer reporting metadata\n version for installed packages w/o explicit metadata. LP #1870197.\n\n1.5.0.1 (2019-01-08)\n--------------------\n\n- Fix broken 'sdist'. LP #1639585.\n\n1.5.0 (2019-01-07)\n------------------\n\n- Fix 'console_scripts' entry point syntax. LP #1810734.\n\n- Add support for JSON output from the CLI. LP #1700580.\n\n- Add support for installed wheels. E.g., 'dist-info/' dirs. LP #1700200.\n\n- Harden metadata extraction against unexpected encodings. LP #1780454.\n\n- Update tests to match pip/setuptools' use of new metadata version.\n LP #1772274.\n\n- Add support for Python 3.6 and 3.7.\n\n- Drop support for Python 3.3.\n\n1.4.2 (2018-03-14)\n------------------\n\n- Use relative imports in pkginfo modules. Supports vendoring of the\n package into setuptools.\n\n- Add support for ``Provides-Extra`` and ``Description-Content-Type`` fields.\n Per https://packaging.python.org/specifications/. See: PEP 566.\n\n- Remove support for old setuptools leaving ``PKG-INFO`` in the root of\n the project directory.\n\n1.4.1 (2016-11-07)\n------------------\n\n- Packaging only change (invalid sdist built for 1.4.0).\n\n1.4.0 (2016-11-04)\n------------------\n\n- Relicense under MIT license: the PSF license is not suitable for\n third-party libraries.\n\n1.3.2 (2016-05-24)\n------------------\n\n- Packaging-only change (automate fix for wheel built for 1.3.1).\n\n1.3.1 (2016-05-24)\n------------------\n\n- Packaging-only change (invalid wheel built for 1.3.0).\n\n1.3.0 (2016-05-23)\n------------------\n\n- Update homepage URL to point to Launchpad, rather than PyPI.\n\n- Add support for building wheels.\n\n- Add support for Python 3.5.\n\n- Drop support for Python 2.6 and 3.2.\n\n1.2.1 (2014-01-02)\n------------------\n\n- Add overlooked Trove classifier for Python 3.4.\n\n1.2 (2014-01-02)\n----------------\n\n- Add support for Python 3.4, PyPy3.\n\n- Add 100% coverage for ``pkginfo.commandline`` module.\n\n1.2b1 (2013-12-05)\n------------------\n\n- Add support for the \"wheel\" distribution format, along with minimal\n metadata 2.0 support (not including new PEP 426 JSON properties).\n Code (re-)borrowed from Donald Stuft's ``twine`` package.\n\n1.1 (2013-10-09)\n----------------\n\n- Fix tests to pass with current PyPy releases.\n\n1.1b1 (2013-05-05)\n------------------\n\n- Support \"develop\" packages which keep their ``*.egg-info`` in a subdirectory.\n See https://bugs.launchpad.net/pkginfo/+bug/919147.\n\n- Add support for \"unpacked SDists\" (thanks to Mike Lundy for the patch).\n\n1.0 (2013-05-05)\n----------------\n\n- No changes from 1.0b2.\n\n1.0b2 (2012-12-28)\n------------------\n\n- Suppress resource warning leaks reported against clients.\n\n- Fix 'commandline' module under Py3k.\n\n1.0b1 (2012-12-28)\n------------------\n\n- Add support for Python 3.2 and 3.3, including testing them under ``tox``.\n\n- Add support for PyPy, including testing it under ``tox``.\n\n- Test supported Python versions under ``tox``.\n\n- Drop support for Python 2.5.\n\n- Add a ``setup.py dev`` alias: runs ``setup.py develop`` and installs\n testing extras (``nose`` and ``coverage``).\n\n0.9.1 (2012-10-22)\n------------------\n\n- Fix test failure under Python >= 2.7, which is enforcing\n 'metadata_version == 1.1' because we have classifiers.\n\n\n0.9 (2012-04-25)\n----------------\n\n- Fix introspection of installed namespace packages.\n They may be installed as eggs or via dist-installed 'egg-info' files.\n https://bugs.launchpad.net/pkginfo/+bug/934311\n\n- Avoid a regression in 0.8 under Python 2.6 / 2.7 when parsing unicode.\n https://bugs.launchpad.net/pkginfo/+bug/733827/comments/3\n\n\n0.8 (2011-03-12)\n----------------\n\n- Work around Python 2.7's breakage of StringIO. Fixes\n https://bugs.launchpad.net/pkginfo/+bug/733827\n\n- Fix bug in introspection of installed packages missing the\n ``__package__`` attribute.\n \n\n0.7 (2010-11-04)\n----------------\n\n- Preserve newlines in the ``description`` field. Thanks to Sridhar\n Ratnakumar for the patch.\n\n- 100% test coverage.\n\n\n0.6 (2010-06-01)\n----------------\n\n- Replace use of ``StringIO.StringIO`` with ``io.StringIO``, where available\n (Python >= 2.6).\n\n- Replace use of ``rfc822`` stdlib module with ``email.parser``, when\n available (Python >= 2.5). Ensured that distributions \"unfold\" wrapped\n continuation lines, stripping any leading / trailing whitespace, no matter\n which module was used for parsing.\n\n- Remove bogus testing dependency on ``zope.testing``.\n\n- Add tests that the \"environment markers\" spelled out in the approved\n PEP 345 are captured.\n\n- Add ``Project-URL`` for ``1.2`` PKG-INFO metdata (defined in the accepted\n version of PEP 345).\n\n\n0.5 (2009-09-11)\n----------------\n\n- Marked package as non-zip-safe.\n\n- Fix Trove metadata misspelling.\n\n- Restore compatibility with Python 2.4.\n\n- Note that the introspection of installed packages / modules works only\n in Python 2.6 or later.\n\n- Add ``Index`` class as an abstraction over a collection of distributions.\n\n- Add ``download_url_prefix`` argument to ``pkginfo`` script. If passed,\n the script will use the prefix to synthesize a ``download_url`` for\n distributions which do not supply that value directly.\n\n\n0.4.1 (2009-05-07)\n------------------\n\n- Fix bugs in handling of installed packages which lack ``__file__``\n or ``PKG-INFO``.\n\n\n0.4 (2009-05-07)\n----------------\n\n- Extend the console script to allow output as CSV or INI. Also, added\n arguments to specify the metadata version and other parsing / output\n policies.\n\n- Add support for the different metadata versions specified in PEPs\n 241, 314, and 345. Distributions now parse and expose only the attributes\n corresponding to their metadata version, which defaults to the version\n parsed from the ``PKG-INFO`` file. The programmer can override that version\n when creating the distribution object.\n\n\n0.3 (2009-05-07)\n----------------\n\n- Add support for introspection of \"development eggs\" (checkouts with\n ``PKG-INFO``, perhaps created via ``setup.py develop``).\n\n- Add a console script, ``pkginfo``, which takes one or more paths\n on the command line and writes out the associated information. Thanks\n to ``runeh`` for the patch!\n\n- Add ``get_metadata`` helper function, which dispatches a given path or\n module across the available distribution types, and returns a distribution\n object. Thanks to ``runeh`` for the patch!\n\n- Make distribution objects support iteration over the metadata fields.\n Thanks to ``runeh`` for the patch!\n\n- Make ``Distribution`` and subclasses new-style classes. Thanks to ``runeh``\n for the patch!\n\n\n0.2 (2009-04-14)\n----------------\n\n- Add support for introspection of ``bdist_egg`` binary distributions.\n\n\n0.1.1 (2009-04-10)\n------------------\n\n- Fix packaging errors.\n\n\n0.1 (2009-04-10)\n----------------\n\n- Initial release.", - "release_date": "2022-01-27T23:56:14", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Maintained by nexB, Inc. Authored by Tres Seaver, Agendaless Consulting", - "email": "tseaver@agendaless.com", - "url": null - } - ], - "keywords": [ - "distribution sdist installed metadata", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: System :: Software Distribution" - ], - "homepage_url": "https://github.com/nexB/pkginfo2", - "download_url": "https://files.pythonhosted.org/packages/90/8d/09cc1c99a30ac14050fc4e04e549e024be83ff72a7f63e75023501baf977/pkginfo2-30.0.0.tar.gz", - "size": 364071, - "sha1": null, - "md5": "8fd5bd0d69938534c9796195164b5928", - "sha256": "5e1afbeb156febb407a9b5c16b51c5b4737c529eeda2b1607e1e277cf260669c", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pkginfo2/30.0.0/json", - "datasource_id": null, - "purl": "pkg:pypi/pkginfo2@30.0.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "pkginfo", - "version": "1.8.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Query metadatdata from sdists / bdists / installed packages.\n``pkginfo`` README\n==================\n\nThis package provides an API for querying the distutils metadata written in\nthe ``PKG-INFO`` file inside a source distriubtion (an ``sdist``) or a\nbinary distribution (e.g., created by running ``bdist_egg``). It can\nalso query the ``EGG-INFO`` directory of an installed distribution, and\nthe ``*.egg-info`` stored in a \"development checkout\"\n(e.g, created by running ``setup.py develop``).\n\n\nPlease see the `pkginfo docs `_\nfor detailed documentation.\n\n\n``pkginfo`` Changelog\n=====================\n\n1.8.3 (2022-06-08)\n------------------\n\n- Specify supported Python versions in 'setup.py' using 'python_requires'.\n LP #1977981.\n\n1.8.2 (2021-12-01)\n------------------\n\n- Add fix for installed distributions with '__package__' set to an empty\n string. LP #1952946.\n\n1.8.1 (2021-11-19)\n------------------\n\n- Add 'MANIFEST.in' to ensure example files used by tests are included\n in source distributions. LP #1951553.\n\n1.8.0 (2021-11-18)\n------------------\n\n- Support new standard metadata location for installed dists. LP #1865286.\n\n- Don't overwrite header-based 'description' with empty payload. LP #1885458.\n\n- Add support for Metadata-Version 2.2. LP #1928729.\n\n- Add support for uncompressed tarballs for sdists. LP #1951457.\n\n- Add support for Python 3.10.\n\n1.7.1 (2021-07-09)\n------------------\n\n- Use Python3 to build docs, and fix doctest examples to use Python3-\n compatible syntax. LP #1933322.\n\n1.7.0 (2021-01-16)\n------------------\n\n- Add support for Python 3.9.\n\n- Drop support for Python 3.5.\n\n1.6.1 (2020-10-26)\n------------------\n\n- Adjust test classifiers to match supported Python versions. LP #1901127.\n\n1.6.0 (2020-10-20)\n------------------\n\n- Add support for Python 3.8.\n LP #1869854.\n\n- Drop support for Python 3.4.\n\n- Update tests to match setuptools' change, no longer reporting metadata\n version for installed packages w/o explicit metadata. LP #1870197.\n\n1.5.0.1 (2019-01-08)\n--------------------\n\n- Fix broken 'sdist'. LP #1639585.\n\n1.5.0 (2019-01-07)\n------------------\n\n- Fix 'console_scripts' entry point syntax. LP #1810734.\n\n- Add support for JSON output from the CLI. LP #1700580.\n\n- Add support for installed wheels. E.g., 'dist-info/' dirs. LP #1700200.\n\n- Harden metadata extraction against unexpected encodings. LP #1780454.\n\n- Update tests to match pip/setuptools' use of new metadata version.\n LP #1772274.\n\n- Add support for Python 3.6 and 3.7.\n\n- Drop support for Python 3.3.\n\n1.4.2 (2018-03-14)\n------------------\n\n- Use relative imports in pkginfo modules. Supports vendoring of the\n package into setuptools.\n\n- Add support for ``Provides-Extra`` and ``Description-Content-Type`` fields.\n Per https://packaging.python.org/specifications/. See: PEP 566.\n\n- Remove support for old setuptools leaving ``PKG-INFO`` in the root of\n the project directory.\n\n1.4.1 (2016-11-07)\n------------------\n\n- Packaging only change (invalid sdist built for 1.4.0).\n\n1.4.0 (2016-11-04)\n------------------\n\n- Relicense under MIT license: the PSF license is not suitable for\n third-party libraries.\n\n1.3.2 (2016-05-24)\n------------------\n\n- Packaging-only change (automate fix for wheel built for 1.3.1).\n\n1.3.1 (2016-05-24)\n------------------\n\n- Packaging-only change (invalid wheel built for 1.3.0).\n\n1.3.0 (2016-05-23)\n------------------\n\n- Update homepage URL to point to Launchpad, rather than PyPI.\n\n- Add support for building wheels.\n\n- Add support for Python 3.5.\n\n- Drop support for Python 2.6 and 3.2.\n\n1.2.1 (2014-01-02)\n------------------\n\n- Add overlooked Trove classifier for Python 3.4.\n\n1.2 (2014-01-02)\n----------------\n\n- Add support for Python 3.4, PyPy3.\n\n- Add 100% coverage for ``pkginfo.commandline`` module.\n\n1.2b1 (2013-12-05)\n------------------\n\n- Add support for the \"wheel\" distribution format, along with minimal\n metadata 2.0 support (not including new PEP 426 JSON properties).\n Code (re-)borrowed from Donald Stuft's ``twine`` package.\n\n1.1 (2013-10-09)\n----------------\n\n- Fix tests to pass with current PyPy releases.\n\n1.1b1 (2013-05-05)\n------------------\n\n- Support \"develop\" packages which keep their ``*.egg-info`` in a subdirectory.\n See https://bugs.launchpad.net/pkginfo/+bug/919147.\n\n- Add support for \"unpacked SDists\" (thanks to Mike Lundy for the patch).\n\n1.0 (2013-05-05)\n----------------\n\n- No changes from 1.0b2.\n\n1.0b2 (2012-12-28)\n------------------\n\n- Suppress resource warning leaks reported against clients.\n\n- Fix 'commandline' module under Py3k.\n\n1.0b1 (2012-12-28)\n------------------\n\n- Add support for Python 3.2 and 3.3, including testing them under ``tox``.\n\n- Add support for PyPy, including testing it under ``tox``.\n\n- Test supported Python versions under ``tox``.\n\n- Drop support for Python 2.5.\n\n- Add a ``setup.py dev`` alias: runs ``setup.py develop`` and installs\n testing extras (``nose`` and ``coverage``).\n\n0.9.1 (2012-10-22)\n------------------\n\n- Fix test failure under Python >= 2.7, which is enforcing\n 'metadata_version == 1.1' because we have classifiers.\n\n\n0.9 (2012-04-25)\n----------------\n\n- Fix introspection of installed namespace packages.\n They may be installed as eggs or via dist-installed 'egg-info' files.\n https://bugs.launchpad.net/pkginfo/+bug/934311\n\n- Avoid a regression in 0.8 under Python 2.6 / 2.7 when parsing unicode.\n https://bugs.launchpad.net/pkginfo/+bug/733827/comments/3\n\n\n0.8 (2011-03-12)\n----------------\n\n- Work around Python 2.7's breakage of StringIO. Fixes\n https://bugs.launchpad.net/pkginfo/+bug/733827\n\n- Fix bug in introspection of installed packages missing the\n ``__package__`` attribute.\n \n\n0.7 (2010-11-04)\n----------------\n\n- Preserve newlines in the ``description`` field. Thanks to Sridhar\n Ratnakumar for the patch.\n\n- 100% test coverage.\n\n\n0.6 (2010-06-01)\n----------------\n\n- Replace use of ``StringIO.StringIO`` with ``io.StringIO``, where available\n (Python >= 2.6).\n\n- Replace use of ``rfc822`` stdlib module with ``email.parser``, when\n available (Python >= 2.5). Ensured that distributions \"unfold\" wrapped\n continuation lines, stripping any leading / trailing whitespace, no matter\n which module was used for parsing.\n\n- Remove bogus testing dependency on ``zope.testing``.\n\n- Add tests that the \"environment markers\" spelled out in the approved\n PEP 345 are captured.\n\n- Add ``Project-URL`` for ``1.2`` PKG-INFO metdata (defined in the accepted\n version of PEP 345).\n\n\n0.5 (2009-09-11)\n----------------\n\n- Marked package as non-zip-safe.\n\n- Fix Trove metadata misspelling.\n\n- Restore compatibility with Python 2.4.\n\n- Note that the introspection of installed packages / modules works only\n in Python 2.6 or later.\n\n- Add ``Index`` class as an abstraction over a collection of distributions.\n\n- Add ``download_url_prefix`` argument to ``pkginfo`` script. If passed,\n the script will use the prefix to synthesize a ``download_url`` for\n distributions which do not supply that value directly.\n\n\n0.4.1 (2009-05-07)\n------------------\n\n- Fix bugs in handling of installed packages which lack ``__file__``\n or ``PKG-INFO``.\n\n\n0.4 (2009-05-07)\n----------------\n\n- Extend the console script to allow output as CSV or INI. Also, added\n arguments to specify the metadata version and other parsing / output\n policies.\n\n- Add support for the different metadata versions specified in PEPs\n 241, 314, and 345. Distributions now parse and expose only the attributes\n corresponding to their metadata version, which defaults to the version\n parsed from the ``PKG-INFO`` file. The programmer can override that version\n when creating the distribution object.\n\n\n0.3 (2009-05-07)\n----------------\n\n- Add support for introspection of \"development eggs\" (checkouts with\n ``PKG-INFO``, perhaps created via ``setup.py develop``).\n\n- Add a console script, ``pkginfo``, which takes one or more paths\n on the command line and writes out the associated information. Thanks\n to ``runeh`` for the patch!\n\n- Add ``get_metadata`` helper function, which dispatches a given path or\n module across the available distribution types, and returns a distribution\n object. Thanks to ``runeh`` for the patch!\n\n- Make distribution objects support iteration over the metadata fields.\n Thanks to ``runeh`` for the patch!\n\n- Make ``Distribution`` and subclasses new-style classes. Thanks to ``runeh``\n for the patch!\n\n\n0.2 (2009-04-14)\n----------------\n\n- Add support for introspection of ``bdist_egg`` binary distributions.\n\n\n0.1.1 (2009-04-10)\n------------------\n\n- Fix packaging errors.\n\n\n0.1 (2009-04-10)\n----------------\n\n- Initial release.", - "release_date": "2022-06-08T18:10:54", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Tres Seaver, Agendaless Consulting", - "email": "tseaver@agendaless.com", - "url": null - } - ], - "keywords": [ - "distribution sdist installed metadata", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: System :: Software Distribution" - ], - "homepage_url": "https://code.launchpad.net/~tseaver/pkginfo/trunk", - "download_url": "https://files.pythonhosted.org/packages/f3/28/ded592460bc65d39a48fe51d7678c408ae895ee3694d4cd404a131a73271/pkginfo-1.8.3-py2.py3-none-any.whl", - "size": 26567, - "sha1": null, - "md5": "12469a5ba29bbf6f1057ee2c5b03e438", - "sha256": "848865108ec99d4901b2f7e84058b6e7660aae8ae10164e015a6dcf5b242a594", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pkginfo/1.8.3/json", - "datasource_id": null, - "purl": "pkg:pypi/pkginfo@1.8.3" - }, - { - "type": "pypi", - "namespace": null, - "name": "pkginfo", - "version": "1.8.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Query metadatdata from sdists / bdists / installed packages.\n``pkginfo`` README\n==================\n\nThis package provides an API for querying the distutils metadata written in\nthe ``PKG-INFO`` file inside a source distriubtion (an ``sdist``) or a\nbinary distribution (e.g., created by running ``bdist_egg``). It can\nalso query the ``EGG-INFO`` directory of an installed distribution, and\nthe ``*.egg-info`` stored in a \"development checkout\"\n(e.g, created by running ``setup.py develop``).\n\n\nPlease see the `pkginfo docs `_\nfor detailed documentation.\n\n\n``pkginfo`` Changelog\n=====================\n\n1.8.3 (2022-06-08)\n------------------\n\n- Specify supported Python versions in 'setup.py' using 'python_requires'.\n LP #1977981.\n\n1.8.2 (2021-12-01)\n------------------\n\n- Add fix for installed distributions with '__package__' set to an empty\n string. LP #1952946.\n\n1.8.1 (2021-11-19)\n------------------\n\n- Add 'MANIFEST.in' to ensure example files used by tests are included\n in source distributions. LP #1951553.\n\n1.8.0 (2021-11-18)\n------------------\n\n- Support new standard metadata location for installed dists. LP #1865286.\n\n- Don't overwrite header-based 'description' with empty payload. LP #1885458.\n\n- Add support for Metadata-Version 2.2. LP #1928729.\n\n- Add support for uncompressed tarballs for sdists. LP #1951457.\n\n- Add support for Python 3.10.\n\n1.7.1 (2021-07-09)\n------------------\n\n- Use Python3 to build docs, and fix doctest examples to use Python3-\n compatible syntax. LP #1933322.\n\n1.7.0 (2021-01-16)\n------------------\n\n- Add support for Python 3.9.\n\n- Drop support for Python 3.5.\n\n1.6.1 (2020-10-26)\n------------------\n\n- Adjust test classifiers to match supported Python versions. LP #1901127.\n\n1.6.0 (2020-10-20)\n------------------\n\n- Add support for Python 3.8.\n LP #1869854.\n\n- Drop support for Python 3.4.\n\n- Update tests to match setuptools' change, no longer reporting metadata\n version for installed packages w/o explicit metadata. LP #1870197.\n\n1.5.0.1 (2019-01-08)\n--------------------\n\n- Fix broken 'sdist'. LP #1639585.\n\n1.5.0 (2019-01-07)\n------------------\n\n- Fix 'console_scripts' entry point syntax. LP #1810734.\n\n- Add support for JSON output from the CLI. LP #1700580.\n\n- Add support for installed wheels. E.g., 'dist-info/' dirs. LP #1700200.\n\n- Harden metadata extraction against unexpected encodings. LP #1780454.\n\n- Update tests to match pip/setuptools' use of new metadata version.\n LP #1772274.\n\n- Add support for Python 3.6 and 3.7.\n\n- Drop support for Python 3.3.\n\n1.4.2 (2018-03-14)\n------------------\n\n- Use relative imports in pkginfo modules. Supports vendoring of the\n package into setuptools.\n\n- Add support for ``Provides-Extra`` and ``Description-Content-Type`` fields.\n Per https://packaging.python.org/specifications/. See: PEP 566.\n\n- Remove support for old setuptools leaving ``PKG-INFO`` in the root of\n the project directory.\n\n1.4.1 (2016-11-07)\n------------------\n\n- Packaging only change (invalid sdist built for 1.4.0).\n\n1.4.0 (2016-11-04)\n------------------\n\n- Relicense under MIT license: the PSF license is not suitable for\n third-party libraries.\n\n1.3.2 (2016-05-24)\n------------------\n\n- Packaging-only change (automate fix for wheel built for 1.3.1).\n\n1.3.1 (2016-05-24)\n------------------\n\n- Packaging-only change (invalid wheel built for 1.3.0).\n\n1.3.0 (2016-05-23)\n------------------\n\n- Update homepage URL to point to Launchpad, rather than PyPI.\n\n- Add support for building wheels.\n\n- Add support for Python 3.5.\n\n- Drop support for Python 2.6 and 3.2.\n\n1.2.1 (2014-01-02)\n------------------\n\n- Add overlooked Trove classifier for Python 3.4.\n\n1.2 (2014-01-02)\n----------------\n\n- Add support for Python 3.4, PyPy3.\n\n- Add 100% coverage for ``pkginfo.commandline`` module.\n\n1.2b1 (2013-12-05)\n------------------\n\n- Add support for the \"wheel\" distribution format, along with minimal\n metadata 2.0 support (not including new PEP 426 JSON properties).\n Code (re-)borrowed from Donald Stuft's ``twine`` package.\n\n1.1 (2013-10-09)\n----------------\n\n- Fix tests to pass with current PyPy releases.\n\n1.1b1 (2013-05-05)\n------------------\n\n- Support \"develop\" packages which keep their ``*.egg-info`` in a subdirectory.\n See https://bugs.launchpad.net/pkginfo/+bug/919147.\n\n- Add support for \"unpacked SDists\" (thanks to Mike Lundy for the patch).\n\n1.0 (2013-05-05)\n----------------\n\n- No changes from 1.0b2.\n\n1.0b2 (2012-12-28)\n------------------\n\n- Suppress resource warning leaks reported against clients.\n\n- Fix 'commandline' module under Py3k.\n\n1.0b1 (2012-12-28)\n------------------\n\n- Add support for Python 3.2 and 3.3, including testing them under ``tox``.\n\n- Add support for PyPy, including testing it under ``tox``.\n\n- Test supported Python versions under ``tox``.\n\n- Drop support for Python 2.5.\n\n- Add a ``setup.py dev`` alias: runs ``setup.py develop`` and installs\n testing extras (``nose`` and ``coverage``).\n\n0.9.1 (2012-10-22)\n------------------\n\n- Fix test failure under Python >= 2.7, which is enforcing\n 'metadata_version == 1.1' because we have classifiers.\n\n\n0.9 (2012-04-25)\n----------------\n\n- Fix introspection of installed namespace packages.\n They may be installed as eggs or via dist-installed 'egg-info' files.\n https://bugs.launchpad.net/pkginfo/+bug/934311\n\n- Avoid a regression in 0.8 under Python 2.6 / 2.7 when parsing unicode.\n https://bugs.launchpad.net/pkginfo/+bug/733827/comments/3\n\n\n0.8 (2011-03-12)\n----------------\n\n- Work around Python 2.7's breakage of StringIO. Fixes\n https://bugs.launchpad.net/pkginfo/+bug/733827\n\n- Fix bug in introspection of installed packages missing the\n ``__package__`` attribute.\n \n\n0.7 (2010-11-04)\n----------------\n\n- Preserve newlines in the ``description`` field. Thanks to Sridhar\n Ratnakumar for the patch.\n\n- 100% test coverage.\n\n\n0.6 (2010-06-01)\n----------------\n\n- Replace use of ``StringIO.StringIO`` with ``io.StringIO``, where available\n (Python >= 2.6).\n\n- Replace use of ``rfc822`` stdlib module with ``email.parser``, when\n available (Python >= 2.5). Ensured that distributions \"unfold\" wrapped\n continuation lines, stripping any leading / trailing whitespace, no matter\n which module was used for parsing.\n\n- Remove bogus testing dependency on ``zope.testing``.\n\n- Add tests that the \"environment markers\" spelled out in the approved\n PEP 345 are captured.\n\n- Add ``Project-URL`` for ``1.2`` PKG-INFO metdata (defined in the accepted\n version of PEP 345).\n\n\n0.5 (2009-09-11)\n----------------\n\n- Marked package as non-zip-safe.\n\n- Fix Trove metadata misspelling.\n\n- Restore compatibility with Python 2.4.\n\n- Note that the introspection of installed packages / modules works only\n in Python 2.6 or later.\n\n- Add ``Index`` class as an abstraction over a collection of distributions.\n\n- Add ``download_url_prefix`` argument to ``pkginfo`` script. If passed,\n the script will use the prefix to synthesize a ``download_url`` for\n distributions which do not supply that value directly.\n\n\n0.4.1 (2009-05-07)\n------------------\n\n- Fix bugs in handling of installed packages which lack ``__file__``\n or ``PKG-INFO``.\n\n\n0.4 (2009-05-07)\n----------------\n\n- Extend the console script to allow output as CSV or INI. Also, added\n arguments to specify the metadata version and other parsing / output\n policies.\n\n- Add support for the different metadata versions specified in PEPs\n 241, 314, and 345. Distributions now parse and expose only the attributes\n corresponding to their metadata version, which defaults to the version\n parsed from the ``PKG-INFO`` file. The programmer can override that version\n when creating the distribution object.\n\n\n0.3 (2009-05-07)\n----------------\n\n- Add support for introspection of \"development eggs\" (checkouts with\n ``PKG-INFO``, perhaps created via ``setup.py develop``).\n\n- Add a console script, ``pkginfo``, which takes one or more paths\n on the command line and writes out the associated information. Thanks\n to ``runeh`` for the patch!\n\n- Add ``get_metadata`` helper function, which dispatches a given path or\n module across the available distribution types, and returns a distribution\n object. Thanks to ``runeh`` for the patch!\n\n- Make distribution objects support iteration over the metadata fields.\n Thanks to ``runeh`` for the patch!\n\n- Make ``Distribution`` and subclasses new-style classes. Thanks to ``runeh``\n for the patch!\n\n\n0.2 (2009-04-14)\n----------------\n\n- Add support for introspection of ``bdist_egg`` binary distributions.\n\n\n0.1.1 (2009-04-10)\n------------------\n\n- Fix packaging errors.\n\n\n0.1 (2009-04-10)\n----------------\n\n- Initial release.", - "release_date": "2022-06-08T18:10:56", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Tres Seaver, Agendaless Consulting", - "email": "tseaver@agendaless.com", - "url": null - } - ], - "keywords": [ - "distribution sdist installed metadata", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: System :: Software Distribution" - ], - "homepage_url": "https://code.launchpad.net/~tseaver/pkginfo/trunk", - "download_url": "https://files.pythonhosted.org/packages/00/91/fe0806e3ebded8c4e52f93ab4d963eef34bb33595c7aa7b5591d32ab5b92/pkginfo-1.8.3.tar.gz", - "size": 375734, - "sha1": null, - "md5": "e67d8f6e37ca37b5512384655bbce760", - "sha256": "a84da4318dd86f870a9447a8c98340aa06216bfc6f2b7bdc4b8766984ae1867c", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pkginfo/1.8.3/json", - "datasource_id": null, - "purl": "pkg:pypi/pkginfo@1.8.3" - }, - { - "type": "pypi", - "namespace": null, - "name": "platformdirs", - "version": "2.4.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\".\nThe problem\n===========\n\n.. image:: https://github.com/platformdirs/platformdirs/workflows/Test/badge.svg\n :target: https://github.com/platformdirs/platformdirs/actions?query=workflow%3ATest\n\nWhen writing desktop application, finding the right location to store user data\nand configuration varies per platform. Even for single-platform apps, there\nmay by plenty of nuances in figuring out the right location.\n\nFor example, if running on macOS, you should use::\n\n ~/Library/Application Support/\n\nIf on Windows (at least English Win XP) that should be::\n\n C:\\Documents and Settings\\\\Application Data\\Local Settings\\\\\n\nor possibly::\n\n C:\\Documents and Settings\\\\Application Data\\\\\n\nfor `roaming profiles `_ but that is another story.\n\nOn Linux (and other Unices), according to the `XDG Basedir Spec`_, it should be::\n\n ~/.local/share/\n\n.. _XDG Basedir Spec: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html\n\n``platformdirs`` to the rescue\n==============================\n\nThis kind of thing is what the ``platformdirs`` module is for.\n``platformdirs`` will help you choose an appropriate:\n\n- user data dir (``user_data_dir``)\n- user config dir (``user_config_dir``)\n- user cache dir (``user_cache_dir``)\n- site data dir (``site_data_dir``)\n- site config dir (``site_config_dir``)\n- user log dir (``user_log_dir``)\n- user documents dir (``user_documents_dir``)\n- user runtime dir (``user_runtime_dir``)\n\nAnd also:\n\n- Is a single module so other Python packages can vendor their own private copy.\n- Is slightly opinionated on the directory names used. Look for \"OPINION\" in\n documentation and code for when an opinion is being applied.\n\nExample output\n==============\n\nOn macOS:\n\n.. code-block:: pycon\n\n >>> from platformdirs import *\n >>> appname = \"SuperApp\"\n >>> appauthor = \"Acme\"\n >>> user_data_dir(appname, appauthor)\n '/Users/trentm/Library/Application Support/SuperApp'\n >>> site_data_dir(appname, appauthor)\n '/Library/Application Support/SuperApp'\n >>> user_cache_dir(appname, appauthor)\n '/Users/trentm/Library/Caches/SuperApp'\n >>> user_log_dir(appname, appauthor)\n '/Users/trentm/Library/Logs/SuperApp'\n >>> user_documents_dir()\n '/Users/trentm/Documents'\n >>> user_runtime_dir(appname, appauthor)\n '/Users/trentm/Library/Caches/TemporaryItems/SuperApp'\n\nOn Windows 7:\n\n.. code-block:: pycon\n\n >>> from platformdirs import *\n >>> appname = \"SuperApp\"\n >>> appauthor = \"Acme\"\n >>> user_data_dir(appname, appauthor)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Local\\\\Acme\\\\SuperApp'\n >>> user_data_dir(appname, appauthor, roaming=True)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Roaming\\\\Acme\\\\SuperApp'\n >>> user_cache_dir(appname, appauthor)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Local\\\\Acme\\\\SuperApp\\\\Cache'\n >>> user_log_dir(appname, appauthor)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Local\\\\Acme\\\\SuperApp\\\\Logs'\n >>> user_documents_dir()\n 'C:\\\\Users\\\\trentm\\\\Documents'\n >>> user_runtime_dir(appname, appauthor)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Local\\\\Temp\\\\Acme\\\\SuperApp'\n\nOn Linux:\n\n.. code-block:: pycon\n\n >>> from platformdirs import *\n >>> appname = \"SuperApp\"\n >>> appauthor = \"Acme\"\n >>> user_data_dir(appname, appauthor)\n '/home/trentm/.local/share/SuperApp\n >>> site_data_dir(appname, appauthor)\n '/usr/local/share/SuperApp'\n >>> site_data_dir(appname, appauthor, multipath=True)\n '/usr/local/share/SuperApp:/usr/share/SuperApp'\n >>> user_cache_dir(appname, appauthor)\n '/home/trentm/.cache/SuperApp'\n >>> user_log_dir(appname, appauthor)\n '/home/trentm/.cache/SuperApp/log'\n >>> user_config_dir(appname)\n '/home/trentm/.config/SuperApp'\n >>> user_documents_dir()\n '/home/trentm/Documents'\n >>> user_runtime_dir(appname, appauthor)\n '/run/user/{os.getuid()}/SuperApp'\n >>> site_config_dir(appname)\n '/etc/xdg/SuperApp'\n >>> os.environ['XDG_CONFIG_DIRS'] = '/etc:/usr/local/etc'\n >>> site_config_dir(appname, multipath=True)\n '/etc/SuperApp:/usr/local/etc/SuperApp'\n\nOn Android::\n\n >>> from platformdirs import *\n >>> appname = \"SuperApp\"\n >>> appauthor = \"Acme\"\n >>> user_data_dir(appname, appauthor)\n '/data/data/com.termux/files/SuperApp'\n >>> user_cache_dir(appname, appauthor)\n '/data/data/com.termux/cache/SuperApp'\n >>> user_log_dir(appname, appauthor)\n '/data/data/com.termux/cache/SuperApp/log'\n >>> user_config_dir(appname)\n '/data/data/com.termux/shared_prefs/SuperApp'\n >>> user_documents_dir()\n '/storage/emulated/0/Documents'\n >>> user_runtime_dir(appname, appauthor)\n '/data/data/com.termux/cache/SuperApp/tmp'\n\n``PlatformDirs`` for convenience\n================================\n\n.. code-block:: pycon\n\n >>> from platformdirs import PlatformDirs\n >>> dirs = PlatformDirs(\"SuperApp\", \"Acme\")\n >>> dirs.user_data_dir\n '/Users/trentm/Library/Application Support/SuperApp'\n >>> dirs.site_data_dir\n '/Library/Application Support/SuperApp'\n >>> dirs.user_cache_dir\n '/Users/trentm/Library/Caches/SuperApp'\n >>> dirs.user_log_dir\n '/Users/trentm/Library/Logs/SuperApp'\n >>> dirs.user_documents_dir\n '/Users/trentm/Documents'\n >>> dirs.user_runtime_dir\n '/Users/trentm/Library/Caches/TemporaryItems/SuperApp'\n\nPer-version isolation\n=====================\n\nIf you have multiple versions of your app in use that you want to be\nable to run side-by-side, then you may want version-isolation for these\ndirs::\n\n >>> from platformdirs import PlatformDirs\n >>> dirs = PlatformDirs(\"SuperApp\", \"Acme\", version=\"1.0\")\n >>> dirs.user_data_dir\n '/Users/trentm/Library/Application Support/SuperApp/1.0'\n >>> dirs.site_data_dir\n '/Library/Application Support/SuperApp/1.0'\n >>> dirs.user_cache_dir\n '/Users/trentm/Library/Caches/SuperApp/1.0'\n >>> dirs.user_log_dir\n '/Users/trentm/Library/Logs/SuperApp/1.0'\n >>> dirs.user_documents_dir\n '/Users/trentm/Documents'\n >>> dirs.user_runtime_dir\n '/Users/trentm/Library/Caches/TemporaryItems/SuperApp/1.0'\n\nBe wary of using this for configuration files though; you'll need to handle\nmigrating configuration files manually.\n\nWhy this Fork?\n==============\n\nThis repository is a friendly fork of the wonderful work started by\n`ActiveState `_ who created\n``appdirs``, this package's ancestor.\n\nMaintaining an open source project is no easy task, particularly\nfrom within an organization, and the Python community is indebted\nto ``appdirs`` (and to Trent Mick and Jeff Rouse in particular) for\ncreating an incredibly useful simple module, as evidenced by the wide\nnumber of users it has attracted over the years.\n\nNonetheless, given the number of long-standing open issues\nand pull requests, and no clear path towards `ensuring\nthat maintenance of the package would continue or grow\n`_, this fork was\ncreated.\n\nContributions are most welcome.", - "release_date": "2021-09-25T20:46:05", - "parties": [ - { - "type": "person", - "role": "maintainer", - "name": "Bern\u00e1t G\u00e1bor, Julian Berman, Ofek Lev, Ronny Pfannschmidt", - "email": "gaborjbernat@gmail.com, Julian@GrayVines.com, oss@ofek.dev, opensource@ronnypfannschmidt.de", - "url": null - } - ], - "keywords": [ - "application directory log cache user", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "https://github.com/platformdirs/platformdirs", - "download_url": "https://files.pythonhosted.org/packages/b1/78/dcfd84d3aabd46a9c77260fb47ea5d244806e4daef83aa6fe5d83adb182c/platformdirs-2.4.0-py3-none-any.whl", - "size": 14400, - "sha1": null, - "md5": "8c8b02ee007d405bf3369b82b7a4c1ca", - "sha256": "8868bbe3c3c80d42f20156f22e7131d2fb321f5bc86a2a345375c6481a67021d", - "sha512": null, - "bug_tracking_url": "https://github.com/platformdirs/platformdirs/issues", - "code_view_url": "https://github.com/platformdirs/platformdirs", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/platformdirs/2.4.0/json", - "datasource_id": null, - "purl": "pkg:pypi/platformdirs@2.4.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "platformdirs", - "version": "2.4.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\".\nThe problem\n===========\n\n.. image:: https://github.com/platformdirs/platformdirs/workflows/Test/badge.svg\n :target: https://github.com/platformdirs/platformdirs/actions?query=workflow%3ATest\n\nWhen writing desktop application, finding the right location to store user data\nand configuration varies per platform. Even for single-platform apps, there\nmay by plenty of nuances in figuring out the right location.\n\nFor example, if running on macOS, you should use::\n\n ~/Library/Application Support/\n\nIf on Windows (at least English Win XP) that should be::\n\n C:\\Documents and Settings\\\\Application Data\\Local Settings\\\\\n\nor possibly::\n\n C:\\Documents and Settings\\\\Application Data\\\\\n\nfor `roaming profiles `_ but that is another story.\n\nOn Linux (and other Unices), according to the `XDG Basedir Spec`_, it should be::\n\n ~/.local/share/\n\n.. _XDG Basedir Spec: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html\n\n``platformdirs`` to the rescue\n==============================\n\nThis kind of thing is what the ``platformdirs`` module is for.\n``platformdirs`` will help you choose an appropriate:\n\n- user data dir (``user_data_dir``)\n- user config dir (``user_config_dir``)\n- user cache dir (``user_cache_dir``)\n- site data dir (``site_data_dir``)\n- site config dir (``site_config_dir``)\n- user log dir (``user_log_dir``)\n- user documents dir (``user_documents_dir``)\n- user runtime dir (``user_runtime_dir``)\n\nAnd also:\n\n- Is a single module so other Python packages can vendor their own private copy.\n- Is slightly opinionated on the directory names used. Look for \"OPINION\" in\n documentation and code for when an opinion is being applied.\n\nExample output\n==============\n\nOn macOS:\n\n.. code-block:: pycon\n\n >>> from platformdirs import *\n >>> appname = \"SuperApp\"\n >>> appauthor = \"Acme\"\n >>> user_data_dir(appname, appauthor)\n '/Users/trentm/Library/Application Support/SuperApp'\n >>> site_data_dir(appname, appauthor)\n '/Library/Application Support/SuperApp'\n >>> user_cache_dir(appname, appauthor)\n '/Users/trentm/Library/Caches/SuperApp'\n >>> user_log_dir(appname, appauthor)\n '/Users/trentm/Library/Logs/SuperApp'\n >>> user_documents_dir()\n '/Users/trentm/Documents'\n >>> user_runtime_dir(appname, appauthor)\n '/Users/trentm/Library/Caches/TemporaryItems/SuperApp'\n\nOn Windows 7:\n\n.. code-block:: pycon\n\n >>> from platformdirs import *\n >>> appname = \"SuperApp\"\n >>> appauthor = \"Acme\"\n >>> user_data_dir(appname, appauthor)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Local\\\\Acme\\\\SuperApp'\n >>> user_data_dir(appname, appauthor, roaming=True)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Roaming\\\\Acme\\\\SuperApp'\n >>> user_cache_dir(appname, appauthor)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Local\\\\Acme\\\\SuperApp\\\\Cache'\n >>> user_log_dir(appname, appauthor)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Local\\\\Acme\\\\SuperApp\\\\Logs'\n >>> user_documents_dir()\n 'C:\\\\Users\\\\trentm\\\\Documents'\n >>> user_runtime_dir(appname, appauthor)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Local\\\\Temp\\\\Acme\\\\SuperApp'\n\nOn Linux:\n\n.. code-block:: pycon\n\n >>> from platformdirs import *\n >>> appname = \"SuperApp\"\n >>> appauthor = \"Acme\"\n >>> user_data_dir(appname, appauthor)\n '/home/trentm/.local/share/SuperApp\n >>> site_data_dir(appname, appauthor)\n '/usr/local/share/SuperApp'\n >>> site_data_dir(appname, appauthor, multipath=True)\n '/usr/local/share/SuperApp:/usr/share/SuperApp'\n >>> user_cache_dir(appname, appauthor)\n '/home/trentm/.cache/SuperApp'\n >>> user_log_dir(appname, appauthor)\n '/home/trentm/.cache/SuperApp/log'\n >>> user_config_dir(appname)\n '/home/trentm/.config/SuperApp'\n >>> user_documents_dir()\n '/home/trentm/Documents'\n >>> user_runtime_dir(appname, appauthor)\n '/run/user/{os.getuid()}/SuperApp'\n >>> site_config_dir(appname)\n '/etc/xdg/SuperApp'\n >>> os.environ['XDG_CONFIG_DIRS'] = '/etc:/usr/local/etc'\n >>> site_config_dir(appname, multipath=True)\n '/etc/SuperApp:/usr/local/etc/SuperApp'\n\nOn Android::\n\n >>> from platformdirs import *\n >>> appname = \"SuperApp\"\n >>> appauthor = \"Acme\"\n >>> user_data_dir(appname, appauthor)\n '/data/data/com.termux/files/SuperApp'\n >>> user_cache_dir(appname, appauthor)\n '/data/data/com.termux/cache/SuperApp'\n >>> user_log_dir(appname, appauthor)\n '/data/data/com.termux/cache/SuperApp/log'\n >>> user_config_dir(appname)\n '/data/data/com.termux/shared_prefs/SuperApp'\n >>> user_documents_dir()\n '/storage/emulated/0/Documents'\n >>> user_runtime_dir(appname, appauthor)\n '/data/data/com.termux/cache/SuperApp/tmp'\n\n``PlatformDirs`` for convenience\n================================\n\n.. code-block:: pycon\n\n >>> from platformdirs import PlatformDirs\n >>> dirs = PlatformDirs(\"SuperApp\", \"Acme\")\n >>> dirs.user_data_dir\n '/Users/trentm/Library/Application Support/SuperApp'\n >>> dirs.site_data_dir\n '/Library/Application Support/SuperApp'\n >>> dirs.user_cache_dir\n '/Users/trentm/Library/Caches/SuperApp'\n >>> dirs.user_log_dir\n '/Users/trentm/Library/Logs/SuperApp'\n >>> dirs.user_documents_dir\n '/Users/trentm/Documents'\n >>> dirs.user_runtime_dir\n '/Users/trentm/Library/Caches/TemporaryItems/SuperApp'\n\nPer-version isolation\n=====================\n\nIf you have multiple versions of your app in use that you want to be\nable to run side-by-side, then you may want version-isolation for these\ndirs::\n\n >>> from platformdirs import PlatformDirs\n >>> dirs = PlatformDirs(\"SuperApp\", \"Acme\", version=\"1.0\")\n >>> dirs.user_data_dir\n '/Users/trentm/Library/Application Support/SuperApp/1.0'\n >>> dirs.site_data_dir\n '/Library/Application Support/SuperApp/1.0'\n >>> dirs.user_cache_dir\n '/Users/trentm/Library/Caches/SuperApp/1.0'\n >>> dirs.user_log_dir\n '/Users/trentm/Library/Logs/SuperApp/1.0'\n >>> dirs.user_documents_dir\n '/Users/trentm/Documents'\n >>> dirs.user_runtime_dir\n '/Users/trentm/Library/Caches/TemporaryItems/SuperApp/1.0'\n\nBe wary of using this for configuration files though; you'll need to handle\nmigrating configuration files manually.\n\nWhy this Fork?\n==============\n\nThis repository is a friendly fork of the wonderful work started by\n`ActiveState `_ who created\n``appdirs``, this package's ancestor.\n\nMaintaining an open source project is no easy task, particularly\nfrom within an organization, and the Python community is indebted\nto ``appdirs`` (and to Trent Mick and Jeff Rouse in particular) for\ncreating an incredibly useful simple module, as evidenced by the wide\nnumber of users it has attracted over the years.\n\nNonetheless, given the number of long-standing open issues\nand pull requests, and no clear path towards `ensuring\nthat maintenance of the package would continue or grow\n`_, this fork was\ncreated.\n\nContributions are most welcome.", - "release_date": "2021-09-25T20:46:06", - "parties": [ - { - "type": "person", - "role": "maintainer", - "name": "Bern\u00e1t G\u00e1bor, Julian Berman, Ofek Lev, Ronny Pfannschmidt", - "email": "gaborjbernat@gmail.com, Julian@GrayVines.com, oss@ofek.dev, opensource@ronnypfannschmidt.de", - "url": null - } - ], - "keywords": [ - "application directory log cache user", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "https://github.com/platformdirs/platformdirs", - "download_url": "https://files.pythonhosted.org/packages/4b/96/d70b9462671fbeaacba4639ff866fb4e9e558580853fc5d6e698d0371ad4/platformdirs-2.4.0.tar.gz", - "size": 24051, - "sha1": null, - "md5": "4e5b836d19600cc4bf0b789ab1de3b51", - "sha256": "367a5e80b3d04d2428ffa76d33f124cf11e8fff2acdaa9b43d545f5c7d661ef2", - "sha512": null, - "bug_tracking_url": "https://github.com/platformdirs/platformdirs/issues", - "code_view_url": "https://github.com/platformdirs/platformdirs", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/platformdirs/2.4.0/json", - "datasource_id": null, - "purl": "pkg:pypi/platformdirs@2.4.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "pluggy", - "version": "1.0.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "plugin and hook calling mechanisms for python\n====================================================\npluggy - A minimalist production ready plugin system\n====================================================\n\n|pypi| |conda-forge| |versions| |github-actions| |gitter| |black| |codecov|\n\nThis is the core framework used by the `pytest`_, `tox`_, and `devpi`_ projects.\n\nPlease `read the docs`_ to learn more!\n\nA definitive example\n====================\n.. code-block:: python\n\n import pluggy\n\n hookspec = pluggy.HookspecMarker(\"myproject\")\n hookimpl = pluggy.HookimplMarker(\"myproject\")\n\n\n class MySpec:\n \"\"\"A hook specification namespace.\"\"\"\n\n @hookspec\n def myhook(self, arg1, arg2):\n \"\"\"My special little hook that you can customize.\"\"\"\n\n\n class Plugin_1:\n \"\"\"A hook implementation namespace.\"\"\"\n\n @hookimpl\n def myhook(self, arg1, arg2):\n print(\"inside Plugin_1.myhook()\")\n return arg1 + arg2\n\n\n class Plugin_2:\n \"\"\"A 2nd hook implementation namespace.\"\"\"\n\n @hookimpl\n def myhook(self, arg1, arg2):\n print(\"inside Plugin_2.myhook()\")\n return arg1 - arg2\n\n\n # create a manager and add the spec\n pm = pluggy.PluginManager(\"myproject\")\n pm.add_hookspecs(MySpec)\n\n # register plugins\n pm.register(Plugin_1())\n pm.register(Plugin_2())\n\n # call our ``myhook`` hook\n results = pm.hook.myhook(arg1=1, arg2=2)\n print(results)\n\n\nRunning this directly gets us::\n\n $ python docs/examples/toy-example.py\n inside Plugin_2.myhook()\n inside Plugin_1.myhook()\n [-1, 3]\n\n\n.. badges\n\n.. |pypi| image:: https://img.shields.io/pypi/v/pluggy.svg\n :target: https://pypi.org/pypi/pluggy\n\n.. |versions| image:: https://img.shields.io/pypi/pyversions/pluggy.svg\n :target: https://pypi.org/pypi/pluggy\n\n.. |github-actions| image:: https://github.com/pytest-dev/pluggy/workflows/main/badge.svg\n :target: https://github.com/pytest-dev/pluggy/actions\n\n.. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pluggy.svg\n :target: https://anaconda.org/conda-forge/pytest\n\n.. |gitter| image:: https://badges.gitter.im/pytest-dev/pluggy.svg\n :alt: Join the chat at https://gitter.im/pytest-dev/pluggy\n :target: https://gitter.im/pytest-dev/pluggy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge\n\n.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/ambv/black\n\n.. |codecov| image:: https://codecov.io/gh/pytest-dev/pluggy/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/pytest-dev/pluggy\n :alt: Code coverage Status\n\n.. links\n.. _pytest:\n http://pytest.org\n.. _tox:\n https://tox.readthedocs.org\n.. _devpi:\n http://doc.devpi.net\n.. _read the docs:\n https://pluggy.readthedocs.io/en/latest/", - "release_date": "2021-08-25T16:25:59", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Holger Krekel", - "email": "holger@merlinux.eu", - "url": null - } - ], - "keywords": [ - "Development Status :: 6 - Mature", - "Intended Audience :: Developers", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Programming Language :: Python :: 3", - "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", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries", - "Topic :: Software Development :: Testing", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/pytest-dev/pluggy", - "download_url": "https://files.pythonhosted.org/packages/9e/01/f38e2ff29715251cf25532b9082a1589ab7e4f571ced434f98d0139336dc/pluggy-1.0.0-py2.py3-none-any.whl", - "size": 13667, - "sha1": null, - "md5": "40cd7d4a87f8ade524489d750647637b", - "sha256": "74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pluggy/1.0.0/json", - "datasource_id": null, - "purl": "pkg:pypi/pluggy@1.0.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "pluggy", - "version": "1.0.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "plugin and hook calling mechanisms for python\n====================================================\npluggy - A minimalist production ready plugin system\n====================================================\n\n|pypi| |conda-forge| |versions| |github-actions| |gitter| |black| |codecov|\n\nThis is the core framework used by the `pytest`_, `tox`_, and `devpi`_ projects.\n\nPlease `read the docs`_ to learn more!\n\nA definitive example\n====================\n.. code-block:: python\n\n import pluggy\n\n hookspec = pluggy.HookspecMarker(\"myproject\")\n hookimpl = pluggy.HookimplMarker(\"myproject\")\n\n\n class MySpec:\n \"\"\"A hook specification namespace.\"\"\"\n\n @hookspec\n def myhook(self, arg1, arg2):\n \"\"\"My special little hook that you can customize.\"\"\"\n\n\n class Plugin_1:\n \"\"\"A hook implementation namespace.\"\"\"\n\n @hookimpl\n def myhook(self, arg1, arg2):\n print(\"inside Plugin_1.myhook()\")\n return arg1 + arg2\n\n\n class Plugin_2:\n \"\"\"A 2nd hook implementation namespace.\"\"\"\n\n @hookimpl\n def myhook(self, arg1, arg2):\n print(\"inside Plugin_2.myhook()\")\n return arg1 - arg2\n\n\n # create a manager and add the spec\n pm = pluggy.PluginManager(\"myproject\")\n pm.add_hookspecs(MySpec)\n\n # register plugins\n pm.register(Plugin_1())\n pm.register(Plugin_2())\n\n # call our ``myhook`` hook\n results = pm.hook.myhook(arg1=1, arg2=2)\n print(results)\n\n\nRunning this directly gets us::\n\n $ python docs/examples/toy-example.py\n inside Plugin_2.myhook()\n inside Plugin_1.myhook()\n [-1, 3]\n\n\n.. badges\n\n.. |pypi| image:: https://img.shields.io/pypi/v/pluggy.svg\n :target: https://pypi.org/pypi/pluggy\n\n.. |versions| image:: https://img.shields.io/pypi/pyversions/pluggy.svg\n :target: https://pypi.org/pypi/pluggy\n\n.. |github-actions| image:: https://github.com/pytest-dev/pluggy/workflows/main/badge.svg\n :target: https://github.com/pytest-dev/pluggy/actions\n\n.. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pluggy.svg\n :target: https://anaconda.org/conda-forge/pytest\n\n.. |gitter| image:: https://badges.gitter.im/pytest-dev/pluggy.svg\n :alt: Join the chat at https://gitter.im/pytest-dev/pluggy\n :target: https://gitter.im/pytest-dev/pluggy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge\n\n.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/ambv/black\n\n.. |codecov| image:: https://codecov.io/gh/pytest-dev/pluggy/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/pytest-dev/pluggy\n :alt: Code coverage Status\n\n.. links\n.. _pytest:\n http://pytest.org\n.. _tox:\n https://tox.readthedocs.org\n.. _devpi:\n http://doc.devpi.net\n.. _read the docs:\n https://pluggy.readthedocs.io/en/latest/", - "release_date": "2021-08-25T16:26:02", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Holger Krekel", - "email": "holger@merlinux.eu", - "url": null - } - ], - "keywords": [ - "Development Status :: 6 - Mature", - "Intended Audience :: Developers", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Programming Language :: Python :: 3", - "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", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries", - "Topic :: Software Development :: Testing", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/pytest-dev/pluggy", - "download_url": "https://files.pythonhosted.org/packages/a1/16/db2d7de3474b6e37cbb9c008965ee63835bba517e22cdb8c35b5116b5ce1/pluggy-1.0.0.tar.gz", - "size": 51510, - "sha1": null, - "md5": "daa6fddfb6cd364f3c82e52098911e4b", - "sha256": "4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pluggy/1.0.0/json", - "datasource_id": null, - "purl": "pkg:pypi/pluggy@1.0.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "py", - "version": "1.11.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "library with cross-python path, ini-parsing, io, code, log facilities\n.. image:: https://img.shields.io/pypi/v/py.svg\n :target: https://pypi.org/project/py\n\n.. image:: https://img.shields.io/conda/vn/conda-forge/py.svg\n :target: https://anaconda.org/conda-forge/py\n\n.. image:: https://img.shields.io/pypi/pyversions/py.svg\n :target: https://pypi.org/project/py\n\n.. image:: https://github.com/pytest-dev/py/workflows/build/badge.svg\n :target: https://github.com/pytest-dev/py/actions\n\n\n**NOTE**: this library is in **maintenance mode** and should not be used in new code.\n\nThe py lib is a Python development support library featuring\nthe following tools and modules:\n\n* ``py.path``: uniform local and svn path objects -> please use pathlib/pathlib2 instead\n* ``py.apipkg``: explicit API control and lazy-importing -> please use the standalone package instead\n* ``py.iniconfig``: easy parsing of .ini files -> please use the standalone package instead\n* ``py.code``: dynamic code generation and introspection (deprecated, moved to ``pytest`` as a implementation detail).\n\n**NOTE**: prior to the 1.4 release this distribution used to\ncontain py.test which is now its own package, see https://docs.pytest.org\n\nFor questions and more information please visit https://py.readthedocs.io\n\nBugs and issues: https://github.com/pytest-dev/py\n\nAuthors: Holger Krekel and others, 2004-2017", - "release_date": "2021-11-04T17:17:00", - "parties": [ - { - "type": "person", - "role": "author", - "name": "holger krekel, Ronny Pfannschmidt, Benjamin Peterson and others", - "email": "pytest-dev@python.org", - "url": null - } - ], - "keywords": [ - "Development Status :: 6 - Mature", - "Intended Audience :: Developers", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries", - "Topic :: Software Development :: Testing", - "Topic :: Utilities" - ], - "homepage_url": "https://py.readthedocs.io/", - "download_url": "https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl", - "size": 98708, - "sha1": null, - "md5": "52d444d43edb21938fad6010a2134cc3", - "sha256": "607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT license", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/py/1.11.0/json", - "datasource_id": null, - "purl": "pkg:pypi/py@1.11.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "py", - "version": "1.11.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "library with cross-python path, ini-parsing, io, code, log facilities\n.. image:: https://img.shields.io/pypi/v/py.svg\n :target: https://pypi.org/project/py\n\n.. image:: https://img.shields.io/conda/vn/conda-forge/py.svg\n :target: https://anaconda.org/conda-forge/py\n\n.. image:: https://img.shields.io/pypi/pyversions/py.svg\n :target: https://pypi.org/project/py\n\n.. image:: https://github.com/pytest-dev/py/workflows/build/badge.svg\n :target: https://github.com/pytest-dev/py/actions\n\n\n**NOTE**: this library is in **maintenance mode** and should not be used in new code.\n\nThe py lib is a Python development support library featuring\nthe following tools and modules:\n\n* ``py.path``: uniform local and svn path objects -> please use pathlib/pathlib2 instead\n* ``py.apipkg``: explicit API control and lazy-importing -> please use the standalone package instead\n* ``py.iniconfig``: easy parsing of .ini files -> please use the standalone package instead\n* ``py.code``: dynamic code generation and introspection (deprecated, moved to ``pytest`` as a implementation detail).\n\n**NOTE**: prior to the 1.4 release this distribution used to\ncontain py.test which is now its own package, see https://docs.pytest.org\n\nFor questions and more information please visit https://py.readthedocs.io\n\nBugs and issues: https://github.com/pytest-dev/py\n\nAuthors: Holger Krekel and others, 2004-2017", - "release_date": "2021-11-04T17:17:01", - "parties": [ - { - "type": "person", - "role": "author", - "name": "holger krekel, Ronny Pfannschmidt, Benjamin Peterson and others", - "email": "pytest-dev@python.org", - "url": null - } - ], - "keywords": [ - "Development Status :: 6 - Mature", - "Intended Audience :: Developers", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries", - "Topic :: Software Development :: Testing", - "Topic :: Utilities" - ], - "homepage_url": "https://py.readthedocs.io/", - "download_url": "https://files.pythonhosted.org/packages/98/ff/fec109ceb715d2a6b4c4a85a61af3b40c723a961e8828319fbcb15b868dc/py-1.11.0.tar.gz", - "size": 207796, - "sha1": null, - "md5": "bde7dcc1cb452a1e10206ef2f811ba88", - "sha256": "51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT license", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/py/1.11.0/json", - "datasource_id": null, - "purl": "pkg:pypi/py@1.11.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "pycodestyle", - "version": "2.8.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "pycodestyle (formerly called pep8) - Python style guide checker\n===============================================================\n\n.. image:: https://github.com/PyCQA/pycodestyle/actions/workflows/main.yml/badge.svg\n :target: https://github.com/PyCQA/pycodestyle/actions/workflows/main.yml\n :alt: Build status\n\n.. image:: https://readthedocs.org/projects/pycodestyle/badge/?version=latest\n :target: https://pycodestyle.pycqa.org\n :alt: Documentation Status\n\n.. image:: https://img.shields.io/pypi/wheel/pycodestyle.svg\n :target: https://pypi.org/project/pycodestyle/\n :alt: Wheel Status\n\n.. image:: https://badges.gitter.im/PyCQA/pycodestyle.svg\n :alt: Join the chat at https://gitter.im/PyCQA/pycodestyle\n :target: https://gitter.im/PyCQA/pycodestyle?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge\n\npycodestyle is a tool to check your Python code against some of the style\nconventions in `PEP 8`_.\n\n.. _PEP 8: http://www.python.org/dev/peps/pep-0008/\n\n.. note::\n\n This package used to be called ``pep8`` but was renamed to ``pycodestyle``\n to reduce confusion. Further discussion can be found `in the issue where\n Guido requested this\n change `_, or in the\n lightning talk at PyCon 2016 by @IanLee1521:\n `slides `_\n `video `_.\n\nFeatures\n--------\n\n* Plugin architecture: Adding new checks is easy.\n\n* Parseable output: Jump to error location in your editor.\n\n* Small: Just one Python file, requires only stdlib. You can use just\n the ``pycodestyle.py`` file for this purpose.\n\n* Comes with a comprehensive test suite.\n\nInstallation\n------------\n\nYou can install, upgrade, and uninstall ``pycodestyle.py`` with these commands::\n\n $ pip install pycodestyle\n $ pip install --upgrade pycodestyle\n $ pip uninstall pycodestyle\n\nThere's also a package for Debian/Ubuntu, but it's not always the\nlatest version.\n\nExample usage and output\n------------------------\n\n::\n\n $ pycodestyle --first optparse.py\n optparse.py:69:11: E401 multiple imports on one line\n optparse.py:77:1: E302 expected 2 blank lines, found 1\n optparse.py:88:5: E301 expected 1 blank line, found 0\n optparse.py:222:34: W602 deprecated form of raising exception\n optparse.py:347:31: E211 whitespace before '('\n optparse.py:357:17: E201 whitespace after '{'\n optparse.py:472:29: E221 multiple spaces before operator\n optparse.py:544:21: W601 .has_key() is deprecated, use 'in'\n\nYou can also make ``pycodestyle.py`` show the source code for each error, and\neven the relevant text from PEP 8::\n\n $ pycodestyle --show-source --show-pep8 testsuite/E40.py\n testsuite/E40.py:2:10: E401 multiple imports on one line\n import os, sys\n ^\n Imports should usually be on separate lines.\n\n Okay: import os\\nimport sys\n E401: import sys, os\n\n\nOr you can display how often each error was found::\n\n $ pycodestyle --statistics -qq Python-2.5/Lib\n 232 E201 whitespace after '['\n 599 E202 whitespace before ')'\n 631 E203 whitespace before ','\n 842 E211 whitespace before '('\n 2531 E221 multiple spaces before operator\n 4473 E301 expected 1 blank line, found 0\n 4006 E302 expected 2 blank lines, found 1\n 165 E303 too many blank lines (4)\n 325 E401 multiple imports on one line\n 3615 E501 line too long (82 characters)\n 612 W601 .has_key() is deprecated, use 'in'\n 1188 W602 deprecated form of raising exception\n\nLinks\n-----\n\n* `Read the documentation `_\n\n* `Fork me on GitHub `_\n\n\nChangelog\n=========\n\n2.8.0 (2021-10-10)\n------------------\n\nChanges:\n\n* Drop python 3.4. PR #982.\n* E712: fix false negative with multiple comparisons. PR #987.\n* E211: fix false positives with ``match``. PR #989.\n* E772: improve performance of bare except check. PR #992.\n* Backport tokenize performance improvement from python 3.10. PR #993.\n* E225: fix for lambdas containing positional-only args. PR #1012.\n* Remove ``indent_size_str`` \"setting\". PR #995.\n* E402: allow ``__all__`` to be typed. PR #1019.\n* E225: fix false positives for ``*`` in ``case``. PR #1003.\n* E201: detect tabs as whitespace. PR #1015.\n\n\n2.7.0 (2021-03-14)\n------------------\n\nChanges:\n\n* Fix physical checks (such as W191) at end of file. PR #961.\n* Add ``--indent-size`` option (defaulting to ``4``). PR #970.\n* W605: fix escaped crlf false positive on windows. PR #976.\n\n\n2.6.0 (2020-05-11)\n------------------\n\nAnnouncements:\n\n* Anthony Sottile (@asottile) joined the team as a core developer. :tada:\n\nChanges:\n\n* E306: fix detection inside ``async def``. PR #929.\n* E301: fix regression disallowing decorated one-liners. PR #927.\n* E714: fix false positive with chained ``is not``. PR #931.\n\n\n2.6.0a1 (2020-04-23)\n--------------------\n\nNew checks:\n\n* E225: require whitespace around ``and`` ``in`` ``is`` and ``or``. PR #847.\n\nChanges:\n\n* E117: fix indentation using tabs by treating as 8-space indents. PR #837.\n* E721: fix false positive with names containg ``istype``. PR #850.\n* E741: allow ``l`` as a named argument in a function call. PR #853.\n* E302: fix false-negative with decorated functions. PR #859.\n* W504: ellipsis (``...``) is no longer treated as a binary operator. PR #875.\n* E402: allow ``with``, ``if``, ``elif``, ``else`` to guard imports. PR #834.\n* Add support for assignment expressions ``:=`` (PEP 572). PR #879.\n* Add support for positional-only arguments ``/`` (PEP 570). PR #872, #918.\n* Add support for python 3.8.\n* Add support for matrix multiplication operator ``@`` (PEP 465). PR #897.\n* Support visual indent for continuation lines for ``with`` / ``assert`` /\n ``raise``. PR #912.\n* E302: allow two blank lines after a block of one-liners. PR #913.\n* E302: allow two-and-fewer newlines at the top of the file. PR #919.\n\n\n2.5.0 (2019-01-29)\n------------------\n\nNew checks:\n\n* E117: Over-indented code blocks\n* W505: Maximum doc-string length only when configured with --max-doc-length\n\nChanges:\n\n* Remove support for EOL Python 2.6 and 3.3. PR #720.\n* Add E117 error for over-indented code blocks.\n* Allow W605 to be silenced by `# noqa` and fix the position reported by W605\n* Allow users to omit blank lines around one-liner definitions of classes and\n functions\n* Include the function return annotation (``->``) as requiring surrounding\n whitespace only on Python 3\n* Verify that only names can follow ``await``. Previously we allowed numbers\n and strings.\n* Add support for Python 3.7\n* Fix detection of annotated argument defaults for E252\n* Correct the position reported by W504\n\n\n2.4.0 (2018-04-10)\n------------------\n\nNew checks:\n\n* Add W504 warning for checking that a break doesn't happen after a binary\n operator. This check is ignored by default. PR #502.\n* Add W605 warning for invalid escape sequences in string literals. PR #676.\n* Add W606 warning for 'async' and 'await' reserved keywords being introduced\n in Python 3.7. PR #684.\n* Add E252 error for missing whitespace around equal sign in type annotated\n function arguments with defaults values. PR #717.\n\nChanges:\n\n* An internal bisect search has replaced a linear search in order to improve\n efficiency. PR #648.\n* pycodestyle now uses PyPI trove classifiers in order to document supported\n python versions on PyPI. PR #654.\n* 'setup.cfg' '[wheel]' section has been renamed to '[bdist_wheel]', as\n the former is legacy. PR #653.\n* pycodestyle now handles very long lines much more efficiently for python\n 3.2+. Fixes #643. PR #644.\n* You can now write 'pycodestyle.StyleGuide(verbose=True)' instead of\n 'pycodestyle.StyleGuide(verbose=True, paths=['-v'])' in order to achieve\n verbosity. PR #663.\n* The distribution of pycodestyle now includes the license text in order to\n comply with open source licenses which require this. PR #694.\n* 'maximum_line_length' now ignores shebang ('#!') lines. PR #736.\n* Add configuration option for the allowed number of blank lines. It is\n implemented as a top level dictionary which can be easily overwritten. Fixes\n #732. PR #733.\n\nBugs:\n\n* Prevent a 'DeprecationWarning', and a 'SyntaxError' in future python, caused\n by an invalid escape sequence. PR #625.\n* Correctly report E501 when the first line of a docstring is too long.\n Resolves #622. PR #630.\n* Support variable annotation when variable start by a keyword, such as class\n variable type annotations in python 3.6. PR #640.\n* pycodestyle internals have been changed in order to allow 'python3 -m\n cProfile' to report correct metrics. PR #647.\n* Fix a spelling mistake in the description of E722. PR #697.\n* 'pycodestyle --diff' now does not break if your 'gitconfig' enables\n 'mnemonicprefix'. PR #706.\n\n2.3.1 (2017-01-31)\n------------------\n\nBugs:\n\n* Fix regression in detection of E302 and E306; #618, #620\n\n2.3.0 (2017-01-30)\n------------------\n\nNew Checks:\n\n* Add E722 warning for bare ``except`` clauses\n* Report E704 for async function definitions (``async def``)\n\nBugs:\n\n* Fix another E305 false positive for variables beginning with \"class\" or\n \"def\"\n* Fix detection of multiple spaces between ``async`` and ``def``\n* Fix handling of variable annotations. Stop reporting E701 on Python 3.6 for\n variable annotations.\n\n2.2.0 (2016-11-14)\n------------------\n\nAnnouncements:\n\n* Added Make target to obtain proper tarball file permissions; #599\n\nBugs:\n\n* Fixed E305 regression caused by #400; #593\n\n2.1.0 (2016-11-04)\n------------------\n\nAnnouncements:\n\n* Change all references to the pep8 project to say pycodestyle; #530\n\nChanges:\n\n* Report E302 for blank lines before an \"async def\"; #556\n* Update our list of tested and supported Python versions which are 2.6, 2.7,\n 3.2, 3.3, 3.4 and 3.5 as well as the nightly Python build and PyPy.\n* Report E742 and E743 for functions and classes badly named 'l', 'O', or 'I'.\n* Report E741 on 'global' and 'nonlocal' statements, as well as prohibited\n single-letter variables.\n* Deprecated use of `[pep8]` section name in favor of `[pycodestyle]`; #591\n* Report E722 when bare except clause is used; #579\n\nBugs:\n\n* Fix opt_type AssertionError when using Flake8 2.6.2 and pycodestyle; #561\n* Require two blank lines after toplevel def, class; #536\n* Remove accidentally quadratic computation based on the number of colons. This\n will make pycodestyle faster in some cases; #314\n\n2.0.0 (2016-05-31)\n------------------\n\nAnnouncements:\n\n* Repository renamed to `pycodestyle`; Issue #466 / #481.\n* Added joint Code of Conduct as member of PyCQA; #483\n\nChanges:\n\n* Added tox test support for Python 3.5 and pypy3\n* Added check E275 for whitespace on `from ... import ...` lines; #489 / #491\n* Added W503 to the list of codes ignored by default ignore list; #498\n* Removed use of project level `.pep8` configuration file; #364\n\nBugs:\n\n* Fixed bug with treating `~` operator as binary; #383 / #384\n* Identify binary operators as unary; #484 / #485\n\n1.7.0 (2016-01-12)\n------------------\n\nAnnouncements:\n\n* Repository moved to PyCQA Organization on GitHub:\n https://github.com/pycqa/pep8\n\nChanges:\n\n* Reverted the fix in #368, \"options passed on command line are only ones\n accepted\" feature. This has many unintended consequences in pep8 and flake8\n and needs to be reworked when I have more time.\n* Added support for Python 3.5. (Issue #420 & #459)\n* Added support for multi-line config_file option parsing. (Issue #429)\n* Improved parameter parsing. (Issues #420 & #456)\n\nBugs:\n\n* Fixed BytesWarning on Python 3. (Issue #459)\n\n1.6.2 (2015-02-15)\n------------------\n\nChanges:\n\n* Added check for breaking around a binary operator. (Issue #197, Pull #305)\n\nBugs:\n\n* Restored config_file parameter in process_options(). (Issue #380)\n\n\n1.6.1 (2015-02-08)\n------------------\n\nChanges:\n\n* Assign variables before referenced. (Issue #287)\n\nBugs:\n\n* Exception thrown due to unassigned ``local_dir`` variable. (Issue #377)\n\n\n1.6.0 (2015-02-06)\n------------------\n\nNews:\n\n* Ian Lee joined the project as a maintainer.\n\nChanges:\n\n* Report E731 for lambda assignment. (Issue #277)\n\n* Report E704 for one-liner def instead of E701.\n Do not report this error in the default configuration. (Issue #277)\n\n* Replace codes E111, E112 and E113 with codes E114, E115 and E116\n for bad indentation of comments. (Issue #274)\n\n* Report E266 instead of E265 when the block comment starts with\n multiple ``#``. (Issue #270)\n\n* Report E402 for import statements not at the top of the file. (Issue #264)\n\n* Do not enforce whitespaces around ``**`` operator. (Issue #292)\n\n* Strip whitespace from around paths during normalization. (Issue #339 / #343)\n\n* Update ``--format`` documentation. (Issue #198 / Pull Request #310)\n\n* Add ``.tox/`` to default excludes. (Issue #335)\n\n* Do not report E121 or E126 in the default configuration. (Issues #256 / #316)\n\n* Allow spaces around the equals sign in an annotated function. (Issue #357)\n\n* Allow trailing backslash if in an inline comment. (Issue #374)\n\n* If ``--config`` is used, only that configuration is processed. Otherwise,\n merge the user and local configurations are merged. (Issue #368 / #369)\n\nBug fixes:\n\n* Don't crash if Checker.build_tokens_line() returns None. (Issue #306)\n\n* Don't crash if os.path.expanduser() throws an ImportError. (Issue #297)\n\n* Missing space around keyword parameter equal not always reported, E251.\n (Issue #323)\n\n* Fix false positive E711/E712/E713. (Issues #330 and #336)\n\n* Do not skip physical checks if the newline is escaped. (Issue #319)\n\n* Flush sys.stdout to avoid race conditions with printing. See flake8 bug:\n https://gitlab.com/pycqa/flake8/issues/17 for more details. (Issue #363)\n\n\n1.5.7 (2014-05-29)\n------------------\n\nBug fixes:\n\n* Skip the traceback on \"Broken pipe\" signal. (Issue #275)\n\n* Do not exit when an option in ``setup.cfg`` or ``tox.ini``\n is not recognized.\n\n* Check the last line even if it does not end with a newline. (Issue #286)\n\n* Always open files in universal newlines mode in Python 2. (Issue #288)\n\n\n1.5.6 (2014-04-14)\n------------------\n\nBug fixes:\n\n* Check the last line even if it has no end-of-line. (Issue #273)\n\n\n1.5.5 (2014-04-10)\n------------------\n\nBug fixes:\n\n* Fix regression with E22 checks and inline comments. (Issue #271)\n\n\n1.5.4 (2014-04-07)\n------------------\n\nBug fixes:\n\n* Fix negative offset with E303 before a multi-line docstring.\n (Issue #269)\n\n\n1.5.3 (2014-04-04)\n------------------\n\nBug fixes:\n\n* Fix wrong offset computation when error is on the last char\n of a physical line. (Issue #268)\n\n\n1.5.2 (2014-04-04)\n------------------\n\nChanges:\n\n* Distribute a universal wheel file.\n\nBug fixes:\n\n* Report correct line number for E303 with comments. (Issue #60)\n\n* Do not allow newline after parameter equal. (Issue #252)\n\n* Fix line number reported for multi-line strings. (Issue #220)\n\n* Fix false positive E121/E126 with multi-line strings. (Issue #265)\n\n* Fix E501 not detected in comments with Python 2.5.\n\n* Fix caret position with ``--show-source`` when line contains tabs.\n\n\n1.5.1 (2014-03-27)\n------------------\n\nBug fixes:\n\n* Fix a crash with E125 on multi-line strings. (Issue #263)\n\n\n1.5 (2014-03-26)\n----------------\n\nChanges:\n\n* Report E129 instead of E125 for visually indented line with same\n indent as next logical line. (Issue #126)\n\n* Report E265 for space before block comment. (Issue #190)\n\n* Report E713 and E714 when operators ``not in`` and ``is not`` are\n recommended. (Issue #236)\n\n* Allow long lines in multiline strings and comments if they cannot\n be wrapped. (Issue #224).\n\n* Optionally disable physical line checks inside multiline strings,\n using ``# noqa``. (Issue #242)\n\n* Change text for E121 to report \"continuation line under-indented\n for hanging indent\" instead of indentation not being a\n multiple of 4.\n\n* Report E131 instead of E121 / E126 if the hanging indent is not\n consistent within the same continuation block. It helps when\n error E121 or E126 is in the ``ignore`` list.\n\n* Report E126 instead of E121 when the continuation line is hanging\n with extra indentation, even if indentation is not a multiple of 4.\n\nBug fixes:\n\n* Allow the checkers to report errors on empty files. (Issue #240)\n\n* Fix ignoring too many checks when ``--select`` is used with codes\n declared in a flake8 extension. (Issue #216)\n\n* Fix regression with multiple brackets. (Issue #214)\n\n* Fix ``StyleGuide`` to parse the local configuration if the\n keyword argument ``paths`` is specified. (Issue #246)\n\n* Fix a false positive E124 for hanging indent. (Issue #254)\n\n* Fix a false positive E126 with embedded colon. (Issue #144)\n\n* Fix a false positive E126 when indenting with tabs. (Issue #204)\n\n* Fix behaviour when ``exclude`` is in the configuration file and\n the current directory is not the project directory. (Issue #247)\n\n* The logical checks can return ``None`` instead of an empty iterator.\n (Issue #250)\n\n* Do not report multiple E101 if only the first indentation starts\n with a tab. (Issue #237)\n\n* Fix a rare false positive W602. (Issue #34)\n\n\n1.4.6 (2013-07-02)\n------------------\n\nChanges:\n\n* Honor ``# noqa`` for errors E711 and E712. (Issue #180)\n\n* When both a ``tox.ini`` and a ``setup.cfg`` are present in the project\n directory, merge their contents. The ``tox.ini`` file takes\n precedence (same as before). (Issue #182)\n\n* Give priority to ``--select`` over ``--ignore``. (Issue #188)\n\n* Compare full path when excluding a file. (Issue #186)\n\n* New option ``--hang-closing`` to switch to the alternative style of\n closing bracket indentation for hanging indent. Add error E133 for\n closing bracket which is missing indentation. (Issue #103)\n\n* Accept both styles of closing bracket indentation for hanging indent.\n Do not report error E123 in the default configuration. (Issue #103)\n\nBug fixes:\n\n* Do not crash when running AST checks and the document contains null bytes.\n (Issue #184)\n\n* Correctly report other E12 errors when E123 is ignored. (Issue #103)\n\n* Fix false positive E261/E262 when the file contains a BOM. (Issue #193)\n\n* Fix E701, E702 and E703 not detected sometimes. (Issue #196)\n\n* Fix E122 not detected in some cases. (Issue #201 and #208)\n\n* Fix false positive E121 with multiple brackets. (Issue #203)\n\n\n1.4.5 (2013-03-06)\n------------------\n\n* When no path is specified, do not try to read from stdin. The feature\n was added in 1.4.3, but it is not supported on Windows. Use ``-``\n filename argument to read from stdin. This usage is supported\n since 1.3.4. (Issue #170)\n\n* Do not require ``setuptools`` in setup.py. It works around an issue\n with ``pip`` and Python 3. (Issue #172)\n\n* Add ``__pycache__`` to the ignore list.\n\n* Change misleading message for E251. (Issue #171)\n\n* Do not report false E302 when the source file has a coding cookie or a\n comment on the first line. (Issue #174)\n\n* Reorganize the tests and add tests for the API and for the command line\n usage and options. (Issues #161 and #162)\n\n* Ignore all checks which are not explicitly selected when ``select`` is\n passed to the ``StyleGuide`` constructor.\n\n\n1.4.4 (2013-02-24)\n------------------\n\n* Report E227 or E228 instead of E225 for whitespace around bitwise, shift\n or modulo operators. (Issue #166)\n\n* Change the message for E226 to make clear that it is about arithmetic\n operators.\n\n* Fix a false positive E128 for continuation line indentation with tabs.\n\n* Fix regression with the ``--diff`` option. (Issue #169)\n\n* Fix the ``TestReport`` class to print the unexpected warnings and\n errors.\n\n\n1.4.3 (2013-02-22)\n------------------\n\n* Hide the ``--doctest`` and ``--testsuite`` options when installed.\n\n* Fix crash with AST checkers when the syntax is invalid. (Issue #160)\n\n* Read from standard input if no path is specified.\n\n* Initiate a graceful shutdown on ``Control+C``.\n\n* Allow changing the ``checker_class`` for the ``StyleGuide``.\n\n\n1.4.2 (2013-02-10)\n------------------\n\n* Support AST checkers provided by third-party applications.\n\n* Register new checkers with ``register_check(func_or_cls, codes)``.\n\n* Allow constructing a ``StyleGuide`` with a custom parser.\n\n* Accept visual indentation without parenthesis after the ``if``\n statement. (Issue #151)\n\n* Fix UnboundLocalError when using ``# noqa`` with continued lines.\n (Issue #158)\n\n* Re-order the lines for the ``StandardReport``.\n\n* Expand tabs when checking E12 continuation lines. (Issue #155)\n\n* Refactor the testing class ``TestReport`` and the specific test\n functions into a separate test module.\n\n\n1.4.1 (2013-01-18)\n------------------\n\n* Allow sphinx.ext.autodoc syntax for comments. (Issue #110)\n\n* Report E703 instead of E702 for the trailing semicolon. (Issue #117)\n\n* Honor ``# noqa`` in addition to ``# nopep8``. (Issue #149)\n\n* Expose the ``OptionParser`` factory for better extensibility.\n\n\n1.4 (2012-12-22)\n----------------\n\n* Report E226 instead of E225 for optional whitespace around common\n operators (``*``, ``**``, ``/``, ``+`` and ``-``). This new error\n code is ignored in the default configuration because PEP 8 recommends\n to \"use your own judgement\". (Issue #96)\n\n* Lines with a ``# nopep8`` at the end will not issue errors on line\n length E501 or continuation line indentation E12*. (Issue #27)\n\n* Fix AssertionError when the source file contains an invalid line\n ending ``\"\\r\\r\\n\"``. (Issue #119)\n\n* Read the ``[pep8]`` section of ``tox.ini`` or ``setup.cfg`` if present.\n (Issue #93 and #141)\n\n* Add the Sphinx-based documentation, and publish it\n on https://pycodestyle.readthedocs.io/. (Issue #105)\n\n\n1.3.4 (2012-12-18)\n------------------\n\n* Fix false positive E124 and E128 with comments. (Issue #100)\n\n* Fix error on stdin when running with bpython. (Issue #101)\n\n* Fix false positive E401. (Issue #104)\n\n* Report E231 for nested dictionary in list. (Issue #142)\n\n* Catch E271 at the beginning of the line. (Issue #133)\n\n* Fix false positive E126 for multi-line comments. (Issue #138)\n\n* Fix false positive E221 when operator is preceded by a comma. (Issue #135)\n\n* Fix ``--diff`` failing on one-line hunk. (Issue #137)\n\n* Fix the ``--exclude`` switch for directory paths. (Issue #111)\n\n* Use ``-`` filename to read from standard input. (Issue #128)\n\n\n1.3.3 (2012-06-27)\n------------------\n\n* Fix regression with continuation line checker. (Issue #98)\n\n\n1.3.2 (2012-06-26)\n------------------\n\n* Revert to the previous behaviour for ``--show-pep8``:\n do not imply ``--first``. (Issue #89)\n\n* Add E902 for IO errors. (Issue #87)\n\n* Fix false positive for E121, and missed E124. (Issue #92)\n\n* Set a sensible default path for config file on Windows. (Issue #95)\n\n* Allow ``verbose`` in the configuration file. (Issue #91)\n\n* Show the enforced ``max-line-length`` in the error message. (Issue #86)\n\n\n1.3.1 (2012-06-18)\n------------------\n\n* Explain which configuration options are expected. Accept and recommend\n the options names with hyphen instead of underscore. (Issue #82)\n\n* Do not read the user configuration when used as a module\n (except if ``config_file=True`` is passed to the ``StyleGuide`` constructor).\n\n* Fix wrong or missing cases for the E12 series.\n\n* Fix cases where E122 was missed. (Issue #81)\n\n\n1.3 (2012-06-15)\n----------------\n\n.. warning::\n The internal API is backwards incompatible.\n\n* Remove global configuration and refactor the library around\n a ``StyleGuide`` class; add the ability to configure various\n reporters. (Issue #35 and #66)\n\n* Read user configuration from ``~/.config/pep8``\n and local configuration from ``./.pep8``. (Issue #22)\n\n* Fix E502 for backslash embedded in multi-line string. (Issue #68)\n\n* Fix E225 for Python 3 iterable unpacking (PEP 3132). (Issue #72)\n\n* Enable the new checkers from the E12 series in the default\n configuration.\n\n* Suggest less error-prone alternatives for E712 errors.\n\n* Rewrite checkers to run faster (E22, E251, E27).\n\n* Fixed a crash when parsed code is invalid (too many\n closing brackets).\n\n* Fix E127 and E128 for continuation line indentation. (Issue #74)\n\n* New option ``--format`` to customize the error format. (Issue #23)\n\n* New option ``--diff`` to check only modified code. The unified\n diff is read from STDIN. Example: ``hg diff | pep8 --diff``\n (Issue #39)\n\n* Correctly report the count of failures and set the exit code to 1\n when the ``--doctest`` or the ``--testsuite`` fails.\n\n* Correctly detect the encoding in Python 3. (Issue #69)\n\n* Drop support for Python 2.3, 2.4 and 3.0. (Issue #78)\n\n\n1.2 (2012-06-01)\n----------------\n\n* Add E121 through E128 for continuation line indentation. These\n checks are disabled by default. If you want to force all checks,\n use switch ``--select=E,W``. Patch by Sam Vilain. (Issue #64)\n\n* Add E721 for direct type comparisons. (Issue #47)\n\n* Add E711 and E712 for comparisons to singletons. (Issue #46)\n\n* Fix spurious E225 and E701 for function annotations. (Issue #29)\n\n* Add E502 for explicit line join between brackets.\n\n* Fix E901 when printing source with ``--show-source``.\n\n* Report all errors for each checker, instead of reporting only the\n first occurrence for each line.\n\n* Option ``--show-pep8`` implies ``--first``.\n\n\n1.1 (2012-05-24)\n----------------\n\n* Add E901 for syntax errors. (Issues #63 and #30)\n\n* Add E271, E272, E273 and E274 for extraneous whitespace around\n keywords. (Issue #57)\n\n* Add ``tox.ini`` configuration file for tests. (Issue #61)\n\n* Add ``.travis.yml`` configuration file for continuous integration.\n (Issue #62)\n\n\n1.0.1 (2012-04-06)\n------------------\n\n* Fix inconsistent version numbers.\n\n\n1.0 (2012-04-04)\n----------------\n\n* Fix W602 ``raise`` to handle multi-char names. (Issue #53)\n\n\n0.7.0 (2012-03-26)\n------------------\n\n* Now ``--first`` prints only the first occurrence of each error.\n The ``--repeat`` flag becomes obsolete because it is the default\n behaviour. (Issue #6)\n\n* Allow specifying ``--max-line-length``. (Issue #36)\n\n* Make the shebang more flexible. (Issue #26)\n\n* Add testsuite to the bundle. (Issue #25)\n\n* Fixes for Jython. (Issue #49)\n\n* Add PyPI classifiers. (Issue #43)\n\n* Fix the ``--exclude`` option. (Issue #48)\n\n* Fix W602, accept ``raise`` with 3 arguments. (Issue #34)\n\n* Correctly select all tests if ``DEFAULT_IGNORE == ''``.\n\n\n0.6.1 (2010-10-03)\n------------------\n\n* Fix inconsistent version numbers. (Issue #21)\n\n\n0.6.0 (2010-09-19)\n------------------\n\n* Test suite reorganized and enhanced in order to check more failures\n with fewer test files. Read the ``run_tests`` docstring for details\n about the syntax.\n\n* Fix E225: accept ``print >>sys.stderr, \"...\"`` syntax.\n\n* Fix E501 for lines containing multibyte encoded characters. (Issue #7)\n\n* Fix E221, E222, E223, E224 not detected in some cases. (Issue #16)\n\n* Fix E211 to reject ``v = dic['a'] ['b']``. (Issue #17)\n\n* Exit code is always 1 if any error or warning is found. (Issue #10)\n\n* ``--ignore`` checks are now really ignored, especially in\n conjunction with ``--count``. (Issue #8)\n\n* Blank lines with spaces yield W293 instead of W291: some developers\n want to ignore this warning and indent the blank lines to paste their\n code easily in the Python interpreter.\n\n* Fix E301: do not require a blank line before an indented block. (Issue #14)\n\n* Fix E203 to accept NumPy slice notation ``a[0, :]``. (Issue #13)\n\n* Performance improvements.\n\n* Fix decoding and checking non-UTF8 files in Python 3.\n\n* Fix E225: reject ``True+False`` when running on Python 3.\n\n* Fix an exception when the line starts with an operator.\n\n* Allow a new line before closing ``)``, ``}`` or ``]``. (Issue #5)\n\n\n0.5.0 (2010-02-17)\n------------------\n\n* Changed the ``--count`` switch to print to sys.stderr and set\n exit code to 1 if any error or warning is found.\n\n* E241 and E242 are removed from the standard checks. If you want to\n include these checks, use switch ``--select=E,W``. (Issue #4)\n\n* Blank line is not mandatory before the first class method or nested\n function definition, even if there's a docstring. (Issue #1)\n\n* Add the switch ``--version``.\n\n* Fix decoding errors with Python 3. (Issue #13 [1]_)\n\n* Add ``--select`` option which is mirror of ``--ignore``.\n\n* Add checks E261 and E262 for spaces before inline comments.\n\n* New check W604 warns about deprecated usage of backticks.\n\n* New check W603 warns about the deprecated operator ``<>``.\n\n* Performance improvement, due to rewriting of E225.\n\n* E225 now accepts:\n\n - no whitespace after unary operator or similar. (Issue #9 [1]_)\n\n - lambda function with argument unpacking or keyword defaults.\n\n* Reserve \"2 blank lines\" for module-level logical blocks. (E303)\n\n* Allow multi-line comments. (E302, issue #10 [1]_)\n\n\n0.4.2 (2009-10-22)\n------------------\n\n* Decorators on classes and class methods are OK now.\n\n\n0.4 (2009-10-20)\n----------------\n\n* Support for all versions of Python from 2.3 to 3.1.\n\n* New and greatly expanded self tests.\n\n* Added ``--count`` option to print the total number of errors and warnings.\n\n* Further improvements to the handling of comments and blank lines.\n (Issue #1 [1]_ and others changes.)\n\n* Check all py files in directory when passed a directory (Issue\n #2 [1]_). This also prevents an exception when traversing directories\n with non ``*.py`` files.\n\n* E231 should allow commas to be followed by ``)``. (Issue #3 [1]_)\n\n* Spaces are no longer required around the equals sign for keyword\n arguments or default parameter values.\n\n\n.. [1] These issues refer to the `previous issue tracker`__.\n.. __: http://github.com/cburroughs/pep8.py/issues\n\n\n0.3.1 (2009-09-14)\n------------------\n\n* Fixes for comments: do not count them when checking for blank lines between\n items.\n\n* Added setup.py for pypi upload and easy_installability.\n\n\n0.2 (2007-10-16)\n----------------\n\n* Loads of fixes and improvements.\n\n\n0.1 (2006-10-01)\n----------------\n\n* First release.", - "release_date": "2021-10-11T00:56:25", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Johann C. Rocholl", - "email": "johann@rocholl.net", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Ian Lee", - "email": "IanLee1521@gmail.com", - "url": null - } - ], - "keywords": [ - "pycodestyle", - "pep8", - "PEP 8", - "PEP-8", - "PEP8", - "Development Status :: 5 - Production/Stable", - "Environment :: Console", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "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", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "https://pycodestyle.pycqa.org/", - "download_url": "https://files.pythonhosted.org/packages/15/94/bc43a2efb7b8615e38acde2b6624cae8c9ec86faf718ff5676c5179a7714/pycodestyle-2.8.0-py2.py3-none-any.whl", - "size": 42112, - "sha1": null, - "md5": "35e8cff40ae075579da219f9ac2bcb75", - "sha256": "720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "Expat license", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pycodestyle/2.8.0/json", - "datasource_id": null, - "purl": "pkg:pypi/pycodestyle@2.8.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "pycodestyle", - "version": "2.8.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "pycodestyle (formerly called pep8) - Python style guide checker\n===============================================================\n\n.. image:: https://github.com/PyCQA/pycodestyle/actions/workflows/main.yml/badge.svg\n :target: https://github.com/PyCQA/pycodestyle/actions/workflows/main.yml\n :alt: Build status\n\n.. image:: https://readthedocs.org/projects/pycodestyle/badge/?version=latest\n :target: https://pycodestyle.pycqa.org\n :alt: Documentation Status\n\n.. image:: https://img.shields.io/pypi/wheel/pycodestyle.svg\n :target: https://pypi.org/project/pycodestyle/\n :alt: Wheel Status\n\n.. image:: https://badges.gitter.im/PyCQA/pycodestyle.svg\n :alt: Join the chat at https://gitter.im/PyCQA/pycodestyle\n :target: https://gitter.im/PyCQA/pycodestyle?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge\n\npycodestyle is a tool to check your Python code against some of the style\nconventions in `PEP 8`_.\n\n.. _PEP 8: http://www.python.org/dev/peps/pep-0008/\n\n.. note::\n\n This package used to be called ``pep8`` but was renamed to ``pycodestyle``\n to reduce confusion. Further discussion can be found `in the issue where\n Guido requested this\n change `_, or in the\n lightning talk at PyCon 2016 by @IanLee1521:\n `slides `_\n `video `_.\n\nFeatures\n--------\n\n* Plugin architecture: Adding new checks is easy.\n\n* Parseable output: Jump to error location in your editor.\n\n* Small: Just one Python file, requires only stdlib. You can use just\n the ``pycodestyle.py`` file for this purpose.\n\n* Comes with a comprehensive test suite.\n\nInstallation\n------------\n\nYou can install, upgrade, and uninstall ``pycodestyle.py`` with these commands::\n\n $ pip install pycodestyle\n $ pip install --upgrade pycodestyle\n $ pip uninstall pycodestyle\n\nThere's also a package for Debian/Ubuntu, but it's not always the\nlatest version.\n\nExample usage and output\n------------------------\n\n::\n\n $ pycodestyle --first optparse.py\n optparse.py:69:11: E401 multiple imports on one line\n optparse.py:77:1: E302 expected 2 blank lines, found 1\n optparse.py:88:5: E301 expected 1 blank line, found 0\n optparse.py:222:34: W602 deprecated form of raising exception\n optparse.py:347:31: E211 whitespace before '('\n optparse.py:357:17: E201 whitespace after '{'\n optparse.py:472:29: E221 multiple spaces before operator\n optparse.py:544:21: W601 .has_key() is deprecated, use 'in'\n\nYou can also make ``pycodestyle.py`` show the source code for each error, and\neven the relevant text from PEP 8::\n\n $ pycodestyle --show-source --show-pep8 testsuite/E40.py\n testsuite/E40.py:2:10: E401 multiple imports on one line\n import os, sys\n ^\n Imports should usually be on separate lines.\n\n Okay: import os\\nimport sys\n E401: import sys, os\n\n\nOr you can display how often each error was found::\n\n $ pycodestyle --statistics -qq Python-2.5/Lib\n 232 E201 whitespace after '['\n 599 E202 whitespace before ')'\n 631 E203 whitespace before ','\n 842 E211 whitespace before '('\n 2531 E221 multiple spaces before operator\n 4473 E301 expected 1 blank line, found 0\n 4006 E302 expected 2 blank lines, found 1\n 165 E303 too many blank lines (4)\n 325 E401 multiple imports on one line\n 3615 E501 line too long (82 characters)\n 612 W601 .has_key() is deprecated, use 'in'\n 1188 W602 deprecated form of raising exception\n\nLinks\n-----\n\n* `Read the documentation `_\n\n* `Fork me on GitHub `_\n\n\nChangelog\n=========\n\n2.8.0 (2021-10-10)\n------------------\n\nChanges:\n\n* Drop python 3.4. PR #982.\n* E712: fix false negative with multiple comparisons. PR #987.\n* E211: fix false positives with ``match``. PR #989.\n* E772: improve performance of bare except check. PR #992.\n* Backport tokenize performance improvement from python 3.10. PR #993.\n* E225: fix for lambdas containing positional-only args. PR #1012.\n* Remove ``indent_size_str`` \"setting\". PR #995.\n* E402: allow ``__all__`` to be typed. PR #1019.\n* E225: fix false positives for ``*`` in ``case``. PR #1003.\n* E201: detect tabs as whitespace. PR #1015.\n\n\n2.7.0 (2021-03-14)\n------------------\n\nChanges:\n\n* Fix physical checks (such as W191) at end of file. PR #961.\n* Add ``--indent-size`` option (defaulting to ``4``). PR #970.\n* W605: fix escaped crlf false positive on windows. PR #976.\n\n\n2.6.0 (2020-05-11)\n------------------\n\nAnnouncements:\n\n* Anthony Sottile (@asottile) joined the team as a core developer. :tada:\n\nChanges:\n\n* E306: fix detection inside ``async def``. PR #929.\n* E301: fix regression disallowing decorated one-liners. PR #927.\n* E714: fix false positive with chained ``is not``. PR #931.\n\n\n2.6.0a1 (2020-04-23)\n--------------------\n\nNew checks:\n\n* E225: require whitespace around ``and`` ``in`` ``is`` and ``or``. PR #847.\n\nChanges:\n\n* E117: fix indentation using tabs by treating as 8-space indents. PR #837.\n* E721: fix false positive with names containg ``istype``. PR #850.\n* E741: allow ``l`` as a named argument in a function call. PR #853.\n* E302: fix false-negative with decorated functions. PR #859.\n* W504: ellipsis (``...``) is no longer treated as a binary operator. PR #875.\n* E402: allow ``with``, ``if``, ``elif``, ``else`` to guard imports. PR #834.\n* Add support for assignment expressions ``:=`` (PEP 572). PR #879.\n* Add support for positional-only arguments ``/`` (PEP 570). PR #872, #918.\n* Add support for python 3.8.\n* Add support for matrix multiplication operator ``@`` (PEP 465). PR #897.\n* Support visual indent for continuation lines for ``with`` / ``assert`` /\n ``raise``. PR #912.\n* E302: allow two blank lines after a block of one-liners. PR #913.\n* E302: allow two-and-fewer newlines at the top of the file. PR #919.\n\n\n2.5.0 (2019-01-29)\n------------------\n\nNew checks:\n\n* E117: Over-indented code blocks\n* W505: Maximum doc-string length only when configured with --max-doc-length\n\nChanges:\n\n* Remove support for EOL Python 2.6 and 3.3. PR #720.\n* Add E117 error for over-indented code blocks.\n* Allow W605 to be silenced by `# noqa` and fix the position reported by W605\n* Allow users to omit blank lines around one-liner definitions of classes and\n functions\n* Include the function return annotation (``->``) as requiring surrounding\n whitespace only on Python 3\n* Verify that only names can follow ``await``. Previously we allowed numbers\n and strings.\n* Add support for Python 3.7\n* Fix detection of annotated argument defaults for E252\n* Correct the position reported by W504\n\n\n2.4.0 (2018-04-10)\n------------------\n\nNew checks:\n\n* Add W504 warning for checking that a break doesn't happen after a binary\n operator. This check is ignored by default. PR #502.\n* Add W605 warning for invalid escape sequences in string literals. PR #676.\n* Add W606 warning for 'async' and 'await' reserved keywords being introduced\n in Python 3.7. PR #684.\n* Add E252 error for missing whitespace around equal sign in type annotated\n function arguments with defaults values. PR #717.\n\nChanges:\n\n* An internal bisect search has replaced a linear search in order to improve\n efficiency. PR #648.\n* pycodestyle now uses PyPI trove classifiers in order to document supported\n python versions on PyPI. PR #654.\n* 'setup.cfg' '[wheel]' section has been renamed to '[bdist_wheel]', as\n the former is legacy. PR #653.\n* pycodestyle now handles very long lines much more efficiently for python\n 3.2+. Fixes #643. PR #644.\n* You can now write 'pycodestyle.StyleGuide(verbose=True)' instead of\n 'pycodestyle.StyleGuide(verbose=True, paths=['-v'])' in order to achieve\n verbosity. PR #663.\n* The distribution of pycodestyle now includes the license text in order to\n comply with open source licenses which require this. PR #694.\n* 'maximum_line_length' now ignores shebang ('#!') lines. PR #736.\n* Add configuration option for the allowed number of blank lines. It is\n implemented as a top level dictionary which can be easily overwritten. Fixes\n #732. PR #733.\n\nBugs:\n\n* Prevent a 'DeprecationWarning', and a 'SyntaxError' in future python, caused\n by an invalid escape sequence. PR #625.\n* Correctly report E501 when the first line of a docstring is too long.\n Resolves #622. PR #630.\n* Support variable annotation when variable start by a keyword, such as class\n variable type annotations in python 3.6. PR #640.\n* pycodestyle internals have been changed in order to allow 'python3 -m\n cProfile' to report correct metrics. PR #647.\n* Fix a spelling mistake in the description of E722. PR #697.\n* 'pycodestyle --diff' now does not break if your 'gitconfig' enables\n 'mnemonicprefix'. PR #706.\n\n2.3.1 (2017-01-31)\n------------------\n\nBugs:\n\n* Fix regression in detection of E302 and E306; #618, #620\n\n2.3.0 (2017-01-30)\n------------------\n\nNew Checks:\n\n* Add E722 warning for bare ``except`` clauses\n* Report E704 for async function definitions (``async def``)\n\nBugs:\n\n* Fix another E305 false positive for variables beginning with \"class\" or\n \"def\"\n* Fix detection of multiple spaces between ``async`` and ``def``\n* Fix handling of variable annotations. Stop reporting E701 on Python 3.6 for\n variable annotations.\n\n2.2.0 (2016-11-14)\n------------------\n\nAnnouncements:\n\n* Added Make target to obtain proper tarball file permissions; #599\n\nBugs:\n\n* Fixed E305 regression caused by #400; #593\n\n2.1.0 (2016-11-04)\n------------------\n\nAnnouncements:\n\n* Change all references to the pep8 project to say pycodestyle; #530\n\nChanges:\n\n* Report E302 for blank lines before an \"async def\"; #556\n* Update our list of tested and supported Python versions which are 2.6, 2.7,\n 3.2, 3.3, 3.4 and 3.5 as well as the nightly Python build and PyPy.\n* Report E742 and E743 for functions and classes badly named 'l', 'O', or 'I'.\n* Report E741 on 'global' and 'nonlocal' statements, as well as prohibited\n single-letter variables.\n* Deprecated use of `[pep8]` section name in favor of `[pycodestyle]`; #591\n* Report E722 when bare except clause is used; #579\n\nBugs:\n\n* Fix opt_type AssertionError when using Flake8 2.6.2 and pycodestyle; #561\n* Require two blank lines after toplevel def, class; #536\n* Remove accidentally quadratic computation based on the number of colons. This\n will make pycodestyle faster in some cases; #314\n\n2.0.0 (2016-05-31)\n------------------\n\nAnnouncements:\n\n* Repository renamed to `pycodestyle`; Issue #466 / #481.\n* Added joint Code of Conduct as member of PyCQA; #483\n\nChanges:\n\n* Added tox test support for Python 3.5 and pypy3\n* Added check E275 for whitespace on `from ... import ...` lines; #489 / #491\n* Added W503 to the list of codes ignored by default ignore list; #498\n* Removed use of project level `.pep8` configuration file; #364\n\nBugs:\n\n* Fixed bug with treating `~` operator as binary; #383 / #384\n* Identify binary operators as unary; #484 / #485\n\n1.7.0 (2016-01-12)\n------------------\n\nAnnouncements:\n\n* Repository moved to PyCQA Organization on GitHub:\n https://github.com/pycqa/pep8\n\nChanges:\n\n* Reverted the fix in #368, \"options passed on command line are only ones\n accepted\" feature. This has many unintended consequences in pep8 and flake8\n and needs to be reworked when I have more time.\n* Added support for Python 3.5. (Issue #420 & #459)\n* Added support for multi-line config_file option parsing. (Issue #429)\n* Improved parameter parsing. (Issues #420 & #456)\n\nBugs:\n\n* Fixed BytesWarning on Python 3. (Issue #459)\n\n1.6.2 (2015-02-15)\n------------------\n\nChanges:\n\n* Added check for breaking around a binary operator. (Issue #197, Pull #305)\n\nBugs:\n\n* Restored config_file parameter in process_options(). (Issue #380)\n\n\n1.6.1 (2015-02-08)\n------------------\n\nChanges:\n\n* Assign variables before referenced. (Issue #287)\n\nBugs:\n\n* Exception thrown due to unassigned ``local_dir`` variable. (Issue #377)\n\n\n1.6.0 (2015-02-06)\n------------------\n\nNews:\n\n* Ian Lee joined the project as a maintainer.\n\nChanges:\n\n* Report E731 for lambda assignment. (Issue #277)\n\n* Report E704 for one-liner def instead of E701.\n Do not report this error in the default configuration. (Issue #277)\n\n* Replace codes E111, E112 and E113 with codes E114, E115 and E116\n for bad indentation of comments. (Issue #274)\n\n* Report E266 instead of E265 when the block comment starts with\n multiple ``#``. (Issue #270)\n\n* Report E402 for import statements not at the top of the file. (Issue #264)\n\n* Do not enforce whitespaces around ``**`` operator. (Issue #292)\n\n* Strip whitespace from around paths during normalization. (Issue #339 / #343)\n\n* Update ``--format`` documentation. (Issue #198 / Pull Request #310)\n\n* Add ``.tox/`` to default excludes. (Issue #335)\n\n* Do not report E121 or E126 in the default configuration. (Issues #256 / #316)\n\n* Allow spaces around the equals sign in an annotated function. (Issue #357)\n\n* Allow trailing backslash if in an inline comment. (Issue #374)\n\n* If ``--config`` is used, only that configuration is processed. Otherwise,\n merge the user and local configurations are merged. (Issue #368 / #369)\n\nBug fixes:\n\n* Don't crash if Checker.build_tokens_line() returns None. (Issue #306)\n\n* Don't crash if os.path.expanduser() throws an ImportError. (Issue #297)\n\n* Missing space around keyword parameter equal not always reported, E251.\n (Issue #323)\n\n* Fix false positive E711/E712/E713. (Issues #330 and #336)\n\n* Do not skip physical checks if the newline is escaped. (Issue #319)\n\n* Flush sys.stdout to avoid race conditions with printing. See flake8 bug:\n https://gitlab.com/pycqa/flake8/issues/17 for more details. (Issue #363)\n\n\n1.5.7 (2014-05-29)\n------------------\n\nBug fixes:\n\n* Skip the traceback on \"Broken pipe\" signal. (Issue #275)\n\n* Do not exit when an option in ``setup.cfg`` or ``tox.ini``\n is not recognized.\n\n* Check the last line even if it does not end with a newline. (Issue #286)\n\n* Always open files in universal newlines mode in Python 2. (Issue #288)\n\n\n1.5.6 (2014-04-14)\n------------------\n\nBug fixes:\n\n* Check the last line even if it has no end-of-line. (Issue #273)\n\n\n1.5.5 (2014-04-10)\n------------------\n\nBug fixes:\n\n* Fix regression with E22 checks and inline comments. (Issue #271)\n\n\n1.5.4 (2014-04-07)\n------------------\n\nBug fixes:\n\n* Fix negative offset with E303 before a multi-line docstring.\n (Issue #269)\n\n\n1.5.3 (2014-04-04)\n------------------\n\nBug fixes:\n\n* Fix wrong offset computation when error is on the last char\n of a physical line. (Issue #268)\n\n\n1.5.2 (2014-04-04)\n------------------\n\nChanges:\n\n* Distribute a universal wheel file.\n\nBug fixes:\n\n* Report correct line number for E303 with comments. (Issue #60)\n\n* Do not allow newline after parameter equal. (Issue #252)\n\n* Fix line number reported for multi-line strings. (Issue #220)\n\n* Fix false positive E121/E126 with multi-line strings. (Issue #265)\n\n* Fix E501 not detected in comments with Python 2.5.\n\n* Fix caret position with ``--show-source`` when line contains tabs.\n\n\n1.5.1 (2014-03-27)\n------------------\n\nBug fixes:\n\n* Fix a crash with E125 on multi-line strings. (Issue #263)\n\n\n1.5 (2014-03-26)\n----------------\n\nChanges:\n\n* Report E129 instead of E125 for visually indented line with same\n indent as next logical line. (Issue #126)\n\n* Report E265 for space before block comment. (Issue #190)\n\n* Report E713 and E714 when operators ``not in`` and ``is not`` are\n recommended. (Issue #236)\n\n* Allow long lines in multiline strings and comments if they cannot\n be wrapped. (Issue #224).\n\n* Optionally disable physical line checks inside multiline strings,\n using ``# noqa``. (Issue #242)\n\n* Change text for E121 to report \"continuation line under-indented\n for hanging indent\" instead of indentation not being a\n multiple of 4.\n\n* Report E131 instead of E121 / E126 if the hanging indent is not\n consistent within the same continuation block. It helps when\n error E121 or E126 is in the ``ignore`` list.\n\n* Report E126 instead of E121 when the continuation line is hanging\n with extra indentation, even if indentation is not a multiple of 4.\n\nBug fixes:\n\n* Allow the checkers to report errors on empty files. (Issue #240)\n\n* Fix ignoring too many checks when ``--select`` is used with codes\n declared in a flake8 extension. (Issue #216)\n\n* Fix regression with multiple brackets. (Issue #214)\n\n* Fix ``StyleGuide`` to parse the local configuration if the\n keyword argument ``paths`` is specified. (Issue #246)\n\n* Fix a false positive E124 for hanging indent. (Issue #254)\n\n* Fix a false positive E126 with embedded colon. (Issue #144)\n\n* Fix a false positive E126 when indenting with tabs. (Issue #204)\n\n* Fix behaviour when ``exclude`` is in the configuration file and\n the current directory is not the project directory. (Issue #247)\n\n* The logical checks can return ``None`` instead of an empty iterator.\n (Issue #250)\n\n* Do not report multiple E101 if only the first indentation starts\n with a tab. (Issue #237)\n\n* Fix a rare false positive W602. (Issue #34)\n\n\n1.4.6 (2013-07-02)\n------------------\n\nChanges:\n\n* Honor ``# noqa`` for errors E711 and E712. (Issue #180)\n\n* When both a ``tox.ini`` and a ``setup.cfg`` are present in the project\n directory, merge their contents. The ``tox.ini`` file takes\n precedence (same as before). (Issue #182)\n\n* Give priority to ``--select`` over ``--ignore``. (Issue #188)\n\n* Compare full path when excluding a file. (Issue #186)\n\n* New option ``--hang-closing`` to switch to the alternative style of\n closing bracket indentation for hanging indent. Add error E133 for\n closing bracket which is missing indentation. (Issue #103)\n\n* Accept both styles of closing bracket indentation for hanging indent.\n Do not report error E123 in the default configuration. (Issue #103)\n\nBug fixes:\n\n* Do not crash when running AST checks and the document contains null bytes.\n (Issue #184)\n\n* Correctly report other E12 errors when E123 is ignored. (Issue #103)\n\n* Fix false positive E261/E262 when the file contains a BOM. (Issue #193)\n\n* Fix E701, E702 and E703 not detected sometimes. (Issue #196)\n\n* Fix E122 not detected in some cases. (Issue #201 and #208)\n\n* Fix false positive E121 with multiple brackets. (Issue #203)\n\n\n1.4.5 (2013-03-06)\n------------------\n\n* When no path is specified, do not try to read from stdin. The feature\n was added in 1.4.3, but it is not supported on Windows. Use ``-``\n filename argument to read from stdin. This usage is supported\n since 1.3.4. (Issue #170)\n\n* Do not require ``setuptools`` in setup.py. It works around an issue\n with ``pip`` and Python 3. (Issue #172)\n\n* Add ``__pycache__`` to the ignore list.\n\n* Change misleading message for E251. (Issue #171)\n\n* Do not report false E302 when the source file has a coding cookie or a\n comment on the first line. (Issue #174)\n\n* Reorganize the tests and add tests for the API and for the command line\n usage and options. (Issues #161 and #162)\n\n* Ignore all checks which are not explicitly selected when ``select`` is\n passed to the ``StyleGuide`` constructor.\n\n\n1.4.4 (2013-02-24)\n------------------\n\n* Report E227 or E228 instead of E225 for whitespace around bitwise, shift\n or modulo operators. (Issue #166)\n\n* Change the message for E226 to make clear that it is about arithmetic\n operators.\n\n* Fix a false positive E128 for continuation line indentation with tabs.\n\n* Fix regression with the ``--diff`` option. (Issue #169)\n\n* Fix the ``TestReport`` class to print the unexpected warnings and\n errors.\n\n\n1.4.3 (2013-02-22)\n------------------\n\n* Hide the ``--doctest`` and ``--testsuite`` options when installed.\n\n* Fix crash with AST checkers when the syntax is invalid. (Issue #160)\n\n* Read from standard input if no path is specified.\n\n* Initiate a graceful shutdown on ``Control+C``.\n\n* Allow changing the ``checker_class`` for the ``StyleGuide``.\n\n\n1.4.2 (2013-02-10)\n------------------\n\n* Support AST checkers provided by third-party applications.\n\n* Register new checkers with ``register_check(func_or_cls, codes)``.\n\n* Allow constructing a ``StyleGuide`` with a custom parser.\n\n* Accept visual indentation without parenthesis after the ``if``\n statement. (Issue #151)\n\n* Fix UnboundLocalError when using ``# noqa`` with continued lines.\n (Issue #158)\n\n* Re-order the lines for the ``StandardReport``.\n\n* Expand tabs when checking E12 continuation lines. (Issue #155)\n\n* Refactor the testing class ``TestReport`` and the specific test\n functions into a separate test module.\n\n\n1.4.1 (2013-01-18)\n------------------\n\n* Allow sphinx.ext.autodoc syntax for comments. (Issue #110)\n\n* Report E703 instead of E702 for the trailing semicolon. (Issue #117)\n\n* Honor ``# noqa`` in addition to ``# nopep8``. (Issue #149)\n\n* Expose the ``OptionParser`` factory for better extensibility.\n\n\n1.4 (2012-12-22)\n----------------\n\n* Report E226 instead of E225 for optional whitespace around common\n operators (``*``, ``**``, ``/``, ``+`` and ``-``). This new error\n code is ignored in the default configuration because PEP 8 recommends\n to \"use your own judgement\". (Issue #96)\n\n* Lines with a ``# nopep8`` at the end will not issue errors on line\n length E501 or continuation line indentation E12*. (Issue #27)\n\n* Fix AssertionError when the source file contains an invalid line\n ending ``\"\\r\\r\\n\"``. (Issue #119)\n\n* Read the ``[pep8]`` section of ``tox.ini`` or ``setup.cfg`` if present.\n (Issue #93 and #141)\n\n* Add the Sphinx-based documentation, and publish it\n on https://pycodestyle.readthedocs.io/. (Issue #105)\n\n\n1.3.4 (2012-12-18)\n------------------\n\n* Fix false positive E124 and E128 with comments. (Issue #100)\n\n* Fix error on stdin when running with bpython. (Issue #101)\n\n* Fix false positive E401. (Issue #104)\n\n* Report E231 for nested dictionary in list. (Issue #142)\n\n* Catch E271 at the beginning of the line. (Issue #133)\n\n* Fix false positive E126 for multi-line comments. (Issue #138)\n\n* Fix false positive E221 when operator is preceded by a comma. (Issue #135)\n\n* Fix ``--diff`` failing on one-line hunk. (Issue #137)\n\n* Fix the ``--exclude`` switch for directory paths. (Issue #111)\n\n* Use ``-`` filename to read from standard input. (Issue #128)\n\n\n1.3.3 (2012-06-27)\n------------------\n\n* Fix regression with continuation line checker. (Issue #98)\n\n\n1.3.2 (2012-06-26)\n------------------\n\n* Revert to the previous behaviour for ``--show-pep8``:\n do not imply ``--first``. (Issue #89)\n\n* Add E902 for IO errors. (Issue #87)\n\n* Fix false positive for E121, and missed E124. (Issue #92)\n\n* Set a sensible default path for config file on Windows. (Issue #95)\n\n* Allow ``verbose`` in the configuration file. (Issue #91)\n\n* Show the enforced ``max-line-length`` in the error message. (Issue #86)\n\n\n1.3.1 (2012-06-18)\n------------------\n\n* Explain which configuration options are expected. Accept and recommend\n the options names with hyphen instead of underscore. (Issue #82)\n\n* Do not read the user configuration when used as a module\n (except if ``config_file=True`` is passed to the ``StyleGuide`` constructor).\n\n* Fix wrong or missing cases for the E12 series.\n\n* Fix cases where E122 was missed. (Issue #81)\n\n\n1.3 (2012-06-15)\n----------------\n\n.. warning::\n The internal API is backwards incompatible.\n\n* Remove global configuration and refactor the library around\n a ``StyleGuide`` class; add the ability to configure various\n reporters. (Issue #35 and #66)\n\n* Read user configuration from ``~/.config/pep8``\n and local configuration from ``./.pep8``. (Issue #22)\n\n* Fix E502 for backslash embedded in multi-line string. (Issue #68)\n\n* Fix E225 for Python 3 iterable unpacking (PEP 3132). (Issue #72)\n\n* Enable the new checkers from the E12 series in the default\n configuration.\n\n* Suggest less error-prone alternatives for E712 errors.\n\n* Rewrite checkers to run faster (E22, E251, E27).\n\n* Fixed a crash when parsed code is invalid (too many\n closing brackets).\n\n* Fix E127 and E128 for continuation line indentation. (Issue #74)\n\n* New option ``--format`` to customize the error format. (Issue #23)\n\n* New option ``--diff`` to check only modified code. The unified\n diff is read from STDIN. Example: ``hg diff | pep8 --diff``\n (Issue #39)\n\n* Correctly report the count of failures and set the exit code to 1\n when the ``--doctest`` or the ``--testsuite`` fails.\n\n* Correctly detect the encoding in Python 3. (Issue #69)\n\n* Drop support for Python 2.3, 2.4 and 3.0. (Issue #78)\n\n\n1.2 (2012-06-01)\n----------------\n\n* Add E121 through E128 for continuation line indentation. These\n checks are disabled by default. If you want to force all checks,\n use switch ``--select=E,W``. Patch by Sam Vilain. (Issue #64)\n\n* Add E721 for direct type comparisons. (Issue #47)\n\n* Add E711 and E712 for comparisons to singletons. (Issue #46)\n\n* Fix spurious E225 and E701 for function annotations. (Issue #29)\n\n* Add E502 for explicit line join between brackets.\n\n* Fix E901 when printing source with ``--show-source``.\n\n* Report all errors for each checker, instead of reporting only the\n first occurrence for each line.\n\n* Option ``--show-pep8`` implies ``--first``.\n\n\n1.1 (2012-05-24)\n----------------\n\n* Add E901 for syntax errors. (Issues #63 and #30)\n\n* Add E271, E272, E273 and E274 for extraneous whitespace around\n keywords. (Issue #57)\n\n* Add ``tox.ini`` configuration file for tests. (Issue #61)\n\n* Add ``.travis.yml`` configuration file for continuous integration.\n (Issue #62)\n\n\n1.0.1 (2012-04-06)\n------------------\n\n* Fix inconsistent version numbers.\n\n\n1.0 (2012-04-04)\n----------------\n\n* Fix W602 ``raise`` to handle multi-char names. (Issue #53)\n\n\n0.7.0 (2012-03-26)\n------------------\n\n* Now ``--first`` prints only the first occurrence of each error.\n The ``--repeat`` flag becomes obsolete because it is the default\n behaviour. (Issue #6)\n\n* Allow specifying ``--max-line-length``. (Issue #36)\n\n* Make the shebang more flexible. (Issue #26)\n\n* Add testsuite to the bundle. (Issue #25)\n\n* Fixes for Jython. (Issue #49)\n\n* Add PyPI classifiers. (Issue #43)\n\n* Fix the ``--exclude`` option. (Issue #48)\n\n* Fix W602, accept ``raise`` with 3 arguments. (Issue #34)\n\n* Correctly select all tests if ``DEFAULT_IGNORE == ''``.\n\n\n0.6.1 (2010-10-03)\n------------------\n\n* Fix inconsistent version numbers. (Issue #21)\n\n\n0.6.0 (2010-09-19)\n------------------\n\n* Test suite reorganized and enhanced in order to check more failures\n with fewer test files. Read the ``run_tests`` docstring for details\n about the syntax.\n\n* Fix E225: accept ``print >>sys.stderr, \"...\"`` syntax.\n\n* Fix E501 for lines containing multibyte encoded characters. (Issue #7)\n\n* Fix E221, E222, E223, E224 not detected in some cases. (Issue #16)\n\n* Fix E211 to reject ``v = dic['a'] ['b']``. (Issue #17)\n\n* Exit code is always 1 if any error or warning is found. (Issue #10)\n\n* ``--ignore`` checks are now really ignored, especially in\n conjunction with ``--count``. (Issue #8)\n\n* Blank lines with spaces yield W293 instead of W291: some developers\n want to ignore this warning and indent the blank lines to paste their\n code easily in the Python interpreter.\n\n* Fix E301: do not require a blank line before an indented block. (Issue #14)\n\n* Fix E203 to accept NumPy slice notation ``a[0, :]``. (Issue #13)\n\n* Performance improvements.\n\n* Fix decoding and checking non-UTF8 files in Python 3.\n\n* Fix E225: reject ``True+False`` when running on Python 3.\n\n* Fix an exception when the line starts with an operator.\n\n* Allow a new line before closing ``)``, ``}`` or ``]``. (Issue #5)\n\n\n0.5.0 (2010-02-17)\n------------------\n\n* Changed the ``--count`` switch to print to sys.stderr and set\n exit code to 1 if any error or warning is found.\n\n* E241 and E242 are removed from the standard checks. If you want to\n include these checks, use switch ``--select=E,W``. (Issue #4)\n\n* Blank line is not mandatory before the first class method or nested\n function definition, even if there's a docstring. (Issue #1)\n\n* Add the switch ``--version``.\n\n* Fix decoding errors with Python 3. (Issue #13 [1]_)\n\n* Add ``--select`` option which is mirror of ``--ignore``.\n\n* Add checks E261 and E262 for spaces before inline comments.\n\n* New check W604 warns about deprecated usage of backticks.\n\n* New check W603 warns about the deprecated operator ``<>``.\n\n* Performance improvement, due to rewriting of E225.\n\n* E225 now accepts:\n\n - no whitespace after unary operator or similar. (Issue #9 [1]_)\n\n - lambda function with argument unpacking or keyword defaults.\n\n* Reserve \"2 blank lines\" for module-level logical blocks. (E303)\n\n* Allow multi-line comments. (E302, issue #10 [1]_)\n\n\n0.4.2 (2009-10-22)\n------------------\n\n* Decorators on classes and class methods are OK now.\n\n\n0.4 (2009-10-20)\n----------------\n\n* Support for all versions of Python from 2.3 to 3.1.\n\n* New and greatly expanded self tests.\n\n* Added ``--count`` option to print the total number of errors and warnings.\n\n* Further improvements to the handling of comments and blank lines.\n (Issue #1 [1]_ and others changes.)\n\n* Check all py files in directory when passed a directory (Issue\n #2 [1]_). This also prevents an exception when traversing directories\n with non ``*.py`` files.\n\n* E231 should allow commas to be followed by ``)``. (Issue #3 [1]_)\n\n* Spaces are no longer required around the equals sign for keyword\n arguments or default parameter values.\n\n\n.. [1] These issues refer to the `previous issue tracker`__.\n.. __: http://github.com/cburroughs/pep8.py/issues\n\n\n0.3.1 (2009-09-14)\n------------------\n\n* Fixes for comments: do not count them when checking for blank lines between\n items.\n\n* Added setup.py for pypi upload and easy_installability.\n\n\n0.2 (2007-10-16)\n----------------\n\n* Loads of fixes and improvements.\n\n\n0.1 (2006-10-01)\n----------------\n\n* First release.", - "release_date": "2021-10-11T00:56:27", + "description": "Safely add untrusted strings to HTML/XML markup.\nMarkupSafe\n==========\n\nMarkupSafe implements a text object that escapes characters so it is\nsafe to use in HTML and XML. Characters that have special meanings are\nreplaced so that they display as the actual characters. This mitigates\ninjection attacks, meaning untrusted user input can safely be displayed\non a page.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U MarkupSafe\n\n.. _pip: https://pip.pypa.io/en/stable/quickstart/\n\n\nExamples\n--------\n\n.. code-block:: pycon\n\n >>> from markupsafe import Markup, escape\n\n >>> # escape replaces special characters and wraps in Markup\n >>> escape(\"\")\n Markup('<script>alert(document.cookie);</script>')\n\n >>> # wrap in Markup to mark text \"safe\" and prevent escaping\n >>> Markup(\"Hello\")\n Markup('hello')\n\n >>> escape(Markup(\"Hello\"))\n Markup('hello')\n\n >>> # Markup is a str subclass\n >>> # methods and operators escape their arguments\n >>> template = Markup(\"Hello {name}\")\n >>> template.format(name='\"World\"')\n Markup('Hello "World"')\n\n\nDonate\n------\n\nThe Pallets organization develops and supports MarkupSafe and other\npopular packages. In order to grow the community of contributors and\nusers, and allow the maintainers to devote more time to the projects,\n`please donate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://markupsafe.palletsprojects.com/\n- Changes: https://markupsafe.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/MarkupSafe/\n- Source Code: https://github.com/pallets/markupsafe/\n- Issue Tracker: https://github.com/pallets/markupsafe/issues/\n- Website: https://palletsprojects.com/p/markupsafe/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", + "release_date": "2021-08-11T18:10:44", "parties": [ { "type": "person", "role": "author", - "name": "Johann C. Rocholl", - "email": "johann@rocholl.net", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Ian Lee", - "email": "IanLee1521@gmail.com", - "url": null - } - ], - "keywords": [ - "pycodestyle", - "pep8", - "PEP 8", - "PEP-8", - "PEP8", - "Development Status :: 5 - Production/Stable", - "Environment :: Console", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "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", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "https://pycodestyle.pycqa.org/", - "download_url": "https://files.pythonhosted.org/packages/08/dc/b29daf0a202b03f57c19e7295b60d1d5e1281c45a6f5f573e41830819918/pycodestyle-2.8.0.tar.gz", - "size": 102299, - "sha1": null, - "md5": "7f4f7cc6634e9388a8bbd35f92e66a6b", - "sha256": "eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "Expat license", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pycodestyle/2.8.0/json", - "datasource_id": null, - "purl": "pkg:pypi/pycodestyle@2.8.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "pycparser", - "version": "2.21", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "C parser in Python\npycparser is a complete parser of the C language, written in\npure Python using the PLY parsing library.\nIt parses C code into an AST and can serve as a front-end for\nC compilers or analysis tools.", - "release_date": "2021-11-06T12:50:13", - "parties": [ + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "url": null + }, { "type": "person", - "role": "author", - "name": "Eli Bendersky", - "email": "eliben@gmail.com", + "role": "maintainer", + "name": "Pallets", + "email": "contact@palletsprojects.com", "url": null } ], "keywords": [ "Development Status :: 5 - Production/Stable", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "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 :: 3.9" + "Environment :: Web Environment", + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Topic :: Internet :: WWW/HTTP :: Dynamic Content", + "Topic :: Text Processing :: Markup :: HTML" ], - "homepage_url": "https://github.com/eliben/pycparser", - "download_url": "https://files.pythonhosted.org/packages/62/d5/5f610ebe421e85889f2e55e33b7f9a6795bd982198517d912eb1c76e1a53/pycparser-2.21-py2.py3-none-any.whl", - "size": 118697, + "homepage_url": "https://palletsprojects.com/p/markupsafe/", + "download_url": "https://files.pythonhosted.org/packages/53/e8/601efa63c4058311a8bda7984a2fe554b9da574044967d7aee253661ee46/MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", + "size": 30770, "sha1": null, - "md5": "763d265dfc20860dfbb4c81458400d03", - "sha256": "8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "md5": "fc893cdd7d045234e0120e6e325fe190", + "sha256": "168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, + "bug_tracking_url": "https://github.com/pallets/markupsafe/issues/", + "code_view_url": "https://github.com/pallets/markupsafe/", "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { - "license": "BSD", + "license": "BSD-3-Clause", "classifiers": [ "License :: OSI Approved :: BSD License" ] @@ -7084,48 +3350,49 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pycparser/2.21/json", + "api_data_url": "https://pypi.org/pypi/markupsafe/2.0.1/json", "datasource_id": null, - "purl": "pkg:pypi/pycparser@2.21" + "purl": "pkg:pypi/markupsafe@2.0.1" }, { "type": "pypi", "namespace": null, - "name": "pycparser", - "version": "2.21", + "name": "mypy-extensions", + "version": "0.4.3", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "C parser in Python\npycparser is a complete parser of the C language, written in\npure Python using the PLY parsing library.\nIt parses C code into an AST and can serve as a front-end for\nC compilers or analysis tools.", - "release_date": "2021-11-06T12:48:46", + "description": "Experimental type system extensions for programs checked with the mypy typechecker.\nMypy Extensions\n===============\n\nThe \"mypy_extensions\" module defines experimental extensions to the\nstandard \"typing\" module that are supported by the mypy typechecker.", + "release_date": "2019-10-17T22:38:56", "parties": [ { "type": "person", "role": "author", - "name": "Eli Bendersky", - "email": "eliben@gmail.com", + "name": "The mypy developers", + "email": "jukka.lehtosalo@iki.fi", "url": null } ], "keywords": [ - "Development Status :: 5 - Production/Stable", + "Development Status :: 2 - Pre-Alpha", + "Environment :: Console", + "Intended Audience :: Developers", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", "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 :: 3.9" + "Topic :: Software Development" ], - "homepage_url": "https://github.com/eliben/pycparser", - "download_url": "https://files.pythonhosted.org/packages/5e/0b/95d387f5f4433cb0f53ff7ad859bd2c6051051cebbb564f139a999ab46de/pycparser-2.21.tar.gz", - "size": 170877, + "homepage_url": "https://github.com/python/mypy_extensions", + "download_url": "https://files.pythonhosted.org/packages/5c/eb/975c7c080f3223a5cdaff09612f3a5221e4ba534f7039db34c35d95fa6a5/mypy_extensions-0.4.3-py2.py3-none-any.whl", + "size": 4470, "sha1": null, - "md5": "48f7d743bf018f7bb2ffc5fb976d1492", - "sha256": "e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206", + "md5": "b9c790261bc8932c80b5938c69e5b65f", + "sha256": "090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -7133,9 +3400,9 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "BSD", + "license": "MIT License", "classifiers": [ - "License :: OSI Approved :: BSD License" + "License :: OSI Approved :: MIT License" ] }, "notice_text": null, @@ -7145,64 +3412,56 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pycparser/2.21/json", + "api_data_url": "https://pypi.org/pypi/mypy-extensions/0.4.3/json", "datasource_id": null, - "purl": "pkg:pypi/pycparser@2.21" + "purl": "pkg:pypi/mypy-extensions@0.4.3" }, { "type": "pypi", "namespace": null, - "name": "pygments", - "version": "2.12.0", + "name": "openpyxl", + "version": "3.0.10", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Pygments is a syntax highlighting package written in Python.", - "release_date": "2022-04-24T13:37:38", + "description": "A Python library to read/write Excel 2010 xlsx/xlsm files\n.. image:: https://coveralls.io/repos/bitbucket/openpyxl/openpyxl/badge.svg?branch=default\n :target: https://coveralls.io/bitbucket/openpyxl/openpyxl?branch=default\n :alt: coverage status\n\nIntroduction\n------------\n\nopenpyxl is a Python library to read/write Excel 2010 xlsx/xlsm/xltx/xltm files.\n\nIt was born from lack of existing library to read/write natively from Python\nthe Office Open XML format.\n\nAll kudos to the PHPExcel team as openpyxl was initially based on PHPExcel.\n\n\nSecurity\n--------\n\nBy default openpyxl does not guard against quadratic blowup or billion laughs\nxml attacks. To guard against these attacks install defusedxml.\n\nMailing List\n------------\n\nThe user list can be found on http://groups.google.com/group/openpyxl-users\n\n\nSample code::\n\n from openpyxl import Workbook\n wb = Workbook()\n\n # grab the active worksheet\n ws = wb.active\n\n # Data can be assigned directly to cells\n ws['A1'] = 42\n\n # Rows can also be appended\n ws.append([1, 2, 3])\n\n # Python types will automatically be converted\n import datetime\n ws['A2'] = datetime.datetime.now()\n\n # Save the file\n wb.save(\"sample.xlsx\")\n\n\nDocumentation\n-------------\n\nThe documentation is at: https://openpyxl.readthedocs.io\n\n* installation methods\n* code examples\n* instructions for contributing\n\nRelease notes: https://openpyxl.readthedocs.io/en/stable/changes.html", + "release_date": "2022-05-19T15:43:03", "parties": [ { "type": "person", "role": "author", - "name": "Georg Brandl", - "email": "georg@python.org", + "name": "See AUTHORS", + "email": "charlie.clark@clark-consulting.eu", "url": null } ], "keywords": [ - "syntax highlighting", - "Development Status :: 6 - Mature", - "Intended Audience :: Developers", - "Intended Audience :: End Users/Desktop", - "Intended Audience :: System Administrators", - "Operating System :: OS Independent", + "Development Status :: 5 - Production/Stable", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Text Processing :: Filters", - "Topic :: Utilities" + "Programming Language :: Python :: 3.9" ], - "homepage_url": "https://pygments.org/", - "download_url": "https://files.pythonhosted.org/packages/5c/8e/1d9017950034297fffa336c72e693a5b51bbf85141b24a763882cf1977b5/Pygments-2.12.0-py3-none-any.whl", - "size": 1093289, + "homepage_url": "https://openpyxl.readthedocs.io", + "download_url": "https://files.pythonhosted.org/packages/7b/60/9afac4fd6feee0ac09339de4101ee452ea643d26e9ce44c7708a0023f503/openpyxl-3.0.10-py2.py3-none-any.whl", + "size": 242144, "sha1": null, - "md5": "4eedd9be3c932cc2b9c3c73b65938663", - "sha256": "dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519", + "md5": "8c57b36e745fe4c437d190272e50debb", + "sha256": "0ab6d25d01799f97a9464630abacbb34aafecdcaa0ef3cba6d6b3499867d0355", "sha512": null, - "bug_tracking_url": "https://github.com/pygments/pygments/issues", - "code_view_url": "https://github.com/pygments/pygments", + "bug_tracking_url": "https://foss.heptapod.net/openpyxl/openpyxl/-/issues", + "code_view_url": "https://foss.heptapod.net/openpyxl/openpyxl", "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { - "license": "BSD License", + "license": "MIT", "classifiers": [ - "License :: OSI Approved :: BSD License" + "License :: OSI Approved :: MIT License" ] }, "notice_text": null, @@ -7212,64 +3471,62 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pygments/2.12.0/json", + "api_data_url": "https://pypi.org/pypi/openpyxl/3.0.10/json", "datasource_id": null, - "purl": "pkg:pypi/pygments@2.12.0" + "purl": "pkg:pypi/openpyxl@3.0.10" }, { "type": "pypi", "namespace": null, - "name": "pygments", - "version": "2.12.0", + "name": "packageurl-python", + "version": "0.9.9", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Pygments is a syntax highlighting package written in Python.", - "release_date": "2022-04-24T13:37:41", + "description": "A purl aka. Package URL parser and builder\n# packageurl-python\n\nPython library to parse and build \"purl\" aka. Package URLs.\nSee https://github.com/package-url/purl-spec for details.\n\nJoin the discussion at https://gitter.im/package-url/Lobby or enter a ticket for support.\n\nLicense: MIT\n\n\nBuild and tests status\n======================\n\n+------------------------------------------------------------------------------------+\n| **Linux (Travis) on Python 2 and 3** |\n+====================================================================================+\n|.. image:: https://api.travis-ci.com/package-url/packageurl-python.png?branch=master|\n| :target: https://travis-ci.com/package-url/packageurl-python |\n| :alt: Linux Master branch tests status |\n+------------------------------------------------------------------------------------+\n\n\nUsage\n=====\n\n::\n\n >>> from packageurl import PackageURL\n >>> purl = PackageURL.from_string(\"pkg:maven/org.apache.commons/io@1.3.4\")\n >>> print(purl.to_dict())\n {'type': 'maven', 'namespace': 'org.apache.commons', 'name': 'io', 'version': '1.3.4', 'qualifiers': None, 'subpath': None}\n >>> print(purl.to_string())\n pkg:maven/org.apache.commons/io@1.3.4\n >>> print(str(purl))\n pkg:maven/org.apache.commons/io@1.3.4\n >>> print(repr(purl))\n PackageURL(type='maven', namespace='org.apache.commons', name='io', version='1.3.4', qualifiers={}, subpath=None)\n\n\nOther utilities:\n\n- packageurl.contrib.django_models.PackageURLMixin is a Django abstract model mixin to use Package URLs in Django.\n- packageurl.contrib.purl2url.get_url(purl) returns the download URL inferred from a Package URL.\n- packageurl.contrib.url2purl.get_purl(url) returns a Package URL inferred from URL.\n\n\nInstall\n=======\n::\n\n pip install packageurl-python\n\nRun tests\n=========\n\ninstall::\n\n python3 thirdparty/virtualenv.pyz --never-download --no-periodic-update .\n bin/pip install -e .\"[test]\"\n\nrun tests::\n\n bin/py.test tests\n\nMake a new release\n==================\n\n- start a new release branch\n- update the CHANGELOG.rst and AUTHORS.rst\n- update README.rst if needed\n- bump version in setup.cfg\n- run all tests\n- install restview and validate that all .rst docs are correct\n- commit and push this branch\n- tag and push that tag\n- make a PR to merge branch\n- once merged, run::\n\n bin/pip install --upgrade pip wheel twine setuptools\n\n- delete the \"dist\" and \"build\" directories::\n\n rm -rf dist/ build/\n\n- create a source distribution and wheel with::\n\n bin/python setup.py sdist bdist_wheel\n\n- finally, upload to PyPI::\n\n bin/twine upload dist/*", + "release_date": "2022-02-15T19:21:48", "parties": [ { "type": "person", "role": "author", - "name": "Georg Brandl", - "email": "georg@python.org", + "name": "the purl authors", + "email": null, "url": null } ], "keywords": [ - "syntax highlighting", - "Development Status :: 6 - Mature", + "package", + "url", + "package manager", + "package url", + "Development Status :: 4 - Beta", "Intended Audience :: Developers", - "Intended Audience :: End Users/Desktop", - "Intended Audience :: System Administrators", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", + "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", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Text Processing :: Filters", + "Topic :: Software Development :: Libraries", "Topic :: Utilities" ], - "homepage_url": "https://pygments.org/", - "download_url": "https://files.pythonhosted.org/packages/59/0f/eb10576eb73b5857bc22610cdfc59e424ced4004fe7132c8f2af2cc168d3/Pygments-2.12.0.tar.gz", - "size": 4282017, + "homepage_url": "https://github.com/package-url/packageurl-python", + "download_url": "https://files.pythonhosted.org/packages/59/48/e9962fd0a4b982e1ed41a64cb38366e680f8d5e501248c0b520a667ccf87/packageurl_python-0.9.9-py3-none-any.whl", + "size": 24764, "sha1": null, - "md5": "2137c19d9ac0cc556badc89e746c0e62", - "sha256": "5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb", + "md5": "510182ba2248cca64795b988219cef26", + "sha256": "07aa852d1c48b0e86e625f6a32d83f96427739806b269d0f8142788ee807114b", "sha512": null, - "bug_tracking_url": "https://github.com/pygments/pygments/issues", - "code_view_url": "https://github.com/pygments/pygments", + "bug_tracking_url": null, + "code_view_url": null, "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { - "license": "BSD License", + "license": "MIT", "classifiers": [ - "License :: OSI Approved :: BSD License" + "License :: OSI Approved :: MIT License" ] }, "notice_text": null, @@ -7279,34 +3536,32 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pygments/2.12.0/json", + "api_data_url": "https://pypi.org/pypi/packageurl-python/0.9.9/json", "datasource_id": null, - "purl": "pkg:pypi/pygments@2.12.0" + "purl": "pkg:pypi/packageurl-python@0.9.9" }, { "type": "pypi", "namespace": null, - "name": "pyparsing", - "version": "3.0.9", + "name": "packaging", + "version": "21.3", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "pyparsing module - Classes and methods to define and execute parsing grammars\nPyParsing -- A Python Parsing Module\n====================================\n\n|Build Status| |Coverage|\n\nIntroduction\n============\n\nThe pyparsing module is an alternative approach to creating and\nexecuting simple grammars, vs. the traditional lex/yacc approach, or the\nuse of regular expressions. The pyparsing module provides a library of\nclasses that client code uses to construct the grammar directly in\nPython code.\n\n*[Since first writing this description of pyparsing in late 2003, this\ntechnique for developing parsers has become more widespread, under the\nname Parsing Expression Grammars - PEGs. See more information on PEGs*\n`here `__\n*.]*\n\nHere is a program to parse ``\"Hello, World!\"`` (or any greeting of the form\n``\"salutation, addressee!\"``):\n\n.. code:: python\n\n from pyparsing import Word, alphas\n greet = Word(alphas) + \",\" + Word(alphas) + \"!\"\n hello = \"Hello, World!\"\n print(hello, \"->\", greet.parseString(hello))\n\nThe program outputs the following::\n\n Hello, World! -> ['Hello', ',', 'World', '!']\n\nThe Python representation of the grammar is quite readable, owing to the\nself-explanatory class names, and the use of '+', '|' and '^' operator\ndefinitions.\n\nThe parsed results returned from ``parseString()`` is a collection of type\n``ParseResults``, which can be accessed as a\nnested list, a dictionary, or an object with named attributes.\n\nThe pyparsing module handles some of the problems that are typically\nvexing when writing text parsers:\n\n- extra or missing whitespace (the above program will also handle ``\"Hello,World!\"``, ``\"Hello , World !\"``, etc.)\n- quoted strings\n- embedded comments\n\nThe examples directory includes a simple SQL parser, simple CORBA IDL\nparser, a config file parser, a chemical formula parser, and a four-\nfunction algebraic notation parser, among many others.\n\nDocumentation\n=============\n\nThere are many examples in the online docstrings of the classes\nand methods in pyparsing. You can find them compiled into `online docs `__. Additional\ndocumentation resources and project info are listed in the online\n`GitHub wiki `__. An\nentire directory of examples can be found `here `__.\n\nLicense\n=======\n\nMIT License. See header of the `pyparsing.py `__ file.\n\nHistory\n=======\n\nSee `CHANGES `__ file.\n\n.. |Build Status| image:: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml/badge.svg\n :target: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml\n.. |Coverage| image:: https://codecov.io/gh/pyparsing/pyparsing/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/pyparsing/pyparsing", - "release_date": "2022-05-10T23:26:03", + "description": "Core utilities for Python packages\npackaging\n=========\n\n.. start-intro\n\nReusable core utilities for various Python Packaging\n`interoperability specifications `_.\n\nThis library provides utilities that implement the interoperability\nspecifications which have clearly one correct behaviour (eg: :pep:`440`)\nor benefit greatly from having a single shared implementation (eg: :pep:`425`).\n\n.. end-intro\n\nThe ``packaging`` project includes the following: version handling, specifiers,\nmarkers, requirements, tags, utilities.\n\nDocumentation\n-------------\n\nThe `documentation`_ provides information and the API for the following:\n\n- Version Handling\n- Specifiers\n- Markers\n- Requirements\n- Tags\n- Utilities\n\nInstallation\n------------\n\nUse ``pip`` to install these utilities::\n\n pip install packaging\n\nDiscussion\n----------\n\nIf you run into bugs, you can file them in our `issue tracker`_.\n\nYou can also join ``#pypa`` on Freenode to ask questions or get involved.\n\n\n.. _`documentation`: https://packaging.pypa.io/\n.. _`issue tracker`: https://github.com/pypa/packaging/issues\n\n\nCode of Conduct\n---------------\n\nEveryone interacting in the packaging project's codebases, issue trackers, chat\nrooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.\n\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md\n\nContributing\n------------\n\nThe ``CONTRIBUTING.rst`` file outlines how to contribute to this project as\nwell as how to report a potential security issue. The documentation for this\nproject also covers information about `project development`_ and `security`_.\n\n.. _`project development`: https://packaging.pypa.io/en/latest/development/\n.. _`security`: https://packaging.pypa.io/en/latest/security/\n\nProject History\n---------------\n\nPlease review the ``CHANGELOG.rst`` file or the `Changelog documentation`_ for\nrecent changes and project history.\n\n.. _`Changelog documentation`: https://packaging.pypa.io/en/latest/changelog/\n\nChangelog\n---------\n\n21.3 - 2021-11-17\n~~~~~~~~~~~~~~~~~\n\n* Add a ``pp3-none-any`` tag (`#311 `__)\n* Replace the blank pyparsing 3 exclusion with a 3.0.5 exclusion (`#481 `__, `#486 `__)\n* Fix a spelling mistake (`#479 `__)\n\n21.2 - 2021-10-29\n~~~~~~~~~~~~~~~~~\n\n* Update documentation entry for 21.1.\n\n21.1 - 2021-10-29\n~~~~~~~~~~~~~~~~~\n\n* Update pin to pyparsing to exclude 3.0.0.\n\n21.0 - 2021-07-03\n~~~~~~~~~~~~~~~~~\n\n* PEP 656: musllinux support (`#411 `__)\n* Drop support for Python 2.7, Python 3.4 and Python 3.5.\n* Replace distutils usage with sysconfig (`#396 `__)\n* Add support for zip files in ``parse_sdist_filename`` (`#429 `__)\n* Use cached ``_hash`` attribute to short-circuit tag equality comparisons (`#417 `__)\n* Specify the default value for the ``specifier`` argument to ``SpecifierSet`` (`#437 `__)\n* Proper keyword-only \"warn\" argument in packaging.tags (`#403 `__)\n* Correctly remove prerelease suffixes from ~= check (`#366 `__)\n* Fix type hints for ``Version.post`` and ``Version.dev`` (`#393 `__)\n* Use typing alias ``UnparsedVersion`` (`#398 `__)\n* Improve type inference for ``packaging.specifiers.filter()`` (`#430 `__)\n* Tighten the return type of ``canonicalize_version()`` (`#402 `__)\n\n20.9 - 2021-01-29\n~~~~~~~~~~~~~~~~~\n\n* Run `isort `_ over the code base (`#377 `__)\n* Add support for the ``macosx_10_*_universal2`` platform tags (`#379 `__)\n* Introduce ``packaging.utils.parse_wheel_filename()`` and ``parse_sdist_filename()``\n (`#387 `__ and `#389 `__)\n\n20.8 - 2020-12-11\n~~~~~~~~~~~~~~~~~\n\n* Revert back to setuptools for compatibility purposes for some Linux distros (`#363 `__)\n* Do not insert an underscore in wheel tags when the interpreter version number\n is more than 2 digits (`#372 `__)\n\n20.7 - 2020-11-28\n~~~~~~~~~~~~~~~~~\n\nNo unreleased changes.\n\n20.6 - 2020-11-28\n~~~~~~~~~~~~~~~~~\n\n.. note:: This release was subsequently yanked, and these changes were included in 20.7.\n\n* Fix flit configuration, to include LICENSE files (`#357 `__)\n* Make `intel` a recognized CPU architecture for the `universal` macOS platform tag (`#361 `__)\n* Add some missing type hints to `packaging.requirements` (issue:`350`)\n\n20.5 - 2020-11-27\n~~~~~~~~~~~~~~~~~\n\n* Officially support Python 3.9 (`#343 `__)\n* Deprecate the ``LegacyVersion`` and ``LegacySpecifier`` classes (`#321 `__)\n* Handle ``OSError`` on non-dynamic executables when attempting to resolve\n the glibc version string.\n\n20.4 - 2020-05-19\n~~~~~~~~~~~~~~~~~\n\n* Canonicalize version before comparing specifiers. (`#282 `__)\n* Change type hint for ``canonicalize_name`` to return\n ``packaging.utils.NormalizedName``.\n This enables the use of static typing tools (like mypy) to detect mixing of\n normalized and un-normalized names.\n\n20.3 - 2020-03-05\n~~~~~~~~~~~~~~~~~\n\n* Fix changelog for 20.2.\n\n20.2 - 2020-03-05\n~~~~~~~~~~~~~~~~~\n\n* Fix a bug that caused a 32-bit OS that runs on a 64-bit ARM CPU (e.g. ARM-v8,\n aarch64), to report the wrong bitness.\n\n20.1 - 2020-01-24\n~~~~~~~~~~~~~~~~~~~\n\n* Fix a bug caused by reuse of an exhausted iterator. (`#257 `__)\n\n20.0 - 2020-01-06\n~~~~~~~~~~~~~~~~~\n\n* Add type hints (`#191 `__)\n\n* Add proper trove classifiers for PyPy support (`#198 `__)\n\n* Scale back depending on ``ctypes`` for manylinux support detection (`#171 `__)\n\n* Use ``sys.implementation.name`` where appropriate for ``packaging.tags`` (`#193 `__)\n\n* Expand upon the API provided by ``packaging.tags``: ``interpreter_name()``, ``mac_platforms()``, ``compatible_tags()``, ``cpython_tags()``, ``generic_tags()`` (`#187 `__)\n\n* Officially support Python 3.8 (`#232 `__)\n\n* Add ``major``, ``minor``, and ``micro`` aliases to ``packaging.version.Version`` (`#226 `__)\n\n* Properly mark ``packaging`` has being fully typed by adding a `py.typed` file (`#226 `__)\n\n19.2 - 2019-09-18\n~~~~~~~~~~~~~~~~~\n\n* Remove dependency on ``attrs`` (`#178 `__, `#179 `__)\n\n* Use appropriate fallbacks for CPython ABI tag (`#181 `__, `#185 `__)\n\n* Add manylinux2014 support (`#186 `__)\n\n* Improve ABI detection (`#181 `__)\n\n* Properly handle debug wheels for Python 3.8 (`#172 `__)\n\n* Improve detection of debug builds on Windows (`#194 `__)\n\n19.1 - 2019-07-30\n~~~~~~~~~~~~~~~~~\n\n* Add the ``packaging.tags`` module. (`#156 `__)\n\n* Correctly handle two-digit versions in ``python_version`` (`#119 `__)\n\n\n19.0 - 2019-01-20\n~~~~~~~~~~~~~~~~~\n\n* Fix string representation of PEP 508 direct URL requirements with markers.\n\n* Better handling of file URLs\n\n This allows for using ``file:///absolute/path``, which was previously\n prevented due to the missing ``netloc``.\n\n This allows for all file URLs that ``urlunparse`` turns back into the\n original URL to be valid.\n\n\n18.0 - 2018-09-26\n~~~~~~~~~~~~~~~~~\n\n* Improve error messages when invalid requirements are given. (`#129 `__)\n\n\n17.1 - 2017-02-28\n~~~~~~~~~~~~~~~~~\n\n* Fix ``utils.canonicalize_version`` when supplying non PEP 440 versions.\n\n\n17.0 - 2017-02-28\n~~~~~~~~~~~~~~~~~\n\n* Drop support for python 2.6, 3.2, and 3.3.\n\n* Define minimal pyparsing version to 2.0.2 (`#91 `__).\n\n* Add ``epoch``, ``release``, ``pre``, ``dev``, and ``post`` attributes to\n ``Version`` and ``LegacyVersion`` (`#34 `__).\n\n* Add ``Version().is_devrelease`` and ``LegacyVersion().is_devrelease`` to\n make it easy to determine if a release is a development release.\n\n* Add ``utils.canonicalize_version`` to canonicalize version strings or\n ``Version`` instances (`#121 `__).\n\n\n16.8 - 2016-10-29\n~~~~~~~~~~~~~~~~~\n\n* Fix markers that utilize ``in`` so that they render correctly.\n\n* Fix an erroneous test on Python RC releases.\n\n\n16.7 - 2016-04-23\n~~~~~~~~~~~~~~~~~\n\n* Add support for the deprecated ``python_implementation`` marker which was\n an undocumented setuptools marker in addition to the newer markers.\n\n\n16.6 - 2016-03-29\n~~~~~~~~~~~~~~~~~\n\n* Add support for the deprecated, PEP 345 environment markers in addition to\n the newer markers.\n\n\n16.5 - 2016-02-26\n~~~~~~~~~~~~~~~~~\n\n* Fix a regression in parsing requirements with whitespaces between the comma\n separators.\n\n\n16.4 - 2016-02-22\n~~~~~~~~~~~~~~~~~\n\n* Fix a regression in parsing requirements like ``foo (==4)``.\n\n\n16.3 - 2016-02-21\n~~~~~~~~~~~~~~~~~\n\n* Fix a bug where ``packaging.requirements:Requirement`` was overly strict when\n matching legacy requirements.\n\n\n16.2 - 2016-02-09\n~~~~~~~~~~~~~~~~~\n\n* Add a function that implements the name canonicalization from PEP 503.\n\n\n16.1 - 2016-02-07\n~~~~~~~~~~~~~~~~~\n\n* Implement requirement specifiers from PEP 508.\n\n\n16.0 - 2016-01-19\n~~~~~~~~~~~~~~~~~\n\n* Relicense so that packaging is available under *either* the Apache License,\n Version 2.0 or a 2 Clause BSD license.\n\n* Support installation of packaging when only distutils is available.\n\n* Fix ``==`` comparison when there is a prefix and a local version in play.\n (`#41 `__).\n\n* Implement environment markers from PEP 508.\n\n\n15.3 - 2015-08-01\n~~~~~~~~~~~~~~~~~\n\n* Normalize post-release spellings for rev/r prefixes. `#35 `__\n\n\n15.2 - 2015-05-13\n~~~~~~~~~~~~~~~~~\n\n* Fix an error where the arbitrary specifier (``===``) was not correctly\n allowing pre-releases when it was being used.\n\n* Expose the specifier and version parts through properties on the\n ``Specifier`` classes.\n\n* Allow iterating over the ``SpecifierSet`` to get access to all of the\n ``Specifier`` instances.\n\n* Allow testing if a version is contained within a specifier via the ``in``\n operator.\n\n\n15.1 - 2015-04-13\n~~~~~~~~~~~~~~~~~\n\n* Fix a logic error that was causing inconsistent answers about whether or not\n a pre-release was contained within a ``SpecifierSet`` or not.\n\n\n15.0 - 2015-01-02\n~~~~~~~~~~~~~~~~~\n\n* Add ``Version().is_postrelease`` and ``LegacyVersion().is_postrelease`` to\n make it easy to determine if a release is a post release.\n\n* Add ``Version().base_version`` and ``LegacyVersion().base_version`` to make\n it easy to get the public version without any pre or post release markers.\n\n* Support the update to PEP 440 which removed the implied ``!=V.*`` when using\n either ``>V`` or ``V`` or ````) operator.\n\n\n14.3 - 2014-11-19\n~~~~~~~~~~~~~~~~~\n\n* **BACKWARDS INCOMPATIBLE** Refactor specifier support so that it can sanely\n handle legacy specifiers as well as PEP 440 specifiers.\n\n* **BACKWARDS INCOMPATIBLE** Move the specifier support out of\n ``packaging.version`` into ``packaging.specifiers``.\n\n\n14.2 - 2014-09-10\n~~~~~~~~~~~~~~~~~\n\n* Add prerelease support to ``Specifier``.\n* Remove the ability to do ``item in Specifier()`` and replace it with\n ``Specifier().contains(item)`` in order to allow flags that signal if a\n prerelease should be accepted or not.\n* Add a method ``Specifier().filter()`` which will take an iterable and returns\n an iterable with items that do not match the specifier filtered out.\n\n\n14.1 - 2014-09-08\n~~~~~~~~~~~~~~~~~\n\n* Allow ``LegacyVersion`` and ``Version`` to be sorted together.\n* Add ``packaging.version.parse()`` to enable easily parsing a version string\n as either a ``Version`` or a ``LegacyVersion`` depending on it's PEP 440\n validity.\n\n\n14.0 - 2014-09-05\n~~~~~~~~~~~~~~~~~\n\n* Initial release.\n\n\n.. _`master`: https://github.com/pypa/packaging/", + "release_date": "2021-11-18T00:39:10", "parties": [ { "type": "person", "role": "author", - "name": null, - "email": "Paul McGuire ", + "name": "Donald Stufft and individual contributors", + "email": "donald@stufft.io", "url": null } ], "keywords": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", - "Intended Audience :: Information Technology", - "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", @@ -7316,15 +3571,14 @@ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Typing :: Typed" + "Programming Language :: Python :: Implementation :: PyPy" ], - "homepage_url": "", - "download_url": "https://files.pythonhosted.org/packages/6c/10/a7d0fa5baea8fe7b50f448ab742f26f52b80bfca85ac2be9d35cdd9a3246/pyparsing-3.0.9-py3-none-any.whl", - "size": 98338, + "homepage_url": "https://github.com/pypa/packaging", + "download_url": "https://files.pythonhosted.org/packages/05/8e/8de486cbd03baba4deef4142bd643a3e7bbe954a784dc1bb17142572d127/packaging-21.3-py3-none-any.whl", + "size": 40750, "sha1": null, - "md5": "9b7c6d2c436bc7eba41f5f239b391b4c", - "sha256": "5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc", + "md5": "670a7057642064a747bd8274b24eb3f9", + "sha256": "ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -7332,8 +3586,10 @@ "copyright": null, "license_expression": null, "declared_license": { + "license": "BSD-2-Clause or Apache-2.0", "classifiers": [ - "License :: OSI Approved :: MIT License" + "License :: OSI Approved :: Apache Software License", + "License :: OSI Approved :: BSD License" ] }, "notice_text": null, @@ -7343,52 +3599,53 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pyparsing/3.0.9/json", + "api_data_url": "https://pypi.org/pypi/packaging/21.3/json", "datasource_id": null, - "purl": "pkg:pypi/pyparsing@3.0.9" + "purl": "pkg:pypi/packaging@21.3" }, { "type": "pypi", "namespace": null, - "name": "pyparsing", - "version": "3.0.9", + "name": "pathspec", + "version": "0.9.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "pyparsing module - Classes and methods to define and execute parsing grammars\nPyParsing -- A Python Parsing Module\n====================================\n\n|Build Status| |Coverage|\n\nIntroduction\n============\n\nThe pyparsing module is an alternative approach to creating and\nexecuting simple grammars, vs. the traditional lex/yacc approach, or the\nuse of regular expressions. The pyparsing module provides a library of\nclasses that client code uses to construct the grammar directly in\nPython code.\n\n*[Since first writing this description of pyparsing in late 2003, this\ntechnique for developing parsers has become more widespread, under the\nname Parsing Expression Grammars - PEGs. See more information on PEGs*\n`here `__\n*.]*\n\nHere is a program to parse ``\"Hello, World!\"`` (or any greeting of the form\n``\"salutation, addressee!\"``):\n\n.. code:: python\n\n from pyparsing import Word, alphas\n greet = Word(alphas) + \",\" + Word(alphas) + \"!\"\n hello = \"Hello, World!\"\n print(hello, \"->\", greet.parseString(hello))\n\nThe program outputs the following::\n\n Hello, World! -> ['Hello', ',', 'World', '!']\n\nThe Python representation of the grammar is quite readable, owing to the\nself-explanatory class names, and the use of '+', '|' and '^' operator\ndefinitions.\n\nThe parsed results returned from ``parseString()`` is a collection of type\n``ParseResults``, which can be accessed as a\nnested list, a dictionary, or an object with named attributes.\n\nThe pyparsing module handles some of the problems that are typically\nvexing when writing text parsers:\n\n- extra or missing whitespace (the above program will also handle ``\"Hello,World!\"``, ``\"Hello , World !\"``, etc.)\n- quoted strings\n- embedded comments\n\nThe examples directory includes a simple SQL parser, simple CORBA IDL\nparser, a config file parser, a chemical formula parser, and a four-\nfunction algebraic notation parser, among many others.\n\nDocumentation\n=============\n\nThere are many examples in the online docstrings of the classes\nand methods in pyparsing. You can find them compiled into `online docs `__. Additional\ndocumentation resources and project info are listed in the online\n`GitHub wiki `__. An\nentire directory of examples can be found `here `__.\n\nLicense\n=======\n\nMIT License. See header of the `pyparsing.py `__ file.\n\nHistory\n=======\n\nSee `CHANGES `__ file.\n\n.. |Build Status| image:: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml/badge.svg\n :target: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml\n.. |Coverage| image:: https://codecov.io/gh/pyparsing/pyparsing/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/pyparsing/pyparsing", - "release_date": "2022-05-10T23:26:05", + "description": "Utility library for gitignore style pattern matching of file paths.\n*pathspec*: Path Specification\n==============================\n\n*pathspec* is a utility library for pattern matching of file paths. So\nfar this only includes Git's wildmatch pattern matching which itself is\nderived from Rsync's wildmatch. Git uses wildmatch for its `gitignore`_\nfiles.\n\n.. _`gitignore`: http://git-scm.com/docs/gitignore\n\n\nTutorial\n--------\n\nSay you have a \"Projects\" directory and you want to back it up, but only\ncertain files, and ignore others depending on certain conditions::\n\n\t>>> import pathspec\n\t>>> # The gitignore-style patterns for files to select, but we're including\n\t>>> # instead of ignoring.\n\t>>> spec = \"\"\"\n\t...\n\t... # This is a comment because the line begins with a hash: \"#\"\n\t...\n\t... # Include several project directories (and all descendants) relative to\n\t... # the current directory. To reference a directory you must end with a\n\t... # slash: \"/\"\n\t... /project-a/\n\t... /project-b/\n\t... /project-c/\n\t...\n\t... # Patterns can be negated by prefixing with exclamation mark: \"!\"\n\t...\n\t... # Ignore temporary files beginning or ending with \"~\" and ending with\n\t... # \".swp\".\n\t... !~*\n\t... !*~\n\t... !*.swp\n\t...\n\t... # These are python projects so ignore compiled python files from\n\t... # testing.\n\t... !*.pyc\n\t...\n\t... # Ignore the build directories but only directly under the project\n\t... # directories.\n\t... !/*/build/\n\t...\n\t... \"\"\"\n\nWe want to use the ``GitWildMatchPattern`` class to compile our patterns. The\n``PathSpec`` class provides an interface around pattern implementations::\n\n\t>>> spec = pathspec.PathSpec.from_lines(pathspec.patterns.GitWildMatchPattern, spec.splitlines())\n\nThat may be a mouthful but it allows for additional patterns to be implemented\nin the future without them having to deal with anything but matching the paths\nsent to them. ``GitWildMatchPattern`` is the implementation of the actual\npattern which internally gets converted into a regular expression.\n``PathSpec`` is a simple wrapper around a list of compiled patterns.\n\nTo make things simpler, we can use the registered name for a pattern class\ninstead of always having to provide a reference to the class itself. The\n``GitWildMatchPattern`` class is registered as **gitwildmatch**::\n\n\t>>> spec = pathspec.PathSpec.from_lines('gitwildmatch', spec.splitlines())\n\nIf we wanted to manually compile the patterns we can just do the following::\n\n\t>>> patterns = map(pathspec.patterns.GitWildMatchPattern, spec.splitlines())\n\t>>> spec = PathSpec(patterns)\n\n``PathSpec.from_lines()`` is simply a class method which does just that.\n\nIf you want to load the patterns from file, you can pass the file instance\ndirectly as well::\n\n\t>>> with open('patterns.list', 'r') as fh:\n\t>>> spec = pathspec.PathSpec.from_lines('gitwildmatch', fh)\n\nYou can perform matching on a whole directory tree with::\n\n\t>>> matches = spec.match_tree('path/to/directory')\n\nOr you can perform matching on a specific set of file paths with::\n\n\t>>> matches = spec.match_files(file_paths)\n\nOr check to see if an individual file matches::\n\n\t>>> is_matched = spec.match_file(file_path)\n\n\nLicense\n-------\n\n*pathspec* is licensed under the `Mozilla Public License Version 2.0`_. See\n`LICENSE`_ or the `FAQ`_ for more information.\n\nIn summary, you may use *pathspec* with any closed or open source project\nwithout affecting the license of the larger work so long as you:\n\n- give credit where credit is due,\n\n- and release any custom changes made to *pathspec*.\n\n.. _`Mozilla Public License Version 2.0`: http://www.mozilla.org/MPL/2.0\n.. _`LICENSE`: LICENSE\n.. _`FAQ`: http://www.mozilla.org/MPL/2.0/FAQ.html\n\n\nSource\n------\n\nThe source code for *pathspec* is available from the GitHub repo\n`cpburnz/python-path-specification`_.\n\n.. _`cpburnz/python-path-specification`: https://github.com/cpburnz/python-path-specification\n\n\nInstallation\n------------\n\n*pathspec* requires the following packages:\n\n- `setuptools`_\n\n*pathspec* can be installed from source with::\n\n\tpython setup.py install\n\n*pathspec* is also available for install through `PyPI`_::\n\n\tpip install pathspec\n\n.. _`setuptools`: https://pypi.python.org/pypi/setuptools\n.. _`PyPI`: http://pypi.python.org/pypi/pathspec\n\n\nDocumentation\n-------------\n\nDocumentation for *pathspec* is available on `Read the Docs`_.\n\n.. _`Read the Docs`: http://python-path-specification.readthedocs.io\n\n\nOther Languages\n---------------\n\n*pathspec* is also available as a `Ruby gem`_.\n\n.. _`Ruby gem`: https://github.com/highb/pathspec-ruby\n\n\nChange History\n==============\n\n0.9.0 (2021-07-17)\n------------------\n\n- `Issue #44`_/`Issue #50`_: Raise `GitWildMatchPatternError` for invalid git patterns.\n- `Issue #45`_: Fix for duplicate leading double-asterisk, and edge cases.\n- `Issue #46`_: Fix matching absolute paths.\n- API change: `util.normalize_files()` now returns a `Dict[str, List[pathlike]]` instead of a `Dict[str, pathlike]`.\n- Added type hinting.\n\n.. _`Issue #44`: https://github.com/cpburnz/python-path-specification/issues/44\n.. _`Issue #45`: https://github.com/cpburnz/python-path-specification/pull/45\n.. _`Issue #46`: https://github.com/cpburnz/python-path-specification/issues/46\n.. _`Issue #50`: https://github.com/cpburnz/python-path-specification/pull/50\n\n\n0.8.1 (2020-11-07)\n------------------\n\n- `Issue #43`_: Add support for addition operator.\n\n.. _`Issue #43`: https://github.com/cpburnz/python-path-specification/pull/43\n\n\n0.8.0 (2020-04-09)\n------------------\n\n- `Issue #30`_: Expose what patterns matched paths. Added `util.detailed_match_files()`.\n- `Issue #31`_: `match_tree()` doesn't return symlinks.\n- `Issue #34`_: Support `pathlib.Path`\\ s.\n- Add `PathSpec.match_tree_entries` and `util.iter_tree_entries()` to support directories and symlinks.\n- API change: `match_tree()` has been renamed to `match_tree_files()`. The old name `match_tree()` is still available as an alias.\n- API change: `match_tree_files()` now returns symlinks. This is a bug fix but it will change the returned results.\n\n.. _`Issue #30`: https://github.com/cpburnz/python-path-specification/issues/30\n.. _`Issue #31`: https://github.com/cpburnz/python-path-specification/issues/31\n.. _`Issue #34`: https://github.com/cpburnz/python-path-specification/issues/34\n\n\n0.7.0 (2019-12-27)\n------------------\n\n- `Issue #28`_: Add support for Python 3.8, and drop Python 3.4.\n- `Issue #29`_: Publish bdist wheel.\n\n.. _`Issue #28`: https://github.com/cpburnz/python-path-specification/pull/28\n.. _`Issue #29`: https://github.com/cpburnz/python-path-specification/pull/29\n\n\n0.6.0 (2019-10-03)\n------------------\n\n- `Issue #24`_: Drop support for Python 2.6, 3.2, and 3.3.\n- `Issue #25`_: Update README.rst.\n- `Issue #26`_: Method to escape gitwildmatch.\n\n.. _`Issue #24`: https://github.com/cpburnz/python-path-specification/pull/24\n.. _`Issue #25`: https://github.com/cpburnz/python-path-specification/pull/25\n.. _`Issue #26`: https://github.com/cpburnz/python-path-specification/pull/26\n\n\n0.5.9 (2018-09-15)\n------------------\n\n- Fixed file system error handling.\n\n\n0.5.8 (2018-09-15)\n------------------\n\n- Improved type checking.\n- Created scripts to test Python 2.6 because Tox removed support for it.\n- Improved byte string handling in Python 3.\n- `Issue #22`_: Handle dangling symlinks.\n\n.. _`Issue #22`: https://github.com/cpburnz/python-path-specification/issues/22\n\n\n0.5.7 (2018-08-14)\n------------------\n\n- `Issue #21`_: Fix collections deprecation warning.\n\n.. _`Issue #21`: https://github.com/cpburnz/python-path-specification/issues/21\n\n\n0.5.6 (2018-04-06)\n------------------\n\n- Improved unit tests.\n- Improved type checking.\n- `Issue #20`_: Support current directory prefix.\n\n.. _`Issue #20`: https://github.com/cpburnz/python-path-specification/issues/20\n\n\n0.5.5 (2017-09-09)\n------------------\n\n- Add documentation link to README.\n\n\n0.5.4 (2017-09-09)\n------------------\n\n- `Issue #17`_: Add link to Ruby implementation of *pathspec*.\n- Add sphinx documentation.\n\n.. _`Issue #17`: https://github.com/cpburnz/python-path-specification/pull/17\n\n\n0.5.3 (2017-07-01)\n------------------\n\n- `Issue #14`_: Fix byte strings for Python 3.\n- `Issue #15`_: Include \"LICENSE\" in source package.\n- `Issue #16`_: Support Python 2.6.\n\n.. _`Issue #14`: https://github.com/cpburnz/python-path-specification/issues/14\n.. _`Issue #15`: https://github.com/cpburnz/python-path-specification/pull/15\n.. _`Issue #16`: https://github.com/cpburnz/python-path-specification/issues/16\n\n\n0.5.2 (2017-04-04)\n------------------\n\n- Fixed change log.\n\n\n0.5.1 (2017-04-04)\n------------------\n\n- `Issue #13`_: Add equality methods to `PathSpec` and `RegexPattern`.\n\n.. _`Issue #13`: https://github.com/cpburnz/python-path-specification/pull/13\n\n\n0.5.0 (2016-08-22)\n------------------\n\n- `Issue #12`_: Add `PathSpec.match_file()`.\n- Renamed `gitignore.GitIgnorePattern` to `patterns.gitwildmatch.GitWildMatchPattern`.\n- Deprecated `gitignore.GitIgnorePattern`.\n\n.. _`Issue #12`: https://github.com/cpburnz/python-path-specification/issues/12\n\n\n0.4.0 (2016-07-15)\n------------------\n\n- `Issue #11`_: Support converting patterns into regular expressions without compiling them.\n- API change: Subclasses of `RegexPattern` should implement `pattern_to_regex()`.\n\n.. _`Issue #11`: https://github.com/cpburnz/python-path-specification/issues/11\n\n\n0.3.4 (2015-08-24)\n------------------\n\n- `Issue #7`_: Fixed non-recursive links.\n- `Issue #8`_: Fixed edge cases in gitignore patterns.\n- `Issue #9`_: Fixed minor usage documentation.\n- Fixed recursion detection.\n- Fixed trivial incompatibility with Python 3.2.\n\n.. _`Issue #7`: https://github.com/cpburnz/python-path-specification/pull/7\n.. _`Issue #8`: https://github.com/cpburnz/python-path-specification/pull/8\n.. _`Issue #9`: https://github.com/cpburnz/python-path-specification/pull/9\n\n\n0.3.3 (2014-11-21)\n------------------\n\n- Improved documentation.\n\n\n0.3.2 (2014-11-08)\n------------------\n\n- `Issue #5`_: Use tox for testing.\n- `Issue #6`_: Fixed matching Windows paths.\n- Improved documentation.\n- API change: `spec.match_tree()` and `spec.match_files()` now return iterators instead of sets.\n\n.. _`Issue #5`: https://github.com/cpburnz/python-path-specification/pull/5\n.. _`Issue #6`: https://github.com/cpburnz/python-path-specification/issues/6\n\n\n0.3.1 (2014-09-17)\n------------------\n\n- Updated README.\n\n\n0.3.0 (2014-09-17)\n------------------\n\n- `Issue #3`_: Fixed trailing slash in gitignore patterns.\n- `Issue #4`_: Fixed test for trailing slash in gitignore patterns.\n- Added registered patterns.\n\n.. _`Issue #3`: https://github.com/cpburnz/python-path-specification/pull/3\n.. _`Issue #4`: https://github.com/cpburnz/python-path-specification/pull/4\n\n\n0.2.2 (2013-12-17)\n------------------\n\n- Fixed setup.py.\n\n\n0.2.1 (2013-12-17)\n------------------\n\n- Added tests.\n- Fixed comment gitignore patterns.\n- Fixed relative path gitignore patterns.\n\n\n0.2.0 (2013-12-07)\n------------------\n\n- Initial release.", + "release_date": "2021-07-18T00:27:58", "parties": [ { "type": "person", "role": "author", - "name": null, - "email": "Paul McGuire ", + "name": "Caleb P. Burns", + "email": "cpburnz@gmail.com", "url": null } ], "keywords": [ - "Development Status :: 5 - Production/Stable", + "Development Status :: 4 - Beta", "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 :: Only", - "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", - "Typing :: Typed" + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Utilities" ], - "homepage_url": "", - "download_url": "https://files.pythonhosted.org/packages/71/22/207523d16464c40a0310d2d4d8926daffa00ac1f5b1576170a32db749636/pyparsing-3.0.9.tar.gz", - "size": 1999906, + "homepage_url": "https://github.com/cpburnz/python-path-specification", + "download_url": "https://files.pythonhosted.org/packages/42/ba/a9d64c7bcbc7e3e8e5f93a52721b377e994c22d16196e2b0f1236774353a/pathspec-0.9.0-py2.py3-none-any.whl", + "size": 31165, "sha1": null, - "md5": "fadc2f3bf5872bf6310576a86c3566e0", - "sha256": "2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", + "md5": "ffa2e0227d4eef53c5329af611e26c32", + "sha256": "7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -7396,8 +3653,9 @@ "copyright": null, "license_expression": null, "declared_license": { + "license": "MPL 2.0", "classifiers": [ - "License :: OSI Approved :: MIT License" + "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)" ] }, "notice_text": null, @@ -7407,53 +3665,44 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pyparsing/3.0.9/json", + "api_data_url": "https://pypi.org/pypi/pathspec/0.9.0/json", "datasource_id": null, - "purl": "pkg:pypi/pyparsing@3.0.9" + "purl": "pkg:pypi/pathspec@0.9.0" }, { "type": "pypi", "namespace": null, - "name": "pytest-forked", - "version": "1.4.0", + "name": "pip-requirements-parser", + "version": "31.2.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "run tests in isolated forked subprocesses\npytest-forked: run each test in a forked subprocess\n====================================================\n\n\n.. warning::\n\n\tthis is a extraction of the xdist --forked module,\n\tfuture maintenance beyond the bare minimum is not planned until a new maintainer is found.\n\n\nThis plugin **does not work on Windows** because there's no ``fork`` support.\n\n\n* ``--forked``: run each test in a forked\n subprocess to survive ``SEGFAULTS`` or otherwise dying processes.\n\n|python| |version| |ci| |pre-commit| |black|\n\n.. |version| image:: http://img.shields.io/pypi/v/pytest-forked.svg\n :target: https://pypi.python.org/pypi/pytest-forked\n\n.. |ci| image:: https://github.com/pytest-dev/pytest-forked/workflows/build/badge.svg\n :target: https://github.com/pytest-dev/pytest-forked/actions\n\n.. |python| image:: https://img.shields.io/pypi/pyversions/pytest-forked.svg\n :target: https://pypi.python.org/pypi/pytest-forked/\n\n.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/ambv/black\n\n.. |pre-commit| image:: https://results.pre-commit.ci/badge/github/pytest-dev/pytest-forked/master.svg\n :target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest-forked/master\n\nInstallation\n-----------------------\n\nInstall the plugin with::\n\n pip install pytest-forked\n\nor use the package in develope/in-place mode with\na checkout of the `pytest-forked repository`_ ::\n\n pip install -e .\n\n\nUsage examples\n---------------------\n\nIf you have tests involving C or C++ libraries you might have to deal\nwith tests crashing the process. For this case you may use the boxing\noptions::\n\n pytest --forked\n\nwhich will run each test in a subprocess and will report if a test\ncrashed the process. You can also combine this option with\nrunning multiple processes via pytest-xdist to speed up the test run\nand use your CPU cores::\n\n pytest -n3 --forked\n\nthis would run 3 testing subprocesses in parallel which each\ncreate new forked subprocesses for each test.\n\n\nYou can also fork for individual tests::\n\n @pytest.mark.forked\n def test_with_leaky_state():\n run_some_monkey_patches()\n\n\nThis test will be unconditionally boxed, regardless of CLI flag.\n\n\n.. _`pytest-forked repository`: https://github.com/pytest-dev/pytest-forked", - "release_date": "2021-12-10T15:43:18", + "description": "pip requirements parser - a mostly correct pip requirements parsing library because it uses pip's own code.\npip-requirements-parser - a mostly correct pip requirements parsing library\n================================================================================\n\nCopyright (c) nexB Inc. and others.\nCopyright (c) The pip developers (see AUTHORS.rst file)\nSPDX-License-Identifier: MIT\nHomepage: https://github.com/nexB/pip-requirements and https://www.aboutcode.org/\n\n\n``pip-requirements-parser`` is a mostly correct pip requirements parsing\nlibrary ... because it uses pip's own code!\n\npip is the ``package installer`` for Python that is using \"requirements\" text\nfiles listing the packages to install.\n\nPer https://pip.pypa.io/en/stable/reference/requirements-file-format/ :\n\n \"The requirements file format is closely tied to a number of internal\n details of pip (e.g., pip\u2019s command line options). The basic format is\n relatively stable and portable but the full syntax, as described here,\n is only intended for consumption by pip, and other tools should take\n that into account before using it for their own purposes.\"\n\nAnd per https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program :\n\n \"[..] pip is a command line program. While it is implemented in Python, and\n so is available from your Python code via import pip, you must not use pip\u2019s\n internal APIs in this way.\"\n \n \"What this means in practice is that everything inside of pip is considered\n an implementation detail. Even the fact that the import name is pip is\n subject to change without notice. While we do try not to break things as\n much as possible, all the internal APIs can change at any time, for any\n reason. It also means that we generally won\u2019t fix issues that are a result\n of using pip in an unsupported way.\"\n\n\nBecause of all this, pip requirements are notoriously difficult to parse right\nin all their diversity because:\n\n- pip does not have a public API and therefore cannot be reliably used as a\n stable library. Some libraries attempt to do this though. (See Alternative)\n\n- The pip requirements file syntax is closely aligned with pip's command line\n interface and command line options. In some ways a pip requirements file is a\n list of pip command line options and arguments. Therefore, it is hard to parse\n these short of reproducing the pip command line options parsing. At least one\n other library is using a command line option parser to parse options correctly.\n\n\nThis ``pip-requirements-parser`` Python library is yet another pip requirements\nfiles parser, but this time doing it hopefully correctly and doing as well as\npip does it, because this is using pip's own code.\n\n\nThe ``pip-requirements-parser`` library offers these key advantages:\n\n- Other requirements parsers typically do not work in all the cases that ``pip``\n supports: parsing any requirement as seen in the wild will fail parsing some\n valid pip requirements. Since the ``pip-requirements-parser`` library is based\n on pip's own code, it works **exactly** like pip and will parse all the\n requirements files that pip can parse.\n\n- The ``pip-requirements-parser`` library offers a simple and stable code API\n that will not change without notice.\n\n- The ``pip-requirements-parser`` library is designed to work offline without\n making any external network call, while the original pip code needs network\n access.\n\n- The ``pip-requirements-parser`` library is a single file that can easily be\n copied around as needed for easy vendoring. This is useful as requirements\n parsing is often needed to bootstrap in a constrained environment.\n\n- The ``pip-requirements-parser`` library has only one external dependency on\n the common \"packaging\" package. Otherwise it uses only the standard library.\n The benefits are the same as being a single file: fewer moving parts helps with\n using it in more cases.\n\n- The ``pip-requirements-parser`` library reuses and passes the full subset of\n the pip test suite that deals with requirements. This is a not really\n surprising since this is pip's own code. The suite suite has been carefully\n ported and adjusted to work with the updated code subset.\n\n- The standard pip requirements parser depends on the ``requests`` HTTP library\n and makes network connection to PyPI and other referenced repositories when\n parsing. The ``pip-requirements-parser`` library works entirely offline and the\n requests dependency and calling has been entirely removed.\n\n- The ``pip-requirements-parser`` library has preserved the complete pip git\n history for the subset of the code we kept. The original pip code was merged\n from multiple modules keeping all the git history at the line/blame level using\n some git fu and git filter repo. The benefit is that we will be able to more\n easily track and merge future pip updates.\n\n- The ``pip-requirements-parser`` library has an extensive test suite made of:\n\n - pip's own tests\n - new unit tests\n - new requirements test files (over 40 new test files)\n - the tests suite of some of the main other requirement parsers including:\n\n - http://github.com/di/pip-api\n - https://github.com/pyupio/dparse\n - https://github.com/landscapeio/requirements-detector\n - https://github.com/madpah/requirements-parser\n\nAs a result, it has likely the most comprehensive requiremente parsing test\nsuite around.\n\n\nUsage\n~~~~~~~~~~\n\nThe entry point is the ``RequirementsFile`` object::\n\n >>> from pip_requirements_parser import RequirementsFile\n >>> rf = RequirementsFile.from_file(\"requirements.txt\")\n\nFrom there, you can dump to a dict::\n >>> rf.to_dict()\n\nOr access the requirements (either InstallRequirement or EditableRequirement\nobjects)::\n\n >>> for req in rf.requirements:\n ... print(req.to_dict())\n ... print(req.dumps())\n\nAnd the various other parsed elements such as options, commenst and invalid lines\nthat have a parsing error::\n\n >>> rf.options\n >>> rf.comment_lines\n >>> rf.invalid_lines\n\nEach of these and the ``requirements`` hahve a \"requirement_line\" attribute\nwith the original text.\n\nFinally you can get a requirements file back as a string::\n\n >>> rf.dumps()\n\n\nAlternative\n------------------\n\nThere are several other parsers that either:\n\n- Implement their own parsing and can therefore miss some subtle differences\n- Or wrap and import pip as a library, working around the lack of pip API\n\nNone of these use the approach of reusing and forking the subset of pip that is\nneeded to parse requirements. The ones that wrap pip require network access\nlike pip does. They potentially need updating each time there is a new pip\nrelease. The ones that reimplement pip parsing may not support all pip\nspecifics.\n\n\nImplement a new pip parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n- pip-api https://github.com/di/pip-api does not support hashes and certain pip options.\n It does however use argparse for parsing options and is therefore correctly\n handling most options. The parser is a single script that only depends on\n packaging (that is vendored). It is not designed to be used as a single script\n though and ``pip`` is a dependency.\n\n- requirements-parser https://github.com/madpah/requirements-parse does not\n support hashes and certain pip options\n\n- dparse https://github.com/pyupio/dparse\n\n- https://github.com/GoogleCloudPlatform/django-cloud-deploy/blob/d316b1e45357761e2b124143e6e12ce34ef6f975/django_cloud_deploy/skeleton/requirements_parser.py\n\n\nReuse and wrap pip's own parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n- requirementslib https://github.com/sarugaku/requirementslib uses pip-shim\n https://github.com/sarugaku/pip-shims which is a set of \"shims\" around each\n pip versions in an attempt to offer an API to pip. Comes with 20+ dependencies,\n\n- micropipenv https://github.com/thoth-station/micropipenv/blob/d0c37c1bf0aadf5149aebe2df0bf1cb12ded4c40/micropipenv.py#L53\n\n- pip-tools https://github.com/jazzband/pip-tools/blob/9e1be05375104c56e07cdb0904e1b50b86f8b550/piptools/_compat/pip_compat.py", + "release_date": "2022-01-28T13:21:39", "parties": [ { "type": "person", - "role": "author", - "name": "pytest-dev", - "email": "pytest-dev@python.org", + "role": "author", + "name": "The pip authors, nexB. Inc. and others", + "email": "info@aboutcode.org", "url": null } ], "keywords": [ - "Development Status :: 7 - Inactive", - "Framework :: Pytest", + "utilities pip requirements parser dependencies pypi", + "Development Status :: 4 - Beta", "Intended Audience :: Developers", - "Operating System :: MacOS :: MacOS X", - "Operating System :: POSIX", - "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Topic :: Software Development :: Quality Assurance", - "Topic :: Software Development :: Testing", + "Topic :: Software Development", "Topic :: Utilities" ], - "homepage_url": "https://github.com/pytest-dev/pytest-forked", - "download_url": "https://files.pythonhosted.org/packages/0c/36/c56ef2aea73912190cdbcc39aaa860db8c07c1a5ce8566994ec9425453db/pytest_forked-1.4.0-py3-none-any.whl", - "size": 4885, + "homepage_url": "https://github.com/nexB/pip-requirements-parser", + "download_url": "https://files.pythonhosted.org/packages/67/2e/94750665759e54b39c9c49eff98d9db1385896c7331b2e44e7c69eec3630/pip_requirements_parser-31.2.0-py3-none-any.whl", + "size": 33025, "sha1": null, - "md5": "bf0249039fb39cb7d6af60f09957e61d", - "sha256": "bbbb6717efc886b9d64537b41fb1497cfaf3c9601276be8da2cccfea5a3c8ad8", + "md5": "1bfb708322e90b0be35a848e63b67dd1", + "sha256": "22fa213a987913385b2484d5698ecfa1d9cf4154978cdf929085548af55355b0", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -7461,10 +3710,7 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] + "license": "MIT" }, "notice_text": null, "source_packages": [], @@ -7473,56 +3719,54 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pytest-forked/1.4.0/json", + "api_data_url": "https://pypi.org/pypi/pip-requirements-parser/31.2.0/json", "datasource_id": null, - "purl": "pkg:pypi/pytest-forked@1.4.0" + "purl": "pkg:pypi/pip-requirements-parser@31.2.0" }, { "type": "pypi", "namespace": null, - "name": "pytest-forked", - "version": "1.4.0", + "name": "pip", + "version": "24.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "run tests in isolated forked subprocesses\npytest-forked: run each test in a forked subprocess\n====================================================\n\n\n.. warning::\n\n\tthis is a extraction of the xdist --forked module,\n\tfuture maintenance beyond the bare minimum is not planned until a new maintainer is found.\n\n\nThis plugin **does not work on Windows** because there's no ``fork`` support.\n\n\n* ``--forked``: run each test in a forked\n subprocess to survive ``SEGFAULTS`` or otherwise dying processes.\n\n|python| |version| |ci| |pre-commit| |black|\n\n.. |version| image:: http://img.shields.io/pypi/v/pytest-forked.svg\n :target: https://pypi.python.org/pypi/pytest-forked\n\n.. |ci| image:: https://github.com/pytest-dev/pytest-forked/workflows/build/badge.svg\n :target: https://github.com/pytest-dev/pytest-forked/actions\n\n.. |python| image:: https://img.shields.io/pypi/pyversions/pytest-forked.svg\n :target: https://pypi.python.org/pypi/pytest-forked/\n\n.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/ambv/black\n\n.. |pre-commit| image:: https://results.pre-commit.ci/badge/github/pytest-dev/pytest-forked/master.svg\n :target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest-forked/master\n\nInstallation\n-----------------------\n\nInstall the plugin with::\n\n pip install pytest-forked\n\nor use the package in develope/in-place mode with\na checkout of the `pytest-forked repository`_ ::\n\n pip install -e .\n\n\nUsage examples\n---------------------\n\nIf you have tests involving C or C++ libraries you might have to deal\nwith tests crashing the process. For this case you may use the boxing\noptions::\n\n pytest --forked\n\nwhich will run each test in a subprocess and will report if a test\ncrashed the process. You can also combine this option with\nrunning multiple processes via pytest-xdist to speed up the test run\nand use your CPU cores::\n\n pytest -n3 --forked\n\nthis would run 3 testing subprocesses in parallel which each\ncreate new forked subprocesses for each test.\n\n\nYou can also fork for individual tests::\n\n @pytest.mark.forked\n def test_with_leaky_state():\n run_some_monkey_patches()\n\n\nThis test will be unconditionally boxed, regardless of CLI flag.\n\n\n.. _`pytest-forked repository`: https://github.com/pytest-dev/pytest-forked", - "release_date": "2021-12-10T15:43:19", + "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 :alt: PyPI\n\n.. image:: https://img.shields.io/pypi/pyversions/pip\n :target: https://pypi.org/project/pip\n :alt: PyPI - Python Version\n\n.. image:: https://readthedocs.org/projects/pip/badge/?version=latest\n :target: https://pip.pypa.io/en/latest\n :alt: Documentation\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\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 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 `PSF 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/installation/\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.. _Issue tracking: https://github.com/pypa/pip/issues\n.. _Discourse channel: https://discuss.python.org/c/packaging\n.. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa\n.. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md", + "release_date": "2024-02-03T09:53:09", "parties": [ { "type": "person", "role": "author", - "name": "pytest-dev", - "email": "pytest-dev@python.org", + "name": null, + "email": "The pip developers ", "url": null } ], "keywords": [ - "Development Status :: 7 - Inactive", - "Framework :: Pytest", + "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", - "Operating System :: MacOS :: MacOS X", - "Operating System :: POSIX", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", - "Topic :: Software Development :: Quality Assurance", - "Topic :: Software Development :: Testing", - "Topic :: Utilities" + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Build Tools" ], - "homepage_url": "https://github.com/pytest-dev/pytest-forked", - "download_url": "https://files.pythonhosted.org/packages/f1/bc/0121a2e386b261b69f4f5aa48e5304c947451dce70d68628cb28d5cd0d28/pytest-forked-1.4.0.tar.gz", - "size": 10197, + "homepage_url": "", + "download_url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", + "size": 2110226, "sha1": null, - "md5": "fc2d4bb78f3a5e7c082173527d5009d3", - "sha256": "8b67587c8f98cbbadfdd804539ed5455b6ed03802203485dd2f53c1422d7440e", + "md5": "74e3c5e4082113b1239ca0e9abfd1e82", + "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", "sha512": null, "bug_tracking_url": null, - "code_view_url": null, + "code_view_url": "https://github.com/pypa/pip", "vcs_url": null, "copyright": null, "license_expression": null, @@ -7539,57 +3783,54 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pytest-forked/1.4.0/json", + "api_data_url": "https://pypi.org/pypi/pip/24.0/json", "datasource_id": null, - "purl": "pkg:pypi/pytest-forked@1.4.0" + "purl": "pkg:pypi/pip@24.0" }, { "type": "pypi", "namespace": null, - "name": "pytest-xdist", - "version": "2.5.0", + "name": "pip", + "version": "24.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "pytest xdist plugin for distributed testing and loop-on-failing modes\n============\npytest-xdist\n============\n\n.. image:: http://img.shields.io/pypi/v/pytest-xdist.svg\n :alt: PyPI version\n :target: https://pypi.python.org/pypi/pytest-xdist\n\n.. image:: https://img.shields.io/conda/vn/conda-forge/pytest-xdist.svg\n :target: https://anaconda.org/conda-forge/pytest-xdist\n\n.. image:: https://img.shields.io/pypi/pyversions/pytest-xdist.svg\n :alt: Python versions\n :target: https://pypi.python.org/pypi/pytest-xdist\n\n.. image:: https://github.com/pytest-dev/pytest-xdist/workflows/build/badge.svg\n :target: https://github.com/pytest-dev/pytest-xdist/actions\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/ambv/black\n\nThe `pytest-xdist`_ plugin extends pytest with new test execution modes, the most used being distributing\ntests across multiple CPUs to speed up test execution::\n\n pytest -n auto\n\nWith this call, pytest will spawn a number of workers processes equal to the number of available CPUs, and distribute\nthe tests randomly across them. There is also a number of `distribution modes`_ to choose from.\n\n**NOTE**: due to how pytest-xdist is implemented, the ``-s/--capture=no`` option does not work.\n\n.. contents:: **Table of Contents**\n\nInstallation\n------------\n\nInstall the plugin with::\n\n pip install pytest-xdist\n\n\nTo use ``psutil`` for detection of the number of CPUs available, install the ``psutil`` extra::\n\n pip install pytest-xdist[psutil]\n\n\nFeatures\n--------\n\n* Test run parallelization_: tests can be executed across multiple CPUs or hosts.\n This allows to speed up development or to use special resources of `remote machines`_.\n\n* ``--looponfail``: run your tests repeatedly in a subprocess. After each run\n pytest waits until a file in your project changes and then re-runs\n the previously failing tests. This is repeated until all tests pass\n after which again a full run is performed.\n\n* `Multi-Platform`_ coverage: you can specify different Python interpreters\n or different platforms and run tests in parallel on all of them.\n\n Before running tests remotely, ``pytest`` efficiently \"rsyncs\" your\n program source code to the remote place.\n You may specify different Python versions and interpreters. It does not\n installs/synchronize dependencies however.\n\n **Note**: this mode exists mostly for backward compatibility, as modern development\n relies on continuous integration for multi-platform testing.\n\n.. _parallelization:\n\nRunning tests across multiple CPUs\n----------------------------------\n\nTo send tests to multiple CPUs, use the ``-n`` (or ``--numprocesses``) option::\n\n pytest -n 8\n\nPass ``-n auto`` to use as many processes as your computer has CPU cores. This\ncan lead to considerable speed ups, especially if your test suite takes a\nnoticeable amount of time.\n\nThe test distribution algorithm is configured with the ``--dist`` command-line option:\n\n.. _distribution modes:\n\n* ``--dist load`` **(default)**: Sends pending tests to any worker that is\n available, without any guaranteed order.\n\n* ``--dist loadscope``: Tests are grouped by **module** for *test functions*\n and by **class** for *test methods*. Groups are distributed to available\n workers as whole units. This guarantees that all tests in a group run in the\n same process. This can be useful if you have expensive module-level or\n class-level fixtures. Grouping by class takes priority over grouping by\n module.\n\n* ``--dist loadfile``: Tests are grouped by their containing file. Groups are\n distributed to available workers as whole units. This guarantees that all\n tests in a file run in the same worker.\n\n* ``--dist loadgroup``: Tests are grouped by the ``xdist_group`` mark. Groups are\n distributed to available workers as whole units. This guarantees that all\n tests with same ``xdist_group`` name run in the same worker.\n\n .. code-block:: python\n\n @pytest.mark.xdist_group(name=\"group1\")\n def test1():\n pass\n\n class TestA:\n @pytest.mark.xdist_group(\"group1\")\n def test2():\n pass\n\n This will make sure ``test1`` and ``TestA::test2`` will run in the same worker.\n Tests without the ``xdist_group`` mark are distributed normally as in the ``--dist=load`` mode.\n\n* ``--dist no``: The normal pytest execution mode, runs one test at a time (no distribution at all).\n\n\nRunning tests in a Python subprocess\n------------------------------------\n\nTo instantiate a ``python3.9`` subprocess and send tests to it, you may type::\n\n pytest -d --tx popen//python=python3.9\n\nThis will start a subprocess which is run with the ``python3.9``\nPython interpreter, found in your system binary lookup path.\n\nIf you prefix the --tx option value like this::\n\n --tx 3*popen//python=python3.9\n\nthen three subprocesses would be created and tests\nwill be load-balanced across these three processes.\n\n.. _boxed:\n\nRunning tests in a boxed subprocess\n-----------------------------------\n\nThis functionality has been moved to the\n`pytest-forked `_ plugin, but the ``--boxed`` option\nis still kept for backward compatibility.\n\n.. _`remote machines`:\n\nSending tests to remote SSH accounts\n------------------------------------\n\nSuppose you have a package ``mypkg`` which contains some\ntests that you can successfully run locally. And you\nhave a ssh-reachable machine ``myhost``. Then\nyou can ad-hoc distribute your tests by typing::\n\n pytest -d --tx ssh=myhostpopen --rsyncdir mypkg mypkg\n\nThis will synchronize your :code:`mypkg` package directory\nto a remote ssh account and then locally collect tests\nand send them to remote places for execution.\n\nYou can specify multiple :code:`--rsyncdir` directories\nto be sent to the remote side.\n\n.. note::\n\n For pytest to collect and send tests correctly\n you not only need to make sure all code and tests\n directories are rsynced, but that any test (sub) directory\n also has an :code:`__init__.py` file because internally\n pytest references tests as a fully qualified python\n module path. **You will otherwise get strange errors**\n during setup of the remote side.\n\n\nYou can specify multiple :code:`--rsyncignore` glob patterns\nto be ignored when file are sent to the remote side.\nThere are also internal ignores: :code:`.*, *.pyc, *.pyo, *~`\nThose you cannot override using rsyncignore command-line or\nini-file option(s).\n\n\nSending tests to remote Socket Servers\n--------------------------------------\n\nDownload the single-module `socketserver.py`_ Python program\nand run it like this::\n\n python socketserver.py\n\nIt will tell you that it starts listening on the default\nport. You can now on your home machine specify this\nnew socket host with something like this::\n\n pytest -d --tx socket=192.168.1.102:8888 --rsyncdir mypkg mypkg\n\n\n.. _`atonce`:\n.. _`Multi-Platform`:\n\n\nRunning tests on many platforms at once\n---------------------------------------\n\nThe basic command to run tests on multiple platforms is::\n\n pytest --dist=each --tx=spec1 --tx=spec2\n\nIf you specify a windows host, an OSX host and a Linux\nenvironment this command will send each tests to all\nplatforms - and report back failures from all platforms\nat once. The specifications strings use the `xspec syntax`_.\n\n.. _`xspec syntax`: https://codespeak.net/execnet/basics.html#xspec\n\n.. _`socketserver.py`: https://raw.githubusercontent.com/pytest-dev/execnet/master/execnet/script/socketserver.py\n\n.. _`execnet`: https://codespeak.net/execnet\n\n\nWhen tests crash\n----------------\n\nIf a test crashes a worker, pytest-xdist will automatically restart that worker\nand report the test\u2019s failure. You can use the ``--max-worker-restart`` option\nto limit the number of worker restarts that are allowed, or disable restarting\naltogether using ``--max-worker-restart 0``.\n\n\nHow-tos\n-------\n\nIdentifying the worker process during a test\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n*New in version 1.15.*\n\nIf you need to determine the identity of a worker process in\na test or fixture, you may use the ``worker_id`` fixture to do so:\n\n.. code-block:: python\n\n @pytest.fixture()\n def user_account(worker_id):\n \"\"\" use a different account in each xdist worker \"\"\"\n return \"account_%s\" % worker_id\n\nWhen ``xdist`` is disabled (running with ``-n0`` for example), then\n``worker_id`` will return ``\"master\"``.\n\nWorker processes also have the following environment variables\ndefined:\n\n* ``PYTEST_XDIST_WORKER``: the name of the worker, e.g., ``\"gw2\"``.\n* ``PYTEST_XDIST_WORKER_COUNT``: the total number of workers in this session,\n e.g., ``\"4\"`` when ``-n 4`` is given in the command-line.\n\nThe information about the worker_id in a test is stored in the ``TestReport`` as\nwell, under the ``worker_id`` attribute.\n\nSince version 2.0, the following functions are also available in the ``xdist`` module:\n\n.. code-block:: python\n\n def is_xdist_worker(request_or_session) -> bool:\n \"\"\"Return `True` if this is an xdist worker, `False` otherwise\n\n :param request_or_session: the `pytest` `request` or `session` object\n \"\"\"\n\n def is_xdist_controller(request_or_session) -> bool:\n \"\"\"Return `True` if this is the xdist controller, `False` otherwise\n\n Note: this method also returns `False` when distribution has not been\n activated at all.\n\n :param request_or_session: the `pytest` `request` or `session` object\n \"\"\"\n\n def is_xdist_master(request_or_session) -> bool:\n \"\"\"Deprecated alias for is_xdist_controller.\"\"\"\n\n def get_xdist_worker_id(request_or_session) -> str:\n \"\"\"Return the id of the current worker ('gw0', 'gw1', etc) or 'master'\n if running on the controller node.\n\n If not distributing tests (for example passing `-n0` or not passing `-n` at all)\n also return 'master'.\n\n :param request_or_session: the `pytest` `request` or `session` object\n \"\"\"\n\n\nIdentifying workers from the system environment\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n*New in version 2.4*\n\nIf the `setproctitle`_ package is installed, ``pytest-xdist`` will use it to\nupdate the process title (command line) on its workers to show their current\nstate. The titles used are ``[pytest-xdist running] file.py/node::id`` and\n``[pytest-xdist idle]``, visible in standard tools like ``ps`` and ``top`` on\nLinux, Mac OS X and BSD systems. For Windows, please follow `setproctitle`_'s\npointer regarding the Process Explorer tool.\n\nThis is intended purely as an UX enhancement, e.g. to track down issues with\nlong-running or CPU intensive tests. Errors in changing the title are ignored\nsilently. Please try not to rely on the title format or title changes in\nexternal scripts.\n\n.. _`setproctitle`: https://pypi.org/project/setproctitle/\n\n\nUniquely identifying the current test run\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n*New in version 1.32.*\n\nIf you need to globally distinguish one test run from others in your\nworkers, you can use the ``testrun_uid`` fixture. For instance, let's say you\nwanted to create a separate database for each test run:\n\n.. code-block:: python\n\n import pytest\n from posix_ipc import Semaphore, O_CREAT\n\n @pytest.fixture(scope=\"session\", autouse=True)\n def create_unique_database(testrun_uid):\n \"\"\" create a unique database for this particular test run \"\"\"\n database_url = f\"psql://myapp-{testrun_uid}\"\n\n with Semaphore(f\"/{testrun_uid}-lock\", flags=O_CREAT, initial_value=1):\n if not database_exists(database_url):\n create_database(database_url)\n\n @pytest.fixture()\n def db(testrun_uid):\n \"\"\" retrieve unique database \"\"\"\n database_url = f\"psql://myapp-{testrun_uid}\"\n return database_get_instance(database_url)\n\n\nAdditionally, during a test run, the following environment variable is defined:\n\n* ``PYTEST_XDIST_TESTRUNUID``: the unique id of the test run.\n\nAccessing ``sys.argv`` from the controller node in workers\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTo access the ``sys.argv`` passed to the command-line of the controller node, use\n``request.config.workerinput[\"mainargv\"]``.\n\n\nSpecifying test exec environments in an ini file\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nYou can use pytest's ini file configuration to avoid typing common options.\nYou can for example make running with three subprocesses your default like this:\n\n.. code-block:: ini\n\n [pytest]\n addopts = -n3\n\nYou can also add default environments like this:\n\n.. code-block:: ini\n\n [pytest]\n addopts = --tx ssh=myhost//python=python3.9 --tx ssh=myhost//python=python3.6\n\nand then just type::\n\n pytest --dist=each\n\nto run tests in each of the environments.\n\n\nSpecifying \"rsync\" dirs in an ini-file\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIn a ``tox.ini`` or ``setup.cfg`` file in your root project directory\nyou may specify directories to include or to exclude in synchronisation:\n\n.. code-block:: ini\n\n [pytest]\n rsyncdirs = . mypkg helperpkg\n rsyncignore = .hg\n\nThese directory specifications are relative to the directory\nwhere the configuration file was found.\n\n.. _`pytest-xdist`: http://pypi.python.org/pypi/pytest-xdist\n.. _`pytest-xdist repository`: https://github.com/pytest-dev/pytest-xdist\n.. _`pytest`: http://pytest.org\n\n\nMaking session-scoped fixtures execute only once\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n``pytest-xdist`` is designed so that each worker process will perform its own collection and execute\na subset of all tests. This means that tests in different processes requesting a high-level\nscoped fixture (for example ``session``) will execute the fixture code more than once, which\nbreaks expectations and might be undesired in certain situations.\n\nWhile ``pytest-xdist`` does not have a builtin support for ensuring a session-scoped fixture is\nexecuted exactly once, this can be achieved by using a lock file for inter-process communication.\n\nThe example below needs to execute the fixture ``session_data`` only once (because it is\nresource intensive, or needs to execute only once to define configuration options, etc), so it makes\nuse of a `FileLock `_ to produce the fixture data only once\nwhen the first process requests the fixture, while the other processes will then read\nthe data from a file.\n\nHere is the code:\n\n.. code-block:: python\n\n import json\n\n import pytest\n from filelock import FileLock\n\n\n @pytest.fixture(scope=\"session\")\n def session_data(tmp_path_factory, worker_id):\n if worker_id == \"master\":\n # not executing in with multiple workers, just produce the data and let\n # pytest's fixture caching do its job\n return produce_expensive_data()\n\n # get the temp directory shared by all workers\n root_tmp_dir = tmp_path_factory.getbasetemp().parent\n\n fn = root_tmp_dir / \"data.json\"\n with FileLock(str(fn) + \".lock\"):\n if fn.is_file():\n data = json.loads(fn.read_text())\n else:\n data = produce_expensive_data()\n fn.write_text(json.dumps(data))\n return data\n\n\nThe example above can also be use in cases a fixture needs to execute exactly once per test session, like\ninitializing a database service and populating initial tables.\n\nThis technique might not work for every case, but should be a starting point for many situations\nwhere executing a high-scope fixture exactly once is important.\n\n\nHow does xdist work?\n--------------------\n\n``xdist`` works by spawning one or more **workers**, which are\ncontrolled by the **controller**. Each **worker** is responsible for\nperforming a full test collection and afterwards running tests as\ndictated by the **controller**.\n\nThe execution flow is:\n\n1. **controller** spawns one or more **workers** at the beginning of the\n test session. The communication between **controller** and **worker**\n nodes makes use of `execnet `__ and\n its\n `gateways `__.\n The actual interpreters executing the code for the **workers** might\n be remote or local.\n\n2. Each **worker** itself is a mini pytest runner. **workers** at this\n point perform a full test collection, sending back the collected\n test-ids back to the **controller** which does not perform any\n collection itself.\n\n3. The **controller** receives the result of the collection from all\n nodes. At this point the **controller** performs some sanity check to\n ensure that all **workers** collected the same tests (including\n order), bailing out otherwise. If all is well, it converts the list\n of test-ids into a list of simple indexes, where each index\n corresponds to the position of that test in the original collection\n list. This works because all nodes have the same collection list, and\n saves bandwidth because the **controller** can now tell one of the\n workers to just *execute test index 3* index of passing the full test\n id.\n\n4. If **dist-mode** is **each**: the **controller** just sends the full\n list of test indexes to each node at this moment.\n\n5. If **dist-mode** is **load**: the **controller** takes around 25% of\n the tests and sends them one by one to each **worker** in a round\n robin fashion. The rest of the tests will be distributed later as\n **workers** finish tests (see below).\n\n6. Note that ``pytest_xdist_make_scheduler`` hook can be used to\n implement custom tests distribution logic.\n\n7. **workers** re-implement ``pytest_runtestloop``: pytest\u2019s default\n implementation basically loops over all collected items in the\n ``session`` object and executes the ``pytest_runtest_protocol`` for\n each test item, but in xdist **workers** sit idly waiting for\n **controller** to send tests for execution. As tests are received by\n **workers**, ``pytest_runtest_protocol`` is executed for each test.\n Here it worth noting an implementation detail: **workers** always\n must keep at least one test item on their queue due to how the\n ``pytest_runtest_protocol(item, nextitem)`` hook is defined: in order\n to pass the ``nextitem`` to the hook, the worker must wait for more\n instructions from controller before executing that remaining test. If\n it receives more tests, then it can safely call\n ``pytest_runtest_protocol`` because it knows what the ``nextitem``\n parameter will be. If it receives a \u201cshutdown\u201d signal, then it can\n execute the hook passing ``nextitem`` as ``None``.\n\n8. As tests are started and completed at the **workers**, the results\n are sent back to the **controller**, which then just forwards the\n results to the appropriate pytest hooks: ``pytest_runtest_logstart``\n and ``pytest_runtest_logreport``. This way other plugins (for example\n ``junitxml``) can work normally. The **controller** (when in\n dist-mode **load**) decides to send more tests to a node when a test\n completes, using some heuristics such as test durations and how many\n tests each **worker** still has to run.\n\n9. When the **controller** has no more pending tests it will send a\n \u201cshutdown\u201d signal to all **workers**, which will then run their\n remaining tests to completion and shut down. At this point the\n **controller** will sit waiting for **workers** to shut down, still\n processing events such as ``pytest_runtest_logreport``.\n\nFAQ\n---\n\n**Question**: Why does each worker do its own collection, as opposed to having the\ncontroller collect once and distribute from that collection to the\nworkers?\n\nIf collection was performed by controller then it would have to\nserialize collected items to send them through the wire, as workers live\nin another process. The problem is that test items are not easily\n(impossible?) to serialize, as they contain references to the test\nfunctions, fixture managers, config objects, etc. Even if one manages to\nserialize it, it seems it would be very hard to get it right and easy to\nbreak by any small change in pytest.", - "release_date": "2021-12-10T11:41:55", + "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 :alt: PyPI\n\n.. image:: https://img.shields.io/pypi/pyversions/pip\n :target: https://pypi.org/project/pip\n :alt: PyPI - Python Version\n\n.. image:: https://readthedocs.org/projects/pip/badge/?version=latest\n :target: https://pip.pypa.io/en/latest\n :alt: Documentation\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\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 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 `PSF 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/installation/\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.. _Issue tracking: https://github.com/pypa/pip/issues\n.. _Discourse channel: https://discuss.python.org/c/packaging\n.. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa\n.. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md", + "release_date": "2024-02-03T09:53:18", "parties": [ { "type": "person", "role": "author", - "name": "holger krekel and contributors", - "email": "pytest-dev@python.org,holger@merlinux.eu", + "name": null, + "email": "The pip developers ", "url": null } ], "keywords": [ "Development Status :: 5 - Production/Stable", - "Framework :: Pytest", "Intended Audience :: Developers", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", - "Topic :: Software Development :: Quality Assurance", - "Topic :: Software Development :: Testing", - "Topic :: Utilities" + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Build Tools" ], - "homepage_url": "https://github.com/pytest-dev/pytest-xdist", - "download_url": "https://files.pythonhosted.org/packages/21/08/b1945d4b4986eb1aa10cf84efc5293bba39da80a2f95db3573dd90678408/pytest_xdist-2.5.0-py3-none-any.whl", - "size": 41698, + "homepage_url": "", + "download_url": "https://files.pythonhosted.org/packages/94/59/6638090c25e9bc4ce0c42817b5a234e183872a1129735a9330c472cc2056/pip-24.0.tar.gz", + "size": 2132709, "sha1": null, - "md5": "7cd826d45ea2ed4c1eb1ce5781db032a", - "sha256": "6fe5c74fec98906deb8f2d2b616b5c782022744978e7bd4695d39c8f42d0ce65", + "md5": "1331aabb4d1a2677f493effeebda3605", + "sha256": "ea9bd1a847e8c5774a5777bb398c19e80bcd4e2aa16a4b301b718fe6f593aba2", "sha512": null, "bug_tracking_url": null, - "code_view_url": null, + "code_view_url": "https://github.com/pypa/pip", "vcs_url": null, "copyright": null, "license_expression": null, @@ -7606,54 +3847,47 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pytest-xdist/2.5.0/json", + "api_data_url": "https://pypi.org/pypi/pip/24.0/json", "datasource_id": null, - "purl": "pkg:pypi/pytest-xdist@2.5.0" + "purl": "pkg:pypi/pip@24.0" }, { "type": "pypi", "namespace": null, - "name": "pytest-xdist", - "version": "2.5.0", + "name": "pipdeptree", + "version": "2.2.1", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "pytest xdist plugin for distributed testing and loop-on-failing modes\n============\npytest-xdist\n============\n\n.. image:: http://img.shields.io/pypi/v/pytest-xdist.svg\n :alt: PyPI version\n :target: https://pypi.python.org/pypi/pytest-xdist\n\n.. image:: https://img.shields.io/conda/vn/conda-forge/pytest-xdist.svg\n :target: https://anaconda.org/conda-forge/pytest-xdist\n\n.. image:: https://img.shields.io/pypi/pyversions/pytest-xdist.svg\n :alt: Python versions\n :target: https://pypi.python.org/pypi/pytest-xdist\n\n.. image:: https://github.com/pytest-dev/pytest-xdist/workflows/build/badge.svg\n :target: https://github.com/pytest-dev/pytest-xdist/actions\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/ambv/black\n\nThe `pytest-xdist`_ plugin extends pytest with new test execution modes, the most used being distributing\ntests across multiple CPUs to speed up test execution::\n\n pytest -n auto\n\nWith this call, pytest will spawn a number of workers processes equal to the number of available CPUs, and distribute\nthe tests randomly across them. There is also a number of `distribution modes`_ to choose from.\n\n**NOTE**: due to how pytest-xdist is implemented, the ``-s/--capture=no`` option does not work.\n\n.. contents:: **Table of Contents**\n\nInstallation\n------------\n\nInstall the plugin with::\n\n pip install pytest-xdist\n\n\nTo use ``psutil`` for detection of the number of CPUs available, install the ``psutil`` extra::\n\n pip install pytest-xdist[psutil]\n\n\nFeatures\n--------\n\n* Test run parallelization_: tests can be executed across multiple CPUs or hosts.\n This allows to speed up development or to use special resources of `remote machines`_.\n\n* ``--looponfail``: run your tests repeatedly in a subprocess. After each run\n pytest waits until a file in your project changes and then re-runs\n the previously failing tests. This is repeated until all tests pass\n after which again a full run is performed.\n\n* `Multi-Platform`_ coverage: you can specify different Python interpreters\n or different platforms and run tests in parallel on all of them.\n\n Before running tests remotely, ``pytest`` efficiently \"rsyncs\" your\n program source code to the remote place.\n You may specify different Python versions and interpreters. It does not\n installs/synchronize dependencies however.\n\n **Note**: this mode exists mostly for backward compatibility, as modern development\n relies on continuous integration for multi-platform testing.\n\n.. _parallelization:\n\nRunning tests across multiple CPUs\n----------------------------------\n\nTo send tests to multiple CPUs, use the ``-n`` (or ``--numprocesses``) option::\n\n pytest -n 8\n\nPass ``-n auto`` to use as many processes as your computer has CPU cores. This\ncan lead to considerable speed ups, especially if your test suite takes a\nnoticeable amount of time.\n\nThe test distribution algorithm is configured with the ``--dist`` command-line option:\n\n.. _distribution modes:\n\n* ``--dist load`` **(default)**: Sends pending tests to any worker that is\n available, without any guaranteed order.\n\n* ``--dist loadscope``: Tests are grouped by **module** for *test functions*\n and by **class** for *test methods*. Groups are distributed to available\n workers as whole units. This guarantees that all tests in a group run in the\n same process. This can be useful if you have expensive module-level or\n class-level fixtures. Grouping by class takes priority over grouping by\n module.\n\n* ``--dist loadfile``: Tests are grouped by their containing file. Groups are\n distributed to available workers as whole units. This guarantees that all\n tests in a file run in the same worker.\n\n* ``--dist loadgroup``: Tests are grouped by the ``xdist_group`` mark. Groups are\n distributed to available workers as whole units. This guarantees that all\n tests with same ``xdist_group`` name run in the same worker.\n\n .. code-block:: python\n\n @pytest.mark.xdist_group(name=\"group1\")\n def test1():\n pass\n\n class TestA:\n @pytest.mark.xdist_group(\"group1\")\n def test2():\n pass\n\n This will make sure ``test1`` and ``TestA::test2`` will run in the same worker.\n Tests without the ``xdist_group`` mark are distributed normally as in the ``--dist=load`` mode.\n\n* ``--dist no``: The normal pytest execution mode, runs one test at a time (no distribution at all).\n\n\nRunning tests in a Python subprocess\n------------------------------------\n\nTo instantiate a ``python3.9`` subprocess and send tests to it, you may type::\n\n pytest -d --tx popen//python=python3.9\n\nThis will start a subprocess which is run with the ``python3.9``\nPython interpreter, found in your system binary lookup path.\n\nIf you prefix the --tx option value like this::\n\n --tx 3*popen//python=python3.9\n\nthen three subprocesses would be created and tests\nwill be load-balanced across these three processes.\n\n.. _boxed:\n\nRunning tests in a boxed subprocess\n-----------------------------------\n\nThis functionality has been moved to the\n`pytest-forked `_ plugin, but the ``--boxed`` option\nis still kept for backward compatibility.\n\n.. _`remote machines`:\n\nSending tests to remote SSH accounts\n------------------------------------\n\nSuppose you have a package ``mypkg`` which contains some\ntests that you can successfully run locally. And you\nhave a ssh-reachable machine ``myhost``. Then\nyou can ad-hoc distribute your tests by typing::\n\n pytest -d --tx ssh=myhostpopen --rsyncdir mypkg mypkg\n\nThis will synchronize your :code:`mypkg` package directory\nto a remote ssh account and then locally collect tests\nand send them to remote places for execution.\n\nYou can specify multiple :code:`--rsyncdir` directories\nto be sent to the remote side.\n\n.. note::\n\n For pytest to collect and send tests correctly\n you not only need to make sure all code and tests\n directories are rsynced, but that any test (sub) directory\n also has an :code:`__init__.py` file because internally\n pytest references tests as a fully qualified python\n module path. **You will otherwise get strange errors**\n during setup of the remote side.\n\n\nYou can specify multiple :code:`--rsyncignore` glob patterns\nto be ignored when file are sent to the remote side.\nThere are also internal ignores: :code:`.*, *.pyc, *.pyo, *~`\nThose you cannot override using rsyncignore command-line or\nini-file option(s).\n\n\nSending tests to remote Socket Servers\n--------------------------------------\n\nDownload the single-module `socketserver.py`_ Python program\nand run it like this::\n\n python socketserver.py\n\nIt will tell you that it starts listening on the default\nport. You can now on your home machine specify this\nnew socket host with something like this::\n\n pytest -d --tx socket=192.168.1.102:8888 --rsyncdir mypkg mypkg\n\n\n.. _`atonce`:\n.. _`Multi-Platform`:\n\n\nRunning tests on many platforms at once\n---------------------------------------\n\nThe basic command to run tests on multiple platforms is::\n\n pytest --dist=each --tx=spec1 --tx=spec2\n\nIf you specify a windows host, an OSX host and a Linux\nenvironment this command will send each tests to all\nplatforms - and report back failures from all platforms\nat once. The specifications strings use the `xspec syntax`_.\n\n.. _`xspec syntax`: https://codespeak.net/execnet/basics.html#xspec\n\n.. _`socketserver.py`: https://raw.githubusercontent.com/pytest-dev/execnet/master/execnet/script/socketserver.py\n\n.. _`execnet`: https://codespeak.net/execnet\n\n\nWhen tests crash\n----------------\n\nIf a test crashes a worker, pytest-xdist will automatically restart that worker\nand report the test\u2019s failure. You can use the ``--max-worker-restart`` option\nto limit the number of worker restarts that are allowed, or disable restarting\naltogether using ``--max-worker-restart 0``.\n\n\nHow-tos\n-------\n\nIdentifying the worker process during a test\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n*New in version 1.15.*\n\nIf you need to determine the identity of a worker process in\na test or fixture, you may use the ``worker_id`` fixture to do so:\n\n.. code-block:: python\n\n @pytest.fixture()\n def user_account(worker_id):\n \"\"\" use a different account in each xdist worker \"\"\"\n return \"account_%s\" % worker_id\n\nWhen ``xdist`` is disabled (running with ``-n0`` for example), then\n``worker_id`` will return ``\"master\"``.\n\nWorker processes also have the following environment variables\ndefined:\n\n* ``PYTEST_XDIST_WORKER``: the name of the worker, e.g., ``\"gw2\"``.\n* ``PYTEST_XDIST_WORKER_COUNT``: the total number of workers in this session,\n e.g., ``\"4\"`` when ``-n 4`` is given in the command-line.\n\nThe information about the worker_id in a test is stored in the ``TestReport`` as\nwell, under the ``worker_id`` attribute.\n\nSince version 2.0, the following functions are also available in the ``xdist`` module:\n\n.. code-block:: python\n\n def is_xdist_worker(request_or_session) -> bool:\n \"\"\"Return `True` if this is an xdist worker, `False` otherwise\n\n :param request_or_session: the `pytest` `request` or `session` object\n \"\"\"\n\n def is_xdist_controller(request_or_session) -> bool:\n \"\"\"Return `True` if this is the xdist controller, `False` otherwise\n\n Note: this method also returns `False` when distribution has not been\n activated at all.\n\n :param request_or_session: the `pytest` `request` or `session` object\n \"\"\"\n\n def is_xdist_master(request_or_session) -> bool:\n \"\"\"Deprecated alias for is_xdist_controller.\"\"\"\n\n def get_xdist_worker_id(request_or_session) -> str:\n \"\"\"Return the id of the current worker ('gw0', 'gw1', etc) or 'master'\n if running on the controller node.\n\n If not distributing tests (for example passing `-n0` or not passing `-n` at all)\n also return 'master'.\n\n :param request_or_session: the `pytest` `request` or `session` object\n \"\"\"\n\n\nIdentifying workers from the system environment\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n*New in version 2.4*\n\nIf the `setproctitle`_ package is installed, ``pytest-xdist`` will use it to\nupdate the process title (command line) on its workers to show their current\nstate. The titles used are ``[pytest-xdist running] file.py/node::id`` and\n``[pytest-xdist idle]``, visible in standard tools like ``ps`` and ``top`` on\nLinux, Mac OS X and BSD systems. For Windows, please follow `setproctitle`_'s\npointer regarding the Process Explorer tool.\n\nThis is intended purely as an UX enhancement, e.g. to track down issues with\nlong-running or CPU intensive tests. Errors in changing the title are ignored\nsilently. Please try not to rely on the title format or title changes in\nexternal scripts.\n\n.. _`setproctitle`: https://pypi.org/project/setproctitle/\n\n\nUniquely identifying the current test run\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n*New in version 1.32.*\n\nIf you need to globally distinguish one test run from others in your\nworkers, you can use the ``testrun_uid`` fixture. For instance, let's say you\nwanted to create a separate database for each test run:\n\n.. code-block:: python\n\n import pytest\n from posix_ipc import Semaphore, O_CREAT\n\n @pytest.fixture(scope=\"session\", autouse=True)\n def create_unique_database(testrun_uid):\n \"\"\" create a unique database for this particular test run \"\"\"\n database_url = f\"psql://myapp-{testrun_uid}\"\n\n with Semaphore(f\"/{testrun_uid}-lock\", flags=O_CREAT, initial_value=1):\n if not database_exists(database_url):\n create_database(database_url)\n\n @pytest.fixture()\n def db(testrun_uid):\n \"\"\" retrieve unique database \"\"\"\n database_url = f\"psql://myapp-{testrun_uid}\"\n return database_get_instance(database_url)\n\n\nAdditionally, during a test run, the following environment variable is defined:\n\n* ``PYTEST_XDIST_TESTRUNUID``: the unique id of the test run.\n\nAccessing ``sys.argv`` from the controller node in workers\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTo access the ``sys.argv`` passed to the command-line of the controller node, use\n``request.config.workerinput[\"mainargv\"]``.\n\n\nSpecifying test exec environments in an ini file\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nYou can use pytest's ini file configuration to avoid typing common options.\nYou can for example make running with three subprocesses your default like this:\n\n.. code-block:: ini\n\n [pytest]\n addopts = -n3\n\nYou can also add default environments like this:\n\n.. code-block:: ini\n\n [pytest]\n addopts = --tx ssh=myhost//python=python3.9 --tx ssh=myhost//python=python3.6\n\nand then just type::\n\n pytest --dist=each\n\nto run tests in each of the environments.\n\n\nSpecifying \"rsync\" dirs in an ini-file\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIn a ``tox.ini`` or ``setup.cfg`` file in your root project directory\nyou may specify directories to include or to exclude in synchronisation:\n\n.. code-block:: ini\n\n [pytest]\n rsyncdirs = . mypkg helperpkg\n rsyncignore = .hg\n\nThese directory specifications are relative to the directory\nwhere the configuration file was found.\n\n.. _`pytest-xdist`: http://pypi.python.org/pypi/pytest-xdist\n.. _`pytest-xdist repository`: https://github.com/pytest-dev/pytest-xdist\n.. _`pytest`: http://pytest.org\n\n\nMaking session-scoped fixtures execute only once\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n``pytest-xdist`` is designed so that each worker process will perform its own collection and execute\na subset of all tests. This means that tests in different processes requesting a high-level\nscoped fixture (for example ``session``) will execute the fixture code more than once, which\nbreaks expectations and might be undesired in certain situations.\n\nWhile ``pytest-xdist`` does not have a builtin support for ensuring a session-scoped fixture is\nexecuted exactly once, this can be achieved by using a lock file for inter-process communication.\n\nThe example below needs to execute the fixture ``session_data`` only once (because it is\nresource intensive, or needs to execute only once to define configuration options, etc), so it makes\nuse of a `FileLock `_ to produce the fixture data only once\nwhen the first process requests the fixture, while the other processes will then read\nthe data from a file.\n\nHere is the code:\n\n.. code-block:: python\n\n import json\n\n import pytest\n from filelock import FileLock\n\n\n @pytest.fixture(scope=\"session\")\n def session_data(tmp_path_factory, worker_id):\n if worker_id == \"master\":\n # not executing in with multiple workers, just produce the data and let\n # pytest's fixture caching do its job\n return produce_expensive_data()\n\n # get the temp directory shared by all workers\n root_tmp_dir = tmp_path_factory.getbasetemp().parent\n\n fn = root_tmp_dir / \"data.json\"\n with FileLock(str(fn) + \".lock\"):\n if fn.is_file():\n data = json.loads(fn.read_text())\n else:\n data = produce_expensive_data()\n fn.write_text(json.dumps(data))\n return data\n\n\nThe example above can also be use in cases a fixture needs to execute exactly once per test session, like\ninitializing a database service and populating initial tables.\n\nThis technique might not work for every case, but should be a starting point for many situations\nwhere executing a high-scope fixture exactly once is important.\n\n\nHow does xdist work?\n--------------------\n\n``xdist`` works by spawning one or more **workers**, which are\ncontrolled by the **controller**. Each **worker** is responsible for\nperforming a full test collection and afterwards running tests as\ndictated by the **controller**.\n\nThe execution flow is:\n\n1. **controller** spawns one or more **workers** at the beginning of the\n test session. The communication between **controller** and **worker**\n nodes makes use of `execnet `__ and\n its\n `gateways `__.\n The actual interpreters executing the code for the **workers** might\n be remote or local.\n\n2. Each **worker** itself is a mini pytest runner. **workers** at this\n point perform a full test collection, sending back the collected\n test-ids back to the **controller** which does not perform any\n collection itself.\n\n3. The **controller** receives the result of the collection from all\n nodes. At this point the **controller** performs some sanity check to\n ensure that all **workers** collected the same tests (including\n order), bailing out otherwise. If all is well, it converts the list\n of test-ids into a list of simple indexes, where each index\n corresponds to the position of that test in the original collection\n list. This works because all nodes have the same collection list, and\n saves bandwidth because the **controller** can now tell one of the\n workers to just *execute test index 3* index of passing the full test\n id.\n\n4. If **dist-mode** is **each**: the **controller** just sends the full\n list of test indexes to each node at this moment.\n\n5. If **dist-mode** is **load**: the **controller** takes around 25% of\n the tests and sends them one by one to each **worker** in a round\n robin fashion. The rest of the tests will be distributed later as\n **workers** finish tests (see below).\n\n6. Note that ``pytest_xdist_make_scheduler`` hook can be used to\n implement custom tests distribution logic.\n\n7. **workers** re-implement ``pytest_runtestloop``: pytest\u2019s default\n implementation basically loops over all collected items in the\n ``session`` object and executes the ``pytest_runtest_protocol`` for\n each test item, but in xdist **workers** sit idly waiting for\n **controller** to send tests for execution. As tests are received by\n **workers**, ``pytest_runtest_protocol`` is executed for each test.\n Here it worth noting an implementation detail: **workers** always\n must keep at least one test item on their queue due to how the\n ``pytest_runtest_protocol(item, nextitem)`` hook is defined: in order\n to pass the ``nextitem`` to the hook, the worker must wait for more\n instructions from controller before executing that remaining test. If\n it receives more tests, then it can safely call\n ``pytest_runtest_protocol`` because it knows what the ``nextitem``\n parameter will be. If it receives a \u201cshutdown\u201d signal, then it can\n execute the hook passing ``nextitem`` as ``None``.\n\n8. As tests are started and completed at the **workers**, the results\n are sent back to the **controller**, which then just forwards the\n results to the appropriate pytest hooks: ``pytest_runtest_logstart``\n and ``pytest_runtest_logreport``. This way other plugins (for example\n ``junitxml``) can work normally. The **controller** (when in\n dist-mode **load**) decides to send more tests to a node when a test\n completes, using some heuristics such as test durations and how many\n tests each **worker** still has to run.\n\n9. When the **controller** has no more pending tests it will send a\n \u201cshutdown\u201d signal to all **workers**, which will then run their\n remaining tests to completion and shut down. At this point the\n **controller** will sit waiting for **workers** to shut down, still\n processing events such as ``pytest_runtest_logreport``.\n\nFAQ\n---\n\n**Question**: Why does each worker do its own collection, as opposed to having the\ncontroller collect once and distribute from that collection to the\nworkers?\n\nIf collection was performed by controller then it would have to\nserialize collected items to send them through the wire, as workers live\nin another process. The problem is that test items are not easily\n(impossible?) to serialize, as they contain references to the test\nfunctions, fixture managers, config objects, etc. Even if one manages to\nserialize it, it seems it would be very hard to get it right and easy to\nbreak by any small change in pytest.", - "release_date": "2021-12-10T11:41:56", + "description": "Command line utility to show dependency tree of packages\npipdeptree\n==========\n\n.. image:: https://github.com/naiquevin/pipdeptree/workflows/check/badge.svg\n :target: https://github.com/naiquevin/pipdeptree/actions\n\n\n``pipdeptree`` is a command line utility for displaying the installed\npython packages in form of a dependency tree. It works for packages\ninstalled globally on a machine as well as in a virtualenv. Since\n``pip freeze`` shows all dependencies as a flat list, finding out\nwhich are the top level packages and which packages do they depend on\nrequires some effort. It's also tedious to resolve conflicting\ndependencies that could have been installed because older version of\n``pip`` didn't have true dependency resolution [1]_. ``pipdeptree``\ncan help here by identifying conflicting dependencies installed in the\nenvironment.\n\nTo some extent, ``pipdeptree`` is inspired by the ``lein deps :tree``\ncommand of `Leiningen `_.\n\n\nInstallation\n------------\n\n.. code-block:: bash\n\n $ pip install pipdeptree\n\npipdeptree has been tested with Python versions ``2.7``, ``3.5``,\n``3.6``, ``3.7``, ``3.8``, ``3.9`` as well as ``pypy2`` and ``pypy3``.\n\nPython ``2.6`` is way past it's end of life but if you ever find\nyourself stuck on a legacy environment, version ``0.9.0`` *might*\nwork.\n\n\nRunning in virtualenvs\n----------------------\n\n`New in ver. 2.0.0`\n\nIf you want to run pipdeptree in the context of a particular\nvirtualenv, you can specify the ``--python`` option. Note that this\ncapability has been recently added in version ``2.0.0``.\n\nAlternately, you may also install pipdeptree inside the virtualenv and\nthen run it from there.\n\n\nUsage and examples\n------------------\n\nTo give you a brief idea, here is the output of ``pipdeptree``\ncompared with ``pip freeze``:\n\n.. code-block:: bash\n\n $ pip freeze\n Flask==0.10.1\n itsdangerous==0.24\n Jinja2==2.11.2\n -e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy\n MarkupSafe==0.22\n pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl\n Werkzeug==0.11.2\n\nAnd now see what ``pipdeptree`` outputs,\n\n.. code-block:: bash\n\n $ pipdeptree\n Warning!!! Possibly conflicting dependencies found:\n * Jinja2==2.11.2\n - MarkupSafe [required: >=0.23, installed: 0.22]\n ------------------------------------------------------------------------\n Flask==0.10.1\n - itsdangerous [required: >=0.21, installed: 0.24]\n - Jinja2 [required: >=2.4, installed: 2.11.2]\n - MarkupSafe [required: >=0.23, installed: 0.22]\n - Werkzeug [required: >=0.7, installed: 0.11.2]\n Lookupy==0.1\n pipdeptree==2.0.0b1\n - pip [required: >=6.0.0, installed: 20.1.1]\n setuptools==47.1.1\n wheel==0.34.2\n\n\nIs it possible to find out why a particular package is installed?\n-----------------------------------------------------------------\n\n`New in ver. 0.5.0`\n\nYes, there's a ``--reverse`` (or simply ``-r``) flag for this. To find\nout which packages depend on a particular package(s), it can be\ncombined with ``--packages`` option as follows:\n\n.. code-block:: bash\n\n $ pipdeptree --reverse --packages itsdangerous,MarkupSafe\n Warning!!! Possibly conflicting dependencies found:\n * Jinja2==2.11.2\n - MarkupSafe [required: >=0.23, installed: 0.22]\n ------------------------------------------------------------------------\n itsdangerous==0.24\n - Flask==0.10.1 [requires: itsdangerous>=0.21]\n MarkupSafe==0.22\n - Jinja2==2.11.2 [requires: MarkupSafe>=0.23]\n - Flask==0.10.1 [requires: Jinja2>=2.4]\n\n\nWhat's with the warning about conflicting dependencies?\n-------------------------------------------------------\n\nAs seen in the above output, ``pipdeptree`` by default warns about\npossible conflicting dependencies. Any package that's specified as a\ndependency of multiple packages with different versions is considered\nas a conflicting dependency. Conflicting dependencies are possible if\nolder version of pip<=20.2 (`without the new resolver\n`_ [1]_) was ever used to\ninstall dependencies at some point. The warning is printed to stderr\ninstead of stdout and it can be completely silenced by specifying the\n``-w silence`` or ``--warn silence`` option. On the other hand, it can\nbe made mode strict with ``--warn fail``, in which case the command\nwill not only print the warnings to stderr but also exit with a\nnon-zero status code. This is useful if you want to fit this tool into\nyour CI pipeline.\n\n**Note**: The ``--warn`` option is added in version ``0.6.0``. If you\nare using an older version, use ``--nowarn`` flag to silence the\nwarnings.\n\n\nWarnings about circular dependencies\n------------------------------------\n\nIn case any of the packages have circular dependencies (eg. package A\ndepends on package B and package B depends on package A), then\n``pipdeptree`` will print warnings about that as well.\n\n.. code-block:: bash\n\n $ pipdeptree --exclude pip,pipdeptree,setuptools,wheel\n Warning!!! Cyclic dependencies found:\n - CircularDependencyA => CircularDependencyB => CircularDependencyA\n - CircularDependencyB => CircularDependencyA => CircularDependencyB\n ------------------------------------------------------------------------\n wsgiref==0.1.2\n argparse==1.2.1\n\nSimilar to the warnings about conflicting dependencies, these too are\nprinted to stderr and can be controlled using the ``--warn`` option.\n\nIn the above example, you can also see ``--exclude`` option which is\nthe opposite of ``--packages`` ie. these packages will be excluded\nfrom the output.\n\n\nUsing pipdeptree to write requirements.txt file\n-----------------------------------------------\n\nIf you wish to track only top level packages in your\n``requirements.txt`` file, it's possible by grep-ing [2]_. only the\ntop-level lines from the output,\n\n.. code-block:: bash\n\n $ pipdeptree --warn silence | grep -E '^\\w+'\n Flask==0.10.1\n gnureadline==8.0.0\n Lookupy==0.1\n pipdeptree==2.0.0b1\n setuptools==47.1.1\n wheel==0.34.2\n\nThere is a problem here though - The output doesn't mention anything\nabout ``Lookupy`` being installed as an *editable* package (refer to\nthe output of ``pip freeze`` above) and information about its source\nis lost. To fix this, ``pipdeptree`` must be run with a ``-f`` or\n``--freeze`` flag.\n\n.. code-block:: bash\n\n $ pipdeptree -f --warn silence | grep -E '^[a-zA-Z0-9\\-]+'\n Flask==0.10.1\n gnureadline==8.0.0\n -e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy\n pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl\n setuptools==47.1.1\n wheel==0.34.2\n\n $ pipdeptree -f --warn silence | grep -E '^[a-zA-Z0-9\\-]+' > requirements.txt\n\nThe freeze flag will not prefix child dependencies with hyphens, so\nyou could dump the entire output of ``pipdeptree -f`` to the\nrequirements.txt file thus making it human-friendly (due to\nindentations) as well as pip-friendly.\n\n.. code-block:: bash\n\n $ pipdeptree -f | tee locked-requirements.txt\n Flask==0.10.1\n itsdangerous==0.24\n Jinja2==2.11.2\n MarkupSafe==0.23\n Werkzeug==0.11.2\n gnureadline==8.0.0\n -e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy\n pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl\n pip==20.1.1\n setuptools==47.1.1\n wheel==0.34.2\n\nOn confirming that there are no conflicting dependencies, you can even\ntreat this as a \"lock file\" where all packages, including the\ntransient dependencies will be pinned to their currently installed\nversions. Note that the ``locked-requirements.txt`` file could end up\nwith duplicate entries. Although ``pip install`` wouldn't complain\nabout that, you can avoid duplicate lines (at the cost of losing\nindentation) as follows,\n\n.. code-block:: bash\n\n $ pipdeptree -f | sed 's/ //g' | sort -u > locked-requirements.txt\n\n\nUsing pipdeptree with external tools\n------------------------------------\n\n`New in ver. 0.5.0`\n\nIt's also possible to have ``pipdeptree`` output json representation\nof the dependency tree so that it may be used as input to other\nexternal tools.\n\n.. code-block:: bash\n\n $ pipdeptree --json\n\nNote that ``--json`` will output a flat list of all packages with\ntheir immediate dependencies. This is not very useful in itself. To\nobtain nested json, use ``--json-tree``\n\n`New in ver. 0.11.0`\n\n.. code-block:: bash\n\n $ pipdeptree --json-tree\n\n\nVisualizing the dependency graph\n--------------------------------\n\n.. image:: https://raw.githubusercontent.com/naiquevin/pipdeptree/master/docs/twine-pdt.png\n\nThe dependency graph can also be visualized using `GraphViz\n`_:\n\n.. code-block:: bash\n\n $ pipdeptree --graph-output dot > dependencies.dot\n $ pipdeptree --graph-output pdf > dependencies.pdf\n $ pipdeptree --graph-output png > dependencies.png\n $ pipdeptree --graph-output svg > dependencies.svg\n\nNote that ``graphviz`` is an optional dependency ie. required only if\nyou want to use ``--graph-output``. If the version of ``graphviz``\ninstalled in the env is older than 0.18.1, then a warning will be\ndisplayed about upgrading ``graphviz``. Support for older versions of\ngraphviz will be dropped soon.\n\nSince version ``2.0.0b1``, ``--package`` and ``--reverse`` flags are\nsupported for all output formats ie. text, json, json-tree and graph.\n\nIn earlier versions, ``--json``, ``--json-tree`` and\n``--graph-output`` options override ``--package`` and ``--reverse``.\n\n\nUsage\n-----\n\n.. code-block:: bash\n\n usage: pipdeptree.py [-h] [-v] [-f] [--python PYTHON] [-a] [-l] [-u]\n [-w [{silence,suppress,fail}]] [-r] [-p PACKAGES]\n [-e PACKAGES] [-j] [--json-tree]\n [--graph-output OUTPUT_FORMAT]\n\n Dependency tree of the installed python packages\n\n optional arguments:\n -h, --help show this help message and exit\n -v, --version show program's version number and exit\n -f, --freeze Print names so as to write freeze files\n --python PYTHON Python to use to look for packages in it (default:\n where installed)\n -a, --all list all deps at top level\n -l, --local-only If in a virtualenv that has global access do not show\n globally installed packages\n -u, --user-only Only show installations in the user site dir\n -w [{silence,suppress,fail}], --warn [{silence,suppress,fail}]\n Warning control. \"suppress\" will show warnings but\n return 0 whether or not they are present. \"silence\"\n will not show warnings at all and always return 0.\n \"fail\" will show warnings and return 1 if any are\n present. The default is \"suppress\".\n -r, --reverse Shows the dependency tree in the reverse fashion ie.\n the sub-dependencies are listed with the list of\n packages that need them under them.\n -p PACKAGES, --packages PACKAGES\n Comma separated list of select packages to show in the\n output. If set, --all will be ignored.\n -e PACKAGES, --exclude PACKAGES\n Comma separated list of select packages to exclude\n from the output. If set, --all will be ignored.\n -j, --json Display dependency tree as json. This will yield \"raw\"\n output that may be used by external tools. This option\n overrides all other options.\n --json-tree Display dependency tree as json which is nested the\n same way as the plain text output printed by default.\n This option overrides all other options (except\n --json).\n --graph-output OUTPUT_FORMAT\n Print a dependency graph in the specified output\n format. Available are all formats supported by\n GraphViz, e.g.: dot, jpeg, pdf, png, svg\n\nKnown issues\n------------\n\n1. ``pipdeptree`` relies on the internal API of ``pip``. I fully\n understand that it's a bad idea but it mostly works! On rare\n occasions, it breaks when a new version of ``pip`` is out with\n backward incompatible changes in internal API. So beware if you are\n using this tool in environments in which ``pip`` version is\n unpinned, specially automation or CD/CI pipelines.\n\n\nLimitations & Alternatives\n--------------------------\n\n``pipdeptree`` merely looks at the installed packages in the current\nenvironment using pip, constructs the tree, then outputs it in the\nspecified format. If you want to generate the dependency tree without\ninstalling the packages, then you need a dependency resolver. You\nmight want to check alternatives such as `pipgrip\n`_ or `poetry\n`_.\n\n\nRuning Tests (for contributors)\n-------------------------------\n\nThere are 2 test suites in this repo:\n\n1. Unit tests that use mock objects. These are configured to run on\n every push to the repo and on every PR thanks to Github Actions.\n\n2. End-to-end tests that are run against actual packages installed in\n virtualenvs\n\nUnit tests can be run against all version of python using `tox\n`_ as follows:\n\n.. code-block:: bash\n\n $ make test-tox-all\n\nThis assumes that you have python versions specified in the\n``tox.ini`` file.\n\nIf you don't want to install all the versions of python but want to\nrun tests quickly against ``Python3.6`` only:\n\n.. code-block:: bash\n\n $ make test\n\nUnit tests are written using ``pytest`` and you can also run the tests\nwith code coverage as follows,\n\n.. code-block:: bash\n\n $ make test-cov\n\nOn the other hand, end-to-end tests actually create virtualenvs,\ninstall packages and then run tests against them. These tests are more\nreliable in the sense that they also test ``pipdeptree`` with the\nlatest version of ``pip`` and ``setuptools``.\n\nThe downside is that when new versions of ``pip`` or ``setuptools``\nare released, these need to be updated. At present the process is\nmanual but I have plans to setup nightly builds for these for faster\nfeedback.\n\nThe end-to-end tests can be run as follows,\n\n.. code-block:: bash\n\n $ make test-e2e # starts with a clean virtualenvs\n\n $ # or\n\n $ make test-e2e-quick # reuses existing virtualenvs\n\nBy default the e2e tests uses python executable ``python3.6``. To use\nan alternate version set the environment var ``E2E_PYTHON_EXE``.\n\n.. code-block:: bash\n\n $ E2E_PYTHON_EXE=python2.7 make test-e2e\n\n\nRelease checklist\n-----------------\n\n#. Make sure that tests pass on Github Actions.\n#. Create a commit with following changes and push it to github\n#. Update the `__version__` in the `pipdeptree.py` file.\n\n #. Add Changelog in `CHANGES.md` file.\n #. Also update `README.md` if required.\n#. Create an annotated tag on the above commit and push the tag to\n github\n#. Upload new version to PyPI.\n\n\nLicense\n-------\n\nMIT (See `LICENSE <./LICENSE>`_)\n\nFootnotes\n---------\n\n.. [1] pip version 20.3 has been released in Nov 2020 with the\n dependency resolver\n _\n\n.. [2] If you are on windows (powershell) you can run\n ``pipdeptree --warn silence | Select-String -Pattern '^\\w+'``\n instead of grep", + "release_date": "2022-01-09T06:14:38", "parties": [ { "type": "person", "role": "author", - "name": "holger krekel and contributors", - "email": "pytest-dev@python.org,holger@merlinux.eu", + "name": "Vineet Naik", + "email": "naikvin@gmail.com", "url": null } ], "keywords": [ - "Development Status :: 5 - Production/Stable", - "Framework :: Pytest", + "Environment :: Console", "Intended Audience :: Developers", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", "Programming Language :: Python", + "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Topic :: Software Development :: Quality Assurance", - "Topic :: Software Development :: Testing", - "Topic :: Utilities" + "Programming Language :: Python :: 3.9" ], - "homepage_url": "https://github.com/pytest-dev/pytest-xdist", - "download_url": "https://files.pythonhosted.org/packages/5d/43/9dbc32d297d6eae85d6c05dc8e8d3371061bd6cbe56a2f645d9ea4b53d9b/pytest-xdist-2.5.0.tar.gz", - "size": 72455, + "homepage_url": "https://github.com/naiquevin/pipdeptree", + "download_url": "https://files.pythonhosted.org/packages/e8/aa/e494d9f1027d2ef599c25ec03ec7e2e15d9e37748ebfded013fc3696d939/pipdeptree-2.2.1-py3-none-any.whl", + "size": 21915, "sha1": null, - "md5": "aaec318fa6e83d99bd366d3ef45252da", - "sha256": "4580deca3ff04ddb2ac53eba39d76cb5dd5edeac050cb6fbc768b0dd712b4edf", + "md5": "2fb740f7fb0720fb3c2567d78d409051", + "sha256": "e20655a38d6e363d8e86d6a85e8a648680a3f4b6d039d6ee3ab0f539da1ad6ce", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -7661,7 +3895,7 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "MIT", + "license": "MIT License", "classifiers": [ "License :: OSI Approved :: MIT License" ] @@ -7673,57 +3907,52 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pytest-xdist/2.5.0/json", + "api_data_url": "https://pypi.org/pypi/pipdeptree/2.2.1/json", "datasource_id": null, - "purl": "pkg:pypi/pytest-xdist@2.5.0" + "purl": "pkg:pypi/pipdeptree@2.2.1" }, { "type": "pypi", "namespace": null, - "name": "pytest", - "version": "7.0.1", + "name": "pkginfo2", + "version": "30.0.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "pytest: simple powerful testing with Python\n.. image:: https://github.com/pytest-dev/pytest/raw/main/doc/en/img/pytest_logo_curves.svg\n :target: https://docs.pytest.org/en/stable/\n :align: center\n :height: 200\n :alt: pytest\n\n\n------\n\n.. image:: https://img.shields.io/pypi/v/pytest.svg\n :target: https://pypi.org/project/pytest/\n\n.. image:: https://img.shields.io/conda/vn/conda-forge/pytest.svg\n :target: https://anaconda.org/conda-forge/pytest\n\n.. image:: https://img.shields.io/pypi/pyversions/pytest.svg\n :target: https://pypi.org/project/pytest/\n\n.. image:: https://codecov.io/gh/pytest-dev/pytest/branch/main/graph/badge.svg\n :target: https://codecov.io/gh/pytest-dev/pytest\n :alt: Code coverage Status\n\n.. image:: https://github.com/pytest-dev/pytest/workflows/main/badge.svg\n :target: https://github.com/pytest-dev/pytest/actions?query=workflow%3Amain\n\n.. image:: https://results.pre-commit.ci/badge/github/pytest-dev/pytest/main.svg\n :target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest/main\n :alt: pre-commit.ci status\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n\n.. image:: https://www.codetriage.com/pytest-dev/pytest/badges/users.svg\n :target: https://www.codetriage.com/pytest-dev/pytest\n\n.. image:: https://readthedocs.org/projects/pytest/badge/?version=latest\n :target: https://pytest.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n\n.. image:: https://img.shields.io/badge/Discord-pytest--dev-blue\n :target: https://discord.com/invite/pytest-dev\n :alt: Discord\n\n.. image:: https://img.shields.io/badge/Libera%20chat-%23pytest-orange\n :target: https://web.libera.chat/#pytest\n :alt: Libera chat\n\n\nThe ``pytest`` framework makes it easy to write small tests, yet\nscales to support complex functional testing for applications and libraries.\n\nAn example of a simple test:\n\n.. code-block:: python\n\n # content of test_sample.py\n def inc(x):\n return x + 1\n\n\n def test_answer():\n assert inc(3) == 5\n\n\nTo execute it::\n\n $ pytest\n ============================= test session starts =============================\n collected 1 items\n\n test_sample.py F\n\n ================================== FAILURES ===================================\n _________________________________ test_answer _________________________________\n\n def test_answer():\n > assert inc(3) == 5\n E assert 4 == 5\n E + where 4 = inc(3)\n\n test_sample.py:5: AssertionError\n ========================== 1 failed in 0.04 seconds ===========================\n\n\nDue to ``pytest``'s detailed assertion introspection, only plain ``assert`` statements are used. See `getting-started `_ for more examples.\n\n\nFeatures\n--------\n\n- Detailed info on failing `assert statements `_ (no need to remember ``self.assert*`` names)\n\n- `Auto-discovery\n `_\n of test modules and functions\n\n- `Modular fixtures `_ for\n managing small or parametrized long-lived test resources\n\n- Can run `unittest `_ (or trial),\n `nose `_ test suites out of the box\n\n- Python 3.6+ and PyPy3\n\n- Rich plugin architecture, with over 850+ `external plugins `_ and thriving community\n\n\nDocumentation\n-------------\n\nFor full documentation, including installation, tutorials and PDF documents, please see https://docs.pytest.org/en/stable/.\n\n\nBugs/Requests\n-------------\n\nPlease use the `GitHub issue tracker `_ to submit bugs or request features.\n\n\nChangelog\n---------\n\nConsult the `Changelog `__ page for fixes and enhancements of each version.\n\n\nSupport pytest\n--------------\n\n`Open Collective`_ is an online funding platform for open and transparent communities.\nIt provides tools to raise money and share your finances in full transparency.\n\nIt is the platform of choice for individuals and companies that want to make one-time or\nmonthly donations directly to the project.\n\nSee more details in the `pytest collective`_.\n\n.. _Open Collective: https://opencollective.com\n.. _pytest collective: https://opencollective.com/pytest\n\n\npytest for enterprise\n---------------------\n\nAvailable as part of the Tidelift Subscription.\n\nThe maintainers of pytest and thousands of other packages are working with Tidelift to deliver commercial support and\nmaintenance for the open source dependencies you use to build your applications.\nSave time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use.\n\n`Learn more. `_\n\nSecurity\n^^^^^^^^\n\npytest has never been associated with a security vulnerability, but in any case, to report a\nsecurity vulnerability please use the `Tidelift security contact `_.\nTidelift will coordinate the fix and disclosure.\n\n\nLicense\n-------\n\nCopyright Holger Krekel and others, 2004.\n\nDistributed under the terms of the `MIT`_ license, pytest is free and open source software.\n\n.. _`MIT`: https://github.com/pytest-dev/pytest/blob/main/LICENSE", - "release_date": "2022-02-11T18:47:56", + "description": "Query metadatdata from sdists / bdists / installed packages. Safer fork of pkginfo to avoid doing arbitrary imports and eval()\n``pkginfo2`` README\n=====================\n\nHomepage URL: https://github.com/nexB/pkginfo2\nSPDX-License-Identifier: MIT\n\nThis package provides an API for querying the distutils metadata written in\nthe ``PKG-INFO`` file inside a source distriubtion (an ``sdist``) or a\nbinary distribution or a wheel (e.g., created by running ``bdist_egg``). It can\nalso query the ``EGG-INFO`` directory of an installed distribution, and\nthe ``*.egg-info`` stored in a \"development checkout\"\n(e.g, created by running ``setup.py develop``), or the ``*.dist-info`` from\nan as-installed package.\n\nThis is a fork of http://bazaar.launchpad.net/~tseaver/pkginfo removing the\nability to import and eval arbitrary code and work with modules known to the\ncurrent interpreter. Use importlib_metadata for this if you need it.\n\n\nPlease see the `pkginfo2 repo at `_\nfor more documentation.\n\n\n``pkginfo2`` Changelog\n=======================\n\n30.0.0 (2022-01-28)\n--------------------\n\n- Forked and rename to pkginfo2. Removed ability to import or eval packages\n or modules.\n- Move the bzr history to git\n\n1.8.2 (2021-12-01)\n------------------\n\n- Add fix for installed distributions with '__package__' set to an empty\n string. LP #1952946.\n\n1.8.1 (2021-11-19)\n------------------\n\n- Add 'MANIFEST.in' to ensure example files used by tests are included\n in source distributions. LP #1951553.\n\n1.8.0 (2021-11-18)\n------------------\n\n- Support new standard metadata location for installed dists. LP #1865286.\n\n- Don't overwrite header-based 'description' with empty payload. LP #1885458.\n\n- Add support for Metadata-Version 2.2. LP #1928729.\n\n- Add support for uncompressed tarballs for sdists. LP #1951457.\n\n- Add support for Python 3.10.\n\n1.7.1 (2021-07-09)\n------------------\n\n- Use Python3 to build docs, and fix doctest examples to use Python3-\n compatible syntax. LP #1933322.\n\n1.7.0 (2021-01-16)\n------------------\n\n- Add support for Python 3.9.\n\n- Drop support for Python 3.5.\n\n1.6.1 (2020-10-26)\n------------------\n\n- Adjust test classifiers to match supported Python versions. LP #1901127.\n\n1.6.0 (2020-10-20)\n------------------\n\n- Add support for Python 3.8.\n LP #1869854.\n\n- Drop support for Python 3.4.\n\n- Update tests to match setuptools' change, no longer reporting metadata\n version for installed packages w/o explicit metadata. LP #1870197.\n\n1.5.0.1 (2019-01-08)\n--------------------\n\n- Fix broken 'sdist'. LP #1639585.\n\n1.5.0 (2019-01-07)\n------------------\n\n- Fix 'console_scripts' entry point syntax. LP #1810734.\n\n- Add support for JSON output from the CLI. LP #1700580.\n\n- Add support for installed wheels. E.g., 'dist-info/' dirs. LP #1700200.\n\n- Harden metadata extraction against unexpected encodings. LP #1780454.\n\n- Update tests to match pip/setuptools' use of new metadata version.\n LP #1772274.\n\n- Add support for Python 3.6 and 3.7.\n\n- Drop support for Python 3.3.\n\n1.4.2 (2018-03-14)\n------------------\n\n- Use relative imports in pkginfo modules. Supports vendoring of the\n package into setuptools.\n\n- Add support for ``Provides-Extra`` and ``Description-Content-Type`` fields.\n Per https://packaging.python.org/specifications/. See: PEP 566.\n\n- Remove support for old setuptools leaving ``PKG-INFO`` in the root of\n the project directory.\n\n1.4.1 (2016-11-07)\n------------------\n\n- Packaging only change (invalid sdist built for 1.4.0).\n\n1.4.0 (2016-11-04)\n------------------\n\n- Relicense under MIT license: the PSF license is not suitable for\n third-party libraries.\n\n1.3.2 (2016-05-24)\n------------------\n\n- Packaging-only change (automate fix for wheel built for 1.3.1).\n\n1.3.1 (2016-05-24)\n------------------\n\n- Packaging-only change (invalid wheel built for 1.3.0).\n\n1.3.0 (2016-05-23)\n------------------\n\n- Update homepage URL to point to Launchpad, rather than PyPI.\n\n- Add support for building wheels.\n\n- Add support for Python 3.5.\n\n- Drop support for Python 2.6 and 3.2.\n\n1.2.1 (2014-01-02)\n------------------\n\n- Add overlooked Trove classifier for Python 3.4.\n\n1.2 (2014-01-02)\n----------------\n\n- Add support for Python 3.4, PyPy3.\n\n- Add 100% coverage for ``pkginfo.commandline`` module.\n\n1.2b1 (2013-12-05)\n------------------\n\n- Add support for the \"wheel\" distribution format, along with minimal\n metadata 2.0 support (not including new PEP 426 JSON properties).\n Code (re-)borrowed from Donald Stuft's ``twine`` package.\n\n1.1 (2013-10-09)\n----------------\n\n- Fix tests to pass with current PyPy releases.\n\n1.1b1 (2013-05-05)\n------------------\n\n- Support \"develop\" packages which keep their ``*.egg-info`` in a subdirectory.\n See https://bugs.launchpad.net/pkginfo/+bug/919147.\n\n- Add support for \"unpacked SDists\" (thanks to Mike Lundy for the patch).\n\n1.0 (2013-05-05)\n----------------\n\n- No changes from 1.0b2.\n\n1.0b2 (2012-12-28)\n------------------\n\n- Suppress resource warning leaks reported against clients.\n\n- Fix 'commandline' module under Py3k.\n\n1.0b1 (2012-12-28)\n------------------\n\n- Add support for Python 3.2 and 3.3, including testing them under ``tox``.\n\n- Add support for PyPy, including testing it under ``tox``.\n\n- Test supported Python versions under ``tox``.\n\n- Drop support for Python 2.5.\n\n- Add a ``setup.py dev`` alias: runs ``setup.py develop`` and installs\n testing extras (``nose`` and ``coverage``).\n\n0.9.1 (2012-10-22)\n------------------\n\n- Fix test failure under Python >= 2.7, which is enforcing\n 'metadata_version == 1.1' because we have classifiers.\n\n\n0.9 (2012-04-25)\n----------------\n\n- Fix introspection of installed namespace packages.\n They may be installed as eggs or via dist-installed 'egg-info' files.\n https://bugs.launchpad.net/pkginfo/+bug/934311\n\n- Avoid a regression in 0.8 under Python 2.6 / 2.7 when parsing unicode.\n https://bugs.launchpad.net/pkginfo/+bug/733827/comments/3\n\n\n0.8 (2011-03-12)\n----------------\n\n- Work around Python 2.7's breakage of StringIO. Fixes\n https://bugs.launchpad.net/pkginfo/+bug/733827\n\n- Fix bug in introspection of installed packages missing the\n ``__package__`` attribute.\n \n\n0.7 (2010-11-04)\n----------------\n\n- Preserve newlines in the ``description`` field. Thanks to Sridhar\n Ratnakumar for the patch.\n\n- 100% test coverage.\n\n\n0.6 (2010-06-01)\n----------------\n\n- Replace use of ``StringIO.StringIO`` with ``io.StringIO``, where available\n (Python >= 2.6).\n\n- Replace use of ``rfc822`` stdlib module with ``email.parser``, when\n available (Python >= 2.5). Ensured that distributions \"unfold\" wrapped\n continuation lines, stripping any leading / trailing whitespace, no matter\n which module was used for parsing.\n\n- Remove bogus testing dependency on ``zope.testing``.\n\n- Add tests that the \"environment markers\" spelled out in the approved\n PEP 345 are captured.\n\n- Add ``Project-URL`` for ``1.2`` PKG-INFO metdata (defined in the accepted\n version of PEP 345).\n\n\n0.5 (2009-09-11)\n----------------\n\n- Marked package as non-zip-safe.\n\n- Fix Trove metadata misspelling.\n\n- Restore compatibility with Python 2.4.\n\n- Note that the introspection of installed packages / modules works only\n in Python 2.6 or later.\n\n- Add ``Index`` class as an abstraction over a collection of distributions.\n\n- Add ``download_url_prefix`` argument to ``pkginfo`` script. If passed,\n the script will use the prefix to synthesize a ``download_url`` for\n distributions which do not supply that value directly.\n\n\n0.4.1 (2009-05-07)\n------------------\n\n- Fix bugs in handling of installed packages which lack ``__file__``\n or ``PKG-INFO``.\n\n\n0.4 (2009-05-07)\n----------------\n\n- Extend the console script to allow output as CSV or INI. Also, added\n arguments to specify the metadata version and other parsing / output\n policies.\n\n- Add support for the different metadata versions specified in PEPs\n 241, 314, and 345. Distributions now parse and expose only the attributes\n corresponding to their metadata version, which defaults to the version\n parsed from the ``PKG-INFO`` file. The programmer can override that version\n when creating the distribution object.\n\n\n0.3 (2009-05-07)\n----------------\n\n- Add support for introspection of \"development eggs\" (checkouts with\n ``PKG-INFO``, perhaps created via ``setup.py develop``).\n\n- Add a console script, ``pkginfo``, which takes one or more paths\n on the command line and writes out the associated information. Thanks\n to ``runeh`` for the patch!\n\n- Add ``get_metadata`` helper function, which dispatches a given path or\n module across the available distribution types, and returns a distribution\n object. Thanks to ``runeh`` for the patch!\n\n- Make distribution objects support iteration over the metadata fields.\n Thanks to ``runeh`` for the patch!\n\n- Make ``Distribution`` and subclasses new-style classes. Thanks to ``runeh``\n for the patch!\n\n\n0.2 (2009-04-14)\n----------------\n\n- Add support for introspection of ``bdist_egg`` binary distributions.\n\n\n0.1.1 (2009-04-10)\n------------------\n\n- Fix packaging errors.\n\n\n0.1 (2009-04-10)\n----------------\n\n- Initial release.", + "release_date": "2022-01-27T23:56:11", "parties": [ { "type": "person", "role": "author", - "name": "Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others", - "email": null, + "name": "Maintained by nexB, Inc. Authored by Tres Seaver, Agendaless Consulting", + "email": "tseaver@agendaless.com", "url": null } ], "keywords": [ - "test", - "unittest", - "Development Status :: 6 - Mature", + "distribution sdist installed metadata", "Intended Audience :: Developers", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", + "Operating System :: OS Independent", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", - "Topic :: Software Development :: Libraries", - "Topic :: Software Development :: Testing", - "Topic :: Utilities" + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: System :: Software Distribution" ], - "homepage_url": "https://docs.pytest.org/en/latest/", - "download_url": "https://files.pythonhosted.org/packages/38/93/c7c0bd1e932b287fb948eb9ce5a3d6307c9fc619db1e199f8c8bc5dad95f/pytest-7.0.1-py3-none-any.whl", - "size": 296985, + "homepage_url": "https://github.com/nexB/pkginfo2", + "download_url": "https://files.pythonhosted.org/packages/49/01/4e506c68c9ea09c702b1eac87e6d2cda6d6633e6ed42ec1f43662e246769/pkginfo2-30.0.0-py3-none-any.whl", + "size": 25701, "sha1": null, - "md5": "f5758c7774cc7ae6caab04e71379fabc", - "sha256": "9ce3ff477af913ecf6321fe337b93a2c0dcf2a0a1439c43f5452112c1e4280db", + "md5": "08f225691729a9b3441cb955c82abce9", + "sha256": "f1558f3ff71c99e8f362b6d079c15ef334dfce8ab2bc623a992341baeb1e7248", "sha512": null, - "bug_tracking_url": "https://github.com/pytest-dev/pytest/issues", - "code_view_url": "https://github.com/pytest-dev/pytest", + "bug_tracking_url": null, + "code_view_url": null, "vcs_url": null, "copyright": null, "license_expression": null, @@ -7740,57 +3969,53 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pytest/7.0.1/json", + "api_data_url": "https://pypi.org/pypi/pkginfo2/30.0.0/json", "datasource_id": null, - "purl": "pkg:pypi/pytest@7.0.1" + "purl": "pkg:pypi/pkginfo2@30.0.0" }, { "type": "pypi", "namespace": null, - "name": "pytest", - "version": "7.0.1", + "name": "pkginfo", + "version": "1.8.3", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "pytest: simple powerful testing with Python\n.. image:: https://github.com/pytest-dev/pytest/raw/main/doc/en/img/pytest_logo_curves.svg\n :target: https://docs.pytest.org/en/stable/\n :align: center\n :height: 200\n :alt: pytest\n\n\n------\n\n.. image:: https://img.shields.io/pypi/v/pytest.svg\n :target: https://pypi.org/project/pytest/\n\n.. image:: https://img.shields.io/conda/vn/conda-forge/pytest.svg\n :target: https://anaconda.org/conda-forge/pytest\n\n.. image:: https://img.shields.io/pypi/pyversions/pytest.svg\n :target: https://pypi.org/project/pytest/\n\n.. image:: https://codecov.io/gh/pytest-dev/pytest/branch/main/graph/badge.svg\n :target: https://codecov.io/gh/pytest-dev/pytest\n :alt: Code coverage Status\n\n.. image:: https://github.com/pytest-dev/pytest/workflows/main/badge.svg\n :target: https://github.com/pytest-dev/pytest/actions?query=workflow%3Amain\n\n.. image:: https://results.pre-commit.ci/badge/github/pytest-dev/pytest/main.svg\n :target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest/main\n :alt: pre-commit.ci status\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n\n.. image:: https://www.codetriage.com/pytest-dev/pytest/badges/users.svg\n :target: https://www.codetriage.com/pytest-dev/pytest\n\n.. image:: https://readthedocs.org/projects/pytest/badge/?version=latest\n :target: https://pytest.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n\n.. image:: https://img.shields.io/badge/Discord-pytest--dev-blue\n :target: https://discord.com/invite/pytest-dev\n :alt: Discord\n\n.. image:: https://img.shields.io/badge/Libera%20chat-%23pytest-orange\n :target: https://web.libera.chat/#pytest\n :alt: Libera chat\n\n\nThe ``pytest`` framework makes it easy to write small tests, yet\nscales to support complex functional testing for applications and libraries.\n\nAn example of a simple test:\n\n.. code-block:: python\n\n # content of test_sample.py\n def inc(x):\n return x + 1\n\n\n def test_answer():\n assert inc(3) == 5\n\n\nTo execute it::\n\n $ pytest\n ============================= test session starts =============================\n collected 1 items\n\n test_sample.py F\n\n ================================== FAILURES ===================================\n _________________________________ test_answer _________________________________\n\n def test_answer():\n > assert inc(3) == 5\n E assert 4 == 5\n E + where 4 = inc(3)\n\n test_sample.py:5: AssertionError\n ========================== 1 failed in 0.04 seconds ===========================\n\n\nDue to ``pytest``'s detailed assertion introspection, only plain ``assert`` statements are used. See `getting-started `_ for more examples.\n\n\nFeatures\n--------\n\n- Detailed info on failing `assert statements `_ (no need to remember ``self.assert*`` names)\n\n- `Auto-discovery\n `_\n of test modules and functions\n\n- `Modular fixtures `_ for\n managing small or parametrized long-lived test resources\n\n- Can run `unittest `_ (or trial),\n `nose `_ test suites out of the box\n\n- Python 3.6+ and PyPy3\n\n- Rich plugin architecture, with over 850+ `external plugins `_ and thriving community\n\n\nDocumentation\n-------------\n\nFor full documentation, including installation, tutorials and PDF documents, please see https://docs.pytest.org/en/stable/.\n\n\nBugs/Requests\n-------------\n\nPlease use the `GitHub issue tracker `_ to submit bugs or request features.\n\n\nChangelog\n---------\n\nConsult the `Changelog `__ page for fixes and enhancements of each version.\n\n\nSupport pytest\n--------------\n\n`Open Collective`_ is an online funding platform for open and transparent communities.\nIt provides tools to raise money and share your finances in full transparency.\n\nIt is the platform of choice for individuals and companies that want to make one-time or\nmonthly donations directly to the project.\n\nSee more details in the `pytest collective`_.\n\n.. _Open Collective: https://opencollective.com\n.. _pytest collective: https://opencollective.com/pytest\n\n\npytest for enterprise\n---------------------\n\nAvailable as part of the Tidelift Subscription.\n\nThe maintainers of pytest and thousands of other packages are working with Tidelift to deliver commercial support and\nmaintenance for the open source dependencies you use to build your applications.\nSave time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use.\n\n`Learn more. `_\n\nSecurity\n^^^^^^^^\n\npytest has never been associated with a security vulnerability, but in any case, to report a\nsecurity vulnerability please use the `Tidelift security contact `_.\nTidelift will coordinate the fix and disclosure.\n\n\nLicense\n-------\n\nCopyright Holger Krekel and others, 2004.\n\nDistributed under the terms of the `MIT`_ license, pytest is free and open source software.\n\n.. _`MIT`: https://github.com/pytest-dev/pytest/blob/main/LICENSE", - "release_date": "2022-02-11T18:47:58", + "description": "Query metadatdata from sdists / bdists / installed packages.\n``pkginfo`` README\n==================\n\nThis package provides an API for querying the distutils metadata written in\nthe ``PKG-INFO`` file inside a source distriubtion (an ``sdist``) or a\nbinary distribution (e.g., created by running ``bdist_egg``). It can\nalso query the ``EGG-INFO`` directory of an installed distribution, and\nthe ``*.egg-info`` stored in a \"development checkout\"\n(e.g, created by running ``setup.py develop``).\n\n\nPlease see the `pkginfo docs `_\nfor detailed documentation.\n\n\n``pkginfo`` Changelog\n=====================\n\n1.8.3 (2022-06-08)\n------------------\n\n- Specify supported Python versions in 'setup.py' using 'python_requires'.\n LP #1977981.\n\n1.8.2 (2021-12-01)\n------------------\n\n- Add fix for installed distributions with '__package__' set to an empty\n string. LP #1952946.\n\n1.8.1 (2021-11-19)\n------------------\n\n- Add 'MANIFEST.in' to ensure example files used by tests are included\n in source distributions. LP #1951553.\n\n1.8.0 (2021-11-18)\n------------------\n\n- Support new standard metadata location for installed dists. LP #1865286.\n\n- Don't overwrite header-based 'description' with empty payload. LP #1885458.\n\n- Add support for Metadata-Version 2.2. LP #1928729.\n\n- Add support for uncompressed tarballs for sdists. LP #1951457.\n\n- Add support for Python 3.10.\n\n1.7.1 (2021-07-09)\n------------------\n\n- Use Python3 to build docs, and fix doctest examples to use Python3-\n compatible syntax. LP #1933322.\n\n1.7.0 (2021-01-16)\n------------------\n\n- Add support for Python 3.9.\n\n- Drop support for Python 3.5.\n\n1.6.1 (2020-10-26)\n------------------\n\n- Adjust test classifiers to match supported Python versions. LP #1901127.\n\n1.6.0 (2020-10-20)\n------------------\n\n- Add support for Python 3.8.\n LP #1869854.\n\n- Drop support for Python 3.4.\n\n- Update tests to match setuptools' change, no longer reporting metadata\n version for installed packages w/o explicit metadata. LP #1870197.\n\n1.5.0.1 (2019-01-08)\n--------------------\n\n- Fix broken 'sdist'. LP #1639585.\n\n1.5.0 (2019-01-07)\n------------------\n\n- Fix 'console_scripts' entry point syntax. LP #1810734.\n\n- Add support for JSON output from the CLI. LP #1700580.\n\n- Add support for installed wheels. E.g., 'dist-info/' dirs. LP #1700200.\n\n- Harden metadata extraction against unexpected encodings. LP #1780454.\n\n- Update tests to match pip/setuptools' use of new metadata version.\n LP #1772274.\n\n- Add support for Python 3.6 and 3.7.\n\n- Drop support for Python 3.3.\n\n1.4.2 (2018-03-14)\n------------------\n\n- Use relative imports in pkginfo modules. Supports vendoring of the\n package into setuptools.\n\n- Add support for ``Provides-Extra`` and ``Description-Content-Type`` fields.\n Per https://packaging.python.org/specifications/. See: PEP 566.\n\n- Remove support for old setuptools leaving ``PKG-INFO`` in the root of\n the project directory.\n\n1.4.1 (2016-11-07)\n------------------\n\n- Packaging only change (invalid sdist built for 1.4.0).\n\n1.4.0 (2016-11-04)\n------------------\n\n- Relicense under MIT license: the PSF license is not suitable for\n third-party libraries.\n\n1.3.2 (2016-05-24)\n------------------\n\n- Packaging-only change (automate fix for wheel built for 1.3.1).\n\n1.3.1 (2016-05-24)\n------------------\n\n- Packaging-only change (invalid wheel built for 1.3.0).\n\n1.3.0 (2016-05-23)\n------------------\n\n- Update homepage URL to point to Launchpad, rather than PyPI.\n\n- Add support for building wheels.\n\n- Add support for Python 3.5.\n\n- Drop support for Python 2.6 and 3.2.\n\n1.2.1 (2014-01-02)\n------------------\n\n- Add overlooked Trove classifier for Python 3.4.\n\n1.2 (2014-01-02)\n----------------\n\n- Add support for Python 3.4, PyPy3.\n\n- Add 100% coverage for ``pkginfo.commandline`` module.\n\n1.2b1 (2013-12-05)\n------------------\n\n- Add support for the \"wheel\" distribution format, along with minimal\n metadata 2.0 support (not including new PEP 426 JSON properties).\n Code (re-)borrowed from Donald Stuft's ``twine`` package.\n\n1.1 (2013-10-09)\n----------------\n\n- Fix tests to pass with current PyPy releases.\n\n1.1b1 (2013-05-05)\n------------------\n\n- Support \"develop\" packages which keep their ``*.egg-info`` in a subdirectory.\n See https://bugs.launchpad.net/pkginfo/+bug/919147.\n\n- Add support for \"unpacked SDists\" (thanks to Mike Lundy for the patch).\n\n1.0 (2013-05-05)\n----------------\n\n- No changes from 1.0b2.\n\n1.0b2 (2012-12-28)\n------------------\n\n- Suppress resource warning leaks reported against clients.\n\n- Fix 'commandline' module under Py3k.\n\n1.0b1 (2012-12-28)\n------------------\n\n- Add support for Python 3.2 and 3.3, including testing them under ``tox``.\n\n- Add support for PyPy, including testing it under ``tox``.\n\n- Test supported Python versions under ``tox``.\n\n- Drop support for Python 2.5.\n\n- Add a ``setup.py dev`` alias: runs ``setup.py develop`` and installs\n testing extras (``nose`` and ``coverage``).\n\n0.9.1 (2012-10-22)\n------------------\n\n- Fix test failure under Python >= 2.7, which is enforcing\n 'metadata_version == 1.1' because we have classifiers.\n\n\n0.9 (2012-04-25)\n----------------\n\n- Fix introspection of installed namespace packages.\n They may be installed as eggs or via dist-installed 'egg-info' files.\n https://bugs.launchpad.net/pkginfo/+bug/934311\n\n- Avoid a regression in 0.8 under Python 2.6 / 2.7 when parsing unicode.\n https://bugs.launchpad.net/pkginfo/+bug/733827/comments/3\n\n\n0.8 (2011-03-12)\n----------------\n\n- Work around Python 2.7's breakage of StringIO. Fixes\n https://bugs.launchpad.net/pkginfo/+bug/733827\n\n- Fix bug in introspection of installed packages missing the\n ``__package__`` attribute.\n \n\n0.7 (2010-11-04)\n----------------\n\n- Preserve newlines in the ``description`` field. Thanks to Sridhar\n Ratnakumar for the patch.\n\n- 100% test coverage.\n\n\n0.6 (2010-06-01)\n----------------\n\n- Replace use of ``StringIO.StringIO`` with ``io.StringIO``, where available\n (Python >= 2.6).\n\n- Replace use of ``rfc822`` stdlib module with ``email.parser``, when\n available (Python >= 2.5). Ensured that distributions \"unfold\" wrapped\n continuation lines, stripping any leading / trailing whitespace, no matter\n which module was used for parsing.\n\n- Remove bogus testing dependency on ``zope.testing``.\n\n- Add tests that the \"environment markers\" spelled out in the approved\n PEP 345 are captured.\n\n- Add ``Project-URL`` for ``1.2`` PKG-INFO metdata (defined in the accepted\n version of PEP 345).\n\n\n0.5 (2009-09-11)\n----------------\n\n- Marked package as non-zip-safe.\n\n- Fix Trove metadata misspelling.\n\n- Restore compatibility with Python 2.4.\n\n- Note that the introspection of installed packages / modules works only\n in Python 2.6 or later.\n\n- Add ``Index`` class as an abstraction over a collection of distributions.\n\n- Add ``download_url_prefix`` argument to ``pkginfo`` script. If passed,\n the script will use the prefix to synthesize a ``download_url`` for\n distributions which do not supply that value directly.\n\n\n0.4.1 (2009-05-07)\n------------------\n\n- Fix bugs in handling of installed packages which lack ``__file__``\n or ``PKG-INFO``.\n\n\n0.4 (2009-05-07)\n----------------\n\n- Extend the console script to allow output as CSV or INI. Also, added\n arguments to specify the metadata version and other parsing / output\n policies.\n\n- Add support for the different metadata versions specified in PEPs\n 241, 314, and 345. Distributions now parse and expose only the attributes\n corresponding to their metadata version, which defaults to the version\n parsed from the ``PKG-INFO`` file. The programmer can override that version\n when creating the distribution object.\n\n\n0.3 (2009-05-07)\n----------------\n\n- Add support for introspection of \"development eggs\" (checkouts with\n ``PKG-INFO``, perhaps created via ``setup.py develop``).\n\n- Add a console script, ``pkginfo``, which takes one or more paths\n on the command line and writes out the associated information. Thanks\n to ``runeh`` for the patch!\n\n- Add ``get_metadata`` helper function, which dispatches a given path or\n module across the available distribution types, and returns a distribution\n object. Thanks to ``runeh`` for the patch!\n\n- Make distribution objects support iteration over the metadata fields.\n Thanks to ``runeh`` for the patch!\n\n- Make ``Distribution`` and subclasses new-style classes. Thanks to ``runeh``\n for the patch!\n\n\n0.2 (2009-04-14)\n----------------\n\n- Add support for introspection of ``bdist_egg`` binary distributions.\n\n\n0.1.1 (2009-04-10)\n------------------\n\n- Fix packaging errors.\n\n\n0.1 (2009-04-10)\n----------------\n\n- Initial release.", + "release_date": "2022-06-08T18:10:54", "parties": [ { "type": "person", "role": "author", - "name": "Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others", - "email": null, + "name": "Tres Seaver, Agendaless Consulting", + "email": "tseaver@agendaless.com", "url": null } ], "keywords": [ - "test", - "unittest", - "Development Status :: 6 - Mature", + "distribution sdist installed metadata", "Intended Audience :: Developers", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", + "Operating System :: OS Independent", + "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", - "Topic :: Software Development :: Libraries", - "Topic :: Software Development :: Testing", - "Topic :: Utilities" + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: System :: Software Distribution" ], - "homepage_url": "https://docs.pytest.org/en/latest/", - "download_url": "https://files.pythonhosted.org/packages/3e/2c/a67ad48759051c7abf82ce182a4e6d766de371b183182d2dde03089e8dfb/pytest-7.0.1.tar.gz", - "size": 1249154, + "homepage_url": "https://code.launchpad.net/~tseaver/pkginfo/trunk", + "download_url": "https://files.pythonhosted.org/packages/f3/28/ded592460bc65d39a48fe51d7678c408ae895ee3694d4cd404a131a73271/pkginfo-1.8.3-py2.py3-none-any.whl", + "size": 26567, "sha1": null, - "md5": "995d64fe44bbe717d03bd703d5c48ec6", - "sha256": "e30905a0c131d3d94b89624a1cc5afec3e0ba2fbdb151867d8e0ebd49850f171", + "md5": "12469a5ba29bbf6f1057ee2c5b03e438", + "sha256": "848865108ec99d4901b2f7e84058b6e7660aae8ae10164e015a6dcf5b242a594", "sha512": null, - "bug_tracking_url": "https://github.com/pytest-dev/pytest/issues", - "code_view_url": "https://github.com/pytest-dev/pytest", + "bug_tracking_url": null, + "code_view_url": null, "vcs_url": null, "copyright": null, "license_expression": null, @@ -7807,36 +4032,37 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pytest/7.0.1/json", + "api_data_url": "https://pypi.org/pypi/pkginfo/1.8.3/json", "datasource_id": null, - "purl": "pkg:pypi/pytest@7.0.1" + "purl": "pkg:pypi/pkginfo@1.8.3" }, { "type": "pypi", "namespace": null, - "name": "pyyaml", - "version": "6.0", + "name": "platformdirs", + "version": "2.4.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "YAML parser and emitter for Python\nYAML is a data serialization format designed for human readability\nand interaction with scripting languages. PyYAML is a YAML parser\nand emitter for Python.\n\nPyYAML features a complete YAML 1.1 parser, Unicode support, pickle\nsupport, capable extension API, and sensible error messages. PyYAML\nsupports standard YAML tags and provides Python-specific tags that\nallow to represent an arbitrary Python object.\n\nPyYAML is applicable for a broad range of tasks from complex\nconfiguration files to object serialization and persistence.", - "release_date": "2021-10-13T19:39:51", + "description": "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\".\nThe problem\n===========\n\n.. image:: https://github.com/platformdirs/platformdirs/workflows/Test/badge.svg\n :target: https://github.com/platformdirs/platformdirs/actions?query=workflow%3ATest\n\nWhen writing desktop application, finding the right location to store user data\nand configuration varies per platform. Even for single-platform apps, there\nmay by plenty of nuances in figuring out the right location.\n\nFor example, if running on macOS, you should use::\n\n ~/Library/Application Support/\n\nIf on Windows (at least English Win XP) that should be::\n\n C:\\Documents and Settings\\\\Application Data\\Local Settings\\\\\n\nor possibly::\n\n C:\\Documents and Settings\\\\Application Data\\\\\n\nfor `roaming profiles `_ but that is another story.\n\nOn Linux (and other Unices), according to the `XDG Basedir Spec`_, it should be::\n\n ~/.local/share/\n\n.. _XDG Basedir Spec: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html\n\n``platformdirs`` to the rescue\n==============================\n\nThis kind of thing is what the ``platformdirs`` module is for.\n``platformdirs`` will help you choose an appropriate:\n\n- user data dir (``user_data_dir``)\n- user config dir (``user_config_dir``)\n- user cache dir (``user_cache_dir``)\n- site data dir (``site_data_dir``)\n- site config dir (``site_config_dir``)\n- user log dir (``user_log_dir``)\n- user documents dir (``user_documents_dir``)\n- user runtime dir (``user_runtime_dir``)\n\nAnd also:\n\n- Is a single module so other Python packages can vendor their own private copy.\n- Is slightly opinionated on the directory names used. Look for \"OPINION\" in\n documentation and code for when an opinion is being applied.\n\nExample output\n==============\n\nOn macOS:\n\n.. code-block:: pycon\n\n >>> from platformdirs import *\n >>> appname = \"SuperApp\"\n >>> appauthor = \"Acme\"\n >>> user_data_dir(appname, appauthor)\n '/Users/trentm/Library/Application Support/SuperApp'\n >>> site_data_dir(appname, appauthor)\n '/Library/Application Support/SuperApp'\n >>> user_cache_dir(appname, appauthor)\n '/Users/trentm/Library/Caches/SuperApp'\n >>> user_log_dir(appname, appauthor)\n '/Users/trentm/Library/Logs/SuperApp'\n >>> user_documents_dir()\n '/Users/trentm/Documents'\n >>> user_runtime_dir(appname, appauthor)\n '/Users/trentm/Library/Caches/TemporaryItems/SuperApp'\n\nOn Windows 7:\n\n.. code-block:: pycon\n\n >>> from platformdirs import *\n >>> appname = \"SuperApp\"\n >>> appauthor = \"Acme\"\n >>> user_data_dir(appname, appauthor)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Local\\\\Acme\\\\SuperApp'\n >>> user_data_dir(appname, appauthor, roaming=True)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Roaming\\\\Acme\\\\SuperApp'\n >>> user_cache_dir(appname, appauthor)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Local\\\\Acme\\\\SuperApp\\\\Cache'\n >>> user_log_dir(appname, appauthor)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Local\\\\Acme\\\\SuperApp\\\\Logs'\n >>> user_documents_dir()\n 'C:\\\\Users\\\\trentm\\\\Documents'\n >>> user_runtime_dir(appname, appauthor)\n 'C:\\\\Users\\\\trentm\\\\AppData\\\\Local\\\\Temp\\\\Acme\\\\SuperApp'\n\nOn Linux:\n\n.. code-block:: pycon\n\n >>> from platformdirs import *\n >>> appname = \"SuperApp\"\n >>> appauthor = \"Acme\"\n >>> user_data_dir(appname, appauthor)\n '/home/trentm/.local/share/SuperApp\n >>> site_data_dir(appname, appauthor)\n '/usr/local/share/SuperApp'\n >>> site_data_dir(appname, appauthor, multipath=True)\n '/usr/local/share/SuperApp:/usr/share/SuperApp'\n >>> user_cache_dir(appname, appauthor)\n '/home/trentm/.cache/SuperApp'\n >>> user_log_dir(appname, appauthor)\n '/home/trentm/.cache/SuperApp/log'\n >>> user_config_dir(appname)\n '/home/trentm/.config/SuperApp'\n >>> user_documents_dir()\n '/home/trentm/Documents'\n >>> user_runtime_dir(appname, appauthor)\n '/run/user/{os.getuid()}/SuperApp'\n >>> site_config_dir(appname)\n '/etc/xdg/SuperApp'\n >>> os.environ['XDG_CONFIG_DIRS'] = '/etc:/usr/local/etc'\n >>> site_config_dir(appname, multipath=True)\n '/etc/SuperApp:/usr/local/etc/SuperApp'\n\nOn Android::\n\n >>> from platformdirs import *\n >>> appname = \"SuperApp\"\n >>> appauthor = \"Acme\"\n >>> user_data_dir(appname, appauthor)\n '/data/data/com.termux/files/SuperApp'\n >>> user_cache_dir(appname, appauthor)\n '/data/data/com.termux/cache/SuperApp'\n >>> user_log_dir(appname, appauthor)\n '/data/data/com.termux/cache/SuperApp/log'\n >>> user_config_dir(appname)\n '/data/data/com.termux/shared_prefs/SuperApp'\n >>> user_documents_dir()\n '/storage/emulated/0/Documents'\n >>> user_runtime_dir(appname, appauthor)\n '/data/data/com.termux/cache/SuperApp/tmp'\n\n``PlatformDirs`` for convenience\n================================\n\n.. code-block:: pycon\n\n >>> from platformdirs import PlatformDirs\n >>> dirs = PlatformDirs(\"SuperApp\", \"Acme\")\n >>> dirs.user_data_dir\n '/Users/trentm/Library/Application Support/SuperApp'\n >>> dirs.site_data_dir\n '/Library/Application Support/SuperApp'\n >>> dirs.user_cache_dir\n '/Users/trentm/Library/Caches/SuperApp'\n >>> dirs.user_log_dir\n '/Users/trentm/Library/Logs/SuperApp'\n >>> dirs.user_documents_dir\n '/Users/trentm/Documents'\n >>> dirs.user_runtime_dir\n '/Users/trentm/Library/Caches/TemporaryItems/SuperApp'\n\nPer-version isolation\n=====================\n\nIf you have multiple versions of your app in use that you want to be\nable to run side-by-side, then you may want version-isolation for these\ndirs::\n\n >>> from platformdirs import PlatformDirs\n >>> dirs = PlatformDirs(\"SuperApp\", \"Acme\", version=\"1.0\")\n >>> dirs.user_data_dir\n '/Users/trentm/Library/Application Support/SuperApp/1.0'\n >>> dirs.site_data_dir\n '/Library/Application Support/SuperApp/1.0'\n >>> dirs.user_cache_dir\n '/Users/trentm/Library/Caches/SuperApp/1.0'\n >>> dirs.user_log_dir\n '/Users/trentm/Library/Logs/SuperApp/1.0'\n >>> dirs.user_documents_dir\n '/Users/trentm/Documents'\n >>> dirs.user_runtime_dir\n '/Users/trentm/Library/Caches/TemporaryItems/SuperApp/1.0'\n\nBe wary of using this for configuration files though; you'll need to handle\nmigrating configuration files manually.\n\nWhy this Fork?\n==============\n\nThis repository is a friendly fork of the wonderful work started by\n`ActiveState `_ who created\n``appdirs``, this package's ancestor.\n\nMaintaining an open source project is no easy task, particularly\nfrom within an organization, and the Python community is indebted\nto ``appdirs`` (and to Trent Mick and Jeff Rouse in particular) for\ncreating an incredibly useful simple module, as evidenced by the wide\nnumber of users it has attracted over the years.\n\nNonetheless, given the number of long-standing open issues\nand pull requests, and no clear path towards `ensuring\nthat maintenance of the package would continue or grow\n`_, this fork was\ncreated.\n\nContributions are most welcome.", + "release_date": "2021-09-25T20:46:05", "parties": [ - { - "type": "person", - "role": "author", - "name": "Kirill Simonov", - "email": "xi@resolvent.net", + { + "type": "person", + "role": "maintainer", + "name": "Bern\u00e1t G\u00e1bor, Julian Berman, Ofek Lev, Ronny Pfannschmidt", + "email": "gaborjbernat@gmail.com, Julian@GrayVines.com, oss@ofek.dev, opensource@ronnypfannschmidt.de", "url": null } ], "keywords": [ + "application directory log cache user", "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Operating System :: OS Independent", - "Programming Language :: Cython", "Programming Language :: Python", "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", @@ -7844,18 +4070,17 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Text Processing :: Markup" + "Topic :: Software Development :: Libraries :: Python Modules" ], - "homepage_url": "https://pyyaml.org/", - "download_url": "https://files.pythonhosted.org/packages/02/25/6ba9f6bb50a3d4fbe22c1a02554dc670682a07c8701d1716d19ddea2c940/PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", - "size": 682157, + "homepage_url": "https://github.com/platformdirs/platformdirs", + "download_url": "https://files.pythonhosted.org/packages/b1/78/dcfd84d3aabd46a9c77260fb47ea5d244806e4daef83aa6fe5d83adb182c/platformdirs-2.4.0-py3-none-any.whl", + "size": 14400, "sha1": null, - "md5": "af1ca2607840fa7ad65b1994c2d723c0", - "sha256": "f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5", + "md5": "8c8b02ee007d405bf3369b82b7a4c1ca", + "sha256": "8868bbe3c3c80d42f20156f22e7131d2fb321f5bc86a2a345375c6481a67021d", "sha512": null, - "bug_tracking_url": "https://github.com/yaml/pyyaml/issues", - "code_view_url": "https://github.com/yaml/pyyaml", + "bug_tracking_url": "https://github.com/platformdirs/platformdirs/issues", + "code_view_url": "https://github.com/platformdirs/platformdirs", "vcs_url": null, "copyright": null, "license_expression": null, @@ -7872,55 +4097,56 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pyyaml/6.0/json", + "api_data_url": "https://pypi.org/pypi/platformdirs/2.4.0/json", "datasource_id": null, - "purl": "pkg:pypi/pyyaml@6.0" + "purl": "pkg:pypi/platformdirs@2.4.0" }, { "type": "pypi", "namespace": null, - "name": "pyyaml", - "version": "6.0", + "name": "pluggy", + "version": "1.0.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "YAML parser and emitter for Python\nYAML is a data serialization format designed for human readability\nand interaction with scripting languages. PyYAML is a YAML parser\nand emitter for Python.\n\nPyYAML features a complete YAML 1.1 parser, Unicode support, pickle\nsupport, capable extension API, and sensible error messages. PyYAML\nsupports standard YAML tags and provides Python-specific tags that\nallow to represent an arbitrary Python object.\n\nPyYAML is applicable for a broad range of tasks from complex\nconfiguration files to object serialization and persistence.", - "release_date": "2021-10-13T19:40:57", + "description": "plugin and hook calling mechanisms for python\n====================================================\npluggy - A minimalist production ready plugin system\n====================================================\n\n|pypi| |conda-forge| |versions| |github-actions| |gitter| |black| |codecov|\n\nThis is the core framework used by the `pytest`_, `tox`_, and `devpi`_ projects.\n\nPlease `read the docs`_ to learn more!\n\nA definitive example\n====================\n.. code-block:: python\n\n import pluggy\n\n hookspec = pluggy.HookspecMarker(\"myproject\")\n hookimpl = pluggy.HookimplMarker(\"myproject\")\n\n\n class MySpec:\n \"\"\"A hook specification namespace.\"\"\"\n\n @hookspec\n def myhook(self, arg1, arg2):\n \"\"\"My special little hook that you can customize.\"\"\"\n\n\n class Plugin_1:\n \"\"\"A hook implementation namespace.\"\"\"\n\n @hookimpl\n def myhook(self, arg1, arg2):\n print(\"inside Plugin_1.myhook()\")\n return arg1 + arg2\n\n\n class Plugin_2:\n \"\"\"A 2nd hook implementation namespace.\"\"\"\n\n @hookimpl\n def myhook(self, arg1, arg2):\n print(\"inside Plugin_2.myhook()\")\n return arg1 - arg2\n\n\n # create a manager and add the spec\n pm = pluggy.PluginManager(\"myproject\")\n pm.add_hookspecs(MySpec)\n\n # register plugins\n pm.register(Plugin_1())\n pm.register(Plugin_2())\n\n # call our ``myhook`` hook\n results = pm.hook.myhook(arg1=1, arg2=2)\n print(results)\n\n\nRunning this directly gets us::\n\n $ python docs/examples/toy-example.py\n inside Plugin_2.myhook()\n inside Plugin_1.myhook()\n [-1, 3]\n\n\n.. badges\n\n.. |pypi| image:: https://img.shields.io/pypi/v/pluggy.svg\n :target: https://pypi.org/pypi/pluggy\n\n.. |versions| image:: https://img.shields.io/pypi/pyversions/pluggy.svg\n :target: https://pypi.org/pypi/pluggy\n\n.. |github-actions| image:: https://github.com/pytest-dev/pluggy/workflows/main/badge.svg\n :target: https://github.com/pytest-dev/pluggy/actions\n\n.. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pluggy.svg\n :target: https://anaconda.org/conda-forge/pytest\n\n.. |gitter| image:: https://badges.gitter.im/pytest-dev/pluggy.svg\n :alt: Join the chat at https://gitter.im/pytest-dev/pluggy\n :target: https://gitter.im/pytest-dev/pluggy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge\n\n.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/ambv/black\n\n.. |codecov| image:: https://codecov.io/gh/pytest-dev/pluggy/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/pytest-dev/pluggy\n :alt: Code coverage Status\n\n.. links\n.. _pytest:\n http://pytest.org\n.. _tox:\n https://tox.readthedocs.org\n.. _devpi:\n http://doc.devpi.net\n.. _read the docs:\n https://pluggy.readthedocs.io/en/latest/", + "release_date": "2021-08-25T16:25:59", "parties": [ { "type": "person", "role": "author", - "name": "Kirill Simonov", - "email": "xi@resolvent.net", + "name": "Holger Krekel", + "email": "holger@merlinux.eu", "url": null } ], "keywords": [ - "Development Status :: 5 - Production/Stable", + "Development Status :: 6 - Mature", "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Cython", - "Programming Language :: Python", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", + "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", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Text Processing :: Markup" + "Topic :: Software Development :: Libraries", + "Topic :: Software Development :: Testing", + "Topic :: Utilities" ], - "homepage_url": "https://pyyaml.org/", - "download_url": "https://files.pythonhosted.org/packages/36/2b/61d51a2c4f25ef062ae3f74576b01638bebad5e045f747ff12643df63844/PyYAML-6.0.tar.gz", - "size": 124996, + "homepage_url": "https://github.com/pytest-dev/pluggy", + "download_url": "https://files.pythonhosted.org/packages/9e/01/f38e2ff29715251cf25532b9082a1589ab7e4f571ced434f98d0139336dc/pluggy-1.0.0-py2.py3-none-any.whl", + "size": 13667, "sha1": null, - "md5": "1d19c798f25e58e3e582f0f8c977dbb8", - "sha256": "68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", + "md5": "40cd7d4a87f8ade524489d750647637b", + "sha256": "74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3", "sha512": null, - "bug_tracking_url": "https://github.com/yaml/pyyaml/issues", - "code_view_url": "https://github.com/yaml/pyyaml", + "bug_tracking_url": null, + "code_view_url": null, "vcs_url": null, "copyright": null, "license_expression": null, @@ -7937,54 +4163,57 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pyyaml/6.0/json", + "api_data_url": "https://pypi.org/pypi/pluggy/1.0.0/json", "datasource_id": null, - "purl": "pkg:pypi/pyyaml@6.0" + "purl": "pkg:pypi/pluggy@1.0.0" }, { "type": "pypi", "namespace": null, - "name": "readme-renderer", - "version": "34.0", + "name": "py", + "version": "1.11.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "readme_renderer is a library for rendering \"readme\" descriptions for Warehouse\nReadme Renderer\n===============\n\nReadme Renderer is a library that will safely render arbitrary\n``README`` files into HTML. It is designed to be used in Warehouse_ to\nrender the ``long_description`` for packages. It can handle Markdown,\nreStructuredText (``.rst``), and plain text.\n\n.. _Warehouse: https://github.com/pypa/warehouse\n\n\nCheck Description Locally\n-------------------------\n\nTo locally check whether your long descriptions will render on PyPI, first\nbuild your distributions, and then use the |twine check|_ command.\n\n\nRender rST Description Locally\n------------------------------\n\nYou can use ``readme_renderer`` on the command line to render an rST file as\nHTML like this: ::\n\n python -m readme_renderer README.rst -o /tmp/README.html\n\nCode of Conduct\n---------------\n\nEveryone interacting in the readme_renderer project's codebases, issue trackers,\nchat rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.\n\n\n.. |twine check| replace:: ``twine check``\n.. _twine check: https://packaging.python.org/guides/making-a-pypi-friendly-readme#validating-restructuredtext-markup\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md", - "release_date": "2022-03-11T20:12:21", + "description": "library with cross-python path, ini-parsing, io, code, log facilities\n.. image:: https://img.shields.io/pypi/v/py.svg\n :target: https://pypi.org/project/py\n\n.. image:: https://img.shields.io/conda/vn/conda-forge/py.svg\n :target: https://anaconda.org/conda-forge/py\n\n.. image:: https://img.shields.io/pypi/pyversions/py.svg\n :target: https://pypi.org/project/py\n\n.. image:: https://github.com/pytest-dev/py/workflows/build/badge.svg\n :target: https://github.com/pytest-dev/py/actions\n\n\n**NOTE**: this library is in **maintenance mode** and should not be used in new code.\n\nThe py lib is a Python development support library featuring\nthe following tools and modules:\n\n* ``py.path``: uniform local and svn path objects -> please use pathlib/pathlib2 instead\n* ``py.apipkg``: explicit API control and lazy-importing -> please use the standalone package instead\n* ``py.iniconfig``: easy parsing of .ini files -> please use the standalone package instead\n* ``py.code``: dynamic code generation and introspection (deprecated, moved to ``pytest`` as a implementation detail).\n\n**NOTE**: prior to the 1.4 release this distribution used to\ncontain py.test which is now its own package, see https://docs.pytest.org\n\nFor questions and more information please visit https://py.readthedocs.io\n\nBugs and issues: https://github.com/pytest-dev/py\n\nAuthors: Holger Krekel and others, 2004-2017", + "release_date": "2021-11-04T17:17:00", "parties": [ { "type": "person", "role": "author", - "name": "The Python Packaging Authority", - "email": "admin@mail.pypi.org", + "name": "holger krekel, Ronny Pfannschmidt, Benjamin Peterson and others", + "email": "pytest-dev@python.org", "url": null } ], "keywords": [ + "Development Status :: 6 - Mature", "Intended Audience :: Developers", - "Natural Language :: English", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", - "Operating System :: POSIX :: BSD", - "Operating System :: POSIX :: Linux", "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy" + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Libraries", + "Topic :: Software Development :: Testing", + "Topic :: Utilities" ], - "homepage_url": "https://github.com/pypa/readme_renderer", - "download_url": "https://files.pythonhosted.org/packages/40/df/a8d87511e806e4c5311d521140a51c34e5ab13e760cd739fc3b89495012d/readme_renderer-34.0-py3-none-any.whl", - "size": 16928, + "homepage_url": "https://py.readthedocs.io/", + "download_url": "https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl", + "size": 98708, "sha1": null, - "md5": "4ab2285b5830e44fc57a6d400b0d5958", - "sha256": "262510fe6aae81ed4e94d8b169077f325614c0b1a45916a80442c6576264a9c2", + "md5": "52d444d43edb21938fad6010a2134cc3", + "sha256": "607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -7992,9 +4221,9 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "Apache License, Version 2.0", + "license": "MIT license", "classifiers": [ - "License :: OSI Approved :: Apache Software License" + "License :: OSI Approved :: MIT License" ] }, "notice_text": null, @@ -8004,54 +4233,64 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/readme-renderer/34.0/json", + "api_data_url": "https://pypi.org/pypi/py/1.11.0/json", "datasource_id": null, - "purl": "pkg:pypi/readme-renderer@34.0" + "purl": "pkg:pypi/py@1.11.0" }, { "type": "pypi", "namespace": null, - "name": "readme-renderer", - "version": "34.0", + "name": "pycodestyle", + "version": "2.8.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "readme_renderer is a library for rendering \"readme\" descriptions for Warehouse\nReadme Renderer\n===============\n\nReadme Renderer is a library that will safely render arbitrary\n``README`` files into HTML. It is designed to be used in Warehouse_ to\nrender the ``long_description`` for packages. It can handle Markdown,\nreStructuredText (``.rst``), and plain text.\n\n.. _Warehouse: https://github.com/pypa/warehouse\n\n\nCheck Description Locally\n-------------------------\n\nTo locally check whether your long descriptions will render on PyPI, first\nbuild your distributions, and then use the |twine check|_ command.\n\n\nRender rST Description Locally\n------------------------------\n\nYou can use ``readme_renderer`` on the command line to render an rST file as\nHTML like this: ::\n\n python -m readme_renderer README.rst -o /tmp/README.html\n\nCode of Conduct\n---------------\n\nEveryone interacting in the readme_renderer project's codebases, issue trackers,\nchat rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.\n\n\n.. |twine check| replace:: ``twine check``\n.. _twine check: https://packaging.python.org/guides/making-a-pypi-friendly-readme#validating-restructuredtext-markup\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md", - "release_date": "2022-03-11T20:12:22", + "description": "pycodestyle (formerly called pep8) - Python style guide checker\n===============================================================\n\n.. image:: https://github.com/PyCQA/pycodestyle/actions/workflows/main.yml/badge.svg\n :target: https://github.com/PyCQA/pycodestyle/actions/workflows/main.yml\n :alt: Build status\n\n.. image:: https://readthedocs.org/projects/pycodestyle/badge/?version=latest\n :target: https://pycodestyle.pycqa.org\n :alt: Documentation Status\n\n.. image:: https://img.shields.io/pypi/wheel/pycodestyle.svg\n :target: https://pypi.org/project/pycodestyle/\n :alt: Wheel Status\n\n.. image:: https://badges.gitter.im/PyCQA/pycodestyle.svg\n :alt: Join the chat at https://gitter.im/PyCQA/pycodestyle\n :target: https://gitter.im/PyCQA/pycodestyle?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge\n\npycodestyle is a tool to check your Python code against some of the style\nconventions in `PEP 8`_.\n\n.. _PEP 8: http://www.python.org/dev/peps/pep-0008/\n\n.. note::\n\n This package used to be called ``pep8`` but was renamed to ``pycodestyle``\n to reduce confusion. Further discussion can be found `in the issue where\n Guido requested this\n change `_, or in the\n lightning talk at PyCon 2016 by @IanLee1521:\n `slides `_\n `video `_.\n\nFeatures\n--------\n\n* Plugin architecture: Adding new checks is easy.\n\n* Parseable output: Jump to error location in your editor.\n\n* Small: Just one Python file, requires only stdlib. You can use just\n the ``pycodestyle.py`` file for this purpose.\n\n* Comes with a comprehensive test suite.\n\nInstallation\n------------\n\nYou can install, upgrade, and uninstall ``pycodestyle.py`` with these commands::\n\n $ pip install pycodestyle\n $ pip install --upgrade pycodestyle\n $ pip uninstall pycodestyle\n\nThere's also a package for Debian/Ubuntu, but it's not always the\nlatest version.\n\nExample usage and output\n------------------------\n\n::\n\n $ pycodestyle --first optparse.py\n optparse.py:69:11: E401 multiple imports on one line\n optparse.py:77:1: E302 expected 2 blank lines, found 1\n optparse.py:88:5: E301 expected 1 blank line, found 0\n optparse.py:222:34: W602 deprecated form of raising exception\n optparse.py:347:31: E211 whitespace before '('\n optparse.py:357:17: E201 whitespace after '{'\n optparse.py:472:29: E221 multiple spaces before operator\n optparse.py:544:21: W601 .has_key() is deprecated, use 'in'\n\nYou can also make ``pycodestyle.py`` show the source code for each error, and\neven the relevant text from PEP 8::\n\n $ pycodestyle --show-source --show-pep8 testsuite/E40.py\n testsuite/E40.py:2:10: E401 multiple imports on one line\n import os, sys\n ^\n Imports should usually be on separate lines.\n\n Okay: import os\\nimport sys\n E401: import sys, os\n\n\nOr you can display how often each error was found::\n\n $ pycodestyle --statistics -qq Python-2.5/Lib\n 232 E201 whitespace after '['\n 599 E202 whitespace before ')'\n 631 E203 whitespace before ','\n 842 E211 whitespace before '('\n 2531 E221 multiple spaces before operator\n 4473 E301 expected 1 blank line, found 0\n 4006 E302 expected 2 blank lines, found 1\n 165 E303 too many blank lines (4)\n 325 E401 multiple imports on one line\n 3615 E501 line too long (82 characters)\n 612 W601 .has_key() is deprecated, use 'in'\n 1188 W602 deprecated form of raising exception\n\nLinks\n-----\n\n* `Read the documentation `_\n\n* `Fork me on GitHub `_\n\n\nChangelog\n=========\n\n2.8.0 (2021-10-10)\n------------------\n\nChanges:\n\n* Drop python 3.4. PR #982.\n* E712: fix false negative with multiple comparisons. PR #987.\n* E211: fix false positives with ``match``. PR #989.\n* E772: improve performance of bare except check. PR #992.\n* Backport tokenize performance improvement from python 3.10. PR #993.\n* E225: fix for lambdas containing positional-only args. PR #1012.\n* Remove ``indent_size_str`` \"setting\". PR #995.\n* E402: allow ``__all__`` to be typed. PR #1019.\n* E225: fix false positives for ``*`` in ``case``. PR #1003.\n* E201: detect tabs as whitespace. PR #1015.\n\n\n2.7.0 (2021-03-14)\n------------------\n\nChanges:\n\n* Fix physical checks (such as W191) at end of file. PR #961.\n* Add ``--indent-size`` option (defaulting to ``4``). PR #970.\n* W605: fix escaped crlf false positive on windows. PR #976.\n\n\n2.6.0 (2020-05-11)\n------------------\n\nAnnouncements:\n\n* Anthony Sottile (@asottile) joined the team as a core developer. :tada:\n\nChanges:\n\n* E306: fix detection inside ``async def``. PR #929.\n* E301: fix regression disallowing decorated one-liners. PR #927.\n* E714: fix false positive with chained ``is not``. PR #931.\n\n\n2.6.0a1 (2020-04-23)\n--------------------\n\nNew checks:\n\n* E225: require whitespace around ``and`` ``in`` ``is`` and ``or``. PR #847.\n\nChanges:\n\n* E117: fix indentation using tabs by treating as 8-space indents. PR #837.\n* E721: fix false positive with names containg ``istype``. PR #850.\n* E741: allow ``l`` as a named argument in a function call. PR #853.\n* E302: fix false-negative with decorated functions. PR #859.\n* W504: ellipsis (``...``) is no longer treated as a binary operator. PR #875.\n* E402: allow ``with``, ``if``, ``elif``, ``else`` to guard imports. PR #834.\n* Add support for assignment expressions ``:=`` (PEP 572). PR #879.\n* Add support for positional-only arguments ``/`` (PEP 570). PR #872, #918.\n* Add support for python 3.8.\n* Add support for matrix multiplication operator ``@`` (PEP 465). PR #897.\n* Support visual indent for continuation lines for ``with`` / ``assert`` /\n ``raise``. PR #912.\n* E302: allow two blank lines after a block of one-liners. PR #913.\n* E302: allow two-and-fewer newlines at the top of the file. PR #919.\n\n\n2.5.0 (2019-01-29)\n------------------\n\nNew checks:\n\n* E117: Over-indented code blocks\n* W505: Maximum doc-string length only when configured with --max-doc-length\n\nChanges:\n\n* Remove support for EOL Python 2.6 and 3.3. PR #720.\n* Add E117 error for over-indented code blocks.\n* Allow W605 to be silenced by `# noqa` and fix the position reported by W605\n* Allow users to omit blank lines around one-liner definitions of classes and\n functions\n* Include the function return annotation (``->``) as requiring surrounding\n whitespace only on Python 3\n* Verify that only names can follow ``await``. Previously we allowed numbers\n and strings.\n* Add support for Python 3.7\n* Fix detection of annotated argument defaults for E252\n* Correct the position reported by W504\n\n\n2.4.0 (2018-04-10)\n------------------\n\nNew checks:\n\n* Add W504 warning for checking that a break doesn't happen after a binary\n operator. This check is ignored by default. PR #502.\n* Add W605 warning for invalid escape sequences in string literals. PR #676.\n* Add W606 warning for 'async' and 'await' reserved keywords being introduced\n in Python 3.7. PR #684.\n* Add E252 error for missing whitespace around equal sign in type annotated\n function arguments with defaults values. PR #717.\n\nChanges:\n\n* An internal bisect search has replaced a linear search in order to improve\n efficiency. PR #648.\n* pycodestyle now uses PyPI trove classifiers in order to document supported\n python versions on PyPI. PR #654.\n* 'setup.cfg' '[wheel]' section has been renamed to '[bdist_wheel]', as\n the former is legacy. PR #653.\n* pycodestyle now handles very long lines much more efficiently for python\n 3.2+. Fixes #643. PR #644.\n* You can now write 'pycodestyle.StyleGuide(verbose=True)' instead of\n 'pycodestyle.StyleGuide(verbose=True, paths=['-v'])' in order to achieve\n verbosity. PR #663.\n* The distribution of pycodestyle now includes the license text in order to\n comply with open source licenses which require this. PR #694.\n* 'maximum_line_length' now ignores shebang ('#!') lines. PR #736.\n* Add configuration option for the allowed number of blank lines. It is\n implemented as a top level dictionary which can be easily overwritten. Fixes\n #732. PR #733.\n\nBugs:\n\n* Prevent a 'DeprecationWarning', and a 'SyntaxError' in future python, caused\n by an invalid escape sequence. PR #625.\n* Correctly report E501 when the first line of a docstring is too long.\n Resolves #622. PR #630.\n* Support variable annotation when variable start by a keyword, such as class\n variable type annotations in python 3.6. PR #640.\n* pycodestyle internals have been changed in order to allow 'python3 -m\n cProfile' to report correct metrics. PR #647.\n* Fix a spelling mistake in the description of E722. PR #697.\n* 'pycodestyle --diff' now does not break if your 'gitconfig' enables\n 'mnemonicprefix'. PR #706.\n\n2.3.1 (2017-01-31)\n------------------\n\nBugs:\n\n* Fix regression in detection of E302 and E306; #618, #620\n\n2.3.0 (2017-01-30)\n------------------\n\nNew Checks:\n\n* Add E722 warning for bare ``except`` clauses\n* Report E704 for async function definitions (``async def``)\n\nBugs:\n\n* Fix another E305 false positive for variables beginning with \"class\" or\n \"def\"\n* Fix detection of multiple spaces between ``async`` and ``def``\n* Fix handling of variable annotations. Stop reporting E701 on Python 3.6 for\n variable annotations.\n\n2.2.0 (2016-11-14)\n------------------\n\nAnnouncements:\n\n* Added Make target to obtain proper tarball file permissions; #599\n\nBugs:\n\n* Fixed E305 regression caused by #400; #593\n\n2.1.0 (2016-11-04)\n------------------\n\nAnnouncements:\n\n* Change all references to the pep8 project to say pycodestyle; #530\n\nChanges:\n\n* Report E302 for blank lines before an \"async def\"; #556\n* Update our list of tested and supported Python versions which are 2.6, 2.7,\n 3.2, 3.3, 3.4 and 3.5 as well as the nightly Python build and PyPy.\n* Report E742 and E743 for functions and classes badly named 'l', 'O', or 'I'.\n* Report E741 on 'global' and 'nonlocal' statements, as well as prohibited\n single-letter variables.\n* Deprecated use of `[pep8]` section name in favor of `[pycodestyle]`; #591\n* Report E722 when bare except clause is used; #579\n\nBugs:\n\n* Fix opt_type AssertionError when using Flake8 2.6.2 and pycodestyle; #561\n* Require two blank lines after toplevel def, class; #536\n* Remove accidentally quadratic computation based on the number of colons. This\n will make pycodestyle faster in some cases; #314\n\n2.0.0 (2016-05-31)\n------------------\n\nAnnouncements:\n\n* Repository renamed to `pycodestyle`; Issue #466 / #481.\n* Added joint Code of Conduct as member of PyCQA; #483\n\nChanges:\n\n* Added tox test support for Python 3.5 and pypy3\n* Added check E275 for whitespace on `from ... import ...` lines; #489 / #491\n* Added W503 to the list of codes ignored by default ignore list; #498\n* Removed use of project level `.pep8` configuration file; #364\n\nBugs:\n\n* Fixed bug with treating `~` operator as binary; #383 / #384\n* Identify binary operators as unary; #484 / #485\n\n1.7.0 (2016-01-12)\n------------------\n\nAnnouncements:\n\n* Repository moved to PyCQA Organization on GitHub:\n https://github.com/pycqa/pep8\n\nChanges:\n\n* Reverted the fix in #368, \"options passed on command line are only ones\n accepted\" feature. This has many unintended consequences in pep8 and flake8\n and needs to be reworked when I have more time.\n* Added support for Python 3.5. (Issue #420 & #459)\n* Added support for multi-line config_file option parsing. (Issue #429)\n* Improved parameter parsing. (Issues #420 & #456)\n\nBugs:\n\n* Fixed BytesWarning on Python 3. (Issue #459)\n\n1.6.2 (2015-02-15)\n------------------\n\nChanges:\n\n* Added check for breaking around a binary operator. (Issue #197, Pull #305)\n\nBugs:\n\n* Restored config_file parameter in process_options(). (Issue #380)\n\n\n1.6.1 (2015-02-08)\n------------------\n\nChanges:\n\n* Assign variables before referenced. (Issue #287)\n\nBugs:\n\n* Exception thrown due to unassigned ``local_dir`` variable. (Issue #377)\n\n\n1.6.0 (2015-02-06)\n------------------\n\nNews:\n\n* Ian Lee joined the project as a maintainer.\n\nChanges:\n\n* Report E731 for lambda assignment. (Issue #277)\n\n* Report E704 for one-liner def instead of E701.\n Do not report this error in the default configuration. (Issue #277)\n\n* Replace codes E111, E112 and E113 with codes E114, E115 and E116\n for bad indentation of comments. (Issue #274)\n\n* Report E266 instead of E265 when the block comment starts with\n multiple ``#``. (Issue #270)\n\n* Report E402 for import statements not at the top of the file. (Issue #264)\n\n* Do not enforce whitespaces around ``**`` operator. (Issue #292)\n\n* Strip whitespace from around paths during normalization. (Issue #339 / #343)\n\n* Update ``--format`` documentation. (Issue #198 / Pull Request #310)\n\n* Add ``.tox/`` to default excludes. (Issue #335)\n\n* Do not report E121 or E126 in the default configuration. (Issues #256 / #316)\n\n* Allow spaces around the equals sign in an annotated function. (Issue #357)\n\n* Allow trailing backslash if in an inline comment. (Issue #374)\n\n* If ``--config`` is used, only that configuration is processed. Otherwise,\n merge the user and local configurations are merged. (Issue #368 / #369)\n\nBug fixes:\n\n* Don't crash if Checker.build_tokens_line() returns None. (Issue #306)\n\n* Don't crash if os.path.expanduser() throws an ImportError. (Issue #297)\n\n* Missing space around keyword parameter equal not always reported, E251.\n (Issue #323)\n\n* Fix false positive E711/E712/E713. (Issues #330 and #336)\n\n* Do not skip physical checks if the newline is escaped. (Issue #319)\n\n* Flush sys.stdout to avoid race conditions with printing. See flake8 bug:\n https://gitlab.com/pycqa/flake8/issues/17 for more details. (Issue #363)\n\n\n1.5.7 (2014-05-29)\n------------------\n\nBug fixes:\n\n* Skip the traceback on \"Broken pipe\" signal. (Issue #275)\n\n* Do not exit when an option in ``setup.cfg`` or ``tox.ini``\n is not recognized.\n\n* Check the last line even if it does not end with a newline. (Issue #286)\n\n* Always open files in universal newlines mode in Python 2. (Issue #288)\n\n\n1.5.6 (2014-04-14)\n------------------\n\nBug fixes:\n\n* Check the last line even if it has no end-of-line. (Issue #273)\n\n\n1.5.5 (2014-04-10)\n------------------\n\nBug fixes:\n\n* Fix regression with E22 checks and inline comments. (Issue #271)\n\n\n1.5.4 (2014-04-07)\n------------------\n\nBug fixes:\n\n* Fix negative offset with E303 before a multi-line docstring.\n (Issue #269)\n\n\n1.5.3 (2014-04-04)\n------------------\n\nBug fixes:\n\n* Fix wrong offset computation when error is on the last char\n of a physical line. (Issue #268)\n\n\n1.5.2 (2014-04-04)\n------------------\n\nChanges:\n\n* Distribute a universal wheel file.\n\nBug fixes:\n\n* Report correct line number for E303 with comments. (Issue #60)\n\n* Do not allow newline after parameter equal. (Issue #252)\n\n* Fix line number reported for multi-line strings. (Issue #220)\n\n* Fix false positive E121/E126 with multi-line strings. (Issue #265)\n\n* Fix E501 not detected in comments with Python 2.5.\n\n* Fix caret position with ``--show-source`` when line contains tabs.\n\n\n1.5.1 (2014-03-27)\n------------------\n\nBug fixes:\n\n* Fix a crash with E125 on multi-line strings. (Issue #263)\n\n\n1.5 (2014-03-26)\n----------------\n\nChanges:\n\n* Report E129 instead of E125 for visually indented line with same\n indent as next logical line. (Issue #126)\n\n* Report E265 for space before block comment. (Issue #190)\n\n* Report E713 and E714 when operators ``not in`` and ``is not`` are\n recommended. (Issue #236)\n\n* Allow long lines in multiline strings and comments if they cannot\n be wrapped. (Issue #224).\n\n* Optionally disable physical line checks inside multiline strings,\n using ``# noqa``. (Issue #242)\n\n* Change text for E121 to report \"continuation line under-indented\n for hanging indent\" instead of indentation not being a\n multiple of 4.\n\n* Report E131 instead of E121 / E126 if the hanging indent is not\n consistent within the same continuation block. It helps when\n error E121 or E126 is in the ``ignore`` list.\n\n* Report E126 instead of E121 when the continuation line is hanging\n with extra indentation, even if indentation is not a multiple of 4.\n\nBug fixes:\n\n* Allow the checkers to report errors on empty files. (Issue #240)\n\n* Fix ignoring too many checks when ``--select`` is used with codes\n declared in a flake8 extension. (Issue #216)\n\n* Fix regression with multiple brackets. (Issue #214)\n\n* Fix ``StyleGuide`` to parse the local configuration if the\n keyword argument ``paths`` is specified. (Issue #246)\n\n* Fix a false positive E124 for hanging indent. (Issue #254)\n\n* Fix a false positive E126 with embedded colon. (Issue #144)\n\n* Fix a false positive E126 when indenting with tabs. (Issue #204)\n\n* Fix behaviour when ``exclude`` is in the configuration file and\n the current directory is not the project directory. (Issue #247)\n\n* The logical checks can return ``None`` instead of an empty iterator.\n (Issue #250)\n\n* Do not report multiple E101 if only the first indentation starts\n with a tab. (Issue #237)\n\n* Fix a rare false positive W602. (Issue #34)\n\n\n1.4.6 (2013-07-02)\n------------------\n\nChanges:\n\n* Honor ``# noqa`` for errors E711 and E712. (Issue #180)\n\n* When both a ``tox.ini`` and a ``setup.cfg`` are present in the project\n directory, merge their contents. The ``tox.ini`` file takes\n precedence (same as before). (Issue #182)\n\n* Give priority to ``--select`` over ``--ignore``. (Issue #188)\n\n* Compare full path when excluding a file. (Issue #186)\n\n* New option ``--hang-closing`` to switch to the alternative style of\n closing bracket indentation for hanging indent. Add error E133 for\n closing bracket which is missing indentation. (Issue #103)\n\n* Accept both styles of closing bracket indentation for hanging indent.\n Do not report error E123 in the default configuration. (Issue #103)\n\nBug fixes:\n\n* Do not crash when running AST checks and the document contains null bytes.\n (Issue #184)\n\n* Correctly report other E12 errors when E123 is ignored. (Issue #103)\n\n* Fix false positive E261/E262 when the file contains a BOM. (Issue #193)\n\n* Fix E701, E702 and E703 not detected sometimes. (Issue #196)\n\n* Fix E122 not detected in some cases. (Issue #201 and #208)\n\n* Fix false positive E121 with multiple brackets. (Issue #203)\n\n\n1.4.5 (2013-03-06)\n------------------\n\n* When no path is specified, do not try to read from stdin. The feature\n was added in 1.4.3, but it is not supported on Windows. Use ``-``\n filename argument to read from stdin. This usage is supported\n since 1.3.4. (Issue #170)\n\n* Do not require ``setuptools`` in setup.py. It works around an issue\n with ``pip`` and Python 3. (Issue #172)\n\n* Add ``__pycache__`` to the ignore list.\n\n* Change misleading message for E251. (Issue #171)\n\n* Do not report false E302 when the source file has a coding cookie or a\n comment on the first line. (Issue #174)\n\n* Reorganize the tests and add tests for the API and for the command line\n usage and options. (Issues #161 and #162)\n\n* Ignore all checks which are not explicitly selected when ``select`` is\n passed to the ``StyleGuide`` constructor.\n\n\n1.4.4 (2013-02-24)\n------------------\n\n* Report E227 or E228 instead of E225 for whitespace around bitwise, shift\n or modulo operators. (Issue #166)\n\n* Change the message for E226 to make clear that it is about arithmetic\n operators.\n\n* Fix a false positive E128 for continuation line indentation with tabs.\n\n* Fix regression with the ``--diff`` option. (Issue #169)\n\n* Fix the ``TestReport`` class to print the unexpected warnings and\n errors.\n\n\n1.4.3 (2013-02-22)\n------------------\n\n* Hide the ``--doctest`` and ``--testsuite`` options when installed.\n\n* Fix crash with AST checkers when the syntax is invalid. (Issue #160)\n\n* Read from standard input if no path is specified.\n\n* Initiate a graceful shutdown on ``Control+C``.\n\n* Allow changing the ``checker_class`` for the ``StyleGuide``.\n\n\n1.4.2 (2013-02-10)\n------------------\n\n* Support AST checkers provided by third-party applications.\n\n* Register new checkers with ``register_check(func_or_cls, codes)``.\n\n* Allow constructing a ``StyleGuide`` with a custom parser.\n\n* Accept visual indentation without parenthesis after the ``if``\n statement. (Issue #151)\n\n* Fix UnboundLocalError when using ``# noqa`` with continued lines.\n (Issue #158)\n\n* Re-order the lines for the ``StandardReport``.\n\n* Expand tabs when checking E12 continuation lines. (Issue #155)\n\n* Refactor the testing class ``TestReport`` and the specific test\n functions into a separate test module.\n\n\n1.4.1 (2013-01-18)\n------------------\n\n* Allow sphinx.ext.autodoc syntax for comments. (Issue #110)\n\n* Report E703 instead of E702 for the trailing semicolon. (Issue #117)\n\n* Honor ``# noqa`` in addition to ``# nopep8``. (Issue #149)\n\n* Expose the ``OptionParser`` factory for better extensibility.\n\n\n1.4 (2012-12-22)\n----------------\n\n* Report E226 instead of E225 for optional whitespace around common\n operators (``*``, ``**``, ``/``, ``+`` and ``-``). This new error\n code is ignored in the default configuration because PEP 8 recommends\n to \"use your own judgement\". (Issue #96)\n\n* Lines with a ``# nopep8`` at the end will not issue errors on line\n length E501 or continuation line indentation E12*. (Issue #27)\n\n* Fix AssertionError when the source file contains an invalid line\n ending ``\"\\r\\r\\n\"``. (Issue #119)\n\n* Read the ``[pep8]`` section of ``tox.ini`` or ``setup.cfg`` if present.\n (Issue #93 and #141)\n\n* Add the Sphinx-based documentation, and publish it\n on https://pycodestyle.readthedocs.io/. (Issue #105)\n\n\n1.3.4 (2012-12-18)\n------------------\n\n* Fix false positive E124 and E128 with comments. (Issue #100)\n\n* Fix error on stdin when running with bpython. (Issue #101)\n\n* Fix false positive E401. (Issue #104)\n\n* Report E231 for nested dictionary in list. (Issue #142)\n\n* Catch E271 at the beginning of the line. (Issue #133)\n\n* Fix false positive E126 for multi-line comments. (Issue #138)\n\n* Fix false positive E221 when operator is preceded by a comma. (Issue #135)\n\n* Fix ``--diff`` failing on one-line hunk. (Issue #137)\n\n* Fix the ``--exclude`` switch for directory paths. (Issue #111)\n\n* Use ``-`` filename to read from standard input. (Issue #128)\n\n\n1.3.3 (2012-06-27)\n------------------\n\n* Fix regression with continuation line checker. (Issue #98)\n\n\n1.3.2 (2012-06-26)\n------------------\n\n* Revert to the previous behaviour for ``--show-pep8``:\n do not imply ``--first``. (Issue #89)\n\n* Add E902 for IO errors. (Issue #87)\n\n* Fix false positive for E121, and missed E124. (Issue #92)\n\n* Set a sensible default path for config file on Windows. (Issue #95)\n\n* Allow ``verbose`` in the configuration file. (Issue #91)\n\n* Show the enforced ``max-line-length`` in the error message. (Issue #86)\n\n\n1.3.1 (2012-06-18)\n------------------\n\n* Explain which configuration options are expected. Accept and recommend\n the options names with hyphen instead of underscore. (Issue #82)\n\n* Do not read the user configuration when used as a module\n (except if ``config_file=True`` is passed to the ``StyleGuide`` constructor).\n\n* Fix wrong or missing cases for the E12 series.\n\n* Fix cases where E122 was missed. (Issue #81)\n\n\n1.3 (2012-06-15)\n----------------\n\n.. warning::\n The internal API is backwards incompatible.\n\n* Remove global configuration and refactor the library around\n a ``StyleGuide`` class; add the ability to configure various\n reporters. (Issue #35 and #66)\n\n* Read user configuration from ``~/.config/pep8``\n and local configuration from ``./.pep8``. (Issue #22)\n\n* Fix E502 for backslash embedded in multi-line string. (Issue #68)\n\n* Fix E225 for Python 3 iterable unpacking (PEP 3132). (Issue #72)\n\n* Enable the new checkers from the E12 series in the default\n configuration.\n\n* Suggest less error-prone alternatives for E712 errors.\n\n* Rewrite checkers to run faster (E22, E251, E27).\n\n* Fixed a crash when parsed code is invalid (too many\n closing brackets).\n\n* Fix E127 and E128 for continuation line indentation. (Issue #74)\n\n* New option ``--format`` to customize the error format. (Issue #23)\n\n* New option ``--diff`` to check only modified code. The unified\n diff is read from STDIN. Example: ``hg diff | pep8 --diff``\n (Issue #39)\n\n* Correctly report the count of failures and set the exit code to 1\n when the ``--doctest`` or the ``--testsuite`` fails.\n\n* Correctly detect the encoding in Python 3. (Issue #69)\n\n* Drop support for Python 2.3, 2.4 and 3.0. (Issue #78)\n\n\n1.2 (2012-06-01)\n----------------\n\n* Add E121 through E128 for continuation line indentation. These\n checks are disabled by default. If you want to force all checks,\n use switch ``--select=E,W``. Patch by Sam Vilain. (Issue #64)\n\n* Add E721 for direct type comparisons. (Issue #47)\n\n* Add E711 and E712 for comparisons to singletons. (Issue #46)\n\n* Fix spurious E225 and E701 for function annotations. (Issue #29)\n\n* Add E502 for explicit line join between brackets.\n\n* Fix E901 when printing source with ``--show-source``.\n\n* Report all errors for each checker, instead of reporting only the\n first occurrence for each line.\n\n* Option ``--show-pep8`` implies ``--first``.\n\n\n1.1 (2012-05-24)\n----------------\n\n* Add E901 for syntax errors. (Issues #63 and #30)\n\n* Add E271, E272, E273 and E274 for extraneous whitespace around\n keywords. (Issue #57)\n\n* Add ``tox.ini`` configuration file for tests. (Issue #61)\n\n* Add ``.travis.yml`` configuration file for continuous integration.\n (Issue #62)\n\n\n1.0.1 (2012-04-06)\n------------------\n\n* Fix inconsistent version numbers.\n\n\n1.0 (2012-04-04)\n----------------\n\n* Fix W602 ``raise`` to handle multi-char names. (Issue #53)\n\n\n0.7.0 (2012-03-26)\n------------------\n\n* Now ``--first`` prints only the first occurrence of each error.\n The ``--repeat`` flag becomes obsolete because it is the default\n behaviour. (Issue #6)\n\n* Allow specifying ``--max-line-length``. (Issue #36)\n\n* Make the shebang more flexible. (Issue #26)\n\n* Add testsuite to the bundle. (Issue #25)\n\n* Fixes for Jython. (Issue #49)\n\n* Add PyPI classifiers. (Issue #43)\n\n* Fix the ``--exclude`` option. (Issue #48)\n\n* Fix W602, accept ``raise`` with 3 arguments. (Issue #34)\n\n* Correctly select all tests if ``DEFAULT_IGNORE == ''``.\n\n\n0.6.1 (2010-10-03)\n------------------\n\n* Fix inconsistent version numbers. (Issue #21)\n\n\n0.6.0 (2010-09-19)\n------------------\n\n* Test suite reorganized and enhanced in order to check more failures\n with fewer test files. Read the ``run_tests`` docstring for details\n about the syntax.\n\n* Fix E225: accept ``print >>sys.stderr, \"...\"`` syntax.\n\n* Fix E501 for lines containing multibyte encoded characters. (Issue #7)\n\n* Fix E221, E222, E223, E224 not detected in some cases. (Issue #16)\n\n* Fix E211 to reject ``v = dic['a'] ['b']``. (Issue #17)\n\n* Exit code is always 1 if any error or warning is found. (Issue #10)\n\n* ``--ignore`` checks are now really ignored, especially in\n conjunction with ``--count``. (Issue #8)\n\n* Blank lines with spaces yield W293 instead of W291: some developers\n want to ignore this warning and indent the blank lines to paste their\n code easily in the Python interpreter.\n\n* Fix E301: do not require a blank line before an indented block. (Issue #14)\n\n* Fix E203 to accept NumPy slice notation ``a[0, :]``. (Issue #13)\n\n* Performance improvements.\n\n* Fix decoding and checking non-UTF8 files in Python 3.\n\n* Fix E225: reject ``True+False`` when running on Python 3.\n\n* Fix an exception when the line starts with an operator.\n\n* Allow a new line before closing ``)``, ``}`` or ``]``. (Issue #5)\n\n\n0.5.0 (2010-02-17)\n------------------\n\n* Changed the ``--count`` switch to print to sys.stderr and set\n exit code to 1 if any error or warning is found.\n\n* E241 and E242 are removed from the standard checks. If you want to\n include these checks, use switch ``--select=E,W``. (Issue #4)\n\n* Blank line is not mandatory before the first class method or nested\n function definition, even if there's a docstring. (Issue #1)\n\n* Add the switch ``--version``.\n\n* Fix decoding errors with Python 3. (Issue #13 [1]_)\n\n* Add ``--select`` option which is mirror of ``--ignore``.\n\n* Add checks E261 and E262 for spaces before inline comments.\n\n* New check W604 warns about deprecated usage of backticks.\n\n* New check W603 warns about the deprecated operator ``<>``.\n\n* Performance improvement, due to rewriting of E225.\n\n* E225 now accepts:\n\n - no whitespace after unary operator or similar. (Issue #9 [1]_)\n\n - lambda function with argument unpacking or keyword defaults.\n\n* Reserve \"2 blank lines\" for module-level logical blocks. (E303)\n\n* Allow multi-line comments. (E302, issue #10 [1]_)\n\n\n0.4.2 (2009-10-22)\n------------------\n\n* Decorators on classes and class methods are OK now.\n\n\n0.4 (2009-10-20)\n----------------\n\n* Support for all versions of Python from 2.3 to 3.1.\n\n* New and greatly expanded self tests.\n\n* Added ``--count`` option to print the total number of errors and warnings.\n\n* Further improvements to the handling of comments and blank lines.\n (Issue #1 [1]_ and others changes.)\n\n* Check all py files in directory when passed a directory (Issue\n #2 [1]_). This also prevents an exception when traversing directories\n with non ``*.py`` files.\n\n* E231 should allow commas to be followed by ``)``. (Issue #3 [1]_)\n\n* Spaces are no longer required around the equals sign for keyword\n arguments or default parameter values.\n\n\n.. [1] These issues refer to the `previous issue tracker`__.\n.. __: http://github.com/cburroughs/pep8.py/issues\n\n\n0.3.1 (2009-09-14)\n------------------\n\n* Fixes for comments: do not count them when checking for blank lines between\n items.\n\n* Added setup.py for pypi upload and easy_installability.\n\n\n0.2 (2007-10-16)\n----------------\n\n* Loads of fixes and improvements.\n\n\n0.1 (2006-10-01)\n----------------\n\n* First release.", + "release_date": "2021-10-11T00:56:25", "parties": [ { "type": "person", "role": "author", - "name": "The Python Packaging Authority", - "email": "admin@mail.pypi.org", + "name": "Johann C. Rocholl", + "email": "johann@rocholl.net", + "url": null + }, + { + "type": "person", + "role": "maintainer", + "name": "Ian Lee", + "email": "IanLee1521@gmail.com", "url": null } ], "keywords": [ + "pycodestyle", + "pep8", + "PEP 8", + "PEP-8", + "PEP8", + "Development Status :: 5 - Production/Stable", + "Environment :: Console", "Intended Audience :: Developers", - "Natural Language :: English", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Operating System :: POSIX :: BSD", - "Operating System :: POSIX :: Linux", + "Operating System :: OS Independent", "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy" + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Libraries :: Python Modules" ], - "homepage_url": "https://github.com/pypa/readme_renderer", - "download_url": "https://files.pythonhosted.org/packages/52/c5/6c090aad067a6f05681367fc33ab2c8d571a3739405bec60f7ba486e83de/readme_renderer-34.0.tar.gz", - "size": 28835, + "homepage_url": "https://pycodestyle.pycqa.org/", + "download_url": "https://files.pythonhosted.org/packages/15/94/bc43a2efb7b8615e38acde2b6624cae8c9ec86faf718ff5676c5179a7714/pycodestyle-2.8.0-py2.py3-none-any.whl", + "size": 42112, "sha1": null, - "md5": "a7e83bdafe0e71b6d4786566de7430fd", - "sha256": "dfb4d17f21706d145f7473e0b61ca245ba58e810cf9b2209a48239677f82e5b0", + "md5": "35e8cff40ae075579da219f9ac2bcb75", + "sha256": "720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -8059,9 +4298,9 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "Apache License, Version 2.0", + "license": "Expat license", "classifiers": [ - "License :: OSI Approved :: Apache Software License" + "License :: OSI Approved :: MIT License" ] }, "notice_text": null, @@ -8071,47 +4310,48 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/readme-renderer/34.0/json", + "api_data_url": "https://pypi.org/pypi/pycodestyle/2.8.0/json", "datasource_id": null, - "purl": "pkg:pypi/readme-renderer@34.0" + "purl": "pkg:pypi/pycodestyle@2.8.0" }, { "type": "pypi", "namespace": null, - "name": "requests-toolbelt", - "version": "0.9.1", + "name": "pycparser", + "version": "2.21", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "A utility belt for advanced users of python-requests\nThe Requests Toolbelt\n=====================\n\nThis is just a collection of utilities for `python-requests`_, but don't \nreally belong in ``requests`` proper. The minimum tested requests version is \n``2.1.0``. In reality, the toolbelt should work with ``2.0.1`` as well, but \nsome idiosyncracies prevent effective or sane testing on that version.\n\n``pip install requests-toolbelt`` to get started!\n\n\nmultipart/form-data Encoder\n---------------------------\n\nThe main attraction is a streaming multipart form-data object, ``MultipartEncoder``.\nIts API looks like this:\n\n.. code-block:: python\n\n from requests_toolbelt import MultipartEncoder\n import requests\n\n m = MultipartEncoder(\n fields={'field0': 'value', 'field1': 'value',\n 'field2': ('filename', open('file.py', 'rb'), 'text/plain')}\n )\n\n r = requests.post('http://httpbin.org/post', data=m,\n headers={'Content-Type': m.content_type})\n\n\nYou can also use ``multipart/form-data`` encoding for requests that don't\nrequire files:\n\n.. code-block:: python\n\n from requests_toolbelt import MultipartEncoder\n import requests\n\n m = MultipartEncoder(fields={'field0': 'value', 'field1': 'value'})\n\n r = requests.post('http://httpbin.org/post', data=m,\n headers={'Content-Type': m.content_type})\n\n\nOr, you can just create the string and examine the data:\n\n.. code-block:: python\n\n # Assuming `m` is one of the above\n m.to_string() # Always returns unicode\n\n\nUser-Agent constructor\n----------------------\n\nYou can easily construct a requests-style ``User-Agent`` string::\n\n from requests_toolbelt import user_agent\n\n headers = {\n 'User-Agent': user_agent('my_package', '0.0.1')\n }\n\n r = requests.get('https://api.github.com/users', headers=headers)\n\n\nSSLAdapter\n----------\n\nThe ``SSLAdapter`` was originally published on `Cory Benfield's blog`_. \nThis adapter allows the user to choose one of the SSL protocols made available \nin Python's ``ssl`` module for outgoing HTTPS connections:\n\n.. code-block:: python\n\n from requests_toolbelt import SSLAdapter\n import requests\n import ssl\n\n s = requests.Session()\n s.mount('https://', SSLAdapter(ssl.PROTOCOL_TLSv1))\n\ncookies/ForgetfulCookieJar\n--------------------------\n\nThe ``ForgetfulCookieJar`` prevents a particular requests session from storing \ncookies:\n\n.. code-block:: python\n\n from requests_toolbelt.cookies.forgetful import ForgetfulCookieJar\n\n session = requests.Session()\n session.cookies = ForgetfulCookieJar()\n\nKnown Issues\n------------\n\nOn Python 3.3.0 and 3.3.1, the standard library's ``http`` module will fail\nwhen passing an instance of the ``MultipartEncoder``. This is fixed in later\nminor releases of Python 3.3. Please consider upgrading to a later minor\nversion or Python 3.4. *There is absolutely nothing this library can do to\nwork around that bug.*\n\nContributing\n------------\n\nPlease read the `suggested workflow\n`_ for\ncontributing to this project.\n\nPlease report any bugs on the `issue tracker`_\n\n.. _Cory Benfield's blog: https://lukasa.co.uk/2013/01/Choosing_SSL_Version_In_Requests/\n.. _python-requests: https://github.com/kennethreitz/requests\n.. _issue tracker: https://github.com/requests/toolbelt/issues\n\n\nHistory\n=======\n\n0.9.1 -- 2019-01-29\n-------------------\n\nFixed Bugs\n~~~~~~~~~~\n\n- Fix import of pyOpenSSL shim from urllib3 for PKCS12 adapter\n\n0.9.0 -- 2019-01-29\n-------------------\n\nNew Features\n~~~~~~~~~~~~\n\n- Add X509 Adapter that can handle PKCS12 \n- Add stateless solution for streaming files by MultipartEncoder from one host to another (in chunks)\n\nFixed Bugs\n~~~~~~~~~~\n\n- Update link to example\n- Move import of ``ABCs`` from collections into version-specific part of\n _compat module\n- Fix backwards incompatibility in ``get_encodings_from_content``\n- Correct callback documentation for ``MultipartEncoderMonitor``\n- Fix bug when ``MultipartEncoder`` is asked to encode zero parts\n- Correct the type of non string request body dumps\n- Removed content from being stored in MultipartDecoder\n- Fix bug by enabling support for contenttype with capital letters. \n- Coerce proxy URL to bytes before dumping request\n- Avoid bailing out with exception upon empty response reason\n- Corrected Pool documentation\n- Corrected parentheses match in example usage\n- Fix \"oject\" to \"object\" in ``MultipartEncoder``\n- Fix URL for the project after the move \n- Add fix for OSX TCPKeepAliveAdapter\n\nMiscellaneous\n~~~~~~~~~~~~~\n\n- Remove py33 from testing and add Python 3.6 and nightly testing to the travis matrix.\n\n0.8.0 -- 2017-05-20\n-------------------\n\nMore information about this release can be found on the `0.8.0 milestone`_.\n\nNew Features\n~~~~~~~~~~~~\n\n- Add ``UserAgentBuilder`` to provide more control over generated User-Agent\n strings.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Include ``_validate_certificate`` in the lits of picked attributes on the\n ``AppEngineAdapter``.\n- Fix backwards incompatibility in ``get_encodings_from_content``\n\n.. _0.8.0 milestone:\n https://github.com/requests/toolbelt/milestones/0.8.0\n\n0.7.1 -- 2017-02-13\n-------------------\n\nMore information about this release can be found on the `0.7.1 milestone`_.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Fixed monkey-patching for the AppEngineAdapter.\n\n- Make it easier to disable certificate verification when monkey-patching\n AppEngine.\n\n- Handle ``multipart/form-data`` bodies without a trailing ``CRLF``.\n\n\n.. links\n.. _0.7.1 milestone:\n https://github.com/requests/toolbelt/milestone/9\n\n0.7.0 -- 2016-07-21\n-------------------\n\nMore information about this release can be found on the `0.7.0 milestone`_.\n\nNew Features\n~~~~~~~~~~~~\n\n- Add ``BaseUrlSession`` to allow developers to have a session that has a\n \"Base\" URL. See the documentation for more details and examples.\n\n- Split the logic of ``stream_response_to_file`` into two separate functions:\n\n * ``get_download_file_path`` to generate the file name from the Response.\n\n * ``stream_response_to_file`` which will use ``get_download_file_path`` if\n necessary\n\nFixed Bugs\n~~~~~~~~~~\n\n- Fixed the issue for people using *very* old versions of Requests where they\n would see an ImportError from ``requests_toolbelt._compat`` when trying to\n import ``connection``.\n\n\n.. _0.7.0 milestone:\n https://github.com/requests/toolbelt/milestones/0.7.0\n\n0.6.2 -- 2016-05-10\n-------------------\n\nFixed Bugs\n~~~~~~~~~~\n\n- When passing a timeout via Requests, it was not appropriately translated to\n the timeout that the urllib3 code was expecting.\n\n0.6.1 -- 2016-05-05\n-------------------\n\nFixed Bugs\n~~~~~~~~~~\n\n- Remove assertion about request URLs in the AppEngineAdapter.\n\n- Prevent pip from installing requests 3.0.0 when that is released until we\n are ready to handle it.\n\n0.6.0 -- 2016-01-27\n-------------------\n\nMore information about this release can be found on the `0.6.0 milestone`_.\n\nNew Features\n~~~~~~~~~~~~\n\n- Add ``AppEngineAdapter`` to support developers using Google's AppEngine\n platform with Requests.\n\n- Add ``GuessProxyAuth`` class to support guessing between Basic and Digest\n Authentication for proxies.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Ensure that proxies use the correct TLS version when using the\n ``SSLAdapter``.\n\n- Fix an ``AttributeError`` when using the ``HTTPProxyDigestAuth`` class.\n\nMiscellaneous\n~~~~~~~~~~~~~\n\n- Drop testing support for Python 3.2. virtualenv and pip have stopped\n supporting it meaning that it is harder to test for this with our CI\n infrastructure. Moving forward we will make a best-effort attempt to\n support 3.2 but will not test for it.\n\n\n.. _0.6.0 milestone:\n https://github.com/requests/toolbelt/milestones/0.6.0\n\n0.5.1 -- 2015-12-16\n-------------------\n\nMore information about this release can be found on the `0.5.1 milestone`_.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Now papers over the differences in requests' ``super_len`` function from\n versions prior to 2.9.0 and versions 2.9.0 and later.\n\n\n.. _0.5.1 milestone:\n https://github.com/requests/toolbelt/milestones/0.5.1\n\n0.5.0 -- 2015-11-24\n-------------------\n\nMore information about this release can be found on the `milestone\n`_\nfor 0.5.0.\n\nNew Features\n~~~~~~~~~~~~\n\n- The ``tee`` submodule was added to ``requests_toolbelt.downloadutils``. It\n allows you to iterate over the bytes of a response while also writing them\n to a file. The ``tee.tee`` function, expects you to pass an open file\n object, while ``tee.tee_to_file`` will use the provided file name to open\n the file for you.\n\n- Added a new parameter to ``requests_toolbelt.utils.user_agent`` that allows\n the user to specify additional items.\n\n- Added nested form-data helper,\n ``requests_toolbelt.utils.formdata.urlencode``.\n\n- Added the ``ForgetfulCookieJar`` to ``requests_toolbelt.cookies``.\n\n- Added utilities for dumping the information about a request-response cycle\n in ``requests_toolbelt.utils.dump``.\n\n- Implemented the API described in the ``requests_toolbelt.threaded`` module\n docstring, i.e., added ``requests_toolbelt.threaded.map`` as an available\n function.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Now papers over the API differences in versions of requests installed from\n system packages versus versions of requests installed from PyPI.\n\n- Allow string types for ``SourceAddressAdapter``.\n\n0.4.0 -- 2015-04-03\n-------------------\n\nFor more information about this release, please see `milestone 0.4.0\n`_\non the project's page.\n\nNew Features\n~~~~~~~~~~~~\n\n- A naive implemenation of a thread pool is now included in the toolbelt. See\n the docs in ``docs/threading.rst`` or on `Read The Docs\n `_.\n\n- The ``StreamingIterator`` now accepts files (such as ``sys.stdin``) without\n a specific length and will properly stream them.\n\n- The ``MultipartEncoder`` now accepts exactly the same format of fields as\n requests' ``files`` parameter does. In other words, you can now also pass in\n extra headers to add to a part in the body. You can also now specify a\n custom ``Content-Type`` for a part.\n\n- An implementation of HTTP Digest Authentication for Proxies is now included.\n\n- A transport adapter that allows a user to specify a specific Certificate\n Fingerprint is now included in the toolbelt.\n\n- A transport adapter that simplifies how users specify socket options is now\n included.\n\n- A transport adapter that simplifies how users can specify TCP Keep-Alive\n options is now included in the toolbelt.\n\n- Deprecated functions from ``requests.utils`` are now included and\n maintained.\n\n- An authentication tool that allows users to specify how to authenticate to\n several different domains at once is now included.\n\n- A function to save streamed responses to disk by analyzing the\n ``Content-Disposition`` header is now included in the toolbelt.\n\nFixed Bugs\n~~~~~~~~~~\n\n- The ``MultipartEncoder`` will now allow users to upload files larger than\n 4GB on 32-bit systems.\n\n- The ``MultipartEncoder`` will now accept empty unicode strings for form\n values.\n\n0.3.1 -- 2014-06-23\n-------------------\n\n- Fix the fact that 0.3.0 bundle did not include the ``StreamingIterator``\n\n0.3.0 -- 2014-05-21\n-------------------\n\nBug Fixes\n~~~~~~~~~\n\n- Complete rewrite of ``MultipartEncoder`` fixes bug where bytes were lost in\n uploads\n\nNew Features\n~~~~~~~~~~~~\n\n- ``MultipartDecoder`` to accept ``multipart/form-data`` response bodies and\n parse them into an easy to use object.\n\n- ``SourceAddressAdapter`` to allow users to choose a local address to bind\n connections to.\n\n- ``GuessAuth`` which accepts a username and password and uses the\n ``WWW-Authenticate`` header to determine how to authenticate against a\n server.\n\n- ``MultipartEncoderMonitor`` wraps an instance of the ``MultipartEncoder``\n and keeps track of how many bytes were read and will call the provided\n callback.\n\n- ``StreamingIterator`` will wrap an iterator and stream the upload instead of\n chunk it, provided you also provide the length of the content you wish to\n upload.\n\n0.2.0 -- 2014-02-24\n-------------------\n\n- Add ability to tell ``MultipartEncoder`` which encoding to use. By default\n it uses 'utf-8'.\n\n- Fix #10 - allow users to install with pip\n\n- Fix #9 - Fix ``MultipartEncoder#to_string`` so that it properly handles file\n objects as fields\n\n0.1.2 -- 2014-01-19\n-------------------\n\n- At some point during development we broke how we handle normal file objects.\n Thanks to @konomae this is now fixed.\n\n0.1.1 -- 2014-01-19\n-------------------\n\n- Handle ``io.BytesIO``-like objects better\n\n0.1.0 -- 2014-01-18\n-------------------\n\n- Add initial implementation of the streaming ``MultipartEncoder``\n\n- Add initial implementation of the ``user_agent`` function\n\n- Add the ``SSLAdapter``", - "release_date": "2019-01-30T01:29:52", + "description": "C parser in Python\npycparser is a complete parser of the C language, written in\npure Python using the PLY parsing library.\nIt parses C code into an AST and can serve as a front-end for\nC compilers or analysis tools.", + "release_date": "2021-11-06T12:50:13", "parties": [ { "type": "person", "role": "author", - "name": "Ian Cordasco, Cory Benfield", - "email": "graffatcolmingov@gmail.com", + "name": "Eli Bendersky", + "email": "eliben@gmail.com", "url": null } ], "keywords": [ "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "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.10", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: Implementation :: CPython" + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9" ], - "homepage_url": "https://toolbelt.readthedocs.org", - "download_url": "https://files.pythonhosted.org/packages/60/ef/7681134338fc097acef8d9b2f8abe0458e4d87559c689a8c306d0957ece5/requests_toolbelt-0.9.1-py2.py3-none-any.whl", - "size": 54314, + "homepage_url": "https://github.com/eliben/pycparser", + "download_url": "https://files.pythonhosted.org/packages/62/d5/5f610ebe421e85889f2e55e33b7f9a6795bd982198517d912eb1c76e1a53/pycparser-2.21-py2.py3-none-any.whl", + "size": 118697, "sha1": null, - "md5": "f3c670220285a4cf8c5cbf1033090461", - "sha256": "380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f", + "md5": "763d265dfc20860dfbb4c81458400d03", + "sha256": "8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -8119,9 +4359,9 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "Apache 2.0", + "license": "BSD", "classifiers": [ - "License :: OSI Approved :: Apache Software License" + "License :: OSI Approved :: BSD License" ] }, "notice_text": null, @@ -8131,57 +4371,64 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/requests-toolbelt/0.9.1/json", + "api_data_url": "https://pypi.org/pypi/pycparser/2.21/json", "datasource_id": null, - "purl": "pkg:pypi/requests-toolbelt@0.9.1" + "purl": "pkg:pypi/pycparser@2.21" }, { "type": "pypi", "namespace": null, - "name": "requests-toolbelt", - "version": "0.9.1", + "name": "pygments", + "version": "2.12.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "A utility belt for advanced users of python-requests\nThe Requests Toolbelt\n=====================\n\nThis is just a collection of utilities for `python-requests`_, but don't \nreally belong in ``requests`` proper. The minimum tested requests version is \n``2.1.0``. In reality, the toolbelt should work with ``2.0.1`` as well, but \nsome idiosyncracies prevent effective or sane testing on that version.\n\n``pip install requests-toolbelt`` to get started!\n\n\nmultipart/form-data Encoder\n---------------------------\n\nThe main attraction is a streaming multipart form-data object, ``MultipartEncoder``.\nIts API looks like this:\n\n.. code-block:: python\n\n from requests_toolbelt import MultipartEncoder\n import requests\n\n m = MultipartEncoder(\n fields={'field0': 'value', 'field1': 'value',\n 'field2': ('filename', open('file.py', 'rb'), 'text/plain')}\n )\n\n r = requests.post('http://httpbin.org/post', data=m,\n headers={'Content-Type': m.content_type})\n\n\nYou can also use ``multipart/form-data`` encoding for requests that don't\nrequire files:\n\n.. code-block:: python\n\n from requests_toolbelt import MultipartEncoder\n import requests\n\n m = MultipartEncoder(fields={'field0': 'value', 'field1': 'value'})\n\n r = requests.post('http://httpbin.org/post', data=m,\n headers={'Content-Type': m.content_type})\n\n\nOr, you can just create the string and examine the data:\n\n.. code-block:: python\n\n # Assuming `m` is one of the above\n m.to_string() # Always returns unicode\n\n\nUser-Agent constructor\n----------------------\n\nYou can easily construct a requests-style ``User-Agent`` string::\n\n from requests_toolbelt import user_agent\n\n headers = {\n 'User-Agent': user_agent('my_package', '0.0.1')\n }\n\n r = requests.get('https://api.github.com/users', headers=headers)\n\n\nSSLAdapter\n----------\n\nThe ``SSLAdapter`` was originally published on `Cory Benfield's blog`_. \nThis adapter allows the user to choose one of the SSL protocols made available \nin Python's ``ssl`` module for outgoing HTTPS connections:\n\n.. code-block:: python\n\n from requests_toolbelt import SSLAdapter\n import requests\n import ssl\n\n s = requests.Session()\n s.mount('https://', SSLAdapter(ssl.PROTOCOL_TLSv1))\n\ncookies/ForgetfulCookieJar\n--------------------------\n\nThe ``ForgetfulCookieJar`` prevents a particular requests session from storing \ncookies:\n\n.. code-block:: python\n\n from requests_toolbelt.cookies.forgetful import ForgetfulCookieJar\n\n session = requests.Session()\n session.cookies = ForgetfulCookieJar()\n\nKnown Issues\n------------\n\nOn Python 3.3.0 and 3.3.1, the standard library's ``http`` module will fail\nwhen passing an instance of the ``MultipartEncoder``. This is fixed in later\nminor releases of Python 3.3. Please consider upgrading to a later minor\nversion or Python 3.4. *There is absolutely nothing this library can do to\nwork around that bug.*\n\nContributing\n------------\n\nPlease read the `suggested workflow\n`_ for\ncontributing to this project.\n\nPlease report any bugs on the `issue tracker`_\n\n.. _Cory Benfield's blog: https://lukasa.co.uk/2013/01/Choosing_SSL_Version_In_Requests/\n.. _python-requests: https://github.com/kennethreitz/requests\n.. _issue tracker: https://github.com/requests/toolbelt/issues\n\n\nHistory\n=======\n\n0.9.1 -- 2019-01-29\n-------------------\n\nFixed Bugs\n~~~~~~~~~~\n\n- Fix import of pyOpenSSL shim from urllib3 for PKCS12 adapter\n\n0.9.0 -- 2019-01-29\n-------------------\n\nNew Features\n~~~~~~~~~~~~\n\n- Add X509 Adapter that can handle PKCS12 \n- Add stateless solution for streaming files by MultipartEncoder from one host to another (in chunks)\n\nFixed Bugs\n~~~~~~~~~~\n\n- Update link to example\n- Move import of ``ABCs`` from collections into version-specific part of\n _compat module\n- Fix backwards incompatibility in ``get_encodings_from_content``\n- Correct callback documentation for ``MultipartEncoderMonitor``\n- Fix bug when ``MultipartEncoder`` is asked to encode zero parts\n- Correct the type of non string request body dumps\n- Removed content from being stored in MultipartDecoder\n- Fix bug by enabling support for contenttype with capital letters. \n- Coerce proxy URL to bytes before dumping request\n- Avoid bailing out with exception upon empty response reason\n- Corrected Pool documentation\n- Corrected parentheses match in example usage\n- Fix \"oject\" to \"object\" in ``MultipartEncoder``\n- Fix URL for the project after the move \n- Add fix for OSX TCPKeepAliveAdapter\n\nMiscellaneous\n~~~~~~~~~~~~~\n\n- Remove py33 from testing and add Python 3.6 and nightly testing to the travis matrix.\n\n0.8.0 -- 2017-05-20\n-------------------\n\nMore information about this release can be found on the `0.8.0 milestone`_.\n\nNew Features\n~~~~~~~~~~~~\n\n- Add ``UserAgentBuilder`` to provide more control over generated User-Agent\n strings.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Include ``_validate_certificate`` in the lits of picked attributes on the\n ``AppEngineAdapter``.\n- Fix backwards incompatibility in ``get_encodings_from_content``\n\n.. _0.8.0 milestone:\n https://github.com/requests/toolbelt/milestones/0.8.0\n\n0.7.1 -- 2017-02-13\n-------------------\n\nMore information about this release can be found on the `0.7.1 milestone`_.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Fixed monkey-patching for the AppEngineAdapter.\n\n- Make it easier to disable certificate verification when monkey-patching\n AppEngine.\n\n- Handle ``multipart/form-data`` bodies without a trailing ``CRLF``.\n\n\n.. links\n.. _0.7.1 milestone:\n https://github.com/requests/toolbelt/milestone/9\n\n0.7.0 -- 2016-07-21\n-------------------\n\nMore information about this release can be found on the `0.7.0 milestone`_.\n\nNew Features\n~~~~~~~~~~~~\n\n- Add ``BaseUrlSession`` to allow developers to have a session that has a\n \"Base\" URL. See the documentation for more details and examples.\n\n- Split the logic of ``stream_response_to_file`` into two separate functions:\n\n * ``get_download_file_path`` to generate the file name from the Response.\n\n * ``stream_response_to_file`` which will use ``get_download_file_path`` if\n necessary\n\nFixed Bugs\n~~~~~~~~~~\n\n- Fixed the issue for people using *very* old versions of Requests where they\n would see an ImportError from ``requests_toolbelt._compat`` when trying to\n import ``connection``.\n\n\n.. _0.7.0 milestone:\n https://github.com/requests/toolbelt/milestones/0.7.0\n\n0.6.2 -- 2016-05-10\n-------------------\n\nFixed Bugs\n~~~~~~~~~~\n\n- When passing a timeout via Requests, it was not appropriately translated to\n the timeout that the urllib3 code was expecting.\n\n0.6.1 -- 2016-05-05\n-------------------\n\nFixed Bugs\n~~~~~~~~~~\n\n- Remove assertion about request URLs in the AppEngineAdapter.\n\n- Prevent pip from installing requests 3.0.0 when that is released until we\n are ready to handle it.\n\n0.6.0 -- 2016-01-27\n-------------------\n\nMore information about this release can be found on the `0.6.0 milestone`_.\n\nNew Features\n~~~~~~~~~~~~\n\n- Add ``AppEngineAdapter`` to support developers using Google's AppEngine\n platform with Requests.\n\n- Add ``GuessProxyAuth`` class to support guessing between Basic and Digest\n Authentication for proxies.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Ensure that proxies use the correct TLS version when using the\n ``SSLAdapter``.\n\n- Fix an ``AttributeError`` when using the ``HTTPProxyDigestAuth`` class.\n\nMiscellaneous\n~~~~~~~~~~~~~\n\n- Drop testing support for Python 3.2. virtualenv and pip have stopped\n supporting it meaning that it is harder to test for this with our CI\n infrastructure. Moving forward we will make a best-effort attempt to\n support 3.2 but will not test for it.\n\n\n.. _0.6.0 milestone:\n https://github.com/requests/toolbelt/milestones/0.6.0\n\n0.5.1 -- 2015-12-16\n-------------------\n\nMore information about this release can be found on the `0.5.1 milestone`_.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Now papers over the differences in requests' ``super_len`` function from\n versions prior to 2.9.0 and versions 2.9.0 and later.\n\n\n.. _0.5.1 milestone:\n https://github.com/requests/toolbelt/milestones/0.5.1\n\n0.5.0 -- 2015-11-24\n-------------------\n\nMore information about this release can be found on the `milestone\n`_\nfor 0.5.0.\n\nNew Features\n~~~~~~~~~~~~\n\n- The ``tee`` submodule was added to ``requests_toolbelt.downloadutils``. It\n allows you to iterate over the bytes of a response while also writing them\n to a file. The ``tee.tee`` function, expects you to pass an open file\n object, while ``tee.tee_to_file`` will use the provided file name to open\n the file for you.\n\n- Added a new parameter to ``requests_toolbelt.utils.user_agent`` that allows\n the user to specify additional items.\n\n- Added nested form-data helper,\n ``requests_toolbelt.utils.formdata.urlencode``.\n\n- Added the ``ForgetfulCookieJar`` to ``requests_toolbelt.cookies``.\n\n- Added utilities for dumping the information about a request-response cycle\n in ``requests_toolbelt.utils.dump``.\n\n- Implemented the API described in the ``requests_toolbelt.threaded`` module\n docstring, i.e., added ``requests_toolbelt.threaded.map`` as an available\n function.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Now papers over the API differences in versions of requests installed from\n system packages versus versions of requests installed from PyPI.\n\n- Allow string types for ``SourceAddressAdapter``.\n\n0.4.0 -- 2015-04-03\n-------------------\n\nFor more information about this release, please see `milestone 0.4.0\n`_\non the project's page.\n\nNew Features\n~~~~~~~~~~~~\n\n- A naive implemenation of a thread pool is now included in the toolbelt. See\n the docs in ``docs/threading.rst`` or on `Read The Docs\n `_.\n\n- The ``StreamingIterator`` now accepts files (such as ``sys.stdin``) without\n a specific length and will properly stream them.\n\n- The ``MultipartEncoder`` now accepts exactly the same format of fields as\n requests' ``files`` parameter does. In other words, you can now also pass in\n extra headers to add to a part in the body. You can also now specify a\n custom ``Content-Type`` for a part.\n\n- An implementation of HTTP Digest Authentication for Proxies is now included.\n\n- A transport adapter that allows a user to specify a specific Certificate\n Fingerprint is now included in the toolbelt.\n\n- A transport adapter that simplifies how users specify socket options is now\n included.\n\n- A transport adapter that simplifies how users can specify TCP Keep-Alive\n options is now included in the toolbelt.\n\n- Deprecated functions from ``requests.utils`` are now included and\n maintained.\n\n- An authentication tool that allows users to specify how to authenticate to\n several different domains at once is now included.\n\n- A function to save streamed responses to disk by analyzing the\n ``Content-Disposition`` header is now included in the toolbelt.\n\nFixed Bugs\n~~~~~~~~~~\n\n- The ``MultipartEncoder`` will now allow users to upload files larger than\n 4GB on 32-bit systems.\n\n- The ``MultipartEncoder`` will now accept empty unicode strings for form\n values.\n\n0.3.1 -- 2014-06-23\n-------------------\n\n- Fix the fact that 0.3.0 bundle did not include the ``StreamingIterator``\n\n0.3.0 -- 2014-05-21\n-------------------\n\nBug Fixes\n~~~~~~~~~\n\n- Complete rewrite of ``MultipartEncoder`` fixes bug where bytes were lost in\n uploads\n\nNew Features\n~~~~~~~~~~~~\n\n- ``MultipartDecoder`` to accept ``multipart/form-data`` response bodies and\n parse them into an easy to use object.\n\n- ``SourceAddressAdapter`` to allow users to choose a local address to bind\n connections to.\n\n- ``GuessAuth`` which accepts a username and password and uses the\n ``WWW-Authenticate`` header to determine how to authenticate against a\n server.\n\n- ``MultipartEncoderMonitor`` wraps an instance of the ``MultipartEncoder``\n and keeps track of how many bytes were read and will call the provided\n callback.\n\n- ``StreamingIterator`` will wrap an iterator and stream the upload instead of\n chunk it, provided you also provide the length of the content you wish to\n upload.\n\n0.2.0 -- 2014-02-24\n-------------------\n\n- Add ability to tell ``MultipartEncoder`` which encoding to use. By default\n it uses 'utf-8'.\n\n- Fix #10 - allow users to install with pip\n\n- Fix #9 - Fix ``MultipartEncoder#to_string`` so that it properly handles file\n objects as fields\n\n0.1.2 -- 2014-01-19\n-------------------\n\n- At some point during development we broke how we handle normal file objects.\n Thanks to @konomae this is now fixed.\n\n0.1.1 -- 2014-01-19\n-------------------\n\n- Handle ``io.BytesIO``-like objects better\n\n0.1.0 -- 2014-01-18\n-------------------\n\n- Add initial implementation of the streaming ``MultipartEncoder``\n\n- Add initial implementation of the ``user_agent`` function\n\n- Add the ``SSLAdapter``", - "release_date": "2019-01-30T01:29:54", + "description": "Pygments is a syntax highlighting package written in Python.", + "release_date": "2022-04-24T13:37:38", "parties": [ { "type": "person", "role": "author", - "name": "Ian Cordasco, Cory Benfield", - "email": "graffatcolmingov@gmail.com", + "name": "Georg Brandl", + "email": "georg@python.org", "url": null } ], "keywords": [ - "Development Status :: 5 - Production/Stable", + "syntax highlighting", + "Development Status :: 6 - Mature", "Intended Audience :: Developers", + "Intended Audience :: End Users/Desktop", + "Intended Audience :: System Administrators", + "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", - "Programming Language :: Python :: Implementation :: CPython" + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Text Processing :: Filters", + "Topic :: Utilities" ], - "homepage_url": "https://toolbelt.readthedocs.org", - "download_url": "https://files.pythonhosted.org/packages/28/30/7bf7e5071081f761766d46820e52f4b16c8a08fef02d2eb4682ca7534310/requests-toolbelt-0.9.1.tar.gz", - "size": 207286, + "homepage_url": "https://pygments.org/", + "download_url": "https://files.pythonhosted.org/packages/5c/8e/1d9017950034297fffa336c72e693a5b51bbf85141b24a763882cf1977b5/Pygments-2.12.0-py3-none-any.whl", + "size": 1093289, "sha1": null, - "md5": "b1509735c4b4cf95df2619facbc3672e", - "sha256": "968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0", + "md5": "4eedd9be3c932cc2b9c3c73b65938663", + "sha256": "dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519", "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, + "bug_tracking_url": "https://github.com/pygments/pygments/issues", + "code_view_url": "https://github.com/pygments/pygments", "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { - "license": "Apache 2.0", + "license": "BSD License", "classifiers": [ - "License :: OSI Approved :: Apache Software License" + "License :: OSI Approved :: BSD License" ] }, "notice_text": null, @@ -8191,39 +4438,37 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/requests-toolbelt/0.9.1/json", + "api_data_url": "https://pypi.org/pypi/pygments/2.12.0/json", "datasource_id": null, - "purl": "pkg:pypi/requests-toolbelt@0.9.1" + "purl": "pkg:pypi/pygments@2.12.0" }, { "type": "pypi", "namespace": null, - "name": "requests", - "version": "2.27.1", + "name": "pyparsing", + "version": "3.0.9", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Python HTTP for Humans.\n# Requests\n\n**Requests** is a simple, yet elegant, HTTP library.\n\n```python\n>>> import requests\n>>> r = requests.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass'))\n>>> r.status_code\n200\n>>> r.headers['content-type']\n'application/json; charset=utf8'\n>>> r.encoding\n'utf-8'\n>>> r.text\n'{\"authenticated\": true, ...'\n>>> r.json()\n{'authenticated': True, ...}\n```\n\nRequests allows you to send HTTP/1.1 requests extremely easily. There\u2019s no need to manually add query strings to your URLs, or to form-encode your `PUT` & `POST` data \u2014 but nowadays, just use the `json` method!\n\nRequests is one of the most downloaded Python packages today, pulling in around `30M downloads / week`\u2014 according to GitHub, Requests is currently [depended upon](https://github.com/psf/requests/network/dependents?package_id=UGFja2FnZS01NzA4OTExNg%3D%3D) by `1,000,000+` repositories. You may certainly put your trust in this code.\n\n[![Downloads](https://pepy.tech/badge/requests/month)](https://pepy.tech/project/requests)\n[![Supported Versions](https://img.shields.io/pypi/pyversions/requests.svg)](https://pypi.org/project/requests)\n[![Contributors](https://img.shields.io/github/contributors/psf/requests.svg)](https://github.com/psf/requests/graphs/contributors)\n\n## Installing Requests and Supported Versions\n\nRequests is available on PyPI:\n\n```console\n$ python -m pip install requests\n```\n\nRequests officially supports Python 2.7 & 3.6+.\n\n## Supported Features & Best\u2013Practices\n\nRequests is ready for the demands of building robust and reliable HTTP\u2013speaking applications, for the needs of today.\n\n- Keep-Alive & Connection Pooling\n- International Domains and URLs\n- Sessions with Cookie Persistence\n- Browser-style TLS/SSL Verification\n- Basic & Digest Authentication\n- Familiar `dict`\u2013like Cookies\n- Automatic Content Decompression and Decoding\n- Multi-part File Uploads\n- SOCKS Proxy Support\n- Connection Timeouts\n- Streaming Downloads\n- Automatic honoring of `.netrc`\n- Chunked HTTP Requests\n\n## API Reference and User Guide available on [Read the Docs](https://requests.readthedocs.io)\n\n[![Read the Docs](https://raw.githubusercontent.com/psf/requests/main/ext/ss.png)](https://requests.readthedocs.io)\n\n## Cloning the repository\n\nWhen cloning the Requests repository, you may need to add the `-c\nfetch.fsck.badTimezone=ignore` flag to avoid an error about a bad commit (see\n[this issue](https://github.com/psf/requests/issues/2690) for more background):\n\n```shell\ngit clone -c fetch.fsck.badTimezone=ignore https://github.com/psf/requests.git\n```\n\nYou can also apply this setting to your global Git config:\n\n```shell\ngit config --global fetch.fsck.badTimezone ignore\n```\n\n---\n\n[![Kenneth Reitz](https://raw.githubusercontent.com/psf/requests/main/ext/kr.png)](https://kennethreitz.org) [![Python Software Foundation](https://raw.githubusercontent.com/psf/requests/main/ext/psf.png)](https://www.python.org/psf)", - "release_date": "2022-01-05T15:40:49", + "description": "pyparsing module - Classes and methods to define and execute parsing grammars\nPyParsing -- A Python Parsing Module\n====================================\n\n|Build Status| |Coverage|\n\nIntroduction\n============\n\nThe pyparsing module is an alternative approach to creating and\nexecuting simple grammars, vs. the traditional lex/yacc approach, or the\nuse of regular expressions. The pyparsing module provides a library of\nclasses that client code uses to construct the grammar directly in\nPython code.\n\n*[Since first writing this description of pyparsing in late 2003, this\ntechnique for developing parsers has become more widespread, under the\nname Parsing Expression Grammars - PEGs. See more information on PEGs*\n`here `__\n*.]*\n\nHere is a program to parse ``\"Hello, World!\"`` (or any greeting of the form\n``\"salutation, addressee!\"``):\n\n.. code:: python\n\n from pyparsing import Word, alphas\n greet = Word(alphas) + \",\" + Word(alphas) + \"!\"\n hello = \"Hello, World!\"\n print(hello, \"->\", greet.parseString(hello))\n\nThe program outputs the following::\n\n Hello, World! -> ['Hello', ',', 'World', '!']\n\nThe Python representation of the grammar is quite readable, owing to the\nself-explanatory class names, and the use of '+', '|' and '^' operator\ndefinitions.\n\nThe parsed results returned from ``parseString()`` is a collection of type\n``ParseResults``, which can be accessed as a\nnested list, a dictionary, or an object with named attributes.\n\nThe pyparsing module handles some of the problems that are typically\nvexing when writing text parsers:\n\n- extra or missing whitespace (the above program will also handle ``\"Hello,World!\"``, ``\"Hello , World !\"``, etc.)\n- quoted strings\n- embedded comments\n\nThe examples directory includes a simple SQL parser, simple CORBA IDL\nparser, a config file parser, a chemical formula parser, and a four-\nfunction algebraic notation parser, among many others.\n\nDocumentation\n=============\n\nThere are many examples in the online docstrings of the classes\nand methods in pyparsing. You can find them compiled into `online docs `__. Additional\ndocumentation resources and project info are listed in the online\n`GitHub wiki `__. An\nentire directory of examples can be found `here `__.\n\nLicense\n=======\n\nMIT License. See header of the `pyparsing.py `__ file.\n\nHistory\n=======\n\nSee `CHANGES `__ file.\n\n.. |Build Status| image:: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml/badge.svg\n :target: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml\n.. |Coverage| image:: https://codecov.io/gh/pyparsing/pyparsing/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/pyparsing/pyparsing", + "release_date": "2022-05-10T23:26:03", "parties": [ { "type": "person", "role": "author", - "name": "Kenneth Reitz", - "email": "me@kennethreitz.org", + "name": null, + "email": "Paul McGuire ", "url": null } ], "keywords": [ "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", "Intended Audience :: Developers", - "Natural Language :: English", + "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 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", @@ -8231,25 +4476,23 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Software Development :: Libraries" + "Typing :: Typed" ], - "homepage_url": "https://requests.readthedocs.io", - "download_url": "https://files.pythonhosted.org/packages/2d/61/08076519c80041bc0ffa1a8af0cbd3bf3e2b62af10435d269a9d0f40564d/requests-2.27.1-py2.py3-none-any.whl", - "size": 63133, + "homepage_url": "", + "download_url": "https://files.pythonhosted.org/packages/6c/10/a7d0fa5baea8fe7b50f448ab742f26f52b80bfca85ac2be9d35cdd9a3246/pyparsing-3.0.9-py3-none-any.whl", + "size": 98338, "sha1": null, - "md5": "435db0f122c83decd27524f690e89650", - "sha256": "f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d", + "md5": "9b7c6d2c436bc7eba41f5f239b391b4c", + "sha256": "5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc", "sha512": null, "bug_tracking_url": null, - "code_view_url": "https://github.com/psf/requests", + "code_view_url": null, "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { - "license": "Apache 2.0", "classifiers": [ - "License :: OSI Approved :: Apache Software License" + "License :: OSI Approved :: MIT License" ] }, "notice_text": null, @@ -8259,65 +4502,63 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/requests/2.27.1/json", + "api_data_url": "https://pypi.org/pypi/pyparsing/3.0.9/json", "datasource_id": null, - "purl": "pkg:pypi/requests@2.27.1" + "purl": "pkg:pypi/pyparsing@3.0.9" }, { "type": "pypi", "namespace": null, - "name": "requests", - "version": "2.27.1", + "name": "pytest-forked", + "version": "1.4.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Python HTTP for Humans.\n# Requests\n\n**Requests** is a simple, yet elegant, HTTP library.\n\n```python\n>>> import requests\n>>> r = requests.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass'))\n>>> r.status_code\n200\n>>> r.headers['content-type']\n'application/json; charset=utf8'\n>>> r.encoding\n'utf-8'\n>>> r.text\n'{\"authenticated\": true, ...'\n>>> r.json()\n{'authenticated': True, ...}\n```\n\nRequests allows you to send HTTP/1.1 requests extremely easily. There\u2019s no need to manually add query strings to your URLs, or to form-encode your `PUT` & `POST` data \u2014 but nowadays, just use the `json` method!\n\nRequests is one of the most downloaded Python packages today, pulling in around `30M downloads / week`\u2014 according to GitHub, Requests is currently [depended upon](https://github.com/psf/requests/network/dependents?package_id=UGFja2FnZS01NzA4OTExNg%3D%3D) by `1,000,000+` repositories. You may certainly put your trust in this code.\n\n[![Downloads](https://pepy.tech/badge/requests/month)](https://pepy.tech/project/requests)\n[![Supported Versions](https://img.shields.io/pypi/pyversions/requests.svg)](https://pypi.org/project/requests)\n[![Contributors](https://img.shields.io/github/contributors/psf/requests.svg)](https://github.com/psf/requests/graphs/contributors)\n\n## Installing Requests and Supported Versions\n\nRequests is available on PyPI:\n\n```console\n$ python -m pip install requests\n```\n\nRequests officially supports Python 2.7 & 3.6+.\n\n## Supported Features & Best\u2013Practices\n\nRequests is ready for the demands of building robust and reliable HTTP\u2013speaking applications, for the needs of today.\n\n- Keep-Alive & Connection Pooling\n- International Domains and URLs\n- Sessions with Cookie Persistence\n- Browser-style TLS/SSL Verification\n- Basic & Digest Authentication\n- Familiar `dict`\u2013like Cookies\n- Automatic Content Decompression and Decoding\n- Multi-part File Uploads\n- SOCKS Proxy Support\n- Connection Timeouts\n- Streaming Downloads\n- Automatic honoring of `.netrc`\n- Chunked HTTP Requests\n\n## API Reference and User Guide available on [Read the Docs](https://requests.readthedocs.io)\n\n[![Read the Docs](https://raw.githubusercontent.com/psf/requests/main/ext/ss.png)](https://requests.readthedocs.io)\n\n## Cloning the repository\n\nWhen cloning the Requests repository, you may need to add the `-c\nfetch.fsck.badTimezone=ignore` flag to avoid an error about a bad commit (see\n[this issue](https://github.com/psf/requests/issues/2690) for more background):\n\n```shell\ngit clone -c fetch.fsck.badTimezone=ignore https://github.com/psf/requests.git\n```\n\nYou can also apply this setting to your global Git config:\n\n```shell\ngit config --global fetch.fsck.badTimezone ignore\n```\n\n---\n\n[![Kenneth Reitz](https://raw.githubusercontent.com/psf/requests/main/ext/kr.png)](https://kennethreitz.org) [![Python Software Foundation](https://raw.githubusercontent.com/psf/requests/main/ext/psf.png)](https://www.python.org/psf)", - "release_date": "2022-01-05T15:40:51", + "description": "run tests in isolated forked subprocesses\npytest-forked: run each test in a forked subprocess\n====================================================\n\n\n.. warning::\n\n\tthis is a extraction of the xdist --forked module,\n\tfuture maintenance beyond the bare minimum is not planned until a new maintainer is found.\n\n\nThis plugin **does not work on Windows** because there's no ``fork`` support.\n\n\n* ``--forked``: run each test in a forked\n subprocess to survive ``SEGFAULTS`` or otherwise dying processes.\n\n|python| |version| |ci| |pre-commit| |black|\n\n.. |version| image:: http://img.shields.io/pypi/v/pytest-forked.svg\n :target: https://pypi.python.org/pypi/pytest-forked\n\n.. |ci| image:: https://github.com/pytest-dev/pytest-forked/workflows/build/badge.svg\n :target: https://github.com/pytest-dev/pytest-forked/actions\n\n.. |python| image:: https://img.shields.io/pypi/pyversions/pytest-forked.svg\n :target: https://pypi.python.org/pypi/pytest-forked/\n\n.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/ambv/black\n\n.. |pre-commit| image:: https://results.pre-commit.ci/badge/github/pytest-dev/pytest-forked/master.svg\n :target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest-forked/master\n\nInstallation\n-----------------------\n\nInstall the plugin with::\n\n pip install pytest-forked\n\nor use the package in develope/in-place mode with\na checkout of the `pytest-forked repository`_ ::\n\n pip install -e .\n\n\nUsage examples\n---------------------\n\nIf you have tests involving C or C++ libraries you might have to deal\nwith tests crashing the process. For this case you may use the boxing\noptions::\n\n pytest --forked\n\nwhich will run each test in a subprocess and will report if a test\ncrashed the process. You can also combine this option with\nrunning multiple processes via pytest-xdist to speed up the test run\nand use your CPU cores::\n\n pytest -n3 --forked\n\nthis would run 3 testing subprocesses in parallel which each\ncreate new forked subprocesses for each test.\n\n\nYou can also fork for individual tests::\n\n @pytest.mark.forked\n def test_with_leaky_state():\n run_some_monkey_patches()\n\n\nThis test will be unconditionally boxed, regardless of CLI flag.\n\n\n.. _`pytest-forked repository`: https://github.com/pytest-dev/pytest-forked", + "release_date": "2021-12-10T15:43:18", "parties": [ { "type": "person", "role": "author", - "name": "Kenneth Reitz", - "email": "me@kennethreitz.org", + "name": "pytest-dev", + "email": "pytest-dev@python.org", "url": null } ], "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", + "Development Status :: 7 - Inactive", + "Framework :: Pytest", "Intended Audience :: Developers", - "Natural Language :: English", - "Operating System :: OS Independent", + "Operating System :: MacOS :: MacOS X", + "Operating System :: POSIX", "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Software Development :: Libraries" + "Topic :: Software Development :: Quality Assurance", + "Topic :: Software Development :: Testing", + "Topic :: Utilities" ], - "homepage_url": "https://requests.readthedocs.io", - "download_url": "https://files.pythonhosted.org/packages/60/f3/26ff3767f099b73e0efa138a9998da67890793bfa475d8278f84a30fec77/requests-2.27.1.tar.gz", - "size": 106758, + "homepage_url": "https://github.com/pytest-dev/pytest-forked", + "download_url": "https://files.pythonhosted.org/packages/0c/36/c56ef2aea73912190cdbcc39aaa860db8c07c1a5ce8566994ec9425453db/pytest_forked-1.4.0-py3-none-any.whl", + "size": 4885, "sha1": null, - "md5": "bcc01b73974a305cc7c5b092e7d07004", - "sha256": "68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61", + "md5": "bf0249039fb39cb7d6af60f09957e61d", + "sha256": "bbbb6717efc886b9d64537b41fb1497cfaf3c9601276be8da2cccfea5a3c8ad8", "sha512": null, "bug_tracking_url": null, - "code_view_url": "https://github.com/psf/requests", + "code_view_url": null, "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { - "license": "Apache 2.0", + "license": "MIT", "classifiers": [ - "License :: OSI Approved :: Apache Software License" + "License :: OSI Approved :: MIT License" ] }, "notice_text": null, @@ -8327,45 +4568,54 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/requests/2.27.1/json", + "api_data_url": "https://pypi.org/pypi/pytest-forked/1.4.0/json", "datasource_id": null, - "purl": "pkg:pypi/requests@2.27.1" + "purl": "pkg:pypi/pytest-forked@1.4.0" }, { "type": "pypi", "namespace": null, - "name": "resolvelib", - "version": "0.8.1", + "name": "pytest-xdist", + "version": "2.5.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Resolve abstract dependencies into concrete ones\n==========\nResolveLib\n==========\n\nResolveLib at the highest level provides a ``Resolver`` class that includes\ndependency resolution logic. You give it some things, and a little information\non how it should interact with them, and it will spit out a resolution result.\n\n\nIntended Usage\n==============\n\n::\n\n import resolvelib\n\n # Things I want to resolve.\n requirements = [...]\n\n # Implement logic so the resolver understands the requirement format.\n class MyProvider:\n ...\n\n provider = MyProvider()\n reporter = resolvelib.BaseReporter()\n\n # Create the (reusable) resolver.\n resolver = resolvelib.Resolver(provider, reporter)\n\n # Kick off the resolution process, and get the final result.\n result = resolver.resolve(requirements)\n\nThe provider interface is specified in ``resolvelib.providers``. You don't\nneed to inherit anything, however, only need to implement the right methods.\n\n\nTerminology\n===========\n\nThe intention of this section is to unify the terms we use when talking about\nthis code base, and packaging in general, to avoid confusion. Class and\nvariable names in the code base should try to stick to terms defined here.\n\nThings passed into ``Resolver.resolve()`` and provided by the provider are all\nconsidered opaque. They don't need to adhere to this set of terminologies.\nNothing can go wrong as long as the provider implementers can keep their heads\nstraight.\n\nPackage\n-------\n\nA thing that can be installed. A Package can have one or more versions\navailable for installation.\n\nVersion\n-------\n\nA string, usually in a number form, describing a snapshot of a Package. This\nnumber should increase when a Package post a new snapshot, i.e. a higher number\nmeans a more up-to-date snapshot.\n\nSpecifier\n---------\n\nA collection of one or more Versions. This could be a wildcard, indicating that\nany Version is acceptable.\n\nCandidate\n---------\n\nA combination of a Package and a Version, i.e. a \"concrete requirement\". Python\npeople sometimes call this a \"locked\" or \"pinned\" dependency. Both of\n\"requirement\" and \"dependency\", however, SHOULD NOT be used when describing a\nCandidate, to avoid confusion.\n\nSome resolver architectures refer this as a \"specification\", but it is not\nused here to avoid confusion with a *Specifier*.\n\nRequirement\n-----------\n\nAn intention to acquire a needed package, i.e. an \"abstract requirement\". A\n\"dependency\", if not clarified otherwise, also refers to this concept.\n\nA Requirement should specify two things: a Package, and a Specifier.\n\nContributing\n============\n\nPlease see `developer documentation <./DEVELOPMENT.rst>`__.", - "release_date": "2021-10-11T21:08:08", + "description": "pytest xdist plugin for distributed testing and loop-on-failing modes\n============\npytest-xdist\n============\n\n.. image:: http://img.shields.io/pypi/v/pytest-xdist.svg\n :alt: PyPI version\n :target: https://pypi.python.org/pypi/pytest-xdist\n\n.. image:: https://img.shields.io/conda/vn/conda-forge/pytest-xdist.svg\n :target: https://anaconda.org/conda-forge/pytest-xdist\n\n.. image:: https://img.shields.io/pypi/pyversions/pytest-xdist.svg\n :alt: Python versions\n :target: https://pypi.python.org/pypi/pytest-xdist\n\n.. image:: https://github.com/pytest-dev/pytest-xdist/workflows/build/badge.svg\n :target: https://github.com/pytest-dev/pytest-xdist/actions\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/ambv/black\n\nThe `pytest-xdist`_ plugin extends pytest with new test execution modes, the most used being distributing\ntests across multiple CPUs to speed up test execution::\n\n pytest -n auto\n\nWith this call, pytest will spawn a number of workers processes equal to the number of available CPUs, and distribute\nthe tests randomly across them. There is also a number of `distribution modes`_ to choose from.\n\n**NOTE**: due to how pytest-xdist is implemented, the ``-s/--capture=no`` option does not work.\n\n.. contents:: **Table of Contents**\n\nInstallation\n------------\n\nInstall the plugin with::\n\n pip install pytest-xdist\n\n\nTo use ``psutil`` for detection of the number of CPUs available, install the ``psutil`` extra::\n\n pip install pytest-xdist[psutil]\n\n\nFeatures\n--------\n\n* Test run parallelization_: tests can be executed across multiple CPUs or hosts.\n This allows to speed up development or to use special resources of `remote machines`_.\n\n* ``--looponfail``: run your tests repeatedly in a subprocess. After each run\n pytest waits until a file in your project changes and then re-runs\n the previously failing tests. This is repeated until all tests pass\n after which again a full run is performed.\n\n* `Multi-Platform`_ coverage: you can specify different Python interpreters\n or different platforms and run tests in parallel on all of them.\n\n Before running tests remotely, ``pytest`` efficiently \"rsyncs\" your\n program source code to the remote place.\n You may specify different Python versions and interpreters. It does not\n installs/synchronize dependencies however.\n\n **Note**: this mode exists mostly for backward compatibility, as modern development\n relies on continuous integration for multi-platform testing.\n\n.. _parallelization:\n\nRunning tests across multiple CPUs\n----------------------------------\n\nTo send tests to multiple CPUs, use the ``-n`` (or ``--numprocesses``) option::\n\n pytest -n 8\n\nPass ``-n auto`` to use as many processes as your computer has CPU cores. This\ncan lead to considerable speed ups, especially if your test suite takes a\nnoticeable amount of time.\n\nThe test distribution algorithm is configured with the ``--dist`` command-line option:\n\n.. _distribution modes:\n\n* ``--dist load`` **(default)**: Sends pending tests to any worker that is\n available, without any guaranteed order.\n\n* ``--dist loadscope``: Tests are grouped by **module** for *test functions*\n and by **class** for *test methods*. Groups are distributed to available\n workers as whole units. This guarantees that all tests in a group run in the\n same process. This can be useful if you have expensive module-level or\n class-level fixtures. Grouping by class takes priority over grouping by\n module.\n\n* ``--dist loadfile``: Tests are grouped by their containing file. Groups are\n distributed to available workers as whole units. This guarantees that all\n tests in a file run in the same worker.\n\n* ``--dist loadgroup``: Tests are grouped by the ``xdist_group`` mark. Groups are\n distributed to available workers as whole units. This guarantees that all\n tests with same ``xdist_group`` name run in the same worker.\n\n .. code-block:: python\n\n @pytest.mark.xdist_group(name=\"group1\")\n def test1():\n pass\n\n class TestA:\n @pytest.mark.xdist_group(\"group1\")\n def test2():\n pass\n\n This will make sure ``test1`` and ``TestA::test2`` will run in the same worker.\n Tests without the ``xdist_group`` mark are distributed normally as in the ``--dist=load`` mode.\n\n* ``--dist no``: The normal pytest execution mode, runs one test at a time (no distribution at all).\n\n\nRunning tests in a Python subprocess\n------------------------------------\n\nTo instantiate a ``python3.9`` subprocess and send tests to it, you may type::\n\n pytest -d --tx popen//python=python3.9\n\nThis will start a subprocess which is run with the ``python3.9``\nPython interpreter, found in your system binary lookup path.\n\nIf you prefix the --tx option value like this::\n\n --tx 3*popen//python=python3.9\n\nthen three subprocesses would be created and tests\nwill be load-balanced across these three processes.\n\n.. _boxed:\n\nRunning tests in a boxed subprocess\n-----------------------------------\n\nThis functionality has been moved to the\n`pytest-forked `_ plugin, but the ``--boxed`` option\nis still kept for backward compatibility.\n\n.. _`remote machines`:\n\nSending tests to remote SSH accounts\n------------------------------------\n\nSuppose you have a package ``mypkg`` which contains some\ntests that you can successfully run locally. And you\nhave a ssh-reachable machine ``myhost``. Then\nyou can ad-hoc distribute your tests by typing::\n\n pytest -d --tx ssh=myhostpopen --rsyncdir mypkg mypkg\n\nThis will synchronize your :code:`mypkg` package directory\nto a remote ssh account and then locally collect tests\nand send them to remote places for execution.\n\nYou can specify multiple :code:`--rsyncdir` directories\nto be sent to the remote side.\n\n.. note::\n\n For pytest to collect and send tests correctly\n you not only need to make sure all code and tests\n directories are rsynced, but that any test (sub) directory\n also has an :code:`__init__.py` file because internally\n pytest references tests as a fully qualified python\n module path. **You will otherwise get strange errors**\n during setup of the remote side.\n\n\nYou can specify multiple :code:`--rsyncignore` glob patterns\nto be ignored when file are sent to the remote side.\nThere are also internal ignores: :code:`.*, *.pyc, *.pyo, *~`\nThose you cannot override using rsyncignore command-line or\nini-file option(s).\n\n\nSending tests to remote Socket Servers\n--------------------------------------\n\nDownload the single-module `socketserver.py`_ Python program\nand run it like this::\n\n python socketserver.py\n\nIt will tell you that it starts listening on the default\nport. You can now on your home machine specify this\nnew socket host with something like this::\n\n pytest -d --tx socket=192.168.1.102:8888 --rsyncdir mypkg mypkg\n\n\n.. _`atonce`:\n.. _`Multi-Platform`:\n\n\nRunning tests on many platforms at once\n---------------------------------------\n\nThe basic command to run tests on multiple platforms is::\n\n pytest --dist=each --tx=spec1 --tx=spec2\n\nIf you specify a windows host, an OSX host and a Linux\nenvironment this command will send each tests to all\nplatforms - and report back failures from all platforms\nat once. The specifications strings use the `xspec syntax`_.\n\n.. _`xspec syntax`: https://codespeak.net/execnet/basics.html#xspec\n\n.. _`socketserver.py`: https://raw.githubusercontent.com/pytest-dev/execnet/master/execnet/script/socketserver.py\n\n.. _`execnet`: https://codespeak.net/execnet\n\n\nWhen tests crash\n----------------\n\nIf a test crashes a worker, pytest-xdist will automatically restart that worker\nand report the test\u2019s failure. You can use the ``--max-worker-restart`` option\nto limit the number of worker restarts that are allowed, or disable restarting\naltogether using ``--max-worker-restart 0``.\n\n\nHow-tos\n-------\n\nIdentifying the worker process during a test\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n*New in version 1.15.*\n\nIf you need to determine the identity of a worker process in\na test or fixture, you may use the ``worker_id`` fixture to do so:\n\n.. code-block:: python\n\n @pytest.fixture()\n def user_account(worker_id):\n \"\"\" use a different account in each xdist worker \"\"\"\n return \"account_%s\" % worker_id\n\nWhen ``xdist`` is disabled (running with ``-n0`` for example), then\n``worker_id`` will return ``\"master\"``.\n\nWorker processes also have the following environment variables\ndefined:\n\n* ``PYTEST_XDIST_WORKER``: the name of the worker, e.g., ``\"gw2\"``.\n* ``PYTEST_XDIST_WORKER_COUNT``: the total number of workers in this session,\n e.g., ``\"4\"`` when ``-n 4`` is given in the command-line.\n\nThe information about the worker_id in a test is stored in the ``TestReport`` as\nwell, under the ``worker_id`` attribute.\n\nSince version 2.0, the following functions are also available in the ``xdist`` module:\n\n.. code-block:: python\n\n def is_xdist_worker(request_or_session) -> bool:\n \"\"\"Return `True` if this is an xdist worker, `False` otherwise\n\n :param request_or_session: the `pytest` `request` or `session` object\n \"\"\"\n\n def is_xdist_controller(request_or_session) -> bool:\n \"\"\"Return `True` if this is the xdist controller, `False` otherwise\n\n Note: this method also returns `False` when distribution has not been\n activated at all.\n\n :param request_or_session: the `pytest` `request` or `session` object\n \"\"\"\n\n def is_xdist_master(request_or_session) -> bool:\n \"\"\"Deprecated alias for is_xdist_controller.\"\"\"\n\n def get_xdist_worker_id(request_or_session) -> str:\n \"\"\"Return the id of the current worker ('gw0', 'gw1', etc) or 'master'\n if running on the controller node.\n\n If not distributing tests (for example passing `-n0` or not passing `-n` at all)\n also return 'master'.\n\n :param request_or_session: the `pytest` `request` or `session` object\n \"\"\"\n\n\nIdentifying workers from the system environment\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n*New in version 2.4*\n\nIf the `setproctitle`_ package is installed, ``pytest-xdist`` will use it to\nupdate the process title (command line) on its workers to show their current\nstate. The titles used are ``[pytest-xdist running] file.py/node::id`` and\n``[pytest-xdist idle]``, visible in standard tools like ``ps`` and ``top`` on\nLinux, Mac OS X and BSD systems. For Windows, please follow `setproctitle`_'s\npointer regarding the Process Explorer tool.\n\nThis is intended purely as an UX enhancement, e.g. to track down issues with\nlong-running or CPU intensive tests. Errors in changing the title are ignored\nsilently. Please try not to rely on the title format or title changes in\nexternal scripts.\n\n.. _`setproctitle`: https://pypi.org/project/setproctitle/\n\n\nUniquely identifying the current test run\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n*New in version 1.32.*\n\nIf you need to globally distinguish one test run from others in your\nworkers, you can use the ``testrun_uid`` fixture. For instance, let's say you\nwanted to create a separate database for each test run:\n\n.. code-block:: python\n\n import pytest\n from posix_ipc import Semaphore, O_CREAT\n\n @pytest.fixture(scope=\"session\", autouse=True)\n def create_unique_database(testrun_uid):\n \"\"\" create a unique database for this particular test run \"\"\"\n database_url = f\"psql://myapp-{testrun_uid}\"\n\n with Semaphore(f\"/{testrun_uid}-lock\", flags=O_CREAT, initial_value=1):\n if not database_exists(database_url):\n create_database(database_url)\n\n @pytest.fixture()\n def db(testrun_uid):\n \"\"\" retrieve unique database \"\"\"\n database_url = f\"psql://myapp-{testrun_uid}\"\n return database_get_instance(database_url)\n\n\nAdditionally, during a test run, the following environment variable is defined:\n\n* ``PYTEST_XDIST_TESTRUNUID``: the unique id of the test run.\n\nAccessing ``sys.argv`` from the controller node in workers\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTo access the ``sys.argv`` passed to the command-line of the controller node, use\n``request.config.workerinput[\"mainargv\"]``.\n\n\nSpecifying test exec environments in an ini file\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nYou can use pytest's ini file configuration to avoid typing common options.\nYou can for example make running with three subprocesses your default like this:\n\n.. code-block:: ini\n\n [pytest]\n addopts = -n3\n\nYou can also add default environments like this:\n\n.. code-block:: ini\n\n [pytest]\n addopts = --tx ssh=myhost//python=python3.9 --tx ssh=myhost//python=python3.6\n\nand then just type::\n\n pytest --dist=each\n\nto run tests in each of the environments.\n\n\nSpecifying \"rsync\" dirs in an ini-file\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIn a ``tox.ini`` or ``setup.cfg`` file in your root project directory\nyou may specify directories to include or to exclude in synchronisation:\n\n.. code-block:: ini\n\n [pytest]\n rsyncdirs = . mypkg helperpkg\n rsyncignore = .hg\n\nThese directory specifications are relative to the directory\nwhere the configuration file was found.\n\n.. _`pytest-xdist`: http://pypi.python.org/pypi/pytest-xdist\n.. _`pytest-xdist repository`: https://github.com/pytest-dev/pytest-xdist\n.. _`pytest`: http://pytest.org\n\n\nMaking session-scoped fixtures execute only once\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n``pytest-xdist`` is designed so that each worker process will perform its own collection and execute\na subset of all tests. This means that tests in different processes requesting a high-level\nscoped fixture (for example ``session``) will execute the fixture code more than once, which\nbreaks expectations and might be undesired in certain situations.\n\nWhile ``pytest-xdist`` does not have a builtin support for ensuring a session-scoped fixture is\nexecuted exactly once, this can be achieved by using a lock file for inter-process communication.\n\nThe example below needs to execute the fixture ``session_data`` only once (because it is\nresource intensive, or needs to execute only once to define configuration options, etc), so it makes\nuse of a `FileLock `_ to produce the fixture data only once\nwhen the first process requests the fixture, while the other processes will then read\nthe data from a file.\n\nHere is the code:\n\n.. code-block:: python\n\n import json\n\n import pytest\n from filelock import FileLock\n\n\n @pytest.fixture(scope=\"session\")\n def session_data(tmp_path_factory, worker_id):\n if worker_id == \"master\":\n # not executing in with multiple workers, just produce the data and let\n # pytest's fixture caching do its job\n return produce_expensive_data()\n\n # get the temp directory shared by all workers\n root_tmp_dir = tmp_path_factory.getbasetemp().parent\n\n fn = root_tmp_dir / \"data.json\"\n with FileLock(str(fn) + \".lock\"):\n if fn.is_file():\n data = json.loads(fn.read_text())\n else:\n data = produce_expensive_data()\n fn.write_text(json.dumps(data))\n return data\n\n\nThe example above can also be use in cases a fixture needs to execute exactly once per test session, like\ninitializing a database service and populating initial tables.\n\nThis technique might not work for every case, but should be a starting point for many situations\nwhere executing a high-scope fixture exactly once is important.\n\n\nHow does xdist work?\n--------------------\n\n``xdist`` works by spawning one or more **workers**, which are\ncontrolled by the **controller**. Each **worker** is responsible for\nperforming a full test collection and afterwards running tests as\ndictated by the **controller**.\n\nThe execution flow is:\n\n1. **controller** spawns one or more **workers** at the beginning of the\n test session. The communication between **controller** and **worker**\n nodes makes use of `execnet `__ and\n its\n `gateways `__.\n The actual interpreters executing the code for the **workers** might\n be remote or local.\n\n2. Each **worker** itself is a mini pytest runner. **workers** at this\n point perform a full test collection, sending back the collected\n test-ids back to the **controller** which does not perform any\n collection itself.\n\n3. The **controller** receives the result of the collection from all\n nodes. At this point the **controller** performs some sanity check to\n ensure that all **workers** collected the same tests (including\n order), bailing out otherwise. If all is well, it converts the list\n of test-ids into a list of simple indexes, where each index\n corresponds to the position of that test in the original collection\n list. This works because all nodes have the same collection list, and\n saves bandwidth because the **controller** can now tell one of the\n workers to just *execute test index 3* index of passing the full test\n id.\n\n4. If **dist-mode** is **each**: the **controller** just sends the full\n list of test indexes to each node at this moment.\n\n5. If **dist-mode** is **load**: the **controller** takes around 25% of\n the tests and sends them one by one to each **worker** in a round\n robin fashion. The rest of the tests will be distributed later as\n **workers** finish tests (see below).\n\n6. Note that ``pytest_xdist_make_scheduler`` hook can be used to\n implement custom tests distribution logic.\n\n7. **workers** re-implement ``pytest_runtestloop``: pytest\u2019s default\n implementation basically loops over all collected items in the\n ``session`` object and executes the ``pytest_runtest_protocol`` for\n each test item, but in xdist **workers** sit idly waiting for\n **controller** to send tests for execution. As tests are received by\n **workers**, ``pytest_runtest_protocol`` is executed for each test.\n Here it worth noting an implementation detail: **workers** always\n must keep at least one test item on their queue due to how the\n ``pytest_runtest_protocol(item, nextitem)`` hook is defined: in order\n to pass the ``nextitem`` to the hook, the worker must wait for more\n instructions from controller before executing that remaining test. If\n it receives more tests, then it can safely call\n ``pytest_runtest_protocol`` because it knows what the ``nextitem``\n parameter will be. If it receives a \u201cshutdown\u201d signal, then it can\n execute the hook passing ``nextitem`` as ``None``.\n\n8. As tests are started and completed at the **workers**, the results\n are sent back to the **controller**, which then just forwards the\n results to the appropriate pytest hooks: ``pytest_runtest_logstart``\n and ``pytest_runtest_logreport``. This way other plugins (for example\n ``junitxml``) can work normally. The **controller** (when in\n dist-mode **load**) decides to send more tests to a node when a test\n completes, using some heuristics such as test durations and how many\n tests each **worker** still has to run.\n\n9. When the **controller** has no more pending tests it will send a\n \u201cshutdown\u201d signal to all **workers**, which will then run their\n remaining tests to completion and shut down. At this point the\n **controller** will sit waiting for **workers** to shut down, still\n processing events such as ``pytest_runtest_logreport``.\n\nFAQ\n---\n\n**Question**: Why does each worker do its own collection, as opposed to having the\ncontroller collect once and distribute from that collection to the\nworkers?\n\nIf collection was performed by controller then it would have to\nserialize collected items to send them through the wire, as workers live\nin another process. The problem is that test items are not easily\n(impossible?) to serialize, as they contain references to the test\nfunctions, fixture managers, config objects, etc. Even if one manages to\nserialize it, it seems it would be very hard to get it right and easy to\nbreak by any small change in pytest.", + "release_date": "2021-12-10T11:41:55", "parties": [ { "type": "person", "role": "author", - "name": "Tzu-ping Chung", - "email": "uranusjr@gmail.com", + "name": "holger krekel and contributors", + "email": "pytest-dev@python.org,holger@merlinux.eu", "url": null } ], "keywords": [ - "dependency", - "resolution", - "Development Status :: 3 - Alpha", + "Development Status :: 5 - Production/Stable", + "Framework :: Pytest", "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python :: 2", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Programming Language :: Python", "Programming Language :: Python :: 3", - "Topic :: Software Development :: Libraries :: Python Modules" + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Topic :: Software Development :: Quality Assurance", + "Topic :: Software Development :: Testing", + "Topic :: Utilities" ], - "homepage_url": "https://github.com/sarugaku/resolvelib", - "download_url": "https://files.pythonhosted.org/packages/98/c0/46cfa3f56e43033b705965120058c018375600fa8fdb44c4e53d75820673/resolvelib-0.8.1-py2.py3-none-any.whl", - "size": 16113, + "homepage_url": "https://github.com/pytest-dev/pytest-xdist", + "download_url": "https://files.pythonhosted.org/packages/21/08/b1945d4b4986eb1aa10cf84efc5293bba39da80a2f95db3573dd90678408/pytest_xdist-2.5.0-py3-none-any.whl", + "size": 41698, "sha1": null, - "md5": "9b92af9306678e346cd7f946a6419748", - "sha256": "d9b7907f055c3b3a2cfc56c914ffd940122915826ff5fb5b1de0c99778f4de98", + "md5": "7cd826d45ea2ed4c1eb1ce5781db032a", + "sha256": "6fe5c74fec98906deb8f2d2b616b5c782022744978e7bd4695d39c8f42d0ce65", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -8373,9 +4623,9 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "ISC License", + "license": "MIT", "classifiers": [ - "License :: OSI Approved :: ISC License (ISCL)" + "License :: OSI Approved :: MIT License" ] }, "notice_text": null, @@ -8385,55 +4635,64 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/resolvelib/0.8.1/json", + "api_data_url": "https://pypi.org/pypi/pytest-xdist/2.5.0/json", "datasource_id": null, - "purl": "pkg:pypi/resolvelib@0.8.1" + "purl": "pkg:pypi/pytest-xdist@2.5.0" }, { "type": "pypi", "namespace": null, - "name": "resolvelib", - "version": "0.8.1", + "name": "pytest", + "version": "7.0.1", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Resolve abstract dependencies into concrete ones\n==========\nResolveLib\n==========\n\nResolveLib at the highest level provides a ``Resolver`` class that includes\ndependency resolution logic. You give it some things, and a little information\non how it should interact with them, and it will spit out a resolution result.\n\n\nIntended Usage\n==============\n\n::\n\n import resolvelib\n\n # Things I want to resolve.\n requirements = [...]\n\n # Implement logic so the resolver understands the requirement format.\n class MyProvider:\n ...\n\n provider = MyProvider()\n reporter = resolvelib.BaseReporter()\n\n # Create the (reusable) resolver.\n resolver = resolvelib.Resolver(provider, reporter)\n\n # Kick off the resolution process, and get the final result.\n result = resolver.resolve(requirements)\n\nThe provider interface is specified in ``resolvelib.providers``. You don't\nneed to inherit anything, however, only need to implement the right methods.\n\n\nTerminology\n===========\n\nThe intention of this section is to unify the terms we use when talking about\nthis code base, and packaging in general, to avoid confusion. Class and\nvariable names in the code base should try to stick to terms defined here.\n\nThings passed into ``Resolver.resolve()`` and provided by the provider are all\nconsidered opaque. They don't need to adhere to this set of terminologies.\nNothing can go wrong as long as the provider implementers can keep their heads\nstraight.\n\nPackage\n-------\n\nA thing that can be installed. A Package can have one or more versions\navailable for installation.\n\nVersion\n-------\n\nA string, usually in a number form, describing a snapshot of a Package. This\nnumber should increase when a Package post a new snapshot, i.e. a higher number\nmeans a more up-to-date snapshot.\n\nSpecifier\n---------\n\nA collection of one or more Versions. This could be a wildcard, indicating that\nany Version is acceptable.\n\nCandidate\n---------\n\nA combination of a Package and a Version, i.e. a \"concrete requirement\". Python\npeople sometimes call this a \"locked\" or \"pinned\" dependency. Both of\n\"requirement\" and \"dependency\", however, SHOULD NOT be used when describing a\nCandidate, to avoid confusion.\n\nSome resolver architectures refer this as a \"specification\", but it is not\nused here to avoid confusion with a *Specifier*.\n\nRequirement\n-----------\n\nAn intention to acquire a needed package, i.e. an \"abstract requirement\". A\n\"dependency\", if not clarified otherwise, also refers to this concept.\n\nA Requirement should specify two things: a Package, and a Specifier.\n\nContributing\n============\n\nPlease see `developer documentation <./DEVELOPMENT.rst>`__.", - "release_date": "2021-10-11T21:08:11", + "description": "pytest: simple powerful testing with Python\n.. image:: https://github.com/pytest-dev/pytest/raw/main/doc/en/img/pytest_logo_curves.svg\n :target: https://docs.pytest.org/en/stable/\n :align: center\n :height: 200\n :alt: pytest\n\n\n------\n\n.. image:: https://img.shields.io/pypi/v/pytest.svg\n :target: https://pypi.org/project/pytest/\n\n.. image:: https://img.shields.io/conda/vn/conda-forge/pytest.svg\n :target: https://anaconda.org/conda-forge/pytest\n\n.. image:: https://img.shields.io/pypi/pyversions/pytest.svg\n :target: https://pypi.org/project/pytest/\n\n.. image:: https://codecov.io/gh/pytest-dev/pytest/branch/main/graph/badge.svg\n :target: https://codecov.io/gh/pytest-dev/pytest\n :alt: Code coverage Status\n\n.. image:: https://github.com/pytest-dev/pytest/workflows/main/badge.svg\n :target: https://github.com/pytest-dev/pytest/actions?query=workflow%3Amain\n\n.. image:: https://results.pre-commit.ci/badge/github/pytest-dev/pytest/main.svg\n :target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest/main\n :alt: pre-commit.ci status\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n\n.. image:: https://www.codetriage.com/pytest-dev/pytest/badges/users.svg\n :target: https://www.codetriage.com/pytest-dev/pytest\n\n.. image:: https://readthedocs.org/projects/pytest/badge/?version=latest\n :target: https://pytest.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n\n.. image:: https://img.shields.io/badge/Discord-pytest--dev-blue\n :target: https://discord.com/invite/pytest-dev\n :alt: Discord\n\n.. image:: https://img.shields.io/badge/Libera%20chat-%23pytest-orange\n :target: https://web.libera.chat/#pytest\n :alt: Libera chat\n\n\nThe ``pytest`` framework makes it easy to write small tests, yet\nscales to support complex functional testing for applications and libraries.\n\nAn example of a simple test:\n\n.. code-block:: python\n\n # content of test_sample.py\n def inc(x):\n return x + 1\n\n\n def test_answer():\n assert inc(3) == 5\n\n\nTo execute it::\n\n $ pytest\n ============================= test session starts =============================\n collected 1 items\n\n test_sample.py F\n\n ================================== FAILURES ===================================\n _________________________________ test_answer _________________________________\n\n def test_answer():\n > assert inc(3) == 5\n E assert 4 == 5\n E + where 4 = inc(3)\n\n test_sample.py:5: AssertionError\n ========================== 1 failed in 0.04 seconds ===========================\n\n\nDue to ``pytest``'s detailed assertion introspection, only plain ``assert`` statements are used. See `getting-started `_ for more examples.\n\n\nFeatures\n--------\n\n- Detailed info on failing `assert statements `_ (no need to remember ``self.assert*`` names)\n\n- `Auto-discovery\n `_\n of test modules and functions\n\n- `Modular fixtures `_ for\n managing small or parametrized long-lived test resources\n\n- Can run `unittest `_ (or trial),\n `nose `_ test suites out of the box\n\n- Python 3.6+ and PyPy3\n\n- Rich plugin architecture, with over 850+ `external plugins `_ and thriving community\n\n\nDocumentation\n-------------\n\nFor full documentation, including installation, tutorials and PDF documents, please see https://docs.pytest.org/en/stable/.\n\n\nBugs/Requests\n-------------\n\nPlease use the `GitHub issue tracker `_ to submit bugs or request features.\n\n\nChangelog\n---------\n\nConsult the `Changelog `__ page for fixes and enhancements of each version.\n\n\nSupport pytest\n--------------\n\n`Open Collective`_ is an online funding platform for open and transparent communities.\nIt provides tools to raise money and share your finances in full transparency.\n\nIt is the platform of choice for individuals and companies that want to make one-time or\nmonthly donations directly to the project.\n\nSee more details in the `pytest collective`_.\n\n.. _Open Collective: https://opencollective.com\n.. _pytest collective: https://opencollective.com/pytest\n\n\npytest for enterprise\n---------------------\n\nAvailable as part of the Tidelift Subscription.\n\nThe maintainers of pytest and thousands of other packages are working with Tidelift to deliver commercial support and\nmaintenance for the open source dependencies you use to build your applications.\nSave time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use.\n\n`Learn more. `_\n\nSecurity\n^^^^^^^^\n\npytest has never been associated with a security vulnerability, but in any case, to report a\nsecurity vulnerability please use the `Tidelift security contact `_.\nTidelift will coordinate the fix and disclosure.\n\n\nLicense\n-------\n\nCopyright Holger Krekel and others, 2004.\n\nDistributed under the terms of the `MIT`_ license, pytest is free and open source software.\n\n.. _`MIT`: https://github.com/pytest-dev/pytest/blob/main/LICENSE", + "release_date": "2022-02-11T18:47:56", "parties": [ { "type": "person", "role": "author", - "name": "Tzu-ping Chung", - "email": "uranusjr@gmail.com", + "name": "Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others", + "email": null, "url": null } ], "keywords": [ - "dependency", - "resolution", - "Development Status :: 3 - Alpha", + "test", + "unittest", + "Development Status :: 6 - Mature", "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python :: 2", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", "Programming Language :: Python :: 3", - "Topic :: Software Development :: Libraries :: Python Modules" + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Topic :: Software Development :: Libraries", + "Topic :: Software Development :: Testing", + "Topic :: Utilities" ], - "homepage_url": "https://github.com/sarugaku/resolvelib", - "download_url": "https://files.pythonhosted.org/packages/ac/20/9541749d77aebf66dd92e2b803f38a50e3a5c76e7876f45eb2b37e758d82/resolvelib-0.8.1.tar.gz", - "size": 17308, + "homepage_url": "https://docs.pytest.org/en/latest/", + "download_url": "https://files.pythonhosted.org/packages/38/93/c7c0bd1e932b287fb948eb9ce5a3d6307c9fc619db1e199f8c8bc5dad95f/pytest-7.0.1-py3-none-any.whl", + "size": 296985, "sha1": null, - "md5": "fbd5fbcac181644333390ea6a71c4edc", - "sha256": "c6ea56732e9fb6fca1b2acc2ccc68a0b6b8c566d8f3e78e0443310ede61dbd37", + "md5": "f5758c7774cc7ae6caab04e71379fabc", + "sha256": "9ce3ff477af913ecf6321fe337b93a2c0dcf2a0a1439c43f5452112c1e4280db", "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, + "bug_tracking_url": "https://github.com/pytest-dev/pytest/issues", + "code_view_url": "https://github.com/pytest-dev/pytest", "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { - "license": "ISC License", + "license": "MIT", "classifiers": [ - "License :: OSI Approved :: ISC License (ISCL)" + "License :: OSI Approved :: MIT License" ] }, "notice_text": null, @@ -8443,57 +4702,62 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/resolvelib/0.8.1/json", + "api_data_url": "https://pypi.org/pypi/pytest/7.0.1/json", "datasource_id": null, - "purl": "pkg:pypi/resolvelib@0.8.1" + "purl": "pkg:pypi/pytest@7.0.1" }, { "type": "pypi", "namespace": null, - "name": "rfc3986", - "version": "1.5.0", + "name": "pyyaml", + "version": "6.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Validating URI References per RFC 3986\nrfc3986\n=======\n\nA Python implementation of `RFC 3986`_ including validation and authority \nparsing.\n\nInstallation\n------------\n\nUse pip to install ``rfc3986`` like so::\n\n pip install rfc3986\n\nLicense\n-------\n\n`Apache License Version 2.0`_\n\nExample Usage\n-------------\n\nThe following are the two most common use cases envisioned for ``rfc3986``.\n\nReplacing ``urlparse``\n``````````````````````\n\nTo parse a URI and receive something very similar to the standard library's\n``urllib.parse.urlparse``\n\n.. code-block:: python\n\n from rfc3986 import urlparse\n\n ssh = urlparse('ssh://user@git.openstack.org:29418/openstack/glance.git')\n print(ssh.scheme) # => ssh\n print(ssh.userinfo) # => user\n print(ssh.params) # => None\n print(ssh.port) # => 29418\n\nTo create a copy of it with new pieces you can use ``copy_with``:\n\n.. code-block:: python\n\n new_ssh = ssh.copy_with(\n scheme='https'\n userinfo='',\n port=443,\n path='/openstack/glance'\n )\n print(new_ssh.scheme) # => https\n print(new_ssh.userinfo) # => None\n # etc.\n\nStrictly Parsing a URI and Applying Validation\n``````````````````````````````````````````````\n\nTo parse a URI into a convenient named tuple, you can simply:\n\n.. code-block:: python\n\n from rfc3986 import uri_reference\n\n example = uri_reference('http://example.com')\n email = uri_reference('mailto:user@domain.com')\n ssh = uri_reference('ssh://user@git.openstack.org:29418/openstack/keystone.git')\n\nWith a parsed URI you can access data about the components:\n\n.. code-block:: python\n\n print(example.scheme) # => http\n print(email.path) # => user@domain.com\n print(ssh.userinfo) # => user\n print(ssh.host) # => git.openstack.org\n print(ssh.port) # => 29418\n\nIt can also parse URIs with unicode present:\n\n.. code-block:: python\n\n uni = uri_reference(b'http://httpbin.org/get?utf8=\\xe2\\x98\\x83') # \u2603\n print(uni.query) # utf8=%E2%98%83\n\nWith a parsed URI you can also validate it:\n\n.. code-block:: python\n\n if ssh.is_valid():\n subprocess.call(['git', 'clone', ssh.unsplit()])\n\nYou can also take a parsed URI and normalize it:\n\n.. code-block:: python\n\n mangled = uri_reference('hTTp://exAMPLe.COM')\n print(mangled.scheme) # => hTTp\n print(mangled.authority) # => exAMPLe.COM\n\n normal = mangled.normalize()\n print(normal.scheme) # => http\n print(mangled.authority) # => example.com\n\nBut these two URIs are (functionally) equivalent:\n\n.. code-block:: python\n\n if normal == mangled:\n webbrowser.open(normal.unsplit())\n\nYour paths, queries, and fragments are safe with us though:\n\n.. code-block:: python\n\n mangled = uri_reference('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth')\n normal = mangled.normalize()\n assert normal == 'hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth'\n assert normal == 'http://example.com/Some/reallY/biZZare/pAth'\n assert normal != 'http://example.com/some/really/bizzare/path'\n\nIf you do not actually need a real reference object and just want to normalize\nyour URI:\n\n.. code-block:: python\n\n from rfc3986 import normalize_uri\n\n assert (normalize_uri('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth') ==\n 'http://example.com/Some/reallY/biZZare/pAth')\n\nYou can also very simply validate a URI:\n\n.. code-block:: python\n\n from rfc3986 import is_valid_uri\n\n assert is_valid_uri('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth')\n\nRequiring Components\n~~~~~~~~~~~~~~~~~~~~\n\nYou can validate that a particular string is a valid URI and require\nindependent components:\n\n.. code-block:: python\n\n from rfc3986 import is_valid_uri\n\n assert is_valid_uri('http://localhost:8774/v2/resource',\n require_scheme=True,\n require_authority=True,\n require_path=True)\n\n # Assert that a mailto URI is invalid if you require an authority\n # component\n assert is_valid_uri('mailto:user@example.com', require_authority=True) is False\n\nIf you have an instance of a ``URIReference``, you can pass the same arguments\nto ``URIReference#is_valid``, e.g.,\n\n.. code-block:: python\n\n from rfc3986 import uri_reference\n\n http = uri_reference('http://localhost:8774/v2/resource')\n assert uri.is_valid(require_scheme=True,\n require_authority=True,\n require_path=True)\n\n # Assert that a mailto URI is invalid if you require an authority\n # component\n mailto = uri_reference('mailto:user@example.com')\n assert uri.is_valid(require_authority=True) is False\n\nAlternatives\n------------\n\n- `rfc3987 `_\n\n This is a direct competitor to this library, with extra features,\n licensed under the GPL.\n\n- `uritools `_\n\n This can parse URIs in the manner of RFC 3986 but provides no validation and\n only recently added Python 3 support.\n\n- Standard library's `urlparse`/`urllib.parse`\n\n The functions in these libraries can only split a URI (valid or not) and\n provide no validation.\n\nContributing\n------------\n\nThis project follows and enforces the Python Software Foundation's `Code of\nConduct `_.\n\nIf you would like to contribute but do not have a bug or feature in mind, feel\nfree to email Ian and find out how you can help.\n\nThe git repository for this project is maintained at\nhttps://github.com/python-hyper/rfc3986\n\n.. _RFC 3986: http://tools.ietf.org/html/rfc3986\n.. _Apache License Version 2.0: https://www.apache.org/licenses/LICENSE-2.0", - "release_date": "2021-05-07T23:29:25", + "description": "YAML parser and emitter for Python\nYAML is a data serialization format designed for human readability\nand interaction with scripting languages. PyYAML is a YAML parser\nand emitter for Python.\n\nPyYAML features a complete YAML 1.1 parser, Unicode support, pickle\nsupport, capable extension API, and sensible error messages. PyYAML\nsupports standard YAML tags and provides Python-specific tags that\nallow to represent an arbitrary Python object.\n\nPyYAML is applicable for a broad range of tasks from complex\nconfiguration files to object serialization and persistence.", + "release_date": "2021-10-13T19:39:51", "parties": [ { "type": "person", "role": "author", - "name": "Ian Stapleton Cordasco", - "email": "graffatcolmingov@gmail.com", + "name": "Kirill Simonov", + "email": "xi@resolvent.net", "url": null } ], "keywords": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", - "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Cython", "Programming Language :: Python", - "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7" + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Text Processing :: Markup" ], - "homepage_url": "http://rfc3986.readthedocs.io", - "download_url": "https://files.pythonhosted.org/packages/c4/e5/63ca2c4edf4e00657584608bee1001302bbf8c5f569340b78304f2f446cb/rfc3986-1.5.0-py2.py3-none-any.whl", - "size": 31976, + "homepage_url": "https://pyyaml.org/", + "download_url": "https://files.pythonhosted.org/packages/02/25/6ba9f6bb50a3d4fbe22c1a02554dc670682a07c8701d1716d19ddea2c940/PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", + "size": 682157, "sha1": null, - "md5": "7f72f95f22ce02cd7e286166322580be", - "sha256": "a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97", + "md5": "af1ca2607840fa7ad65b1994c2d723c0", + "sha256": "f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5", "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, + "bug_tracking_url": "https://github.com/yaml/pyyaml/issues", + "code_view_url": "https://github.com/yaml/pyyaml", "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { - "license": "Apache 2.0", + "license": "MIT", "classifiers": [ - "License :: OSI Approved :: Apache Software License" + "License :: OSI Approved :: MIT License" ] }, "notice_text": null, @@ -8503,47 +4767,54 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/rfc3986/1.5.0/json", + "api_data_url": "https://pypi.org/pypi/pyyaml/6.0/json", "datasource_id": null, - "purl": "pkg:pypi/rfc3986@1.5.0" + "purl": "pkg:pypi/pyyaml@6.0" }, { "type": "pypi", "namespace": null, - "name": "rfc3986", - "version": "1.5.0", + "name": "readme-renderer", + "version": "34.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Validating URI References per RFC 3986\nrfc3986\n=======\n\nA Python implementation of `RFC 3986`_ including validation and authority \nparsing.\n\nInstallation\n------------\n\nUse pip to install ``rfc3986`` like so::\n\n pip install rfc3986\n\nLicense\n-------\n\n`Apache License Version 2.0`_\n\nExample Usage\n-------------\n\nThe following are the two most common use cases envisioned for ``rfc3986``.\n\nReplacing ``urlparse``\n``````````````````````\n\nTo parse a URI and receive something very similar to the standard library's\n``urllib.parse.urlparse``\n\n.. code-block:: python\n\n from rfc3986 import urlparse\n\n ssh = urlparse('ssh://user@git.openstack.org:29418/openstack/glance.git')\n print(ssh.scheme) # => ssh\n print(ssh.userinfo) # => user\n print(ssh.params) # => None\n print(ssh.port) # => 29418\n\nTo create a copy of it with new pieces you can use ``copy_with``:\n\n.. code-block:: python\n\n new_ssh = ssh.copy_with(\n scheme='https'\n userinfo='',\n port=443,\n path='/openstack/glance'\n )\n print(new_ssh.scheme) # => https\n print(new_ssh.userinfo) # => None\n # etc.\n\nStrictly Parsing a URI and Applying Validation\n``````````````````````````````````````````````\n\nTo parse a URI into a convenient named tuple, you can simply:\n\n.. code-block:: python\n\n from rfc3986 import uri_reference\n\n example = uri_reference('http://example.com')\n email = uri_reference('mailto:user@domain.com')\n ssh = uri_reference('ssh://user@git.openstack.org:29418/openstack/keystone.git')\n\nWith a parsed URI you can access data about the components:\n\n.. code-block:: python\n\n print(example.scheme) # => http\n print(email.path) # => user@domain.com\n print(ssh.userinfo) # => user\n print(ssh.host) # => git.openstack.org\n print(ssh.port) # => 29418\n\nIt can also parse URIs with unicode present:\n\n.. code-block:: python\n\n uni = uri_reference(b'http://httpbin.org/get?utf8=\\xe2\\x98\\x83') # \u2603\n print(uni.query) # utf8=%E2%98%83\n\nWith a parsed URI you can also validate it:\n\n.. code-block:: python\n\n if ssh.is_valid():\n subprocess.call(['git', 'clone', ssh.unsplit()])\n\nYou can also take a parsed URI and normalize it:\n\n.. code-block:: python\n\n mangled = uri_reference('hTTp://exAMPLe.COM')\n print(mangled.scheme) # => hTTp\n print(mangled.authority) # => exAMPLe.COM\n\n normal = mangled.normalize()\n print(normal.scheme) # => http\n print(mangled.authority) # => example.com\n\nBut these two URIs are (functionally) equivalent:\n\n.. code-block:: python\n\n if normal == mangled:\n webbrowser.open(normal.unsplit())\n\nYour paths, queries, and fragments are safe with us though:\n\n.. code-block:: python\n\n mangled = uri_reference('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth')\n normal = mangled.normalize()\n assert normal == 'hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth'\n assert normal == 'http://example.com/Some/reallY/biZZare/pAth'\n assert normal != 'http://example.com/some/really/bizzare/path'\n\nIf you do not actually need a real reference object and just want to normalize\nyour URI:\n\n.. code-block:: python\n\n from rfc3986 import normalize_uri\n\n assert (normalize_uri('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth') ==\n 'http://example.com/Some/reallY/biZZare/pAth')\n\nYou can also very simply validate a URI:\n\n.. code-block:: python\n\n from rfc3986 import is_valid_uri\n\n assert is_valid_uri('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth')\n\nRequiring Components\n~~~~~~~~~~~~~~~~~~~~\n\nYou can validate that a particular string is a valid URI and require\nindependent components:\n\n.. code-block:: python\n\n from rfc3986 import is_valid_uri\n\n assert is_valid_uri('http://localhost:8774/v2/resource',\n require_scheme=True,\n require_authority=True,\n require_path=True)\n\n # Assert that a mailto URI is invalid if you require an authority\n # component\n assert is_valid_uri('mailto:user@example.com', require_authority=True) is False\n\nIf you have an instance of a ``URIReference``, you can pass the same arguments\nto ``URIReference#is_valid``, e.g.,\n\n.. code-block:: python\n\n from rfc3986 import uri_reference\n\n http = uri_reference('http://localhost:8774/v2/resource')\n assert uri.is_valid(require_scheme=True,\n require_authority=True,\n require_path=True)\n\n # Assert that a mailto URI is invalid if you require an authority\n # component\n mailto = uri_reference('mailto:user@example.com')\n assert uri.is_valid(require_authority=True) is False\n\nAlternatives\n------------\n\n- `rfc3987 `_\n\n This is a direct competitor to this library, with extra features,\n licensed under the GPL.\n\n- `uritools `_\n\n This can parse URIs in the manner of RFC 3986 but provides no validation and\n only recently added Python 3 support.\n\n- Standard library's `urlparse`/`urllib.parse`\n\n The functions in these libraries can only split a URI (valid or not) and\n provide no validation.\n\nContributing\n------------\n\nThis project follows and enforces the Python Software Foundation's `Code of\nConduct `_.\n\nIf you would like to contribute but do not have a bug or feature in mind, feel\nfree to email Ian and find out how you can help.\n\nThe git repository for this project is maintained at\nhttps://github.com/python-hyper/rfc3986\n\n.. _RFC 3986: http://tools.ietf.org/html/rfc3986\n.. _Apache License Version 2.0: https://www.apache.org/licenses/LICENSE-2.0", - "release_date": "2021-05-07T23:29:27", + "description": "readme_renderer is a library for rendering \"readme\" descriptions for Warehouse\nReadme Renderer\n===============\n\nReadme Renderer is a library that will safely render arbitrary\n``README`` files into HTML. It is designed to be used in Warehouse_ to\nrender the ``long_description`` for packages. It can handle Markdown,\nreStructuredText (``.rst``), and plain text.\n\n.. _Warehouse: https://github.com/pypa/warehouse\n\n\nCheck Description Locally\n-------------------------\n\nTo locally check whether your long descriptions will render on PyPI, first\nbuild your distributions, and then use the |twine check|_ command.\n\n\nRender rST Description Locally\n------------------------------\n\nYou can use ``readme_renderer`` on the command line to render an rST file as\nHTML like this: ::\n\n python -m readme_renderer README.rst -o /tmp/README.html\n\nCode of Conduct\n---------------\n\nEveryone interacting in the readme_renderer project's codebases, issue trackers,\nchat rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.\n\n\n.. |twine check| replace:: ``twine check``\n.. _twine check: https://packaging.python.org/guides/making-a-pypi-friendly-readme#validating-restructuredtext-markup\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md", + "release_date": "2022-03-11T20:12:21", "parties": [ { "type": "person", "role": "author", - "name": "Ian Stapleton Cordasco", - "email": "graffatcolmingov@gmail.com", + "name": "The Python Packaging Authority", + "email": "admin@mail.pypi.org", "url": null } ], "keywords": [ - "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Natural Language :: English", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Operating System :: POSIX :: BSD", + "Operating System :: POSIX :: Linux", "Programming Language :: Python", - "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7" + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy" ], - "homepage_url": "http://rfc3986.readthedocs.io", - "download_url": "https://files.pythonhosted.org/packages/79/30/5b1b6c28c105629cc12b33bdcbb0b11b5bb1880c6cfbd955f9e792921aa8/rfc3986-1.5.0.tar.gz", - "size": 49378, + "homepage_url": "https://github.com/pypa/readme_renderer", + "download_url": "https://files.pythonhosted.org/packages/40/df/a8d87511e806e4c5311d521140a51c34e5ab13e760cd739fc3b89495012d/readme_renderer-34.0-py3-none-any.whl", + "size": 16928, "sha1": null, - "md5": "0e3a03c3eb3b679d5a253b168bb5774a", - "sha256": "270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835", + "md5": "4ab2285b5830e44fc57a6d400b0d5958", + "sha256": "262510fe6aae81ed4e94d8b169077f325614c0b1a45916a80442c6576264a9c2", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -8551,7 +4822,7 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "Apache 2.0", + "license": "Apache License, Version 2.0", "classifiers": [ "License :: OSI Approved :: Apache Software License" ] @@ -8563,44 +4834,47 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/rfc3986/1.5.0/json", + "api_data_url": "https://pypi.org/pypi/readme-renderer/34.0/json", "datasource_id": null, - "purl": "pkg:pypi/rfc3986@1.5.0" + "purl": "pkg:pypi/readme-renderer@34.0" }, { "type": "pypi", "namespace": null, - "name": "saneyaml", - "version": "0.5.2", + "name": "requests-toolbelt", + "version": "0.9.1", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Read and write readable YAML safely preserving order and avoiding bad surprises with unwanted infered type conversions. This library is a PyYaml wrapper with sane behaviour to read and write readable YAML safely, typically when used for configuration.\n========\nsaneyaml\n========\n\nThis micro library is a PyYaml wrapper with sane behaviour to read and\nwrite readable YAML safely, typically when used with configuration files.\n\nWith saneyaml you can dump readable and clean YAML and load safely any YAML\npreserving ordering and avoiding surprises of type conversions by loading\neverything except booleans as strings.\nOptionally you can check for duplicated map keys when loading YAML.\n\nWorks with Python 3. Requires PyYAML 5.x.\n\nlicense: apache-2.0\nhomepage_url: https://github.com/nexB/saneyaml\n\nUsage::\n\n pip install saneyaml\n\n >>> from saneyaml import load\n >>> from saneyaml import dump\n >>> a=load('''version: 3.0.0.dev6\n ... \n ... description: |\n ... AboutCode Toolkit is a tool to process ABOUT files. An ABOUT file\n ... provides a way to document a software component.\n ... ''')\n >>> a\n dict([\n (u'version', u'3.0.0.dev6'), \n (u'description', u'AboutCode Toolkit is a tool to process ABOUT files. '\n 'An ABOUT file\\nprovides a way to document a software component.\\n')])\n\n >>> pprint(a.items())\n [(u'version', u'3.0.0.dev6'),\n (u'description',\n u'AboutCode Toolkit is a tool to process ABOUT files. An ABOUT file\\nprovides a way to document a software component.\\n')]\n >>> print(dump(a))\n version: 3.0.0.dev6\n description: |\n AboutCode Toolkit is a tool to process ABOUT files. An ABOUT file\n provides a way to document a software component.", - "release_date": "2021-03-31T12:38:43", + "description": "A utility belt for advanced users of python-requests\nThe Requests Toolbelt\n=====================\n\nThis is just a collection of utilities for `python-requests`_, but don't \nreally belong in ``requests`` proper. The minimum tested requests version is \n``2.1.0``. In reality, the toolbelt should work with ``2.0.1`` as well, but \nsome idiosyncracies prevent effective or sane testing on that version.\n\n``pip install requests-toolbelt`` to get started!\n\n\nmultipart/form-data Encoder\n---------------------------\n\nThe main attraction is a streaming multipart form-data object, ``MultipartEncoder``.\nIts API looks like this:\n\n.. code-block:: python\n\n from requests_toolbelt import MultipartEncoder\n import requests\n\n m = MultipartEncoder(\n fields={'field0': 'value', 'field1': 'value',\n 'field2': ('filename', open('file.py', 'rb'), 'text/plain')}\n )\n\n r = requests.post('http://httpbin.org/post', data=m,\n headers={'Content-Type': m.content_type})\n\n\nYou can also use ``multipart/form-data`` encoding for requests that don't\nrequire files:\n\n.. code-block:: python\n\n from requests_toolbelt import MultipartEncoder\n import requests\n\n m = MultipartEncoder(fields={'field0': 'value', 'field1': 'value'})\n\n r = requests.post('http://httpbin.org/post', data=m,\n headers={'Content-Type': m.content_type})\n\n\nOr, you can just create the string and examine the data:\n\n.. code-block:: python\n\n # Assuming `m` is one of the above\n m.to_string() # Always returns unicode\n\n\nUser-Agent constructor\n----------------------\n\nYou can easily construct a requests-style ``User-Agent`` string::\n\n from requests_toolbelt import user_agent\n\n headers = {\n 'User-Agent': user_agent('my_package', '0.0.1')\n }\n\n r = requests.get('https://api.github.com/users', headers=headers)\n\n\nSSLAdapter\n----------\n\nThe ``SSLAdapter`` was originally published on `Cory Benfield's blog`_. \nThis adapter allows the user to choose one of the SSL protocols made available \nin Python's ``ssl`` module for outgoing HTTPS connections:\n\n.. code-block:: python\n\n from requests_toolbelt import SSLAdapter\n import requests\n import ssl\n\n s = requests.Session()\n s.mount('https://', SSLAdapter(ssl.PROTOCOL_TLSv1))\n\ncookies/ForgetfulCookieJar\n--------------------------\n\nThe ``ForgetfulCookieJar`` prevents a particular requests session from storing \ncookies:\n\n.. code-block:: python\n\n from requests_toolbelt.cookies.forgetful import ForgetfulCookieJar\n\n session = requests.Session()\n session.cookies = ForgetfulCookieJar()\n\nKnown Issues\n------------\n\nOn Python 3.3.0 and 3.3.1, the standard library's ``http`` module will fail\nwhen passing an instance of the ``MultipartEncoder``. This is fixed in later\nminor releases of Python 3.3. Please consider upgrading to a later minor\nversion or Python 3.4. *There is absolutely nothing this library can do to\nwork around that bug.*\n\nContributing\n------------\n\nPlease read the `suggested workflow\n`_ for\ncontributing to this project.\n\nPlease report any bugs on the `issue tracker`_\n\n.. _Cory Benfield's blog: https://lukasa.co.uk/2013/01/Choosing_SSL_Version_In_Requests/\n.. _python-requests: https://github.com/kennethreitz/requests\n.. _issue tracker: https://github.com/requests/toolbelt/issues\n\n\nHistory\n=======\n\n0.9.1 -- 2019-01-29\n-------------------\n\nFixed Bugs\n~~~~~~~~~~\n\n- Fix import of pyOpenSSL shim from urllib3 for PKCS12 adapter\n\n0.9.0 -- 2019-01-29\n-------------------\n\nNew Features\n~~~~~~~~~~~~\n\n- Add X509 Adapter that can handle PKCS12 \n- Add stateless solution for streaming files by MultipartEncoder from one host to another (in chunks)\n\nFixed Bugs\n~~~~~~~~~~\n\n- Update link to example\n- Move import of ``ABCs`` from collections into version-specific part of\n _compat module\n- Fix backwards incompatibility in ``get_encodings_from_content``\n- Correct callback documentation for ``MultipartEncoderMonitor``\n- Fix bug when ``MultipartEncoder`` is asked to encode zero parts\n- Correct the type of non string request body dumps\n- Removed content from being stored in MultipartDecoder\n- Fix bug by enabling support for contenttype with capital letters. \n- Coerce proxy URL to bytes before dumping request\n- Avoid bailing out with exception upon empty response reason\n- Corrected Pool documentation\n- Corrected parentheses match in example usage\n- Fix \"oject\" to \"object\" in ``MultipartEncoder``\n- Fix URL for the project after the move \n- Add fix for OSX TCPKeepAliveAdapter\n\nMiscellaneous\n~~~~~~~~~~~~~\n\n- Remove py33 from testing and add Python 3.6 and nightly testing to the travis matrix.\n\n0.8.0 -- 2017-05-20\n-------------------\n\nMore information about this release can be found on the `0.8.0 milestone`_.\n\nNew Features\n~~~~~~~~~~~~\n\n- Add ``UserAgentBuilder`` to provide more control over generated User-Agent\n strings.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Include ``_validate_certificate`` in the lits of picked attributes on the\n ``AppEngineAdapter``.\n- Fix backwards incompatibility in ``get_encodings_from_content``\n\n.. _0.8.0 milestone:\n https://github.com/requests/toolbelt/milestones/0.8.0\n\n0.7.1 -- 2017-02-13\n-------------------\n\nMore information about this release can be found on the `0.7.1 milestone`_.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Fixed monkey-patching for the AppEngineAdapter.\n\n- Make it easier to disable certificate verification when monkey-patching\n AppEngine.\n\n- Handle ``multipart/form-data`` bodies without a trailing ``CRLF``.\n\n\n.. links\n.. _0.7.1 milestone:\n https://github.com/requests/toolbelt/milestone/9\n\n0.7.0 -- 2016-07-21\n-------------------\n\nMore information about this release can be found on the `0.7.0 milestone`_.\n\nNew Features\n~~~~~~~~~~~~\n\n- Add ``BaseUrlSession`` to allow developers to have a session that has a\n \"Base\" URL. See the documentation for more details and examples.\n\n- Split the logic of ``stream_response_to_file`` into two separate functions:\n\n * ``get_download_file_path`` to generate the file name from the Response.\n\n * ``stream_response_to_file`` which will use ``get_download_file_path`` if\n necessary\n\nFixed Bugs\n~~~~~~~~~~\n\n- Fixed the issue for people using *very* old versions of Requests where they\n would see an ImportError from ``requests_toolbelt._compat`` when trying to\n import ``connection``.\n\n\n.. _0.7.0 milestone:\n https://github.com/requests/toolbelt/milestones/0.7.0\n\n0.6.2 -- 2016-05-10\n-------------------\n\nFixed Bugs\n~~~~~~~~~~\n\n- When passing a timeout via Requests, it was not appropriately translated to\n the timeout that the urllib3 code was expecting.\n\n0.6.1 -- 2016-05-05\n-------------------\n\nFixed Bugs\n~~~~~~~~~~\n\n- Remove assertion about request URLs in the AppEngineAdapter.\n\n- Prevent pip from installing requests 3.0.0 when that is released until we\n are ready to handle it.\n\n0.6.0 -- 2016-01-27\n-------------------\n\nMore information about this release can be found on the `0.6.0 milestone`_.\n\nNew Features\n~~~~~~~~~~~~\n\n- Add ``AppEngineAdapter`` to support developers using Google's AppEngine\n platform with Requests.\n\n- Add ``GuessProxyAuth`` class to support guessing between Basic and Digest\n Authentication for proxies.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Ensure that proxies use the correct TLS version when using the\n ``SSLAdapter``.\n\n- Fix an ``AttributeError`` when using the ``HTTPProxyDigestAuth`` class.\n\nMiscellaneous\n~~~~~~~~~~~~~\n\n- Drop testing support for Python 3.2. virtualenv and pip have stopped\n supporting it meaning that it is harder to test for this with our CI\n infrastructure. Moving forward we will make a best-effort attempt to\n support 3.2 but will not test for it.\n\n\n.. _0.6.0 milestone:\n https://github.com/requests/toolbelt/milestones/0.6.0\n\n0.5.1 -- 2015-12-16\n-------------------\n\nMore information about this release can be found on the `0.5.1 milestone`_.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Now papers over the differences in requests' ``super_len`` function from\n versions prior to 2.9.0 and versions 2.9.0 and later.\n\n\n.. _0.5.1 milestone:\n https://github.com/requests/toolbelt/milestones/0.5.1\n\n0.5.0 -- 2015-11-24\n-------------------\n\nMore information about this release can be found on the `milestone\n`_\nfor 0.5.0.\n\nNew Features\n~~~~~~~~~~~~\n\n- The ``tee`` submodule was added to ``requests_toolbelt.downloadutils``. It\n allows you to iterate over the bytes of a response while also writing them\n to a file. The ``tee.tee`` function, expects you to pass an open file\n object, while ``tee.tee_to_file`` will use the provided file name to open\n the file for you.\n\n- Added a new parameter to ``requests_toolbelt.utils.user_agent`` that allows\n the user to specify additional items.\n\n- Added nested form-data helper,\n ``requests_toolbelt.utils.formdata.urlencode``.\n\n- Added the ``ForgetfulCookieJar`` to ``requests_toolbelt.cookies``.\n\n- Added utilities for dumping the information about a request-response cycle\n in ``requests_toolbelt.utils.dump``.\n\n- Implemented the API described in the ``requests_toolbelt.threaded`` module\n docstring, i.e., added ``requests_toolbelt.threaded.map`` as an available\n function.\n\nFixed Bugs\n~~~~~~~~~~\n\n- Now papers over the API differences in versions of requests installed from\n system packages versus versions of requests installed from PyPI.\n\n- Allow string types for ``SourceAddressAdapter``.\n\n0.4.0 -- 2015-04-03\n-------------------\n\nFor more information about this release, please see `milestone 0.4.0\n`_\non the project's page.\n\nNew Features\n~~~~~~~~~~~~\n\n- A naive implemenation of a thread pool is now included in the toolbelt. See\n the docs in ``docs/threading.rst`` or on `Read The Docs\n `_.\n\n- The ``StreamingIterator`` now accepts files (such as ``sys.stdin``) without\n a specific length and will properly stream them.\n\n- The ``MultipartEncoder`` now accepts exactly the same format of fields as\n requests' ``files`` parameter does. In other words, you can now also pass in\n extra headers to add to a part in the body. You can also now specify a\n custom ``Content-Type`` for a part.\n\n- An implementation of HTTP Digest Authentication for Proxies is now included.\n\n- A transport adapter that allows a user to specify a specific Certificate\n Fingerprint is now included in the toolbelt.\n\n- A transport adapter that simplifies how users specify socket options is now\n included.\n\n- A transport adapter that simplifies how users can specify TCP Keep-Alive\n options is now included in the toolbelt.\n\n- Deprecated functions from ``requests.utils`` are now included and\n maintained.\n\n- An authentication tool that allows users to specify how to authenticate to\n several different domains at once is now included.\n\n- A function to save streamed responses to disk by analyzing the\n ``Content-Disposition`` header is now included in the toolbelt.\n\nFixed Bugs\n~~~~~~~~~~\n\n- The ``MultipartEncoder`` will now allow users to upload files larger than\n 4GB on 32-bit systems.\n\n- The ``MultipartEncoder`` will now accept empty unicode strings for form\n values.\n\n0.3.1 -- 2014-06-23\n-------------------\n\n- Fix the fact that 0.3.0 bundle did not include the ``StreamingIterator``\n\n0.3.0 -- 2014-05-21\n-------------------\n\nBug Fixes\n~~~~~~~~~\n\n- Complete rewrite of ``MultipartEncoder`` fixes bug where bytes were lost in\n uploads\n\nNew Features\n~~~~~~~~~~~~\n\n- ``MultipartDecoder`` to accept ``multipart/form-data`` response bodies and\n parse them into an easy to use object.\n\n- ``SourceAddressAdapter`` to allow users to choose a local address to bind\n connections to.\n\n- ``GuessAuth`` which accepts a username and password and uses the\n ``WWW-Authenticate`` header to determine how to authenticate against a\n server.\n\n- ``MultipartEncoderMonitor`` wraps an instance of the ``MultipartEncoder``\n and keeps track of how many bytes were read and will call the provided\n callback.\n\n- ``StreamingIterator`` will wrap an iterator and stream the upload instead of\n chunk it, provided you also provide the length of the content you wish to\n upload.\n\n0.2.0 -- 2014-02-24\n-------------------\n\n- Add ability to tell ``MultipartEncoder`` which encoding to use. By default\n it uses 'utf-8'.\n\n- Fix #10 - allow users to install with pip\n\n- Fix #9 - Fix ``MultipartEncoder#to_string`` so that it properly handles file\n objects as fields\n\n0.1.2 -- 2014-01-19\n-------------------\n\n- At some point during development we broke how we handle normal file objects.\n Thanks to @konomae this is now fixed.\n\n0.1.1 -- 2014-01-19\n-------------------\n\n- Handle ``io.BytesIO``-like objects better\n\n0.1.0 -- 2014-01-18\n-------------------\n\n- Add initial implementation of the streaming ``MultipartEncoder``\n\n- Add initial implementation of the ``user_agent`` function\n\n- Add the ``SSLAdapter``", + "release_date": "2019-01-30T01:29:52", "parties": [ { "type": "person", "role": "author", - "name": "nexB. Inc. and others", - "email": "info@aboutcode.org", + "name": "Ian Cordasco, Cory Benfield", + "email": "graffatcolmingov@gmail.com", "url": null } ], "keywords": [ - "utilities yaml pyyaml block flow", "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Topic :: Software Development", - "Topic :: Utilities" + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: Implementation :: CPython" ], - "homepage_url": "https://github.com/nexB/saneyaml", - "download_url": "https://files.pythonhosted.org/packages/7e/62/68fe1eb6012393324af20f772fc37b2148cadcebbd8a610949e5a1b145b4/saneyaml-0.5.2-py3-none-any.whl", - "size": 11091, + "homepage_url": "https://toolbelt.readthedocs.org", + "download_url": "https://files.pythonhosted.org/packages/60/ef/7681134338fc097acef8d9b2f8abe0458e4d87559c689a8c306d0957ece5/requests_toolbelt-0.9.1-py2.py3-none-any.whl", + "size": 54314, "sha1": null, - "md5": "c82c53bde03e33dc149cba792e12ea62", - "sha256": "e54ed827973647ee9be8e8c091536b55ad22b3f9b1296e36701a3544822e7eac", + "md5": "f3c670220285a4cf8c5cbf1033090461", + "sha256": "380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -8608,7 +4882,10 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "Apache-2.0" + "license": "Apache 2.0", + "classifiers": [ + "License :: OSI Approved :: Apache Software License" + ] }, "notice_text": null, "source_packages": [], @@ -8617,52 +4894,66 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/saneyaml/0.5.2/json", + "api_data_url": "https://pypi.org/pypi/requests-toolbelt/0.9.1/json", "datasource_id": null, - "purl": "pkg:pypi/saneyaml@0.5.2" + "purl": "pkg:pypi/requests-toolbelt@0.9.1" }, { "type": "pypi", "namespace": null, - "name": "saneyaml", - "version": "0.5.2", + "name": "requests", + "version": "2.27.1", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Read and write readable YAML safely preserving order and avoiding bad surprises with unwanted infered type conversions. This library is a PyYaml wrapper with sane behaviour to read and write readable YAML safely, typically when used for configuration.\n========\nsaneyaml\n========\n\nThis micro library is a PyYaml wrapper with sane behaviour to read and\nwrite readable YAML safely, typically when used with configuration files.\n\nWith saneyaml you can dump readable and clean YAML and load safely any YAML\npreserving ordering and avoiding surprises of type conversions by loading\neverything except booleans as strings.\nOptionally you can check for duplicated map keys when loading YAML.\n\nWorks with Python 3. Requires PyYAML 5.x.\n\nlicense: apache-2.0\nhomepage_url: https://github.com/nexB/saneyaml\n\nUsage::\n\n pip install saneyaml\n\n >>> from saneyaml import load\n >>> from saneyaml import dump\n >>> a=load('''version: 3.0.0.dev6\n ... \n ... description: |\n ... AboutCode Toolkit is a tool to process ABOUT files. An ABOUT file\n ... provides a way to document a software component.\n ... ''')\n >>> a\n dict([\n (u'version', u'3.0.0.dev6'), \n (u'description', u'AboutCode Toolkit is a tool to process ABOUT files. '\n 'An ABOUT file\\nprovides a way to document a software component.\\n')])\n\n >>> pprint(a.items())\n [(u'version', u'3.0.0.dev6'),\n (u'description',\n u'AboutCode Toolkit is a tool to process ABOUT files. An ABOUT file\\nprovides a way to document a software component.\\n')]\n >>> print(dump(a))\n version: 3.0.0.dev6\n description: |\n AboutCode Toolkit is a tool to process ABOUT files. An ABOUT file\n provides a way to document a software component.", - "release_date": "2021-03-31T12:38:45", + "description": "Python HTTP for Humans.\n# Requests\n\n**Requests** is a simple, yet elegant, HTTP library.\n\n```python\n>>> import requests\n>>> r = requests.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass'))\n>>> r.status_code\n200\n>>> r.headers['content-type']\n'application/json; charset=utf8'\n>>> r.encoding\n'utf-8'\n>>> r.text\n'{\"authenticated\": true, ...'\n>>> r.json()\n{'authenticated': True, ...}\n```\n\nRequests allows you to send HTTP/1.1 requests extremely easily. There\u2019s no need to manually add query strings to your URLs, or to form-encode your `PUT` & `POST` data \u2014 but nowadays, just use the `json` method!\n\nRequests is one of the most downloaded Python packages today, pulling in around `30M downloads / week`\u2014 according to GitHub, Requests is currently [depended upon](https://github.com/psf/requests/network/dependents?package_id=UGFja2FnZS01NzA4OTExNg%3D%3D) by `1,000,000+` repositories. You may certainly put your trust in this code.\n\n[![Downloads](https://pepy.tech/badge/requests/month)](https://pepy.tech/project/requests)\n[![Supported Versions](https://img.shields.io/pypi/pyversions/requests.svg)](https://pypi.org/project/requests)\n[![Contributors](https://img.shields.io/github/contributors/psf/requests.svg)](https://github.com/psf/requests/graphs/contributors)\n\n## Installing Requests and Supported Versions\n\nRequests is available on PyPI:\n\n```console\n$ python -m pip install requests\n```\n\nRequests officially supports Python 2.7 & 3.6+.\n\n## Supported Features & Best\u2013Practices\n\nRequests is ready for the demands of building robust and reliable HTTP\u2013speaking applications, for the needs of today.\n\n- Keep-Alive & Connection Pooling\n- International Domains and URLs\n- Sessions with Cookie Persistence\n- Browser-style TLS/SSL Verification\n- Basic & Digest Authentication\n- Familiar `dict`\u2013like Cookies\n- Automatic Content Decompression and Decoding\n- Multi-part File Uploads\n- SOCKS Proxy Support\n- Connection Timeouts\n- Streaming Downloads\n- Automatic honoring of `.netrc`\n- Chunked HTTP Requests\n\n## API Reference and User Guide available on [Read the Docs](https://requests.readthedocs.io)\n\n[![Read the Docs](https://raw.githubusercontent.com/psf/requests/main/ext/ss.png)](https://requests.readthedocs.io)\n\n## Cloning the repository\n\nWhen cloning the Requests repository, you may need to add the `-c\nfetch.fsck.badTimezone=ignore` flag to avoid an error about a bad commit (see\n[this issue](https://github.com/psf/requests/issues/2690) for more background):\n\n```shell\ngit clone -c fetch.fsck.badTimezone=ignore https://github.com/psf/requests.git\n```\n\nYou can also apply this setting to your global Git config:\n\n```shell\ngit config --global fetch.fsck.badTimezone ignore\n```\n\n---\n\n[![Kenneth Reitz](https://raw.githubusercontent.com/psf/requests/main/ext/kr.png)](https://kennethreitz.org) [![Python Software Foundation](https://raw.githubusercontent.com/psf/requests/main/ext/psf.png)](https://www.python.org/psf)", + "release_date": "2022-01-05T15:40:49", "parties": [ { "type": "person", "role": "author", - "name": "nexB. Inc. and others", - "email": "info@aboutcode.org", + "name": "Kenneth Reitz", + "email": "me@kennethreitz.org", "url": null } ], "keywords": [ - "utilities yaml pyyaml block flow", "Development Status :: 5 - Production/Stable", + "Environment :: Web Environment", "Intended Audience :: Developers", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Topic :: Software Development", - "Topic :: Utilities" + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Software Development :: Libraries" ], - "homepage_url": "https://github.com/nexB/saneyaml", - "download_url": "https://files.pythonhosted.org/packages/d1/4a/7374cac103bdfec7c199606784119bee9171ba051290b219ffec1bedc650/saneyaml-0.5.2.tar.gz", - "size": 32034, + "homepage_url": "https://requests.readthedocs.io", + "download_url": "https://files.pythonhosted.org/packages/2d/61/08076519c80041bc0ffa1a8af0cbd3bf3e2b62af10435d269a9d0f40564d/requests-2.27.1-py2.py3-none-any.whl", + "size": 63133, "sha1": null, - "md5": "4985d7a8f4ad5af6ae53132e8d23a247", - "sha256": "d6074f1959041342ab41d74a6f904720ffbcf63c94467858e0e22e17e3c43d41", + "md5": "435db0f122c83decd27524f690e89650", + "sha256": "f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d", "sha512": null, "bug_tracking_url": null, - "code_view_url": null, + "code_view_url": "https://github.com/psf/requests", "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { - "license": "Apache-2.0" + "license": "Apache 2.0", + "classifiers": [ + "License :: OSI Approved :: Apache Software License" + ] }, "notice_text": null, "source_packages": [], @@ -8671,48 +4962,45 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/saneyaml/0.5.2/json", + "api_data_url": "https://pypi.org/pypi/requests/2.27.1/json", "datasource_id": null, - "purl": "pkg:pypi/saneyaml@0.5.2" + "purl": "pkg:pypi/requests@2.27.1" }, { "type": "pypi", "namespace": null, - "name": "secretstorage", - "version": "3.3.2", + "name": "resolvelib", + "version": "0.8.1", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Python bindings to FreeDesktop.org Secret Service API\n.. image:: https://github.com/mitya57/secretstorage/workflows/tests/badge.svg\n :target: https://github.com/mitya57/secretstorage/actions\n :alt: GitHub Actions status\n.. image:: https://codecov.io/gh/mitya57/secretstorage/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/mitya57/secretstorage\n :alt: Coverage status\n.. image:: https://readthedocs.org/projects/secretstorage/badge/?version=latest\n :target: https://secretstorage.readthedocs.io/en/latest/\n :alt: ReadTheDocs status\n\nModule description\n==================\n\nThis module provides a way for securely storing passwords and other secrets.\n\nIt uses D-Bus `Secret Service`_ API that is supported by GNOME Keyring,\nKSecretsService and KeePassXC.\n\nThe main classes provided are ``secretstorage.Item``, representing a secret\nitem (that has a *label*, a *secret* and some *attributes*) and\n``secretstorage.Collection``, a place items are stored in.\n\nSecretStorage supports most of the functions provided by Secret Service,\nincluding creating and deleting items and collections, editing items,\nlocking and unlocking collections (asynchronous unlocking is also supported).\n\nThe documentation can be found on `secretstorage.readthedocs.io`_.\n\n.. _`Secret Service`: https://specifications.freedesktop.org/secret-service/\n.. _`secretstorage.readthedocs.io`: https://secretstorage.readthedocs.io/en/latest/\n\nBuilding the module\n===================\n\n.. note::\n SecretStorage 3.x supports Python 3.6 and newer versions.\n If you have an older version of Python, install SecretStorage 2.x::\n\n pip install \"SecretStorage < 3\"\n\nSecretStorage requires these packages to work:\n\n* Jeepney_\n* `python-cryptography`_\n\nTo build SecretStorage, use this command::\n\n python3 setup.py build\n\nIf you have Sphinx_ installed, you can also build the documentation::\n\n python3 setup.py build_sphinx\n\n.. _Jeepney: https://pypi.org/project/jeepney/\n.. _`python-cryptography`: https://pypi.org/project/cryptography/\n.. _Sphinx: http://sphinx-doc.org/\n\nTesting the module\n==================\n\nFirst, make sure that you have the Secret Service daemon installed.\nThe `GNOME Keyring`_ is the reference server-side implementation for the\nSecret Service specification.\n\n.. _`GNOME Keyring`: https://download.gnome.org/sources/gnome-keyring/\n\nThen, start the daemon and unlock the ``default`` collection, if needed.\nThe testsuite will fail to run if the ``default`` collection exists and is\nlocked. If it does not exist, the testsuite can also use the temporary\n``session`` collection, as provided by the GNOME Keyring.\n\nThen, run the Python unittest module::\n\n python3 -m unittest discover -s tests\n\nIf you want to run the tests in an isolated or headless environment, run\nthis command in a D-Bus session::\n\n dbus-run-session -- python3 -m unittest discover -s tests\n\nGet the code\n============\n\nSecretStorage is available under BSD license. The source code can be found\non GitHub_.\n\n.. _GitHub: https://github.com/mitya57/secretstorage", - "release_date": "2022-04-19T08:43:42", + "description": "Resolve abstract dependencies into concrete ones\n==========\nResolveLib\n==========\n\nResolveLib at the highest level provides a ``Resolver`` class that includes\ndependency resolution logic. You give it some things, and a little information\non how it should interact with them, and it will spit out a resolution result.\n\n\nIntended Usage\n==============\n\n::\n\n import resolvelib\n\n # Things I want to resolve.\n requirements = [...]\n\n # Implement logic so the resolver understands the requirement format.\n class MyProvider:\n ...\n\n provider = MyProvider()\n reporter = resolvelib.BaseReporter()\n\n # Create the (reusable) resolver.\n resolver = resolvelib.Resolver(provider, reporter)\n\n # Kick off the resolution process, and get the final result.\n result = resolver.resolve(requirements)\n\nThe provider interface is specified in ``resolvelib.providers``. You don't\nneed to inherit anything, however, only need to implement the right methods.\n\n\nTerminology\n===========\n\nThe intention of this section is to unify the terms we use when talking about\nthis code base, and packaging in general, to avoid confusion. Class and\nvariable names in the code base should try to stick to terms defined here.\n\nThings passed into ``Resolver.resolve()`` and provided by the provider are all\nconsidered opaque. They don't need to adhere to this set of terminologies.\nNothing can go wrong as long as the provider implementers can keep their heads\nstraight.\n\nPackage\n-------\n\nA thing that can be installed. A Package can have one or more versions\navailable for installation.\n\nVersion\n-------\n\nA string, usually in a number form, describing a snapshot of a Package. This\nnumber should increase when a Package post a new snapshot, i.e. a higher number\nmeans a more up-to-date snapshot.\n\nSpecifier\n---------\n\nA collection of one or more Versions. This could be a wildcard, indicating that\nany Version is acceptable.\n\nCandidate\n---------\n\nA combination of a Package and a Version, i.e. a \"concrete requirement\". Python\npeople sometimes call this a \"locked\" or \"pinned\" dependency. Both of\n\"requirement\" and \"dependency\", however, SHOULD NOT be used when describing a\nCandidate, to avoid confusion.\n\nSome resolver architectures refer this as a \"specification\", but it is not\nused here to avoid confusion with a *Specifier*.\n\nRequirement\n-----------\n\nAn intention to acquire a needed package, i.e. an \"abstract requirement\". A\n\"dependency\", if not clarified otherwise, also refers to this concept.\n\nA Requirement should specify two things: a Package, and a Specifier.\n\nContributing\n============\n\nPlease see `developer documentation <./DEVELOPMENT.rst>`__.", + "release_date": "2021-10-11T21:08:08", "parties": [ { "type": "person", "role": "author", - "name": "Dmitry Shachnev", - "email": "mitya57@gmail.com", + "name": "Tzu-ping Chung", + "email": "uranusjr@gmail.com", "url": null } ], "keywords": [ - "Development Status :: 5 - Production/Stable", - "Operating System :: POSIX", - "Programming Language :: Python", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Topic :: Security", + "dependency", + "resolution", + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules" ], - "homepage_url": "https://github.com/mitya57/secretstorage", - "download_url": "https://files.pythonhosted.org/packages/54/42/7cf083c31a9739b40ed683fad17460d1db97ecd23c344df25e41fa9e85e2/SecretStorage-3.3.2-py3-none-any.whl", - "size": 15104, + "homepage_url": "https://github.com/sarugaku/resolvelib", + "download_url": "https://files.pythonhosted.org/packages/98/c0/46cfa3f56e43033b705965120058c018375600fa8fdb44c4e53d75820673/resolvelib-0.8.1-py2.py3-none-any.whl", + "size": 16113, "sha1": null, - "md5": "00bff7c27476e1a3072a6c454b4b6ace", - "sha256": "755dc845b6ad76dcbcbc07ea3da75ae54bb1ea529eb72d15f83d26499a5df319", + "md5": "9b92af9306678e346cd7f946a6419748", + "sha256": "d9b7907f055c3b3a2cfc56c914ffd940122915826ff5fb5b1de0c99778f4de98", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -8720,9 +5008,9 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "BSD 3-Clause License", + "license": "ISC License", "classifiers": [ - "License :: OSI Approved :: BSD License" + "License :: OSI Approved :: ISC License (ISCL)" ] }, "notice_text": null, @@ -8732,48 +5020,47 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/secretstorage/3.3.2/json", + "api_data_url": "https://pypi.org/pypi/resolvelib/0.8.1/json", "datasource_id": null, - "purl": "pkg:pypi/secretstorage@3.3.2" + "purl": "pkg:pypi/resolvelib@0.8.1" }, { "type": "pypi", "namespace": null, - "name": "secretstorage", - "version": "3.3.2", + "name": "rfc3986", + "version": "1.5.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Python bindings to FreeDesktop.org Secret Service API\n.. image:: https://github.com/mitya57/secretstorage/workflows/tests/badge.svg\n :target: https://github.com/mitya57/secretstorage/actions\n :alt: GitHub Actions status\n.. image:: https://codecov.io/gh/mitya57/secretstorage/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/mitya57/secretstorage\n :alt: Coverage status\n.. image:: https://readthedocs.org/projects/secretstorage/badge/?version=latest\n :target: https://secretstorage.readthedocs.io/en/latest/\n :alt: ReadTheDocs status\n\nModule description\n==================\n\nThis module provides a way for securely storing passwords and other secrets.\n\nIt uses D-Bus `Secret Service`_ API that is supported by GNOME Keyring,\nKSecretsService and KeePassXC.\n\nThe main classes provided are ``secretstorage.Item``, representing a secret\nitem (that has a *label*, a *secret* and some *attributes*) and\n``secretstorage.Collection``, a place items are stored in.\n\nSecretStorage supports most of the functions provided by Secret Service,\nincluding creating and deleting items and collections, editing items,\nlocking and unlocking collections (asynchronous unlocking is also supported).\n\nThe documentation can be found on `secretstorage.readthedocs.io`_.\n\n.. _`Secret Service`: https://specifications.freedesktop.org/secret-service/\n.. _`secretstorage.readthedocs.io`: https://secretstorage.readthedocs.io/en/latest/\n\nBuilding the module\n===================\n\n.. note::\n SecretStorage 3.x supports Python 3.6 and newer versions.\n If you have an older version of Python, install SecretStorage 2.x::\n\n pip install \"SecretStorage < 3\"\n\nSecretStorage requires these packages to work:\n\n* Jeepney_\n* `python-cryptography`_\n\nTo build SecretStorage, use this command::\n\n python3 setup.py build\n\nIf you have Sphinx_ installed, you can also build the documentation::\n\n python3 setup.py build_sphinx\n\n.. _Jeepney: https://pypi.org/project/jeepney/\n.. _`python-cryptography`: https://pypi.org/project/cryptography/\n.. _Sphinx: http://sphinx-doc.org/\n\nTesting the module\n==================\n\nFirst, make sure that you have the Secret Service daemon installed.\nThe `GNOME Keyring`_ is the reference server-side implementation for the\nSecret Service specification.\n\n.. _`GNOME Keyring`: https://download.gnome.org/sources/gnome-keyring/\n\nThen, start the daemon and unlock the ``default`` collection, if needed.\nThe testsuite will fail to run if the ``default`` collection exists and is\nlocked. If it does not exist, the testsuite can also use the temporary\n``session`` collection, as provided by the GNOME Keyring.\n\nThen, run the Python unittest module::\n\n python3 -m unittest discover -s tests\n\nIf you want to run the tests in an isolated or headless environment, run\nthis command in a D-Bus session::\n\n dbus-run-session -- python3 -m unittest discover -s tests\n\nGet the code\n============\n\nSecretStorage is available under BSD license. The source code can be found\non GitHub_.\n\n.. _GitHub: https://github.com/mitya57/secretstorage", - "release_date": "2022-04-19T08:43:43", + "description": "Validating URI References per RFC 3986\nrfc3986\n=======\n\nA Python implementation of `RFC 3986`_ including validation and authority \nparsing.\n\nInstallation\n------------\n\nUse pip to install ``rfc3986`` like so::\n\n pip install rfc3986\n\nLicense\n-------\n\n`Apache License Version 2.0`_\n\nExample Usage\n-------------\n\nThe following are the two most common use cases envisioned for ``rfc3986``.\n\nReplacing ``urlparse``\n``````````````````````\n\nTo parse a URI and receive something very similar to the standard library's\n``urllib.parse.urlparse``\n\n.. code-block:: python\n\n from rfc3986 import urlparse\n\n ssh = urlparse('ssh://user@git.openstack.org:29418/openstack/glance.git')\n print(ssh.scheme) # => ssh\n print(ssh.userinfo) # => user\n print(ssh.params) # => None\n print(ssh.port) # => 29418\n\nTo create a copy of it with new pieces you can use ``copy_with``:\n\n.. code-block:: python\n\n new_ssh = ssh.copy_with(\n scheme='https'\n userinfo='',\n port=443,\n path='/openstack/glance'\n )\n print(new_ssh.scheme) # => https\n print(new_ssh.userinfo) # => None\n # etc.\n\nStrictly Parsing a URI and Applying Validation\n``````````````````````````````````````````````\n\nTo parse a URI into a convenient named tuple, you can simply:\n\n.. code-block:: python\n\n from rfc3986 import uri_reference\n\n example = uri_reference('http://example.com')\n email = uri_reference('mailto:user@domain.com')\n ssh = uri_reference('ssh://user@git.openstack.org:29418/openstack/keystone.git')\n\nWith a parsed URI you can access data about the components:\n\n.. code-block:: python\n\n print(example.scheme) # => http\n print(email.path) # => user@domain.com\n print(ssh.userinfo) # => user\n print(ssh.host) # => git.openstack.org\n print(ssh.port) # => 29418\n\nIt can also parse URIs with unicode present:\n\n.. code-block:: python\n\n uni = uri_reference(b'http://httpbin.org/get?utf8=\\xe2\\x98\\x83') # \u2603\n print(uni.query) # utf8=%E2%98%83\n\nWith a parsed URI you can also validate it:\n\n.. code-block:: python\n\n if ssh.is_valid():\n subprocess.call(['git', 'clone', ssh.unsplit()])\n\nYou can also take a parsed URI and normalize it:\n\n.. code-block:: python\n\n mangled = uri_reference('hTTp://exAMPLe.COM')\n print(mangled.scheme) # => hTTp\n print(mangled.authority) # => exAMPLe.COM\n\n normal = mangled.normalize()\n print(normal.scheme) # => http\n print(mangled.authority) # => example.com\n\nBut these two URIs are (functionally) equivalent:\n\n.. code-block:: python\n\n if normal == mangled:\n webbrowser.open(normal.unsplit())\n\nYour paths, queries, and fragments are safe with us though:\n\n.. code-block:: python\n\n mangled = uri_reference('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth')\n normal = mangled.normalize()\n assert normal == 'hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth'\n assert normal == 'http://example.com/Some/reallY/biZZare/pAth'\n assert normal != 'http://example.com/some/really/bizzare/path'\n\nIf you do not actually need a real reference object and just want to normalize\nyour URI:\n\n.. code-block:: python\n\n from rfc3986 import normalize_uri\n\n assert (normalize_uri('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth') ==\n 'http://example.com/Some/reallY/biZZare/pAth')\n\nYou can also very simply validate a URI:\n\n.. code-block:: python\n\n from rfc3986 import is_valid_uri\n\n assert is_valid_uri('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth')\n\nRequiring Components\n~~~~~~~~~~~~~~~~~~~~\n\nYou can validate that a particular string is a valid URI and require\nindependent components:\n\n.. code-block:: python\n\n from rfc3986 import is_valid_uri\n\n assert is_valid_uri('http://localhost:8774/v2/resource',\n require_scheme=True,\n require_authority=True,\n require_path=True)\n\n # Assert that a mailto URI is invalid if you require an authority\n # component\n assert is_valid_uri('mailto:user@example.com', require_authority=True) is False\n\nIf you have an instance of a ``URIReference``, you can pass the same arguments\nto ``URIReference#is_valid``, e.g.,\n\n.. code-block:: python\n\n from rfc3986 import uri_reference\n\n http = uri_reference('http://localhost:8774/v2/resource')\n assert uri.is_valid(require_scheme=True,\n require_authority=True,\n require_path=True)\n\n # Assert that a mailto URI is invalid if you require an authority\n # component\n mailto = uri_reference('mailto:user@example.com')\n assert uri.is_valid(require_authority=True) is False\n\nAlternatives\n------------\n\n- `rfc3987 `_\n\n This is a direct competitor to this library, with extra features,\n licensed under the GPL.\n\n- `uritools `_\n\n This can parse URIs in the manner of RFC 3986 but provides no validation and\n only recently added Python 3 support.\n\n- Standard library's `urlparse`/`urllib.parse`\n\n The functions in these libraries can only split a URI (valid or not) and\n provide no validation.\n\nContributing\n------------\n\nThis project follows and enforces the Python Software Foundation's `Code of\nConduct `_.\n\nIf you would like to contribute but do not have a bug or feature in mind, feel\nfree to email Ian and find out how you can help.\n\nThe git repository for this project is maintained at\nhttps://github.com/python-hyper/rfc3986\n\n.. _RFC 3986: http://tools.ietf.org/html/rfc3986\n.. _Apache License Version 2.0: https://www.apache.org/licenses/LICENSE-2.0", + "release_date": "2021-05-07T23:29:25", "parties": [ { "type": "person", "role": "author", - "name": "Dmitry Shachnev", - "email": "mitya57@gmail.com", + "name": "Ian Stapleton Cordasco", + "email": "graffatcolmingov@gmail.com", "url": null } ], "keywords": [ "Development Status :: 5 - Production/Stable", - "Operating System :: POSIX", + "Intended Audience :: Developers", + "Natural Language :: English", "Programming Language :: Python", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", + "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 :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Topic :: Security", - "Topic :: Software Development :: Libraries :: Python Modules" + "Programming Language :: Python :: 3.7" ], - "homepage_url": "https://github.com/mitya57/secretstorage", - "download_url": "https://files.pythonhosted.org/packages/bc/3b/6e294fcaa5aed4059f2aa01a1ee7d343953521f8e0f6965ebcf63c950269/SecretStorage-3.3.2.tar.gz", - "size": 19285, + "homepage_url": "http://rfc3986.readthedocs.io", + "download_url": "https://files.pythonhosted.org/packages/c4/e5/63ca2c4edf4e00657584608bee1001302bbf8c5f569340b78304f2f446cb/rfc3986-1.5.0-py2.py3-none-any.whl", + "size": 31976, "sha1": null, - "md5": "4de3603efceaeba6194a833c32365812", - "sha256": "0a8eb9645b320881c222e827c26f4cfcf55363e8b374a021981ef886657a912f", + "md5": "7f72f95f22ce02cd7e286166322580be", + "sha256": "a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -8781,9 +5068,9 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "BSD 3-Clause License", + "license": "Apache 2.0", "classifiers": [ - "License :: OSI Approved :: BSD License" + "License :: OSI Approved :: Apache Software License" ] }, "notice_text": null, @@ -8793,43 +5080,44 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/secretstorage/3.3.2/json", + "api_data_url": "https://pypi.org/pypi/rfc3986/1.5.0/json", "datasource_id": null, - "purl": "pkg:pypi/secretstorage@3.3.2" + "purl": "pkg:pypi/rfc3986@1.5.0" }, { "type": "pypi", "namespace": null, - "name": "six", - "version": "1.16.0", + "name": "saneyaml", + "version": "0.5.2", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Python 2 and 3 compatibility utilities\n.. image:: https://img.shields.io/pypi/v/six.svg\n :target: https://pypi.org/project/six/\n :alt: six on PyPI\n\n.. image:: https://travis-ci.org/benjaminp/six.svg?branch=master\n :target: https://travis-ci.org/benjaminp/six\n :alt: six on TravisCI\n\n.. image:: https://readthedocs.org/projects/six/badge/?version=latest\n :target: https://six.readthedocs.io/\n :alt: six's documentation on Read the Docs\n\n.. image:: https://img.shields.io/badge/license-MIT-green.svg\n :target: https://github.com/benjaminp/six/blob/master/LICENSE\n :alt: MIT License badge\n\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 Python 2.7 and 3.3+. 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://six.readthedocs.io/.\n\nBugs can be reported to https://github.com/benjaminp/six. The code can also\nbe found there.", - "release_date": "2021-05-05T14:18:17", + "description": "Read and write readable YAML safely preserving order and avoiding bad surprises with unwanted infered type conversions. This library is a PyYaml wrapper with sane behaviour to read and write readable YAML safely, typically when used for configuration.\n========\nsaneyaml\n========\n\nThis micro library is a PyYaml wrapper with sane behaviour to read and\nwrite readable YAML safely, typically when used with configuration files.\n\nWith saneyaml you can dump readable and clean YAML and load safely any YAML\npreserving ordering and avoiding surprises of type conversions by loading\neverything except booleans as strings.\nOptionally you can check for duplicated map keys when loading YAML.\n\nWorks with Python 3. Requires PyYAML 5.x.\n\nlicense: apache-2.0\nhomepage_url: https://github.com/nexB/saneyaml\n\nUsage::\n\n pip install saneyaml\n\n >>> from saneyaml import load\n >>> from saneyaml import dump\n >>> a=load('''version: 3.0.0.dev6\n ... \n ... description: |\n ... AboutCode Toolkit is a tool to process ABOUT files. An ABOUT file\n ... provides a way to document a software component.\n ... ''')\n >>> a\n dict([\n (u'version', u'3.0.0.dev6'), \n (u'description', u'AboutCode Toolkit is a tool to process ABOUT files. '\n 'An ABOUT file\\nprovides a way to document a software component.\\n')])\n\n >>> pprint(a.items())\n [(u'version', u'3.0.0.dev6'),\n (u'description',\n u'AboutCode Toolkit is a tool to process ABOUT files. An ABOUT file\\nprovides a way to document a software component.\\n')]\n >>> print(dump(a))\n version: 3.0.0.dev6\n description: |\n AboutCode Toolkit is a tool to process ABOUT files. An ABOUT file\n provides a way to document a software component.", + "release_date": "2021-03-31T12:38:43", "parties": [ { "type": "person", "role": "author", - "name": "Benjamin Peterson", - "email": "benjamin@python.org", + "name": "nexB. Inc. and others", + "email": "info@aboutcode.org", "url": null } ], "keywords": [ + "utilities yaml pyyaml block flow", "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", - "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", - "Topic :: Software Development :: Libraries", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Software Development", "Topic :: Utilities" ], - "homepage_url": "https://github.com/benjaminp/six", - "download_url": "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", - "size": 11053, + "homepage_url": "https://github.com/nexB/saneyaml", + "download_url": "https://files.pythonhosted.org/packages/7e/62/68fe1eb6012393324af20f772fc37b2148cadcebbd8a610949e5a1b145b4/saneyaml-0.5.2-py3-none-any.whl", + "size": 11091, "sha1": null, - "md5": "529d7fd7e14612ccde86417b4402d6f3", - "sha256": "8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", + "md5": "c82c53bde03e33dc149cba792e12ea62", + "sha256": "e54ed827973647ee9be8e8c091536b55ad22b3f9b1296e36701a3544822e7eac", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -8837,10 +5125,7 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] + "license": "Apache-2.0" }, "notice_text": null, "source_packages": [], @@ -8849,43 +5134,48 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/six/1.16.0/json", + "api_data_url": "https://pypi.org/pypi/saneyaml/0.5.2/json", "datasource_id": null, - "purl": "pkg:pypi/six@1.16.0" + "purl": "pkg:pypi/saneyaml@0.5.2" }, { "type": "pypi", "namespace": null, - "name": "six", - "version": "1.16.0", + "name": "secretstorage", + "version": "3.3.2", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "Python 2 and 3 compatibility utilities\n.. image:: https://img.shields.io/pypi/v/six.svg\n :target: https://pypi.org/project/six/\n :alt: six on PyPI\n\n.. image:: https://travis-ci.org/benjaminp/six.svg?branch=master\n :target: https://travis-ci.org/benjaminp/six\n :alt: six on TravisCI\n\n.. image:: https://readthedocs.org/projects/six/badge/?version=latest\n :target: https://six.readthedocs.io/\n :alt: six's documentation on Read the Docs\n\n.. image:: https://img.shields.io/badge/license-MIT-green.svg\n :target: https://github.com/benjaminp/six/blob/master/LICENSE\n :alt: MIT License badge\n\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 Python 2.7 and 3.3+. 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://six.readthedocs.io/.\n\nBugs can be reported to https://github.com/benjaminp/six. The code can also\nbe found there.", - "release_date": "2021-05-05T14:18:18", + "description": "Python bindings to FreeDesktop.org Secret Service API\n.. image:: https://github.com/mitya57/secretstorage/workflows/tests/badge.svg\n :target: https://github.com/mitya57/secretstorage/actions\n :alt: GitHub Actions status\n.. image:: https://codecov.io/gh/mitya57/secretstorage/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/mitya57/secretstorage\n :alt: Coverage status\n.. image:: https://readthedocs.org/projects/secretstorage/badge/?version=latest\n :target: https://secretstorage.readthedocs.io/en/latest/\n :alt: ReadTheDocs status\n\nModule description\n==================\n\nThis module provides a way for securely storing passwords and other secrets.\n\nIt uses D-Bus `Secret Service`_ API that is supported by GNOME Keyring,\nKSecretsService and KeePassXC.\n\nThe main classes provided are ``secretstorage.Item``, representing a secret\nitem (that has a *label*, a *secret* and some *attributes*) and\n``secretstorage.Collection``, a place items are stored in.\n\nSecretStorage supports most of the functions provided by Secret Service,\nincluding creating and deleting items and collections, editing items,\nlocking and unlocking collections (asynchronous unlocking is also supported).\n\nThe documentation can be found on `secretstorage.readthedocs.io`_.\n\n.. _`Secret Service`: https://specifications.freedesktop.org/secret-service/\n.. _`secretstorage.readthedocs.io`: https://secretstorage.readthedocs.io/en/latest/\n\nBuilding the module\n===================\n\n.. note::\n SecretStorage 3.x supports Python 3.6 and newer versions.\n If you have an older version of Python, install SecretStorage 2.x::\n\n pip install \"SecretStorage < 3\"\n\nSecretStorage requires these packages to work:\n\n* Jeepney_\n* `python-cryptography`_\n\nTo build SecretStorage, use this command::\n\n python3 setup.py build\n\nIf you have Sphinx_ installed, you can also build the documentation::\n\n python3 setup.py build_sphinx\n\n.. _Jeepney: https://pypi.org/project/jeepney/\n.. _`python-cryptography`: https://pypi.org/project/cryptography/\n.. _Sphinx: http://sphinx-doc.org/\n\nTesting the module\n==================\n\nFirst, make sure that you have the Secret Service daemon installed.\nThe `GNOME Keyring`_ is the reference server-side implementation for the\nSecret Service specification.\n\n.. _`GNOME Keyring`: https://download.gnome.org/sources/gnome-keyring/\n\nThen, start the daemon and unlock the ``default`` collection, if needed.\nThe testsuite will fail to run if the ``default`` collection exists and is\nlocked. If it does not exist, the testsuite can also use the temporary\n``session`` collection, as provided by the GNOME Keyring.\n\nThen, run the Python unittest module::\n\n python3 -m unittest discover -s tests\n\nIf you want to run the tests in an isolated or headless environment, run\nthis command in a D-Bus session::\n\n dbus-run-session -- python3 -m unittest discover -s tests\n\nGet the code\n============\n\nSecretStorage is available under BSD license. The source code can be found\non GitHub_.\n\n.. _GitHub: https://github.com/mitya57/secretstorage", + "release_date": "2022-04-19T08:43:42", "parties": [ { "type": "person", "role": "author", - "name": "Benjamin Peterson", - "email": "benjamin@python.org", + "name": "Dmitry Shachnev", + "email": "mitya57@gmail.com", "url": null } ], "keywords": [ "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities" + "Operating System :: POSIX", + "Programming Language :: Python", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Topic :: Security", + "Topic :: Software Development :: Libraries :: Python Modules" ], - "homepage_url": "https://github.com/benjaminp/six", - "download_url": "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", - "size": 34041, + "homepage_url": "https://github.com/mitya57/secretstorage", + "download_url": "https://files.pythonhosted.org/packages/54/42/7cf083c31a9739b40ed683fad17460d1db97ecd23c344df25e41fa9e85e2/SecretStorage-3.3.2-py3-none-any.whl", + "size": 15104, "sha1": null, - "md5": "a7c927740e4964dd29b72cebfc1429bb", - "sha256": "1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "md5": "00bff7c27476e1a3072a6c454b4b6ace", + "sha256": "755dc845b6ad76dcbcbc07ea3da75ae54bb1ea529eb72d15f83d26499a5df319", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -8893,9 +5183,9 @@ "copyright": null, "license_expression": null, "declared_license": { - "license": "MIT", + "license": "BSD 3-Clause License", "classifiers": [ - "License :: OSI Approved :: MIT License" + "License :: OSI Approved :: BSD License" ] }, "notice_text": null, @@ -8905,56 +5195,43 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/six/1.16.0/json", + "api_data_url": "https://pypi.org/pypi/secretstorage/3.3.2/json", "datasource_id": null, - "purl": "pkg:pypi/six@1.16.0" + "purl": "pkg:pypi/secretstorage@3.3.2" }, { "type": "pypi", "namespace": null, - "name": "soupsieve", - "version": "2.3.2.post1", + "name": "six", + "version": "1.16.0", "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": "A modern CSS selector implementation for Beautiful Soup.\n[![Donate via PayPal][donate-image]][donate-link]\n[![Discord][discord-image]][discord-link]\n[![Build][github-ci-image]][github-ci-link]\n[![Coverage Status][codecov-image]][codecov-link]\n[![PyPI Version][pypi-image]][pypi-link]\n[![PyPI - Python Version][python-image]][pypi-link]\n![License][license-image-mit]\n\n# Soup Sieve\n\n## Overview\n\nSoup Sieve is a CSS selector library designed to be used with [Beautiful Soup 4][bs4]. It aims to provide selecting,\nmatching, and filtering using modern CSS selectors. Soup Sieve currently provides selectors from the CSS level 1\nspecifications up through the latest CSS level 4 drafts and beyond (though some are not yet implemented).\n\nSoup Sieve was written with the intent to replace Beautiful Soup's builtin select feature, and as of Beautiful Soup\nversion 4.7.0, it now is :confetti_ball:. Soup Sieve can also be imported in order to use its API directly for\nmore controlled, specialized parsing.\n\nSoup Sieve has implemented most of the CSS selectors up through the latest CSS draft specifications, though there are a\nnumber that don't make sense in a non-browser environment. Selectors that cannot provide meaningful functionality simply\ndo not match anything. Some of the supported selectors are:\n\n- `.classes`\n- `#ids`\n- `[attributes=value]`\n- `parent child`\n- `parent > child`\n- `sibling ~ sibling`\n- `sibling + sibling`\n- `:not(element.class, element2.class)`\n- `:is(element.class, element2.class)`\n- `parent:has(> child)`\n- and [many more](https://facelessuser.github.io/soupsieve/selectors/)\n\n\n## Installation\n\nYou must have Beautiful Soup already installed:\n\n```\npip install beautifulsoup4\n```\n\nIn most cases, assuming you've installed version 4.7.0, that should be all you need to do, but if you've installed via\nsome alternative method, and Soup Sieve is not automatically installed, you can install it directly:\n\n```\npip install soupsieve\n```\n\nIf you want to manually install it from source, first ensure that [`build`](https://pypi.org/project/build/) is\ninstalled:\n\n```\npip install build\n```\n\nThen navigate to the root of the project and build the wheel and install (replacing `` with the current version):\n\n```\npython -m build -w\npip install dist/soupsive--py3-none-any.whl\n```\n\n## Documentation\n\nDocumentation is found here: https://facelessuser.github.io/soupsieve/.\n\n## License\n\nMIT License\n\nCopyright (c) 2018 - 2022 Isaac Muse \n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit\npersons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the\nSoftware.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\nWARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n[bs4]: https://beautiful-soup-4.readthedocs.io/en/latest/#\n\n[github-ci-image]: https://github.com/facelessuser/soupsieve/workflows/build/badge.svg?branch=master&event=push\n[github-ci-link]: https://github.com/facelessuser/soupsieve/actions?query=workflow%3Abuild+branch%3Amaster\n[discord-image]: https://img.shields.io/discord/678289859768745989?logo=discord&logoColor=aaaaaa&color=mediumpurple&labelColor=333333\n[discord-link]:https://discord.gg/XBnPUZF\n[codecov-image]: https://img.shields.io/codecov/c/github/facelessuser/soupsieve/master.svg?logo=codecov&logoColor=aaaaaa&labelColor=333333\n[codecov-link]: https://codecov.io/github/facelessuser/soupsieve\n[pypi-image]: https://img.shields.io/pypi/v/soupsieve.svg?logo=pypi&logoColor=aaaaaa&labelColor=333333\n[pypi-link]: https://pypi.python.org/pypi/soupsieve\n[python-image]: https://img.shields.io/pypi/pyversions/soupsieve?logo=python&logoColor=aaaaaa&labelColor=333333\n[license-image-mit]: https://img.shields.io/badge/license-MIT-blue.svg?labelColor=333333\n[donate-image]: https://img.shields.io/badge/Donate-PayPal-3fabd1?logo=paypal\n[donate-link]: https://www.paypal.me/facelessuser", - "release_date": "2022-04-14T12:57:59", + "description": "Python 2 and 3 compatibility utilities\n.. image:: https://img.shields.io/pypi/v/six.svg\n :target: https://pypi.org/project/six/\n :alt: six on PyPI\n\n.. image:: https://travis-ci.org/benjaminp/six.svg?branch=master\n :target: https://travis-ci.org/benjaminp/six\n :alt: six on TravisCI\n\n.. image:: https://readthedocs.org/projects/six/badge/?version=latest\n :target: https://six.readthedocs.io/\n :alt: six's documentation on Read the Docs\n\n.. image:: https://img.shields.io/badge/license-MIT-green.svg\n :target: https://github.com/benjaminp/six/blob/master/LICENSE\n :alt: MIT License badge\n\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 Python 2.7 and 3.3+. 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://six.readthedocs.io/.\n\nBugs can be reported to https://github.com/benjaminp/six. The code can also\nbe found there.", + "release_date": "2021-05-05T14:18:17", "parties": [ { "type": "person", "role": "author", - "name": null, - "email": "Isaac Muse ", + "name": "Benjamin Peterson", + "email": "benjamin@python.org", "url": null } ], "keywords": [ - "CSS", - "HTML", - "XML", - "filter", - "query", - "selector", - "soup", "Development Status :: 5 - Production/Stable", - "Environment :: Console", "Intended Audience :: Developers", - "Operating System :: OS Independent", + "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Software Development :: Libraries :: Python Modules", - "Typing :: Typed" + "Topic :: Software Development :: Libraries", + "Topic :: Utilities" ], - "homepage_url": "", - "download_url": "https://files.pythonhosted.org/packages/16/e3/4ad79882b92617e3a4a0df1960d6bce08edfb637737ac5c3f3ba29022e25/soupsieve-2.3.2.post1-py3-none-any.whl", - "size": 37377, + "homepage_url": "https://github.com/benjaminp/six", + "download_url": "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", + "size": 11053, "sha1": null, - "md5": "61533b2123a0ea20b36847cdd862ba34", - "sha256": "3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759", + "md5": "529d7fd7e14612ccde86417b4402d6f3", + "sha256": "8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -8962,6 +5239,7 @@ "copyright": null, "license_expression": null, "declared_license": { + "license": "MIT", "classifiers": [ "License :: OSI Approved :: MIT License" ] @@ -8973,9 +5251,9 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/soupsieve/2.3.2.post1/json", + "api_data_url": "https://pypi.org/pypi/six/1.16.0/json", "datasource_id": null, - "purl": "pkg:pypi/soupsieve@2.3.2.post1" + "purl": "pkg:pypi/six@1.16.0" }, { "type": "pypi", @@ -8986,7 +5264,7 @@ "subpath": null, "primary_language": "Python", "description": "A modern CSS selector implementation for Beautiful Soup.\n[![Donate via PayPal][donate-image]][donate-link]\n[![Discord][discord-image]][discord-link]\n[![Build][github-ci-image]][github-ci-link]\n[![Coverage Status][codecov-image]][codecov-link]\n[![PyPI Version][pypi-image]][pypi-link]\n[![PyPI - Python Version][python-image]][pypi-link]\n![License][license-image-mit]\n\n# Soup Sieve\n\n## Overview\n\nSoup Sieve is a CSS selector library designed to be used with [Beautiful Soup 4][bs4]. It aims to provide selecting,\nmatching, and filtering using modern CSS selectors. Soup Sieve currently provides selectors from the CSS level 1\nspecifications up through the latest CSS level 4 drafts and beyond (though some are not yet implemented).\n\nSoup Sieve was written with the intent to replace Beautiful Soup's builtin select feature, and as of Beautiful Soup\nversion 4.7.0, it now is :confetti_ball:. Soup Sieve can also be imported in order to use its API directly for\nmore controlled, specialized parsing.\n\nSoup Sieve has implemented most of the CSS selectors up through the latest CSS draft specifications, though there are a\nnumber that don't make sense in a non-browser environment. Selectors that cannot provide meaningful functionality simply\ndo not match anything. Some of the supported selectors are:\n\n- `.classes`\n- `#ids`\n- `[attributes=value]`\n- `parent child`\n- `parent > child`\n- `sibling ~ sibling`\n- `sibling + sibling`\n- `:not(element.class, element2.class)`\n- `:is(element.class, element2.class)`\n- `parent:has(> child)`\n- and [many more](https://facelessuser.github.io/soupsieve/selectors/)\n\n\n## Installation\n\nYou must have Beautiful Soup already installed:\n\n```\npip install beautifulsoup4\n```\n\nIn most cases, assuming you've installed version 4.7.0, that should be all you need to do, but if you've installed via\nsome alternative method, and Soup Sieve is not automatically installed, you can install it directly:\n\n```\npip install soupsieve\n```\n\nIf you want to manually install it from source, first ensure that [`build`](https://pypi.org/project/build/) is\ninstalled:\n\n```\npip install build\n```\n\nThen navigate to the root of the project and build the wheel and install (replacing `` with the current version):\n\n```\npython -m build -w\npip install dist/soupsive--py3-none-any.whl\n```\n\n## Documentation\n\nDocumentation is found here: https://facelessuser.github.io/soupsieve/.\n\n## License\n\nMIT License\n\nCopyright (c) 2018 - 2022 Isaac Muse \n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit\npersons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the\nSoftware.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\nWARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n[bs4]: https://beautiful-soup-4.readthedocs.io/en/latest/#\n\n[github-ci-image]: https://github.com/facelessuser/soupsieve/workflows/build/badge.svg?branch=master&event=push\n[github-ci-link]: https://github.com/facelessuser/soupsieve/actions?query=workflow%3Abuild+branch%3Amaster\n[discord-image]: https://img.shields.io/discord/678289859768745989?logo=discord&logoColor=aaaaaa&color=mediumpurple&labelColor=333333\n[discord-link]:https://discord.gg/XBnPUZF\n[codecov-image]: https://img.shields.io/codecov/c/github/facelessuser/soupsieve/master.svg?logo=codecov&logoColor=aaaaaa&labelColor=333333\n[codecov-link]: https://codecov.io/github/facelessuser/soupsieve\n[pypi-image]: https://img.shields.io/pypi/v/soupsieve.svg?logo=pypi&logoColor=aaaaaa&labelColor=333333\n[pypi-link]: https://pypi.python.org/pypi/soupsieve\n[python-image]: https://img.shields.io/pypi/pyversions/soupsieve?logo=python&logoColor=aaaaaa&labelColor=333333\n[license-image-mit]: https://img.shields.io/badge/license-MIT-blue.svg?labelColor=333333\n[donate-image]: https://img.shields.io/badge/Donate-PayPal-3fabd1?logo=paypal\n[donate-link]: https://www.paypal.me/facelessuser", - "release_date": "2022-04-14T12:58:00", + "release_date": "2022-04-14T12:57:59", "parties": [ { "type": "person", @@ -9018,11 +5296,11 @@ "Typing :: Typed" ], "homepage_url": "", - "download_url": "https://files.pythonhosted.org/packages/f3/03/bac179d539362319b4779a00764e95f7542f4920084163db6b0fd4742d38/soupsieve-2.3.2.post1.tar.gz", - "size": 102814, + "download_url": "https://files.pythonhosted.org/packages/16/e3/4ad79882b92617e3a4a0df1960d6bce08edfb637737ac5c3f3ba29022e25/soupsieve-2.3.2.post1-py3-none-any.whl", + "size": 37377, "sha1": null, - "md5": "4c824620563604cbf783de149c8b8889", - "sha256": "fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d", + "md5": "61533b2123a0ea20b36847cdd862ba34", + "sha256": "3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -9111,72 +5389,6 @@ "datasource_id": null, "purl": "pkg:pypi/text-unidecode@1.3" }, - { - "type": "pypi", - "namespace": null, - "name": "text-unidecode", - "version": "1.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "The most basic Text::Unidecode port\nText-Unidecode\n==============\n\n.. image:: https://travis-ci.org/kmike/text-unidecode.svg?branch=master\n :target: https://travis-ci.org/kmike/text-unidecode\n :alt: Build Status\n\ntext-unidecode is the most basic port of the\n`Text::Unidecode `_\nPerl library.\n\nThere are other Python ports of Text::Unidecode (unidecode_\nand isounidecode_). unidecode_ is GPL; isounidecode_ uses too much memory,\nand it didn't support Python 3 when this package was created.\n\nYou can redistribute it and/or modify this port under the terms of either:\n\n* `Artistic License`_, or\n* GPL or GPLv2+\n\nIf you're OK with GPL-only, use unidecode_ (it has better memory usage and\nbetter transliteration quality).\n\n``text-unidecode`` supports Python 2.7 and 3.4+.\n\n.. _unidecode: https://pypi.python.org/pypi/Unidecode/\n.. _isounidecode: https://pypi.python.org/pypi/isounidecode/\n.. _Artistic License: https://opensource.org/licenses/Artistic-Perl-1.0\n\nInstallation\n------------\n\n::\n\n pip install text-unidecode\n\nUsage\n-----\n\n::\n\n >>> from text_unidecode import unidecode\n >>> unidecode(u'\u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0442\u0435\u043a\u0441\u0442')\n 'kakoi-to tekst'", - "release_date": "2019-08-30T21:36:45", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Mikhail Korobov", - "email": "kmike84@gmail.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "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 :: 3.7", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Text Processing :: Linguistic" - ], - "homepage_url": "https://github.com/kmike/text-unidecode/", - "download_url": "https://files.pythonhosted.org/packages/ab/e2/e9a00f0ccb71718418230718b3d900e71a5d16e701a3dae079a21e9cd8f8/text-unidecode-1.3.tar.gz", - "size": 76885, - "sha1": null, - "md5": "53a0a6c5aef8f5eb5834e78e0fdf0499", - "sha256": "bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "Artistic License", - "classifiers": [ - "License :: OSI Approved :: Artistic License", - "License :: OSI Approved :: GNU General Public License (GPL)", - "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/text-unidecode/1.3/json", - "datasource_id": null, - "purl": "pkg:pypi/text-unidecode@1.3" - }, { "type": "pypi", "namespace": null, @@ -9218,140 +5430,9 @@ "homepage_url": "https://github.com/uiri/toml", "download_url": "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", "size": 16588, - "sha1": null, - "md5": "dc26cd71b80d6757139f38156a43c545", - "sha256": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/toml/0.10.2/json", - "datasource_id": null, - "purl": "pkg:pypi/toml@0.10.2" - }, - { - "type": "pypi", - "namespace": null, - "name": "toml", - "version": "0.10.2", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Python Library for Tom's Obvious, Minimal Language\n****\nTOML\n****\n\n.. image:: https://img.shields.io/pypi/v/toml\n :target: https://pypi.org/project/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\n*toml.dump* takes a dictionary and a file descriptor and returns a string containing the\ncorresponding TOML-formatted data.\n\n.. code:: pycon\n\n >>> with open('new_toml_file.toml', 'w') as f:\n ... new_toml_string = toml.dump(parsed_toml, f)\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": "2020-11-01T01:40:22", - "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 :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy" - ], - "homepage_url": "https://github.com/uiri/toml", - "download_url": "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", - "size": 22253, - "sha1": null, - "md5": "59bce5d8d67e858735ec3f399ec90253", - "sha256": "b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/toml/0.10.2/json", - "datasource_id": null, - "purl": "pkg:pypi/toml@0.10.2" - }, - { - "type": "pypi", - "namespace": null, - "name": "tomli", - "version": "1.2.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "[![Build Status](https://github.com/hukkin/tomli/workflows/Tests/badge.svg?branch=master)](https://github.com/hukkin/tomli/actions?query=workflow%3ATests+branch%3Amaster+event%3Apush)\n[![codecov.io](https://codecov.io/gh/hukkin/tomli/branch/master/graph/badge.svg)](https://codecov.io/gh/hukkin/tomli)\n[![PyPI version](https://img.shields.io/pypi/v/tomli)](https://pypi.org/project/tomli)\n\n# Tomli\n\n> A lil' TOML parser\n\n**Table of Contents** *generated with [mdformat-toc](https://github.com/hukkin/mdformat-toc)*\n\n\n\n- [Intro](#intro)\n- [Installation](#installation)\n- [Usage](#usage)\n - [Parse a TOML string](#parse-a-toml-string)\n - [Parse a TOML file](#parse-a-toml-file)\n - [Handle invalid TOML](#handle-invalid-toml)\n - [Construct `decimal.Decimal`s from TOML floats](#construct-decimaldecimals-from-toml-floats)\n- [FAQ](#faq)\n - [Why this parser?](#why-this-parser)\n - [Is comment preserving round-trip parsing supported?](#is-comment-preserving-round-trip-parsing-supported)\n - [Is there a `dumps`, `write` or `encode` function?](#is-there-a-dumps-write-or-encode-function)\n - [How do TOML types map into Python types?](#how-do-toml-types-map-into-python-types)\n- [Performance](#performance)\n\n\n\n## Intro\n\nTomli is a Python library for parsing [TOML](https://toml.io).\nTomli is fully compatible with [TOML v1.0.0](https://toml.io/en/v1.0.0).\n\n## Installation\n\n```bash\npip install tomli\n```\n\n## Usage\n\n### Parse a TOML string\n\n```python\nimport tomli\n\ntoml_str = \"\"\"\n gretzky = 99\n\n [kurri]\n jari = 17\n \"\"\"\n\ntoml_dict = tomli.loads(toml_str)\nassert toml_dict == {\"gretzky\": 99, \"kurri\": {\"jari\": 17}}\n```\n\n### Parse a TOML file\n\n```python\nimport tomli\n\nwith open(\"path_to_file/conf.toml\", \"rb\") as f:\n toml_dict = tomli.load(f)\n```\n\nThe file must be opened in binary mode (with the `\"rb\"` flag).\nBinary mode will enforce decoding the file as UTF-8 with universal newlines disabled,\nboth of which are required to correctly parse TOML.\nSupport for text file objects is deprecated for removal in the next major release.\n\n### Handle invalid TOML\n\n```python\nimport tomli\n\ntry:\n toml_dict = tomli.loads(\"]] this is invalid TOML [[\")\nexcept tomli.TOMLDecodeError:\n print(\"Yep, definitely not valid.\")\n```\n\nNote that while the `TOMLDecodeError` type is public API, error messages of raised instances of it are not.\nError messages should not be assumed to stay constant across Tomli versions.\n\n### Construct `decimal.Decimal`s from TOML floats\n\n```python\nfrom decimal import Decimal\nimport tomli\n\ntoml_dict = tomli.loads(\"precision-matters = 0.982492\", parse_float=Decimal)\nassert toml_dict[\"precision-matters\"] == Decimal(\"0.982492\")\n```\n\nNote that `decimal.Decimal` can be replaced with another callable that converts a TOML float from string to a Python type.\nThe `decimal.Decimal` is, however, a practical choice for use cases where float inaccuracies can not be tolerated.\n\nIllegal types include `dict`, `list`, and anything that has the `append` attribute.\nParsing floats into an illegal type results in undefined behavior.\n\n## FAQ\n\n### Why this parser?\n\n- it's lil'\n- pure Python with zero dependencies\n- the fastest pure Python parser [\\*](#performance):\n 15x as fast as [tomlkit](https://pypi.org/project/tomlkit/),\n 2.4x as fast as [toml](https://pypi.org/project/toml/)\n- outputs [basic data types](#how-do-toml-types-map-into-python-types) only\n- 100% spec compliant: passes all tests in\n [a test set](https://github.com/toml-lang/compliance/pull/8)\n soon to be merged to the official\n [compliance tests for TOML](https://github.com/toml-lang/compliance)\n repository\n- thoroughly tested: 100% branch coverage\n\n### Is comment preserving round-trip parsing supported?\n\nNo.\n\nThe `tomli.loads` function returns a plain `dict` that is populated with builtin types and types from the standard library only.\nPreserving comments requires a custom type to be returned so will not be supported,\nat least not by the `tomli.loads` and `tomli.load` functions.\n\nLook into [TOML Kit](https://github.com/sdispater/tomlkit) if preservation of style is what you need.\n\n### Is there a `dumps`, `write` or `encode` function?\n\n[Tomli-W](https://github.com/hukkin/tomli-w) is the write-only counterpart of Tomli, providing `dump` and `dumps` functions.\n\nThe core library does not include write capability, as most TOML use cases are read-only, and Tomli intends to be minimal.\n\n### How do TOML types map into Python types?\n\n| TOML type | Python type | Details |\n| ---------------- | ------------------- | ------------------------------------------------------------ |\n| Document Root | `dict` | |\n| Key | `str` | |\n| String | `str` | |\n| Integer | `int` | |\n| Float | `float` | |\n| Boolean | `bool` | |\n| Offset Date-Time | `datetime.datetime` | `tzinfo` attribute set to an instance of `datetime.timezone` |\n| Local Date-Time | `datetime.datetime` | `tzinfo` attribute set to `None` |\n| Local Date | `datetime.date` | |\n| Local Time | `datetime.time` | |\n| Array | `list` | |\n| Table | `dict` | |\n| Inline Table | `dict` | |\n\n## Performance\n\nThe `benchmark/` folder in this repository contains a performance benchmark for comparing the various Python TOML parsers.\nThe benchmark can be run with `tox -e benchmark-pypi`.\nRunning the benchmark on my personal computer output the following:\n\n```console\nfoo@bar:~/dev/tomli$ tox -e benchmark-pypi\nbenchmark-pypi installed: attrs==19.3.0,click==7.1.2,pytomlpp==1.0.2,qtoml==0.3.0,rtoml==0.7.0,toml==0.10.2,tomli==1.1.0,tomlkit==0.7.2\nbenchmark-pypi run-test-pre: PYTHONHASHSEED='2658546909'\nbenchmark-pypi run-test: commands[0] | python -c 'import datetime; print(datetime.date.today())'\n2021-07-23\nbenchmark-pypi run-test: commands[1] | python --version\nPython 3.8.10\nbenchmark-pypi run-test: commands[2] | python benchmark/run.py\nParsing data.toml 5000 times:\n------------------------------------------------------\n parser | exec time | performance (more is better)\n-----------+------------+-----------------------------\n rtoml | 0.901 s | baseline (100%)\n pytomlpp | 1.08 s | 83.15%\n tomli | 3.89 s | 23.15%\n toml | 9.36 s | 9.63%\n qtoml | 11.5 s | 7.82%\n tomlkit | 56.8 s | 1.59%\n```\n\nThe parsers are ordered from fastest to slowest, using the fastest parser as baseline.\nTomli performed the best out of all pure Python TOML parsers,\nlosing only to pytomlpp (wraps C++) and rtoml (wraps Rust).", - "release_date": "2021-12-13T22:25:05", - "parties": [ - { - "type": "person", - "role": "author", - "name": null, - "email": "Taneli Hukkinen ", - "url": null - } - ], - "keywords": [ - "toml", - "Operating System :: MacOS", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX :: Linux", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Libraries :: Python Modules", - "Typing :: Typed" - ], - "homepage_url": "", - "download_url": "https://files.pythonhosted.org/packages/05/e4/74f9440db36734d7ba83c574c1e7024009ce849208a41f90e94a134dc6d1/tomli-1.2.3-py3-none-any.whl", - "size": 12122, - "sha1": null, - "md5": "bb3def426bcaebfc80b6ebe741f410fb", - "sha256": "e3069e4be3ead9668e21cb9b074cd948f7b3113fd9c8bba083f48247aab8b11c", + "sha1": null, + "md5": "dc26cd71b80d6757139f38156a43c545", + "sha256": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -9359,6 +5440,7 @@ "copyright": null, "license_expression": null, "declared_license": { + "license": "MIT", "classifiers": [ "License :: OSI Approved :: MIT License" ] @@ -9370,9 +5452,9 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/tomli/1.2.3/json", + "api_data_url": "https://pypi.org/pypi/toml/0.10.2/json", "datasource_id": null, - "purl": "pkg:pypi/tomli@1.2.3" + "purl": "pkg:pypi/toml@0.10.2" }, { "type": "pypi", @@ -9383,7 +5465,7 @@ "subpath": null, "primary_language": "Python", "description": "[![Build Status](https://github.com/hukkin/tomli/workflows/Tests/badge.svg?branch=master)](https://github.com/hukkin/tomli/actions?query=workflow%3ATests+branch%3Amaster+event%3Apush)\n[![codecov.io](https://codecov.io/gh/hukkin/tomli/branch/master/graph/badge.svg)](https://codecov.io/gh/hukkin/tomli)\n[![PyPI version](https://img.shields.io/pypi/v/tomli)](https://pypi.org/project/tomli)\n\n# Tomli\n\n> A lil' TOML parser\n\n**Table of Contents** *generated with [mdformat-toc](https://github.com/hukkin/mdformat-toc)*\n\n\n\n- [Intro](#intro)\n- [Installation](#installation)\n- [Usage](#usage)\n - [Parse a TOML string](#parse-a-toml-string)\n - [Parse a TOML file](#parse-a-toml-file)\n - [Handle invalid TOML](#handle-invalid-toml)\n - [Construct `decimal.Decimal`s from TOML floats](#construct-decimaldecimals-from-toml-floats)\n- [FAQ](#faq)\n - [Why this parser?](#why-this-parser)\n - [Is comment preserving round-trip parsing supported?](#is-comment-preserving-round-trip-parsing-supported)\n - [Is there a `dumps`, `write` or `encode` function?](#is-there-a-dumps-write-or-encode-function)\n - [How do TOML types map into Python types?](#how-do-toml-types-map-into-python-types)\n- [Performance](#performance)\n\n\n\n## Intro\n\nTomli is a Python library for parsing [TOML](https://toml.io).\nTomli is fully compatible with [TOML v1.0.0](https://toml.io/en/v1.0.0).\n\n## Installation\n\n```bash\npip install tomli\n```\n\n## Usage\n\n### Parse a TOML string\n\n```python\nimport tomli\n\ntoml_str = \"\"\"\n gretzky = 99\n\n [kurri]\n jari = 17\n \"\"\"\n\ntoml_dict = tomli.loads(toml_str)\nassert toml_dict == {\"gretzky\": 99, \"kurri\": {\"jari\": 17}}\n```\n\n### Parse a TOML file\n\n```python\nimport tomli\n\nwith open(\"path_to_file/conf.toml\", \"rb\") as f:\n toml_dict = tomli.load(f)\n```\n\nThe file must be opened in binary mode (with the `\"rb\"` flag).\nBinary mode will enforce decoding the file as UTF-8 with universal newlines disabled,\nboth of which are required to correctly parse TOML.\nSupport for text file objects is deprecated for removal in the next major release.\n\n### Handle invalid TOML\n\n```python\nimport tomli\n\ntry:\n toml_dict = tomli.loads(\"]] this is invalid TOML [[\")\nexcept tomli.TOMLDecodeError:\n print(\"Yep, definitely not valid.\")\n```\n\nNote that while the `TOMLDecodeError` type is public API, error messages of raised instances of it are not.\nError messages should not be assumed to stay constant across Tomli versions.\n\n### Construct `decimal.Decimal`s from TOML floats\n\n```python\nfrom decimal import Decimal\nimport tomli\n\ntoml_dict = tomli.loads(\"precision-matters = 0.982492\", parse_float=Decimal)\nassert toml_dict[\"precision-matters\"] == Decimal(\"0.982492\")\n```\n\nNote that `decimal.Decimal` can be replaced with another callable that converts a TOML float from string to a Python type.\nThe `decimal.Decimal` is, however, a practical choice for use cases where float inaccuracies can not be tolerated.\n\nIllegal types include `dict`, `list`, and anything that has the `append` attribute.\nParsing floats into an illegal type results in undefined behavior.\n\n## FAQ\n\n### Why this parser?\n\n- it's lil'\n- pure Python with zero dependencies\n- the fastest pure Python parser [\\*](#performance):\n 15x as fast as [tomlkit](https://pypi.org/project/tomlkit/),\n 2.4x as fast as [toml](https://pypi.org/project/toml/)\n- outputs [basic data types](#how-do-toml-types-map-into-python-types) only\n- 100% spec compliant: passes all tests in\n [a test set](https://github.com/toml-lang/compliance/pull/8)\n soon to be merged to the official\n [compliance tests for TOML](https://github.com/toml-lang/compliance)\n repository\n- thoroughly tested: 100% branch coverage\n\n### Is comment preserving round-trip parsing supported?\n\nNo.\n\nThe `tomli.loads` function returns a plain `dict` that is populated with builtin types and types from the standard library only.\nPreserving comments requires a custom type to be returned so will not be supported,\nat least not by the `tomli.loads` and `tomli.load` functions.\n\nLook into [TOML Kit](https://github.com/sdispater/tomlkit) if preservation of style is what you need.\n\n### Is there a `dumps`, `write` or `encode` function?\n\n[Tomli-W](https://github.com/hukkin/tomli-w) is the write-only counterpart of Tomli, providing `dump` and `dumps` functions.\n\nThe core library does not include write capability, as most TOML use cases are read-only, and Tomli intends to be minimal.\n\n### How do TOML types map into Python types?\n\n| TOML type | Python type | Details |\n| ---------------- | ------------------- | ------------------------------------------------------------ |\n| Document Root | `dict` | |\n| Key | `str` | |\n| String | `str` | |\n| Integer | `int` | |\n| Float | `float` | |\n| Boolean | `bool` | |\n| Offset Date-Time | `datetime.datetime` | `tzinfo` attribute set to an instance of `datetime.timezone` |\n| Local Date-Time | `datetime.datetime` | `tzinfo` attribute set to `None` |\n| Local Date | `datetime.date` | |\n| Local Time | `datetime.time` | |\n| Array | `list` | |\n| Table | `dict` | |\n| Inline Table | `dict` | |\n\n## Performance\n\nThe `benchmark/` folder in this repository contains a performance benchmark for comparing the various Python TOML parsers.\nThe benchmark can be run with `tox -e benchmark-pypi`.\nRunning the benchmark on my personal computer output the following:\n\n```console\nfoo@bar:~/dev/tomli$ tox -e benchmark-pypi\nbenchmark-pypi installed: attrs==19.3.0,click==7.1.2,pytomlpp==1.0.2,qtoml==0.3.0,rtoml==0.7.0,toml==0.10.2,tomli==1.1.0,tomlkit==0.7.2\nbenchmark-pypi run-test-pre: PYTHONHASHSEED='2658546909'\nbenchmark-pypi run-test: commands[0] | python -c 'import datetime; print(datetime.date.today())'\n2021-07-23\nbenchmark-pypi run-test: commands[1] | python --version\nPython 3.8.10\nbenchmark-pypi run-test: commands[2] | python benchmark/run.py\nParsing data.toml 5000 times:\n------------------------------------------------------\n parser | exec time | performance (more is better)\n-----------+------------+-----------------------------\n rtoml | 0.901 s | baseline (100%)\n pytomlpp | 1.08 s | 83.15%\n tomli | 3.89 s | 23.15%\n toml | 9.36 s | 9.63%\n qtoml | 11.5 s | 7.82%\n tomlkit | 56.8 s | 1.59%\n```\n\nThe parsers are ordered from fastest to slowest, using the fastest parser as baseline.\nTomli performed the best out of all pure Python TOML parsers,\nlosing only to pytomlpp (wraps C++) and rtoml (wraps Rust).", - "release_date": "2021-12-13T22:25:06", + "release_date": "2021-12-13T22:25:05", "parties": [ { "type": "person", @@ -9410,11 +5492,11 @@ "Typing :: Typed" ], "homepage_url": "", - "download_url": "https://files.pythonhosted.org/packages/fb/2e/d0a8276b0cf9b9e34fd0660c330acc59656f53bb2209adc75af863a3582d/tomli-1.2.3.tar.gz", - "size": 15094, + "download_url": "https://files.pythonhosted.org/packages/05/e4/74f9440db36734d7ba83c574c1e7024009ce849208a41f90e94a134dc6d1/tomli-1.2.3-py3-none-any.whl", + "size": 12122, "sha1": null, - "md5": "807cc80e6a2697375f431b757994b7c5", - "sha256": "05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f", + "md5": "bb3def426bcaebfc80b6ebe741f410fb", + "sha256": "e3069e4be3ead9668e21cb9b074cd948f7b3113fd9c8bba083f48247aab8b11c", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -9552,121 +5634,6 @@ "datasource_id": null, "purl": "pkg:pypi/tqdm@4.64.0" }, - { - "type": "pypi", - "namespace": null, - "name": "tqdm", - "version": "4.64.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Fast, Extensible Progress Meter\n|Logo|\n\ntqdm\n====\n\n|Py-Versions| |Versions| |Conda-Forge-Status| |Docker| |Snapcraft|\n\n|Build-Status| |Coverage-Status| |Branch-Coverage-Status| |Codacy-Grade| |Libraries-Rank| |PyPI-Downloads|\n\n|LICENCE| |OpenHub-Status| |binder-demo| |awesome-python|\n\n``tqdm`` derives from the Arabic word *taqaddum* (\u062a\u0642\u062f\u0651\u0645) which can mean \"progress,\"\nand is an abbreviation for \"I love you so much\" in Spanish (*te quiero demasiado*).\n\nInstantly make your loops show a smart progress meter - just wrap any\niterable with ``tqdm(iterable)``, and you're done!\n\n.. code:: python\n\n from tqdm import tqdm\n for i in tqdm(range(10000)):\n ...\n\n``76%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | 7568/10000 [00:33<00:10, 229.00it/s]``\n\n``trange(N)`` can be also used as a convenient shortcut for\n``tqdm(range(N))``.\n\n|Screenshot|\n |Video| |Slides| |Merch|\n\nIt can also be executed as a module with pipes:\n\n.. code:: sh\n\n $ seq 9999999 | tqdm --bytes | wc -l\n 75.2MB [00:00, 217MB/s]\n 9999999\n\n $ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \\\n > backup.tgz\n 32%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258d | 8.89G/27.9G [00:42<01:31, 223MB/s]\n\nOverhead is low -- about 60ns per iteration (80ns with ``tqdm.gui``), and is\nunit tested against performance regression.\nBy comparison, the well-established\n`ProgressBar `__ has\nan 800ns/iter overhead.\n\nIn addition to its low overhead, ``tqdm`` uses smart algorithms to predict\nthe remaining time and to skip unnecessary iteration displays, which allows\nfor a negligible overhead in most cases.\n\n``tqdm`` works on any platform\n(Linux, Windows, Mac, FreeBSD, NetBSD, Solaris/SunOS),\nin any console or in a GUI, and is also friendly with IPython/Jupyter notebooks.\n\n``tqdm`` does not require any dependencies (not even ``curses``!), just\nPython and an environment supporting ``carriage return \\r`` and\n``line feed \\n`` control characters.\n\n------------------------------------------\n\n.. contents:: Table of contents\n :backlinks: top\n :local:\n\n\nInstallation\n------------\n\nLatest PyPI stable release\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n|Versions| |PyPI-Downloads| |Libraries-Dependents|\n\n.. code:: sh\n\n pip install tqdm\n\nLatest development release on GitHub\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n|GitHub-Status| |GitHub-Stars| |GitHub-Commits| |GitHub-Forks| |GitHub-Updated|\n\nPull and install pre-release ``devel`` branch:\n\n.. code:: sh\n\n pip install \"git+https://github.com/tqdm/tqdm.git@devel#egg=tqdm\"\n\nLatest Conda release\n~~~~~~~~~~~~~~~~~~~~\n\n|Conda-Forge-Status|\n\n.. code:: sh\n\n conda install -c conda-forge tqdm\n\nLatest Snapcraft release\n~~~~~~~~~~~~~~~~~~~~~~~~\n\n|Snapcraft|\n\nThere are 3 channels to choose from:\n\n.. code:: sh\n\n snap install tqdm # implies --stable, i.e. latest tagged release\n snap install tqdm --candidate # master branch\n snap install tqdm --edge # devel branch\n\nNote that ``snap`` binaries are purely for CLI use (not ``import``-able), and\nautomatically set up ``bash`` tab-completion.\n\nLatest Docker release\n~~~~~~~~~~~~~~~~~~~~~\n\n|Docker|\n\n.. code:: sh\n\n docker pull tqdm/tqdm\n docker run -i --rm tqdm/tqdm --help\n\nOther\n~~~~~\n\nThere are other (unofficial) places where ``tqdm`` may be downloaded, particularly for CLI use:\n\n|Repology|\n\n.. |Repology| image:: https://repology.org/badge/tiny-repos/python:tqdm.svg\n :target: https://repology.org/project/python:tqdm/versions\n\nChangelog\n---------\n\nThe list of all changes is available either on GitHub's Releases:\n|GitHub-Status|, on the\n`wiki `__, or on the\n`website `__.\n\n\nUsage\n-----\n\n``tqdm`` is very versatile and can be used in a number of ways.\nThe three main ones are given below.\n\nIterable-based\n~~~~~~~~~~~~~~\n\nWrap ``tqdm()`` around any iterable:\n\n.. code:: python\n\n from tqdm import tqdm\n from time import sleep\n\n text = \"\"\n for char in tqdm([\"a\", \"b\", \"c\", \"d\"]):\n sleep(0.25)\n text = text + char\n\n``trange(i)`` is a special optimised instance of ``tqdm(range(i))``:\n\n.. code:: python\n\n from tqdm import trange\n\n for i in trange(100):\n sleep(0.01)\n\nInstantiation outside of the loop allows for manual control over ``tqdm()``:\n\n.. code:: python\n\n pbar = tqdm([\"a\", \"b\", \"c\", \"d\"])\n for char in pbar:\n sleep(0.25)\n pbar.set_description(\"Processing %s\" % char)\n\nManual\n~~~~~~\n\nManual control of ``tqdm()`` updates using a ``with`` statement:\n\n.. code:: python\n\n with tqdm(total=100) as pbar:\n for i in range(10):\n sleep(0.1)\n pbar.update(10)\n\nIf the optional variable ``total`` (or an iterable with ``len()``) is\nprovided, predictive stats are displayed.\n\n``with`` is also optional (you can just assign ``tqdm()`` to a variable,\nbut in this case don't forget to ``del`` or ``close()`` at the end:\n\n.. code:: python\n\n pbar = tqdm(total=100)\n for i in range(10):\n sleep(0.1)\n pbar.update(10)\n pbar.close()\n\nModule\n~~~~~~\n\nPerhaps the most wonderful use of ``tqdm`` is in a script or on the command\nline. Simply inserting ``tqdm`` (or ``python -m tqdm``) between pipes will pass\nthrough all ``stdin`` to ``stdout`` while printing progress to ``stderr``.\n\nThe example below demonstrate counting the number of lines in all Python files\nin the current directory, with timing information included.\n\n.. code:: sh\n\n $ time find . -name '*.py' -type f -exec cat \\{} \\; | wc -l\n 857365\n\n real 0m3.458s\n user 0m0.274s\n sys 0m3.325s\n\n $ time find . -name '*.py' -type f -exec cat \\{} \\; | tqdm | wc -l\n 857366it [00:03, 246471.31it/s]\n 857365\n\n real 0m3.585s\n user 0m0.862s\n sys 0m3.358s\n\nNote that the usual arguments for ``tqdm`` can also be specified.\n\n.. code:: sh\n\n $ find . -name '*.py' -type f -exec cat \\{} \\; |\n tqdm --unit loc --unit_scale --total 857366 >> /dev/null\n 100%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588| 857K/857K [00:04<00:00, 246Kloc/s]\n\nBacking up a large directory?\n\n.. code:: sh\n\n $ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \\\n > backup.tgz\n 44%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258a | 153M/352M [00:14<00:18, 11.0MB/s]\n\nThis can be beautified further:\n\n.. code:: sh\n\n $ BYTES=\"$(du -sb docs/ | cut -f1)\"\n $ tar -cf - docs/ \\\n | tqdm --bytes --total \"$BYTES\" --desc Processing | gzip \\\n | tqdm --bytes --total \"$BYTES\" --desc Compressed --position 1 \\\n > ~/backup.tgz\n Processing: 100%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588| 352M/352M [00:14<00:00, 30.2MB/s]\n Compressed: 42%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258e | 148M/352M [00:14<00:19, 10.9MB/s]\n\nOr done on a file level using 7-zip:\n\n.. code:: sh\n\n $ 7z a -bd -r backup.7z docs/ | grep Compressing \\\n | tqdm --total $(find docs/ -type f | wc -l) --unit files \\\n | grep -v Compressing\n 100%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2589| 15327/15327 [01:00<00:00, 712.96files/s]\n\nPre-existing CLI programs already outputting basic progress information will\nbenefit from ``tqdm``'s ``--update`` and ``--update_to`` flags:\n\n.. code:: sh\n\n $ seq 3 0.1 5 | tqdm --total 5 --update_to --null\n 100%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588| 5.0/5 [00:00<00:00, 9673.21it/s]\n $ seq 10 | tqdm --update --null # 1 + 2 + ... + 10 = 55 iterations\n 55it [00:00, 90006.52it/s]\n\nFAQ and Known Issues\n--------------------\n\n|GitHub-Issues|\n\nThe most common issues relate to excessive output on multiple lines, instead\nof a neat one-line progress bar.\n\n- Consoles in general: require support for carriage return (``CR``, ``\\r``).\n- Nested progress bars:\n\n * Consoles in general: require support for moving cursors up to the\n previous line. For example,\n `IDLE `__,\n `ConEmu `__ and\n `PyCharm `__ (also\n `here `__,\n `here `__, and\n `here `__)\n lack full support.\n * Windows: additionally may require the Python module ``colorama``\n to ensure nested bars stay within their respective lines.\n\n- Unicode:\n\n * Environments which report that they support unicode will have solid smooth\n progressbars. The fallback is an ``ascii``-only bar.\n * Windows consoles often only partially support unicode and thus\n `often require explicit ascii=True `__\n (also `here `__). This is due to\n either normal-width unicode characters being incorrectly displayed as\n \"wide\", or some unicode characters not rendering.\n\n- Wrapping generators:\n\n * Generator wrapper functions tend to hide the length of iterables.\n ``tqdm`` does not.\n * Replace ``tqdm(enumerate(...))`` with ``enumerate(tqdm(...))`` or\n ``tqdm(enumerate(x), total=len(x), ...)``.\n The same applies to ``numpy.ndenumerate``.\n * Replace ``tqdm(zip(a, b))`` with ``zip(tqdm(a), b)`` or even\n ``zip(tqdm(a), tqdm(b))``.\n * The same applies to ``itertools``.\n * Some useful convenience functions can be found under ``tqdm.contrib``.\n\n- `Hanging pipes in python2 `__:\n when using ``tqdm`` on the CLI, you may need to use Python 3.5+ for correct\n buffering.\n- `No intermediate output in docker-compose `__:\n use ``docker-compose run`` instead of ``docker-compose up`` and ``tty: true``.\n\nIf you come across any other difficulties, browse and file |GitHub-Issues|.\n\nDocumentation\n-------------\n\n|Py-Versions| |README-Hits| (Since 19 May 2016)\n\n.. code:: python\n\n class tqdm():\n \"\"\"\n Decorate an iterable object, returning an iterator which acts exactly\n like the original iterable, but prints a dynamically updating\n progressbar every time a value is requested.\n \"\"\"\n\n def __init__(self, iterable=None, desc=None, total=None, leave=True,\n file=None, ncols=None, mininterval=0.1,\n maxinterval=10.0, miniters=None, ascii=None, disable=False,\n unit='it', unit_scale=False, dynamic_ncols=False,\n smoothing=0.3, bar_format=None, initial=0, position=None,\n postfix=None, unit_divisor=1000):\n\nParameters\n~~~~~~~~~~\n\n* iterable : iterable, optional \n Iterable to decorate with a progressbar.\n Leave blank to manually manage the updates.\n* desc : str, optional \n Prefix for the progressbar.\n* total : int or float, optional \n The number of expected iterations. If unspecified,\n len(iterable) is used if possible. If float(\"inf\") or as a last\n resort, only basic progress statistics are displayed\n (no ETA, no progressbar).\n If ``gui`` is True and this parameter needs subsequent updating,\n specify an initial arbitrary large positive number,\n e.g. 9e9.\n* leave : bool, optional \n If [default: True], keeps all traces of the progressbar\n upon termination of iteration.\n If ``None``, will leave only if ``position`` is ``0``.\n* file : ``io.TextIOWrapper`` or ``io.StringIO``, optional \n Specifies where to output the progress messages\n (default: sys.stderr). Uses ``file.write(str)`` and ``file.flush()``\n methods. For encoding, see ``write_bytes``.\n* ncols : int, optional \n The width of the entire output message. If specified,\n dynamically resizes the progressbar to stay within this bound.\n If unspecified, attempts to use environment width. The\n fallback is a meter width of 10 and no limit for the counter and\n statistics. If 0, will not print any meter (only stats).\n* mininterval : float, optional \n Minimum progress display update interval [default: 0.1] seconds.\n* maxinterval : float, optional \n Maximum progress display update interval [default: 10] seconds.\n Automatically adjusts ``miniters`` to correspond to ``mininterval``\n after long display update lag. Only works if ``dynamic_miniters``\n or monitor thread is enabled.\n* miniters : int or float, optional \n Minimum progress display update interval, in iterations.\n If 0 and ``dynamic_miniters``, will automatically adjust to equal\n ``mininterval`` (more CPU efficient, good for tight loops).\n If > 0, will skip display of specified number of iterations.\n Tweak this and ``mininterval`` to get very efficient loops.\n If your progress is erratic with both fast and slow iterations\n (network, skipping items, etc) you should set miniters=1.\n* ascii : bool or str, optional \n If unspecified or False, use unicode (smooth blocks) to fill\n the meter. The fallback is to use ASCII characters \" 123456789#\".\n* disable : bool, optional \n Whether to disable the entire progressbar wrapper\n [default: False]. If set to None, disable on non-TTY.\n* unit : str, optional \n String that will be used to define the unit of each iteration\n [default: it].\n* unit_scale : bool or int or float, optional \n If 1 or True, the number of iterations will be reduced/scaled\n automatically and a metric prefix following the\n International System of Units standard will be added\n (kilo, mega, etc.) [default: False]. If any other non-zero\n number, will scale ``total`` and ``n``.\n* dynamic_ncols : bool, optional \n If set, constantly alters ``ncols`` and ``nrows`` to the\n environment (allowing for window resizes) [default: False].\n* smoothing : float, optional \n Exponential moving average smoothing factor for speed estimates\n (ignored in GUI mode). Ranges from 0 (average speed) to 1\n (current/instantaneous speed) [default: 0.3].\n* bar_format : str, optional \n Specify a custom bar string formatting. May impact performance.\n [default: '{l_bar}{bar}{r_bar}'], where\n l_bar='{desc}: {percentage:3.0f}%|' and\n r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, '\n '{rate_fmt}{postfix}]'\n Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt,\n percentage, elapsed, elapsed_s, ncols, nrows, desc, unit,\n rate, rate_fmt, rate_noinv, rate_noinv_fmt,\n rate_inv, rate_inv_fmt, postfix, unit_divisor,\n remaining, remaining_s, eta.\n Note that a trailing \": \" is automatically removed after {desc}\n if the latter is empty.\n* initial : int or float, optional \n The initial counter value. Useful when restarting a progress\n bar [default: 0]. If using float, consider specifying ``{n:.3f}``\n or similar in ``bar_format``, or specifying ``unit_scale``.\n* position : int, optional \n Specify the line offset to print this bar (starting from 0)\n Automatic if unspecified.\n Useful to manage multiple bars at once (eg, from threads).\n* postfix : dict or ``*``, optional \n Specify additional stats to display at the end of the bar.\n Calls ``set_postfix(**postfix)`` if possible (dict).\n* unit_divisor : float, optional \n [default: 1000], ignored unless ``unit_scale`` is True.\n* write_bytes : bool, optional \n If (default: None) and ``file`` is unspecified,\n bytes will be written in Python 2. If ``True`` will also write\n bytes. In all other cases will default to unicode.\n* lock_args : tuple, optional \n Passed to ``refresh`` for intermediate output\n (initialisation, iterating, and updating).\n* nrows : int, optional \n The screen height. If specified, hides nested bars outside this\n bound. If unspecified, attempts to use environment height.\n The fallback is 20.\n* colour : str, optional \n Bar colour (e.g. 'green', '#00ff00').\n* delay : float, optional \n Don't display until [default: 0] seconds have elapsed.\n\nExtra CLI Options\n~~~~~~~~~~~~~~~~~\n\n* delim : chr, optional \n Delimiting character [default: '\\n']. Use '\\0' for null.\n N.B.: on Windows systems, Python converts '\\n' to '\\r\\n'.\n* buf_size : int, optional \n String buffer size in bytes [default: 256]\n used when ``delim`` is specified.\n* bytes : bool, optional \n If true, will count bytes, ignore ``delim``, and default\n ``unit_scale`` to True, ``unit_divisor`` to 1024, and ``unit`` to 'B'.\n* tee : bool, optional \n If true, passes ``stdin`` to both ``stderr`` and ``stdout``.\n* update : bool, optional \n If true, will treat input as newly elapsed iterations,\n i.e. numbers to pass to ``update()``. Note that this is slow\n (~2e5 it/s) since every input must be decoded as a number.\n* update_to : bool, optional \n If true, will treat input as total elapsed iterations,\n i.e. numbers to assign to ``self.n``. Note that this is slow\n (~2e5 it/s) since every input must be decoded as a number.\n* null : bool, optional \n If true, will discard input (no stdout).\n* manpath : str, optional \n Directory in which to install tqdm man pages.\n* comppath : str, optional \n Directory in which to place tqdm completion.\n* log : str, optional \n CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET.\n\nReturns\n~~~~~~~\n\n* out : decorated iterator. \n\n.. code:: python\n\n class tqdm():\n def update(self, n=1):\n \"\"\"\n Manually update the progress bar, useful for streams\n such as reading files.\n E.g.:\n >>> t = tqdm(total=filesize) # Initialise\n >>> for current_buffer in stream:\n ... ...\n ... t.update(len(current_buffer))\n >>> t.close()\n The last line is highly recommended, but possibly not necessary if\n ``t.update()`` will be called in such a way that ``filesize`` will be\n exactly reached and printed.\n\n Parameters\n ----------\n n : int or float, optional\n Increment to add to the internal counter of iterations\n [default: 1]. If using float, consider specifying ``{n:.3f}``\n or similar in ``bar_format``, or specifying ``unit_scale``.\n\n Returns\n -------\n out : bool or None\n True if a ``display()`` was triggered.\n \"\"\"\n\n def close(self):\n \"\"\"Cleanup and (if leave=False) close the progressbar.\"\"\"\n\n def clear(self, nomove=False):\n \"\"\"Clear current bar display.\"\"\"\n\n def refresh(self):\n \"\"\"\n Force refresh the display of this bar.\n\n Parameters\n ----------\n nolock : bool, optional\n If ``True``, does not lock.\n If [default: ``False``]: calls ``acquire()`` on internal lock.\n lock_args : tuple, optional\n Passed to internal lock's ``acquire()``.\n If specified, will only ``display()`` if ``acquire()`` returns ``True``.\n \"\"\"\n\n def unpause(self):\n \"\"\"Restart tqdm timer from last print time.\"\"\"\n\n def reset(self, total=None):\n \"\"\"\n Resets to 0 iterations for repeated use.\n\n Consider combining with ``leave=True``.\n\n Parameters\n ----------\n total : int or float, optional. Total to use for the new bar.\n \"\"\"\n\n def set_description(self, desc=None, refresh=True):\n \"\"\"\n Set/modify description of the progress bar.\n\n Parameters\n ----------\n desc : str, optional\n refresh : bool, optional\n Forces refresh [default: True].\n \"\"\"\n\n def set_postfix(self, ordered_dict=None, refresh=True, **tqdm_kwargs):\n \"\"\"\n Set/modify postfix (additional stats)\n with automatic formatting based on datatype.\n\n Parameters\n ----------\n ordered_dict : dict or OrderedDict, optional\n refresh : bool, optional\n Forces refresh [default: True].\n kwargs : dict, optional\n \"\"\"\n\n @classmethod\n def write(cls, s, file=sys.stdout, end=\"\\n\"):\n \"\"\"Print a message via tqdm (without overlap with bars).\"\"\"\n\n @property\n def format_dict(self):\n \"\"\"Public API for read-only member access.\"\"\"\n\n def display(self, msg=None, pos=None):\n \"\"\"\n Use ``self.sp`` to display ``msg`` in the specified ``pos``.\n\n Consider overloading this function when inheriting to use e.g.:\n ``self.some_frontend(**self.format_dict)`` instead of ``self.sp``.\n\n Parameters\n ----------\n msg : str, optional. What to display (default: ``repr(self)``).\n pos : int, optional. Position to ``moveto``\n (default: ``abs(self.pos)``).\n \"\"\"\n\n @classmethod\n @contextmanager\n def wrapattr(cls, stream, method, total=None, bytes=True, **tqdm_kwargs):\n \"\"\"\n stream : file-like object.\n method : str, \"read\" or \"write\". The result of ``read()`` and\n the first argument of ``write()`` should have a ``len()``.\n\n >>> with tqdm.wrapattr(file_obj, \"read\", total=file_obj.size) as fobj:\n ... while True:\n ... chunk = fobj.read(chunk_size)\n ... if not chunk:\n ... break\n \"\"\"\n\n @classmethod\n def pandas(cls, *targs, **tqdm_kwargs):\n \"\"\"Registers the current `tqdm` class with `pandas`.\"\"\"\n\n def trange(*args, **tqdm_kwargs):\n \"\"\"\n A shortcut for `tqdm(xrange(*args), **tqdm_kwargs)`.\n On Python3+, `range` is used instead of `xrange`.\n \"\"\"\n\nConvenience Functions\n~~~~~~~~~~~~~~~~~~~~~\n\n.. code:: python\n\n def tqdm.contrib.tenumerate(iterable, start=0, total=None,\n tqdm_class=tqdm.auto.tqdm, **tqdm_kwargs):\n \"\"\"Equivalent of `numpy.ndenumerate` or builtin `enumerate`.\"\"\"\n\n def tqdm.contrib.tzip(iter1, *iter2plus, **tqdm_kwargs):\n \"\"\"Equivalent of builtin `zip`.\"\"\"\n\n def tqdm.contrib.tmap(function, *sequences, **tqdm_kwargs):\n \"\"\"Equivalent of builtin `map`.\"\"\"\n\nSubmodules\n~~~~~~~~~~\n\n.. code:: python\n\n class tqdm.notebook.tqdm(tqdm.tqdm):\n \"\"\"IPython/Jupyter Notebook widget.\"\"\"\n\n class tqdm.auto.tqdm(tqdm.tqdm):\n \"\"\"Automatically chooses beween `tqdm.notebook` and `tqdm.tqdm`.\"\"\"\n\n class tqdm.asyncio.tqdm(tqdm.tqdm):\n \"\"\"Asynchronous version.\"\"\"\n @classmethod\n def as_completed(cls, fs, *, loop=None, timeout=None, total=None,\n **tqdm_kwargs):\n \"\"\"Wrapper for `asyncio.as_completed`.\"\"\"\n\n class tqdm.gui.tqdm(tqdm.tqdm):\n \"\"\"Matplotlib GUI version.\"\"\"\n\n class tqdm.tk.tqdm(tqdm.tqdm):\n \"\"\"Tkinter GUI version.\"\"\"\n\n class tqdm.rich.tqdm(tqdm.tqdm):\n \"\"\"`rich.progress` version.\"\"\"\n\n class tqdm.keras.TqdmCallback(keras.callbacks.Callback):\n \"\"\"Keras callback for epoch and batch progress.\"\"\"\n\n class tqdm.dask.TqdmCallback(dask.callbacks.Callback):\n \"\"\"Dask callback for task progress.\"\"\"\n\n\n``contrib``\n+++++++++++\n\nThe ``tqdm.contrib`` package also contains experimental modules:\n\n- ``tqdm.contrib.itertools``: Thin wrappers around ``itertools``\n- ``tqdm.contrib.concurrent``: Thin wrappers around ``concurrent.futures``\n- ``tqdm.contrib.slack``: Posts to `Slack `__ bots\n- ``tqdm.contrib.discord``: Posts to `Discord `__ bots\n- ``tqdm.contrib.telegram``: Posts to `Telegram `__ bots\n- ``tqdm.contrib.bells``: Automagically enables all optional features\n\n * ``auto``, ``pandas``, ``slack``, ``discord``, ``telegram``\n\nExamples and Advanced Usage\n---------------------------\n\n- See the `examples `__\n folder;\n- import the module and run ``help()``;\n- consult the `wiki `__;\n\n * this has an\n `excellent article `__\n on how to make a **great** progressbar;\n\n- check out the `slides from PyData London `__, or\n- run the |binder-demo|.\n\nDescription and additional stats\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nCustom information can be displayed and updated dynamically on ``tqdm`` bars\nwith the ``desc`` and ``postfix`` arguments:\n\n.. code:: python\n\n from tqdm import tqdm, trange\n from random import random, randint\n from time import sleep\n\n with trange(10) as t:\n for i in t:\n # Description will be displayed on the left\n t.set_description('GEN %i' % i)\n # Postfix will be displayed on the right,\n # formatted automatically based on argument's datatype\n t.set_postfix(loss=random(), gen=randint(1,999), str='h',\n lst=[1, 2])\n sleep(0.1)\n\n with tqdm(total=10, bar_format=\"{postfix[0]} {postfix[1][value]:>8.2g}\",\n postfix=[\"Batch\", dict(value=0)]) as t:\n for i in range(10):\n sleep(0.1)\n t.postfix[1][\"value\"] = i / 2\n t.update()\n\nPoints to remember when using ``{postfix[...]}`` in the ``bar_format`` string:\n\n- ``postfix`` also needs to be passed as an initial argument in a compatible\n format, and\n- ``postfix`` will be auto-converted to a string if it is a ``dict``-like\n object. To prevent this behaviour, insert an extra item into the dictionary\n where the key is not a string.\n\nAdditional ``bar_format`` parameters may also be defined by overriding\n``format_dict``, and the bar itself may be modified using ``ascii``:\n\n.. code:: python\n\n from tqdm import tqdm\n class TqdmExtraFormat(tqdm):\n \"\"\"Provides a `total_time` format parameter\"\"\"\n @property\n def format_dict(self):\n d = super(TqdmExtraFormat, self).format_dict\n total_time = d[\"elapsed\"] * (d[\"total\"] or 0) / max(d[\"n\"], 1)\n d.update(total_time=self.format_interval(total_time) + \" in total\")\n return d\n\n for i in TqdmExtraFormat(\n range(9), ascii=\" .oO0\",\n bar_format=\"{total_time}: {percentage:.0f}%|{bar}{r_bar}\"):\n if i == 4:\n break\n\n.. code::\n\n 00:00 in total: 44%|0000. | 4/9 [00:00<00:00, 962.93it/s]\n\nNote that ``{bar}`` also supports a format specifier ``[width][type]``.\n\n- ``width``\n\n * unspecified (default): automatic to fill ``ncols``\n * ``int >= 0``: fixed width overriding ``ncols`` logic\n * ``int < 0``: subtract from the automatic default\n\n- ``type``\n\n * ``a``: ascii (``ascii=True`` override)\n * ``u``: unicode (``ascii=False`` override)\n * ``b``: blank (``ascii=\" \"`` override)\n\nThis means a fixed bar with right-justified text may be created by using:\n``bar_format=\"{l_bar}{bar:10}|{bar:-10b}right-justified\"``\n\nNested progress bars\n~~~~~~~~~~~~~~~~~~~~\n\n``tqdm`` supports nested progress bars. Here's an example:\n\n.. code:: python\n\n from tqdm.auto import trange\n from time import sleep\n\n for i in trange(4, desc='1st loop'):\n for j in trange(5, desc='2nd loop'):\n for k in trange(50, desc='3rd loop', leave=False):\n sleep(0.01)\n\nFor manual control over positioning (e.g. for multi-processing use),\nyou may specify ``position=n`` where ``n=0`` for the outermost bar,\n``n=1`` for the next, and so on.\nHowever, it's best to check if ``tqdm`` can work without manual ``position``\nfirst.\n\n.. code:: python\n\n from time import sleep\n from tqdm import trange, tqdm\n from multiprocessing import Pool, RLock, freeze_support\n\n L = list(range(9))\n\n def progresser(n):\n interval = 0.001 / (n + 2)\n total = 5000\n text = \"#{}, est. {:<04.2}s\".format(n, interval * total)\n for _ in trange(total, desc=text, position=n):\n sleep(interval)\n\n if __name__ == '__main__':\n freeze_support() # for Windows support\n tqdm.set_lock(RLock()) # for managing output contention\n p = Pool(initializer=tqdm.set_lock, initargs=(tqdm.get_lock(),))\n p.map(progresser, L)\n\nNote that in Python 3, ``tqdm.write`` is thread-safe:\n\n.. code:: python\n\n from time import sleep\n from tqdm import tqdm, trange\n from concurrent.futures import ThreadPoolExecutor\n\n L = list(range(9))\n\n def progresser(n):\n interval = 0.001 / (n + 2)\n total = 5000\n text = \"#{}, est. {:<04.2}s\".format(n, interval * total)\n for _ in trange(total, desc=text):\n sleep(interval)\n if n == 6:\n tqdm.write(\"n == 6 completed.\")\n tqdm.write(\"`tqdm.write()` is thread-safe in py3!\")\n\n if __name__ == '__main__':\n with ThreadPoolExecutor() as p:\n p.map(progresser, L)\n\nHooks and callbacks\n~~~~~~~~~~~~~~~~~~~\n\n``tqdm`` can easily support callbacks/hooks and manual updates.\nHere's an example with ``urllib``:\n\n**``urllib.urlretrieve`` documentation**\n\n | [...]\n | If present, the hook function will be called once\n | on establishment of the network connection and once after each block read\n | thereafter. The hook will be passed three arguments; a count of blocks\n | transferred so far, a block size in bytes, and the total size of the file.\n | [...]\n\n.. code:: python\n\n import urllib, os\n from tqdm import tqdm\n urllib = getattr(urllib, 'request', urllib)\n\n class TqdmUpTo(tqdm):\n \"\"\"Provides `update_to(n)` which uses `tqdm.update(delta_n)`.\"\"\"\n def update_to(self, b=1, bsize=1, tsize=None):\n \"\"\"\n b : int, optional\n Number of blocks transferred so far [default: 1].\n bsize : int, optional\n Size of each block (in tqdm units) [default: 1].\n tsize : int, optional\n Total size (in tqdm units). If [default: None] remains unchanged.\n \"\"\"\n if tsize is not None:\n self.total = tsize\n return self.update(b * bsize - self.n) # also sets self.n = b * bsize\n\n eg_link = \"https://caspersci.uk.to/matryoshka.zip\"\n with TqdmUpTo(unit='B', unit_scale=True, unit_divisor=1024, miniters=1,\n desc=eg_link.split('/')[-1]) as t: # all optional kwargs\n urllib.urlretrieve(eg_link, filename=os.devnull,\n reporthook=t.update_to, data=None)\n t.total = t.n\n\nInspired by `twine#242 `__.\nFunctional alternative in\n`examples/tqdm_wget.py `__.\n\nIt is recommend to use ``miniters=1`` whenever there is potentially\nlarge differences in iteration speed (e.g. downloading a file over\na patchy connection).\n\n**Wrapping read/write methods**\n\nTo measure throughput through a file-like object's ``read`` or ``write``\nmethods, use ``CallbackIOWrapper``:\n\n.. code:: python\n\n from tqdm.auto import tqdm\n from tqdm.utils import CallbackIOWrapper\n\n with tqdm(total=file_obj.size,\n unit='B', unit_scale=True, unit_divisor=1024) as t:\n fobj = CallbackIOWrapper(t.update, file_obj, \"read\")\n while True:\n chunk = fobj.read(chunk_size)\n if not chunk:\n break\n t.reset()\n # ... continue to use `t` for something else\n\nAlternatively, use the even simpler ``wrapattr`` convenience function,\nwhich would condense both the ``urllib`` and ``CallbackIOWrapper`` examples\ndown to:\n\n.. code:: python\n\n import urllib, os\n from tqdm import tqdm\n\n eg_link = \"https://caspersci.uk.to/matryoshka.zip\"\n response = getattr(urllib, 'request', urllib).urlopen(eg_link)\n with tqdm.wrapattr(open(os.devnull, \"wb\"), \"write\",\n miniters=1, desc=eg_link.split('/')[-1],\n total=getattr(response, 'length', None)) as fout:\n for chunk in response:\n fout.write(chunk)\n\nThe ``requests`` equivalent is nearly identical:\n\n.. code:: python\n\n import requests, os\n from tqdm import tqdm\n\n eg_link = \"https://caspersci.uk.to/matryoshka.zip\"\n response = requests.get(eg_link, stream=True)\n with tqdm.wrapattr(open(os.devnull, \"wb\"), \"write\",\n miniters=1, desc=eg_link.split('/')[-1],\n total=int(response.headers.get('content-length', 0))) as fout:\n for chunk in response.iter_content(chunk_size=4096):\n fout.write(chunk)\n\n**Custom callback**\n\n``tqdm`` is known for intelligently skipping unnecessary displays. To make a\ncustom callback take advantage of this, simply use the return value of\n``update()``. This is set to ``True`` if a ``display()`` was triggered.\n\n.. code:: python\n\n from tqdm.auto import tqdm as std_tqdm\n\n def external_callback(*args, **kwargs):\n ...\n\n class TqdmExt(std_tqdm):\n def update(self, n=1):\n displayed = super(TqdmExt, self).update(n)\n if displayed:\n external_callback(**self.format_dict)\n return displayed\n\n``asyncio``\n~~~~~~~~~~~\n\nNote that ``break`` isn't currently caught by asynchronous iterators.\nThis means that ``tqdm`` cannot clean up after itself in this case:\n\n.. code:: python\n\n from tqdm.asyncio import tqdm\n\n async for i in tqdm(range(9)):\n if i == 2:\n break\n\nInstead, either call ``pbar.close()`` manually or use the context manager syntax:\n\n.. code:: python\n\n from tqdm.asyncio import tqdm\n\n with tqdm(range(9)) as pbar:\n async for i in pbar:\n if i == 2:\n break\n\nPandas Integration\n~~~~~~~~~~~~~~~~~~\n\nDue to popular demand we've added support for ``pandas`` -- here's an example\nfor ``DataFrame.progress_apply`` and ``DataFrameGroupBy.progress_apply``:\n\n.. code:: python\n\n import pandas as pd\n import numpy as np\n from tqdm import tqdm\n\n df = pd.DataFrame(np.random.randint(0, 100, (100000, 6)))\n\n # Register `pandas.progress_apply` and `pandas.Series.map_apply` with `tqdm`\n # (can use `tqdm.gui.tqdm`, `tqdm.notebook.tqdm`, optional kwargs, etc.)\n tqdm.pandas(desc=\"my bar!\")\n\n # Now you can use `progress_apply` instead of `apply`\n # and `progress_map` instead of `map`\n df.progress_apply(lambda x: x**2)\n # can also groupby:\n # df.groupby(0).progress_apply(lambda x: x**2)\n\nIn case you're interested in how this works (and how to modify it for your\nown callbacks), see the\n`examples `__\nfolder or import the module and run ``help()``.\n\nKeras Integration\n~~~~~~~~~~~~~~~~~\n\nA ``keras`` callback is also available:\n\n.. code:: python\n\n from tqdm.keras import TqdmCallback\n\n ...\n\n model.fit(..., verbose=0, callbacks=[TqdmCallback()])\n\nDask Integration\n~~~~~~~~~~~~~~~~\n\nA ``dask`` callback is also available:\n\n.. code:: python\n\n from tqdm.dask import TqdmCallback\n\n with TqdmCallback(desc=\"compute\"):\n ...\n arr.compute()\n\n # or use callback globally\n cb = TqdmCallback(desc=\"global\")\n cb.register()\n arr.compute()\n\nIPython/Jupyter Integration\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIPython/Jupyter is supported via the ``tqdm.notebook`` submodule:\n\n.. code:: python\n\n from tqdm.notebook import trange, tqdm\n from time import sleep\n\n for i in trange(3, desc='1st loop'):\n for j in tqdm(range(100), desc='2nd loop'):\n sleep(0.01)\n\nIn addition to ``tqdm`` features, the submodule provides a native Jupyter\nwidget (compatible with IPython v1-v4 and Jupyter), fully working nested bars\nand colour hints (blue: normal, green: completed, red: error/interrupt,\nlight blue: no ETA); as demonstrated below.\n\n|Screenshot-Jupyter1|\n|Screenshot-Jupyter2|\n|Screenshot-Jupyter3|\n\nThe ``notebook`` version supports percentage or pixels for overall width\n(e.g.: ``ncols='100%'`` or ``ncols='480px'``).\n\nIt is also possible to let ``tqdm`` automatically choose between\nconsole or notebook versions by using the ``autonotebook`` submodule:\n\n.. code:: python\n\n from tqdm.autonotebook import tqdm\n tqdm.pandas()\n\nNote that this will issue a ``TqdmExperimentalWarning`` if run in a notebook\nsince it is not meant to be possible to distinguish between ``jupyter notebook``\nand ``jupyter console``. Use ``auto`` instead of ``autonotebook`` to suppress\nthis warning.\n\nNote that notebooks will display the bar in the cell where it was created.\nThis may be a different cell from the one where it is used.\nIf this is not desired, either\n\n- delay the creation of the bar to the cell where it must be displayed, or\n- create the bar with ``display=False``, and in a later cell call\n ``display(bar.container)``:\n\n.. code:: python\n\n from tqdm.notebook import tqdm\n pbar = tqdm(..., display=False)\n\n.. code:: python\n\n # different cell\n display(pbar.container)\n\nThe ``keras`` callback has a ``display()`` method which can be used likewise:\n\n.. code:: python\n\n from tqdm.keras import TqdmCallback\n cbk = TqdmCallback(display=False)\n\n.. code:: python\n\n # different cell\n cbk.display()\n model.fit(..., verbose=0, callbacks=[cbk])\n\nAnother possibility is to have a single bar (near the top of the notebook)\nwhich is constantly re-used (using ``reset()`` rather than ``close()``).\nFor this reason, the notebook version (unlike the CLI version) does not\nautomatically call ``close()`` upon ``Exception``.\n\n.. code:: python\n\n from tqdm.notebook import tqdm\n pbar = tqdm()\n\n.. code:: python\n\n # different cell\n iterable = range(100)\n pbar.reset(total=len(iterable)) # initialise with new `total`\n for i in iterable:\n pbar.update()\n pbar.refresh() # force print final status but don't `close()`\n\nCustom Integration\n~~~~~~~~~~~~~~~~~~\n\nTo change the default arguments (such as making ``dynamic_ncols=True``),\nsimply use built-in Python magic:\n\n.. code:: python\n\n from functools import partial\n from tqdm import tqdm as std_tqdm\n tqdm = partial(std_tqdm, dynamic_ncols=True)\n\nFor further customisation,\n``tqdm`` may be inherited from to create custom callbacks (as with the\n``TqdmUpTo`` example `above <#hooks-and-callbacks>`__) or for custom frontends\n(e.g. GUIs such as notebook or plotting packages). In the latter case:\n\n1. ``def __init__()`` to call ``super().__init__(..., gui=True)`` to disable\n terminal ``status_printer`` creation.\n2. Redefine: ``close()``, ``clear()``, ``display()``.\n\nConsider overloading ``display()`` to use e.g.\n``self.frontend(**self.format_dict)`` instead of ``self.sp(repr(self))``.\n\nSome submodule examples of inheritance:\n\n- `tqdm/notebook.py `__\n- `tqdm/gui.py `__\n- `tqdm/tk.py `__\n- `tqdm/contrib/slack.py `__\n- `tqdm/contrib/discord.py `__\n- `tqdm/contrib/telegram.py `__\n\nDynamic Monitor/Meter\n~~~~~~~~~~~~~~~~~~~~~\n\nYou can use a ``tqdm`` as a meter which is not monotonically increasing.\nThis could be because ``n`` decreases (e.g. a CPU usage monitor) or ``total``\nchanges.\n\nOne example would be recursively searching for files. The ``total`` is the\nnumber of objects found so far, while ``n`` is the number of those objects which\nare files (rather than folders):\n\n.. code:: python\n\n from tqdm import tqdm\n import os.path\n\n def find_files_recursively(path, show_progress=True):\n files = []\n # total=1 assumes `path` is a file\n t = tqdm(total=1, unit=\"file\", disable=not show_progress)\n if not os.path.exists(path):\n raise IOError(\"Cannot find:\" + path)\n\n def append_found_file(f):\n files.append(f)\n t.update()\n\n def list_found_dir(path):\n \"\"\"returns os.listdir(path) assuming os.path.isdir(path)\"\"\"\n listing = os.listdir(path)\n # subtract 1 since a \"file\" we found was actually this directory\n t.total += len(listing) - 1\n # fancy way to give info without forcing a refresh\n t.set_postfix(dir=path[-10:], refresh=False)\n t.update(0) # may trigger a refresh\n return listing\n\n def recursively_search(path):\n if os.path.isdir(path):\n for f in list_found_dir(path):\n recursively_search(os.path.join(path, f))\n else:\n append_found_file(path)\n\n recursively_search(path)\n t.set_postfix(dir=path)\n t.close()\n return files\n\nUsing ``update(0)`` is a handy way to let ``tqdm`` decide when to trigger a\ndisplay refresh to avoid console spamming.\n\nWriting messages\n~~~~~~~~~~~~~~~~\n\nThis is a work in progress (see\n`#737 `__).\n\nSince ``tqdm`` uses a simple printing mechanism to display progress bars,\nyou should not write any message in the terminal using ``print()`` while\na progressbar is open.\n\nTo write messages in the terminal without any collision with ``tqdm`` bar\ndisplay, a ``.write()`` method is provided:\n\n.. code:: python\n\n from tqdm.auto import tqdm, trange\n from time import sleep\n\n bar = trange(10)\n for i in bar:\n # Print using tqdm class method .write()\n sleep(0.1)\n if not (i % 3):\n tqdm.write(\"Done task %i\" % i)\n # Can also use bar.write()\n\nBy default, this will print to standard output ``sys.stdout``. but you can\nspecify any file-like object using the ``file`` argument. For example, this\ncan be used to redirect the messages writing to a log file or class.\n\nRedirecting writing\n~~~~~~~~~~~~~~~~~~~\n\nIf using a library that can print messages to the console, editing the library\nby replacing ``print()`` with ``tqdm.write()`` may not be desirable.\nIn that case, redirecting ``sys.stdout`` to ``tqdm.write()`` is an option.\n\nTo redirect ``sys.stdout``, create a file-like class that will write\nany input string to ``tqdm.write()``, and supply the arguments\n``file=sys.stdout, dynamic_ncols=True``.\n\nA reusable canonical example is given below:\n\n.. code:: python\n\n from time import sleep\n import contextlib\n import sys\n from tqdm import tqdm\n from tqdm.contrib import DummyTqdmFile\n\n\n @contextlib.contextmanager\n def std_out_err_redirect_tqdm():\n orig_out_err = sys.stdout, sys.stderr\n try:\n sys.stdout, sys.stderr = map(DummyTqdmFile, orig_out_err)\n yield orig_out_err[0]\n # Relay exceptions\n except Exception as exc:\n raise exc\n # Always restore sys.stdout/err if necessary\n finally:\n sys.stdout, sys.stderr = orig_out_err\n\n def some_fun(i):\n print(\"Fee, fi, fo,\".split()[i])\n\n # Redirect stdout to tqdm.write() (don't forget the `as save_stdout`)\n with std_out_err_redirect_tqdm() as orig_stdout:\n # tqdm needs the original stdout\n # and dynamic_ncols=True to autodetect console width\n for i in tqdm(range(3), file=orig_stdout, dynamic_ncols=True):\n sleep(.5)\n some_fun(i)\n\n # After the `with`, printing is restored\n print(\"Done!\")\n\nRedirecting ``logging``\n~~~~~~~~~~~~~~~~~~~~~~~\n\nSimilar to ``sys.stdout``/``sys.stderr`` as detailed above, console ``logging``\nmay also be redirected to ``tqdm.write()``.\n\nWarning: if also redirecting ``sys.stdout``/``sys.stderr``, make sure to\nredirect ``logging`` first if needed.\n\nHelper methods are available in ``tqdm.contrib.logging``. For example:\n\n.. code:: python\n\n import logging\n from tqdm import trange\n from tqdm.contrib.logging import logging_redirect_tqdm\n\n LOG = logging.getLogger(__name__)\n\n if __name__ == '__main__':\n logging.basicConfig(level=logging.INFO)\n with logging_redirect_tqdm():\n for i in trange(9):\n if i == 4:\n LOG.info(\"console logging redirected to `tqdm.write()`\")\n # logging restored\n\nMonitoring thread, intervals and miniters\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``tqdm`` implements a few tricks to increase efficiency and reduce overhead.\n\n- Avoid unnecessary frequent bar refreshing: ``mininterval`` defines how long\n to wait between each refresh. ``tqdm`` always gets updated in the background,\n but it will display only every ``mininterval``.\n- Reduce number of calls to check system clock/time.\n- ``mininterval`` is more intuitive to configure than ``miniters``.\n A clever adjustment system ``dynamic_miniters`` will automatically adjust\n ``miniters`` to the amount of iterations that fit into time ``mininterval``.\n Essentially, ``tqdm`` will check if it's time to print without actually\n checking time. This behaviour can be still be bypassed by manually setting\n ``miniters``.\n\nHowever, consider a case with a combination of fast and slow iterations.\nAfter a few fast iterations, ``dynamic_miniters`` will set ``miniters`` to a\nlarge number. When iteration rate subsequently slows, ``miniters`` will\nremain large and thus reduce display update frequency. To address this:\n\n- ``maxinterval`` defines the maximum time between display refreshes.\n A concurrent monitoring thread checks for overdue updates and forces one\n where necessary.\n\nThe monitoring thread should not have a noticeable overhead, and guarantees\nupdates at least every 10 seconds by default.\nThis value can be directly changed by setting the ``monitor_interval`` of\nany ``tqdm`` instance (i.e. ``t = tqdm.tqdm(...); t.monitor_interval = 2``).\nThe monitor thread may be disabled application-wide by setting\n``tqdm.tqdm.monitor_interval = 0`` before instantiation of any ``tqdm`` bar.\n\n\nMerch\n-----\n\nYou can buy `tqdm branded merch `__ now!\n\nContributions\n-------------\n\n|GitHub-Commits| |GitHub-Issues| |GitHub-PRs| |OpenHub-Status| |GitHub-Contributions| |CII Best Practices|\n\nAll source code is hosted on `GitHub `__.\nContributions are welcome.\n\nSee the\n`CONTRIBUTING `__\nfile for more information.\n\nDevelopers who have made significant contributions, ranked by *SLoC*\n(surviving lines of code,\n`git fame `__ ``-wMC --excl '\\.(png|gif|jpg)$'``),\nare:\n\n==================== ======================================================== ==== ================================\nName ID SLoC Notes\n==================== ======================================================== ==== ================================\nCasper da Costa-Luis `casperdcl `__ ~78% primary maintainer |Gift-Casper|\nStephen Larroque `lrq3000 `__ ~10% team member\nMartin Zugnoni `martinzugnoni `__ ~4%\nDaniel Ecer `de-code `__ ~2%\nRichard Sheridan `richardsheridan `__ ~1%\nGuangshuo Chen `chengs `__ ~1%\nKyle Altendorf `altendky `__ <1%\nMatthew Stevens `mjstevens777 `__ <1%\nHadrien Mary `hadim `__ <1% team member\nNoam Yorav-Raphael `noamraph `__ <1% original author\nMikhail Korobov `kmike `__ <1% team member\n==================== ======================================================== ==== ================================\n\nPorts to Other Languages\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nA list is available on\n`this wiki page `__.\n\n\nLICENCE\n-------\n\nOpen Source (OSI approved): |LICENCE|\n\nCitation information: |DOI|\n\n|README-Hits| (Since 19 May 2016)\n\n.. |Logo| image:: https://img.tqdm.ml/logo.gif\n.. |Screenshot| image:: https://img.tqdm.ml/tqdm.gif\n.. |Video| image:: https://img.tqdm.ml/video.jpg\n :target: https://tqdm.github.io/video\n.. |Slides| image:: https://img.tqdm.ml/slides.jpg\n :target: https://tqdm.github.io/PyData2019/slides.html\n.. |Merch| image:: https://img.tqdm.ml/merch.jpg\n :target: https://tqdm.github.io/merch\n.. |Build-Status| image:: https://img.shields.io/github/workflow/status/tqdm/tqdm/Test/master?logo=GitHub\n :target: https://github.com/tqdm/tqdm/actions?query=workflow%3ATest\n.. |Coverage-Status| image:: https://img.shields.io/coveralls/github/tqdm/tqdm/master?logo=coveralls\n :target: https://coveralls.io/github/tqdm/tqdm\n.. |Branch-Coverage-Status| image:: https://codecov.io/gh/tqdm/tqdm/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/tqdm/tqdm\n.. |Codacy-Grade| image:: https://app.codacy.com/project/badge/Grade/3f965571598f44549c7818f29cdcf177\n :target: https://www.codacy.com/gh/tqdm/tqdm/dashboard\n.. |CII Best Practices| image:: https://bestpractices.coreinfrastructure.org/projects/3264/badge\n :target: https://bestpractices.coreinfrastructure.org/projects/3264\n.. |GitHub-Status| image:: https://img.shields.io/github/tag/tqdm/tqdm.svg?maxAge=86400&logo=github&logoColor=white\n :target: https://github.com/tqdm/tqdm/releases\n.. |GitHub-Forks| image:: https://img.shields.io/github/forks/tqdm/tqdm.svg?logo=github&logoColor=white\n :target: https://github.com/tqdm/tqdm/network\n.. |GitHub-Stars| image:: https://img.shields.io/github/stars/tqdm/tqdm.svg?logo=github&logoColor=white\n :target: https://github.com/tqdm/tqdm/stargazers\n.. |GitHub-Commits| image:: https://img.shields.io/github/commit-activity/y/tqdm/tqdm.svg?logo=git&logoColor=white\n :target: https://github.com/tqdm/tqdm/graphs/commit-activity\n.. |GitHub-Issues| image:: https://img.shields.io/github/issues-closed/tqdm/tqdm.svg?logo=github&logoColor=white\n :target: https://github.com/tqdm/tqdm/issues?q=\n.. |GitHub-PRs| image:: https://img.shields.io/github/issues-pr-closed/tqdm/tqdm.svg?logo=github&logoColor=white\n :target: https://github.com/tqdm/tqdm/pulls\n.. |GitHub-Contributions| image:: https://img.shields.io/github/contributors/tqdm/tqdm.svg?logo=github&logoColor=white\n :target: https://github.com/tqdm/tqdm/graphs/contributors\n.. |GitHub-Updated| image:: https://img.shields.io/github/last-commit/tqdm/tqdm/master.svg?logo=github&logoColor=white&label=pushed\n :target: https://github.com/tqdm/tqdm/pulse\n.. |Gift-Casper| image:: https://img.shields.io/badge/dynamic/json.svg?color=ff69b4&label=gifts%20received&prefix=%C2%A3&query=%24..sum&url=https%3A%2F%2Fcaspersci.uk.to%2Fgifts.json\n :target: https://cdcl.ml/sponsor\n.. |Versions| image:: https://img.shields.io/pypi/v/tqdm.svg\n :target: https://tqdm.github.io/releases\n.. |PyPI-Downloads| image:: https://img.shields.io/pypi/dm/tqdm.svg?label=pypi%20downloads&logo=PyPI&logoColor=white\n :target: https://pepy.tech/project/tqdm\n.. |Py-Versions| image:: https://img.shields.io/pypi/pyversions/tqdm.svg?logo=python&logoColor=white\n :target: https://pypi.org/project/tqdm\n.. |Conda-Forge-Status| image:: https://img.shields.io/conda/v/conda-forge/tqdm.svg?label=conda-forge&logo=conda-forge\n :target: https://anaconda.org/conda-forge/tqdm\n.. |Snapcraft| image:: https://img.shields.io/badge/snap-install-82BEA0.svg?logo=snapcraft\n :target: https://snapcraft.io/tqdm\n.. |Docker| image:: https://img.shields.io/badge/docker-pull-blue.svg?logo=docker&logoColor=white\n :target: https://hub.docker.com/r/tqdm/tqdm\n.. |Libraries-Rank| image:: https://img.shields.io/librariesio/sourcerank/pypi/tqdm.svg?logo=koding&logoColor=white\n :target: https://libraries.io/pypi/tqdm\n.. |Libraries-Dependents| image:: https://img.shields.io/librariesio/dependent-repos/pypi/tqdm.svg?logo=koding&logoColor=white\n :target: https://github.com/tqdm/tqdm/network/dependents\n.. |OpenHub-Status| image:: https://www.openhub.net/p/tqdm/widgets/project_thin_badge?format=gif\n :target: https://www.openhub.net/p/tqdm?ref=Thin+badge\n.. |awesome-python| image:: https://awesome.re/mentioned-badge.svg\n :target: https://github.com/vinta/awesome-python\n.. |LICENCE| image:: https://img.shields.io/pypi/l/tqdm.svg\n :target: https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE\n.. |DOI| image:: https://img.shields.io/badge/DOI-10.5281/zenodo.595120-blue.svg\n :target: https://doi.org/10.5281/zenodo.595120\n.. |binder-demo| image:: https://mybinder.org/badge_logo.svg\n :target: https://mybinder.org/v2/gh/tqdm/tqdm/master?filepath=DEMO.ipynb\n.. |Screenshot-Jupyter1| image:: https://img.tqdm.ml/jupyter-1.gif\n.. |Screenshot-Jupyter2| image:: https://img.tqdm.ml/jupyter-2.gif\n.. |Screenshot-Jupyter3| image:: https://img.tqdm.ml/jupyter-3.gif\n.. |README-Hits| image:: https://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm&style=social&r=https://github.com/tqdm/tqdm&l=https://img.tqdm.ml/favicon.png&f=https://img.tqdm.ml/logo.gif\n :target: https://caspersci.uk.to/cgi-bin/hits.cgi?q=tqdm&a=plot&r=https://github.com/tqdm/tqdm&l=https://img.tqdm.ml/favicon.png&f=https://img.tqdm.ml/logo.gif&style=social", - "release_date": "2022-04-04T01:48:49", - "parties": [ - { - "type": "person", - "role": "maintainer", - "name": "tqdm developers", - "email": "python.tqdm@gmail.com", - "url": null - } - ], - "keywords": [ - "progressbar", - "progressmeter", - "progress", - "bar", - "meter", - "rate", - "eta", - "console", - "terminal", - "time", - "Development Status :: 5 - Production/Stable", - "Environment :: Console", - "Environment :: MacOS X", - "Environment :: Other Environment", - "Environment :: Win32 (MS Windows)", - "Environment :: X11 Applications", - "Framework :: IPython", - "Framework :: Jupyter", - "Intended Audience :: Developers", - "Intended Audience :: Education", - "Intended Audience :: End Users/Desktop", - "Intended Audience :: Other Audience", - "Intended Audience :: System Administrators", - "Operating System :: MacOS", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft", - "Operating System :: Microsoft :: MS-DOS", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Operating System :: POSIX :: BSD", - "Operating System :: POSIX :: BSD :: FreeBSD", - "Operating System :: POSIX :: Linux", - "Operating System :: POSIX :: SunOS/Solaris", - "Operating System :: Unix", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation", - "Programming Language :: Python :: Implementation :: IronPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Programming Language :: Unix Shell", - "Topic :: Desktop Environment", - "Topic :: Education :: Computer Aided Instruction (CAI)", - "Topic :: Education :: Testing", - "Topic :: Office/Business", - "Topic :: Other/Nonlisted Topic", - "Topic :: Software Development :: Build Tools", - "Topic :: Software Development :: Libraries", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Software Development :: Pre-processors", - "Topic :: Software Development :: User Interfaces", - "Topic :: System :: Installation/Setup", - "Topic :: System :: Logging", - "Topic :: System :: Monitoring", - "Topic :: System :: Shells", - "Topic :: Terminals", - "Topic :: Utilities" - ], - "homepage_url": "https://tqdm.github.io", - "download_url": "https://files.pythonhosted.org/packages/98/2a/838de32e09bd511cf69fe4ae13ffc748ac143449bfc24bb3fd172d53a84f/tqdm-4.64.0.tar.gz", - "size": 169499, - "sha1": null, - "md5": "231212e145ac51214286b310704447d4", - "sha256": "40be55d30e200777a307a7585aee69e4eabb46b4ec6a4b4a5f2d9f11e7d5408d", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/tqdm/tqdm", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MPLv2.0, MIT Licences", - "classifiers": [ - "License :: OSI Approved :: MIT License", - "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/tqdm/4.64.0/json", - "datasource_id": null, - "purl": "pkg:pypi/tqdm@4.64.0" - }, { "type": "pypi", "namespace": null, @@ -9704,159 +5671,21 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython" ], - "homepage_url": "https://twine.readthedocs.io/", - "download_url": "https://files.pythonhosted.org/packages/5e/74/ea7dfb86223695fd8efa256a24d1520729dde79a4e628ee6879f0f136d40/twine-3.8.0-py3-none-any.whl", - "size": 36057, - "sha1": null, - "md5": "56a7992f5d1a5901484ca4f5c896625b", - "sha256": "d0550fca9dc19f3d5e8eadfce0c227294df0a2a951251a4385797c8a6198b7c8", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/pypa/twine/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "classifiers": [ - "License :: OSI Approved :: Apache Software License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/twine/3.8.0/json", - "datasource_id": null, - "purl": "pkg:pypi/twine@3.8.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "twine", - "version": "3.8.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Collection of utilities for publishing packages on PyPI\n.. image:: https://img.shields.io/pypi/v/twine.svg\n :target: https://pypi.org/project/twine\n\n.. image:: https://img.shields.io/pypi/pyversions/twine.svg\n :target: https://pypi.org/project/twine\n\n.. image:: https://img.shields.io/readthedocs/twine\n :target: https://twine.readthedocs.io\n\n.. image:: https://img.shields.io/github/workflow/status/pypa/twine/Main\n :target: https://github.com/pypa/twine/actions\n\n.. image:: https://img.shields.io/codecov/c/github/pypa/twine\n :target: https://codecov.io/gh/pypa/twine\n\ntwine\n=====\n\nTwine is a utility for `publishing`_ Python packages on `PyPI`_.\n\nIt provides build system independent uploads of source and binary\n`distribution artifacts `_ for both new and existing\n`projects`_.\n\nSee our `documentation`_ for a description of features, installation\nand usage instructions, and links to additional resources.\n\nContributing\n------------\n\nSee our `developer documentation`_ for how to get started, an\narchitectural overview, and our future development plans.\n\nCode of Conduct\n---------------\n\nEveryone interacting in the Twine project's codebases, issue\ntrackers, chat rooms, and mailing lists is expected to follow the\n`PSF Code of Conduct`_.\n\n.. _`publishing`: https://packaging.python.org/tutorials/packaging-projects/\n.. _`PyPI`: https://pypi.org\n.. _`distributions`:\n https://packaging.python.org/glossary/#term-Distribution-Package\n.. _`projects`: https://packaging.python.org/glossary/#term-Project\n.. _`documentation`: https://twine.readthedocs.io/\n.. _`developer documentation`:\n https://twine.readthedocs.io/en/latest/contributing.html\n.. _`PSF Code of Conduct`: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md", - "release_date": "2022-02-02T18:50:23", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Donald Stufft and individual contributors", - "email": "donald@stufft.io", - "url": null - } - ], - "keywords": [ - "Intended Audience :: Developers", - "Natural Language :: English", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Operating System :: POSIX :: BSD", - "Operating System :: POSIX :: Linux", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython" - ], - "homepage_url": "https://twine.readthedocs.io/", - "download_url": "https://files.pythonhosted.org/packages/d1/3e/ce331d7e215abdc16c53e65f8506bfccf4840ce191b709a37b8c83cc32c7/twine-3.8.0.tar.gz", - "size": 214568, - "sha1": null, - "md5": "7f904fed5983ea072e1b229486ba4647", - "sha256": "8efa52658e0ae770686a13b675569328f1fba9837e5de1867bfe5f46a9aefe19", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/pypa/twine/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "classifiers": [ - "License :: OSI Approved :: Apache Software License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/twine/3.8.0/json", - "datasource_id": null, - "purl": "pkg:pypi/twine@3.8.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "typing-extensions", - "version": "4.1.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Backported and Experimental Type Hints for Python 3.6+\nTyping Extensions -- Backported and Experimental Type Hints for Python\n\nThe ``typing`` module was added to the standard library in Python 3.5, but\nmany new features have been added to the module since then.\nThis means users of older Python versions who are unable to upgrade will not be\nable to take advantage of new types added to the ``typing`` module, such as\n``typing.Protocol`` or ``typing.TypedDict``.\n\nThe ``typing_extensions`` module contains backports of these changes.\nExperimental types that may eventually be added to the ``typing``\nmodule are also included in ``typing_extensions``.", - "release_date": "2022-02-14T03:19:55", - "parties": [ - { - "type": "person", - "role": "author", - "name": null, - "email": "\"Guido van Rossum, Jukka Lehtosalo, \u0141ukasz Langa, Michael Lee\" ", - "url": null - } - ], - "keywords": [ - "annotations", - "backport", - "checker", - "checking", - "function", - "hinting", - "hints", - "type", - "typechecking", - "typehinting", - "typehints", - "typing", - "Development Status :: 3 - Alpha", - "Environment :: Console", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Topic :: Software Development" - ], - "homepage_url": "", - "download_url": "https://files.pythonhosted.org/packages/45/6b/44f7f8f1e110027cf88956b59f2fad776cca7e1704396d043f89effd3a0e/typing_extensions-4.1.1-py3-none-any.whl", - "size": 26844, + "homepage_url": "https://twine.readthedocs.io/", + "download_url": "https://files.pythonhosted.org/packages/5e/74/ea7dfb86223695fd8efa256a24d1520729dde79a4e628ee6879f0f136d40/twine-3.8.0-py3-none-any.whl", + "size": 36057, "sha1": null, - "md5": "51e77e114d727c80f57551ca7aabb015", - "sha256": "21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2", + "md5": "56a7992f5d1a5901484ca4f5c896625b", + "sha256": "d0550fca9dc19f3d5e8eadfce0c227294df0a2a951251a4385797c8a6198b7c8", "sha512": null, "bug_tracking_url": null, - "code_view_url": null, + "code_view_url": "https://github.com/pypa/twine/", "vcs_url": null, "copyright": null, "license_expression": null, "declared_license": { "classifiers": [ - "License :: OSI Approved :: Python Software Foundation License" + "License :: OSI Approved :: Apache Software License" ] }, "notice_text": null, @@ -9866,9 +5695,9 @@ "dependencies": [], "repository_homepage_url": null, "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/typing-extensions/4.1.1/json", + "api_data_url": "https://pypi.org/pypi/twine/3.8.0/json", "datasource_id": null, - "purl": "pkg:pypi/typing-extensions@4.1.1" + "purl": "pkg:pypi/twine@3.8.0" }, { "type": "pypi", @@ -9879,7 +5708,7 @@ "subpath": null, "primary_language": "Python", "description": "Backported and Experimental Type Hints for Python 3.6+\nTyping Extensions -- Backported and Experimental Type Hints for Python\n\nThe ``typing`` module was added to the standard library in Python 3.5, but\nmany new features have been added to the module since then.\nThis means users of older Python versions who are unable to upgrade will not be\nable to take advantage of new types added to the ``typing`` module, such as\n``typing.Protocol`` or ``typing.TypedDict``.\n\nThe ``typing_extensions`` module contains backports of these changes.\nExperimental types that may eventually be added to the ``typing``\nmodule are also included in ``typing_extensions``.", - "release_date": "2022-02-14T03:19:57", + "release_date": "2022-02-14T03:19:55", "parties": [ { "type": "person", @@ -9916,11 +5745,11 @@ "Topic :: Software Development" ], "homepage_url": "", - "download_url": "https://files.pythonhosted.org/packages/b1/5a/8b5fbb891ef3f81fc923bf3cb4a578c0abf9471eb50ce0f51c74212182ab/typing_extensions-4.1.1.tar.gz", - "size": 26694, + "download_url": "https://files.pythonhosted.org/packages/45/6b/44f7f8f1e110027cf88956b59f2fad776cca7e1704396d043f89effd3a0e/typing_extensions-4.1.1-py3-none-any.whl", + "size": 26844, "sha1": null, - "md5": "3cd9b7b9a465afbcca8548e11668ca64", - "sha256": "1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42", + "md5": "51e77e114d727c80f57551ca7aabb015", + "sha256": "21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2", "sha512": null, "bug_tracking_url": null, "code_view_url": null, @@ -10012,75 +5841,6 @@ "datasource_id": null, "purl": "pkg:pypi/urllib3@1.26.9" }, - { - "type": "pypi", - "namespace": null, - "name": "urllib3", - "version": "1.26.9", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "HTTP library with thread-safe connection pooling, file post, and more.\nurllib3 is a powerful, *user-friendly* HTTP client for Python. Much of the\nPython ecosystem already uses urllib3 and you should too.\nurllib3 brings many critical features that are missing from the Python\nstandard libraries:\n\n- Thread safety.\n- Connection pooling.\n- Client-side SSL/TLS verification.\n- File uploads with multipart encoding.\n- Helpers for retrying requests and dealing with HTTP redirects.\n- Support for gzip, deflate, and brotli encoding.\n- Proxy support for HTTP and SOCKS.\n- 100% test coverage.\n\nurllib3 is powerful and easy to use:\n\n.. code-block:: python\n\n >>> import urllib3\n >>> http = urllib3.PoolManager()\n >>> r = http.request('GET', 'http://httpbin.org/robots.txt')\n >>> r.status\n 200\n >>> r.data\n 'User-agent: *\\nDisallow: /deny\\n'\n\n\nInstalling\n----------\n\nurllib3 can be installed with `pip `_::\n\n $ python -m pip install urllib3\n\nAlternatively, you can grab the latest source code from `GitHub `_::\n\n $ git clone git://github.com/urllib3/urllib3.git\n $ pip install .\n\n\nDocumentation\n-------------\n\nurllib3 has usage and reference documentation at `urllib3.readthedocs.io `_.\n\n\nContributing\n------------\n\nurllib3 happily accepts contributions. Please see our\n`contributing documentation `_\nfor some tips on getting started.\n\n\nSecurity Disclosures\n--------------------\n\nTo report a security vulnerability, please use the\n`Tidelift security contact `_.\nTidelift will coordinate the fix and disclosure with maintainers.\n\n\nMaintainers\n-----------\n\n- `@sethmlarson `__ (Seth M. Larson)\n- `@pquentin `__ (Quentin Pradet)\n- `@theacodes `__ (Thea Flowers)\n- `@haikuginger `__ (Jess Shapiro)\n- `@lukasa `__ (Cory Benfield)\n- `@sigmavirus24 `__ (Ian Stapleton Cordasco)\n- `@shazow `__ (Andrey Petrov)\n\n\ud83d\udc4b\n\n\nSponsorship\n-----------\n\nIf your company benefits from this library, please consider `sponsoring its\ndevelopment `_.\n\n\nFor Enterprise\n--------------\n\n.. |tideliftlogo| image:: https://nedbatchelder.com/pix/Tidelift_Logos_RGB_Tidelift_Shorthand_On-White_small.png\n :width: 75\n :alt: Tidelift\n\n.. list-table::\n :widths: 10 100\n\n * - |tideliftlogo|\n - Professional support for urllib3 is available as part of the `Tidelift\n Subscription`_. Tidelift gives software development teams a single source for\n purchasing and maintaining their software, with professional grade assurances\n from the experts who know it best, while seamlessly integrating with existing\n tools.\n\n.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-urllib3?utm_source=pypi-urllib3&utm_medium=referral&utm_campaign=readme\n\n\nChanges\n=======\n\n1.26.9 (2022-03-16)\n-------------------\n\n* Changed ``urllib3[brotli]`` extra to favor installing Brotli libraries that are still\n receiving updates like ``brotli`` and ``brotlicffi`` instead of ``brotlipy``.\n This change does not impact behavior of urllib3, only which dependencies are installed.\n* Fixed a socket leaking when ``HTTPSConnection.connect()`` raises an exception.\n* Fixed ``server_hostname`` being forwarded from ``PoolManager`` to ``HTTPConnectionPool``\n when requesting an HTTP URL. Should only be forwarded when requesting an HTTPS URL.\n\n\n1.26.8 (2022-01-07)\n-------------------\n\n* Added extra message to ``urllib3.exceptions.ProxyError`` when urllib3 detects that\n a proxy is configured to use HTTPS but the proxy itself appears to only use HTTP.\n* Added a mention of the size of the connection pool when discarding a connection due to the pool being full.\n* Added explicit support for Python 3.11.\n* Deprecated the ``Retry.MAX_BACKOFF`` class property in favor of ``Retry.DEFAULT_MAX_BACKOFF``\n to better match the rest of the default parameter names. ``Retry.MAX_BACKOFF`` is removed in v2.0.\n* Changed location of the vendored ``ssl.match_hostname`` function from ``urllib3.packages.ssl_match_hostname``\n to ``urllib3.util.ssl_match_hostname`` to ensure Python 3.10+ compatibility after being repackaged\n by downstream distributors.\n* Fixed absolute imports, all imports are now relative.\n\n\n1.26.7 (2021-09-22)\n-------------------\n\n* Fixed a bug with HTTPS hostname verification involving IP addresses and lack\n of SNI. (Issue #2400)\n* Fixed a bug where IPv6 braces weren't stripped during certificate hostname\n matching. (Issue #2240)\n\n\n1.26.6 (2021-06-25)\n-------------------\n\n* Deprecated the ``urllib3.contrib.ntlmpool`` module. urllib3 is not able to support\n it properly due to `reasons listed in this issue `_.\n If you are a user of this module please leave a comment.\n* Changed ``HTTPConnection.request_chunked()`` to not erroneously emit multiple\n ``Transfer-Encoding`` headers in the case that one is already specified.\n* Fixed typo in deprecation message to recommend ``Retry.DEFAULT_ALLOWED_METHODS``.\n\n\n1.26.5 (2021-05-26)\n-------------------\n\n* Fixed deprecation warnings emitted in Python 3.10.\n* Updated vendored ``six`` library to 1.16.0.\n* Improved performance of URL parser when splitting\n the authority component.\n\n\n1.26.4 (2021-03-15)\n-------------------\n\n* Changed behavior of the default ``SSLContext`` when connecting to HTTPS proxy\n during HTTPS requests. The default ``SSLContext`` now sets ``check_hostname=True``.\n\n\n1.26.3 (2021-01-26)\n-------------------\n\n* Fixed bytes and string comparison issue with headers (Pull #2141)\n\n* Changed ``ProxySchemeUnknown`` error message to be\n more actionable if the user supplies a proxy URL without\n a scheme. (Pull #2107)\n\n\n1.26.2 (2020-11-12)\n-------------------\n\n* Fixed an issue where ``wrap_socket`` and ``CERT_REQUIRED`` wouldn't\n be imported properly on Python 2.7.8 and earlier (Pull #2052)\n\n\n1.26.1 (2020-11-11)\n-------------------\n\n* Fixed an issue where two ``User-Agent`` headers would be sent if a\n ``User-Agent`` header key is passed as ``bytes`` (Pull #2047)\n\n\n1.26.0 (2020-11-10)\n-------------------\n\n* **NOTE: urllib3 v2.0 will drop support for Python 2**.\n `Read more in the v2.0 Roadmap `_.\n\n* Added support for HTTPS proxies contacting HTTPS servers (Pull #1923, Pull #1806)\n\n* Deprecated negotiating TLSv1 and TLSv1.1 by default. Users that\n still wish to use TLS earlier than 1.2 without a deprecation warning\n should opt-in explicitly by setting ``ssl_version=ssl.PROTOCOL_TLSv1_1`` (Pull #2002)\n **Starting in urllib3 v2.0: Connections that receive a ``DeprecationWarning`` will fail**\n\n* Deprecated ``Retry`` options ``Retry.DEFAULT_METHOD_WHITELIST``, ``Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST``\n and ``Retry(method_whitelist=...)`` in favor of ``Retry.DEFAULT_ALLOWED_METHODS``,\n ``Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT``, and ``Retry(allowed_methods=...)``\n (Pull #2000) **Starting in urllib3 v2.0: Deprecated options will be removed**\n\n* Added default ``User-Agent`` header to every request (Pull #1750)\n\n* Added ``urllib3.util.SKIP_HEADER`` for skipping ``User-Agent``, ``Accept-Encoding``, \n and ``Host`` headers from being automatically emitted with requests (Pull #2018)\n\n* Collapse ``transfer-encoding: chunked`` request data and framing into\n the same ``socket.send()`` call (Pull #1906)\n\n* Send ``http/1.1`` ALPN identifier with every TLS handshake by default (Pull #1894)\n\n* Properly terminate SecureTransport connections when CA verification fails (Pull #1977)\n\n* Don't emit an ``SNIMissingWarning`` when passing ``server_hostname=None``\n to SecureTransport (Pull #1903)\n\n* Disabled requesting TLSv1.2 session tickets as they weren't being used by urllib3 (Pull #1970)\n\n* Suppress ``BrokenPipeError`` when writing request body after the server\n has closed the socket (Pull #1524)\n\n* Wrap ``ssl.SSLError`` that can be raised from reading a socket (e.g. \"bad MAC\")\n into an ``urllib3.exceptions.SSLError`` (Pull #1939)\n\n\n1.25.11 (2020-10-19)\n--------------------\n\n* Fix retry backoff time parsed from ``Retry-After`` header when given\n in the HTTP date format. The HTTP date was parsed as the local timezone\n rather than accounting for the timezone in the HTTP date (typically\n UTC) (Pull #1932, Pull #1935, Pull #1938, Pull #1949)\n\n* Fix issue where an error would be raised when the ``SSLKEYLOGFILE``\n environment variable was set to the empty string. Now ``SSLContext.keylog_file``\n is not set in this situation (Pull #2016)\n\n\n1.25.10 (2020-07-22)\n--------------------\n\n* Added support for ``SSLKEYLOGFILE`` environment variable for\n logging TLS session keys with use with programs like\n Wireshark for decrypting captured web traffic (Pull #1867)\n\n* Fixed loading of SecureTransport libraries on macOS Big Sur\n due to the new dynamic linker cache (Pull #1905)\n\n* Collapse chunked request bodies data and framing into one\n call to ``send()`` to reduce the number of TCP packets by 2-4x (Pull #1906)\n\n* Don't insert ``None`` into ``ConnectionPool`` if the pool\n was empty when requesting a connection (Pull #1866)\n\n* Avoid ``hasattr`` call in ``BrotliDecoder.decompress()`` (Pull #1858)\n\n\n1.25.9 (2020-04-16)\n-------------------\n\n* Added ``InvalidProxyConfigurationWarning`` which is raised when\n erroneously specifying an HTTPS proxy URL. urllib3 doesn't currently\n support connecting to HTTPS proxies but will soon be able to\n and we would like users to migrate properly without much breakage.\n\n See `this GitHub issue `_\n for more information on how to fix your proxy config. (Pull #1851)\n\n* Drain connection after ``PoolManager`` redirect (Pull #1817)\n\n* Ensure ``load_verify_locations`` raises ``SSLError`` for all backends (Pull #1812)\n\n* Rename ``VerifiedHTTPSConnection`` to ``HTTPSConnection`` (Pull #1805)\n\n* Allow the CA certificate data to be passed as a string (Pull #1804)\n\n* Raise ``ValueError`` if method contains control characters (Pull #1800)\n\n* Add ``__repr__`` to ``Timeout`` (Pull #1795)\n\n\n1.25.8 (2020-01-20)\n-------------------\n\n* Drop support for EOL Python 3.4 (Pull #1774)\n\n* Optimize _encode_invalid_chars (Pull #1787)\n\n\n1.25.7 (2019-11-11)\n-------------------\n\n* Preserve ``chunked`` parameter on retries (Pull #1715, Pull #1734)\n\n* Allow unset ``SERVER_SOFTWARE`` in App Engine (Pull #1704, Issue #1470)\n\n* Fix issue where URL fragment was sent within the request target. (Pull #1732)\n\n* Fix issue where an empty query section in a URL would fail to parse. (Pull #1732)\n\n* Remove TLS 1.3 support in SecureTransport due to Apple removing support (Pull #1703)\n\n\n1.25.6 (2019-09-24)\n-------------------\n\n* Fix issue where tilde (``~``) characters were incorrectly\n percent-encoded in the path. (Pull #1692)\n\n\n1.25.5 (2019-09-19)\n-------------------\n\n* Add mitigation for BPO-37428 affecting Python <3.7.4 and OpenSSL 1.1.1+ which\n caused certificate verification to be enabled when using ``cert_reqs=CERT_NONE``.\n (Issue #1682)\n\n\n1.25.4 (2019-09-19)\n-------------------\n\n* Propagate Retry-After header settings to subsequent retries. (Pull #1607)\n\n* Fix edge case where Retry-After header was still respected even when\n explicitly opted out of. (Pull #1607)\n\n* Remove dependency on ``rfc3986`` for URL parsing.\n\n* Fix issue where URLs containing invalid characters within ``Url.auth`` would\n raise an exception instead of percent-encoding those characters.\n\n* Add support for ``HTTPResponse.auto_close = False`` which makes HTTP responses\n work well with BufferedReaders and other ``io`` module features. (Pull #1652)\n\n* Percent-encode invalid characters in URL for ``HTTPConnectionPool.request()`` (Pull #1673)\n\n\n1.25.3 (2019-05-23)\n-------------------\n\n* Change ``HTTPSConnection`` to load system CA certificates\n when ``ca_certs``, ``ca_cert_dir``, and ``ssl_context`` are\n unspecified. (Pull #1608, Issue #1603)\n\n* Upgrade bundled rfc3986 to v1.3.2. (Pull #1609, Issue #1605)\n\n\n1.25.2 (2019-04-28)\n-------------------\n\n* Change ``is_ipaddress`` to not detect IPvFuture addresses. (Pull #1583)\n\n* Change ``parse_url`` to percent-encode invalid characters within the\n path, query, and target components. (Pull #1586)\n\n\n1.25.1 (2019-04-24)\n-------------------\n\n* Add support for Google's ``Brotli`` package. (Pull #1572, Pull #1579)\n\n* Upgrade bundled rfc3986 to v1.3.1 (Pull #1578)\n\n\n1.25 (2019-04-22)\n-----------------\n\n* Require and validate certificates by default when using HTTPS (Pull #1507)\n\n* Upgraded ``urllib3.utils.parse_url()`` to be RFC 3986 compliant. (Pull #1487)\n\n* Added support for ``key_password`` for ``HTTPSConnectionPool`` to use\n encrypted ``key_file`` without creating your own ``SSLContext`` object. (Pull #1489)\n\n* Add TLSv1.3 support to CPython, pyOpenSSL, and SecureTransport ``SSLContext``\n implementations. (Pull #1496)\n\n* Switched the default multipart header encoder from RFC 2231 to HTML 5 working draft. (Issue #303, Pull #1492)\n\n* Fixed issue where OpenSSL would block if an encrypted client private key was\n given and no password was given. Instead an ``SSLError`` is raised. (Pull #1489)\n\n* Added support for Brotli content encoding. It is enabled automatically if\n ``brotlipy`` package is installed which can be requested with\n ``urllib3[brotli]`` extra. (Pull #1532)\n\n* Drop ciphers using DSS key exchange from default TLS cipher suites.\n Improve default ciphers when using SecureTransport. (Pull #1496)\n\n* Implemented a more efficient ``HTTPResponse.__iter__()`` method. (Issue #1483)\n\n1.24.3 (2019-05-01)\n-------------------\n\n* Apply fix for CVE-2019-9740. (Pull #1591)\n\n1.24.2 (2019-04-17)\n-------------------\n\n* Don't load system certificates by default when any other ``ca_certs``, ``ca_certs_dir`` or\n ``ssl_context`` parameters are specified.\n\n* Remove Authorization header regardless of case when redirecting to cross-site. (Issue #1510)\n\n* Add support for IPv6 addresses in subjectAltName section of certificates. (Issue #1269)\n\n\n1.24.1 (2018-11-02)\n-------------------\n\n* Remove quadratic behavior within ``GzipDecoder.decompress()`` (Issue #1467)\n\n* Restored functionality of ``ciphers`` parameter for ``create_urllib3_context()``. (Issue #1462)\n\n\n1.24 (2018-10-16)\n-----------------\n\n* Allow key_server_hostname to be specified when initializing a PoolManager to allow custom SNI to be overridden. (Pull #1449)\n\n* Test against Python 3.7 on AppVeyor. (Pull #1453)\n\n* Early-out ipv6 checks when running on App Engine. (Pull #1450)\n\n* Change ambiguous description of backoff_factor (Pull #1436)\n\n* Add ability to handle multiple Content-Encodings (Issue #1441 and Pull #1442)\n\n* Skip DNS names that can't be idna-decoded when using pyOpenSSL (Issue #1405).\n\n* Add a server_hostname parameter to HTTPSConnection which allows for\n overriding the SNI hostname sent in the handshake. (Pull #1397)\n\n* Drop support for EOL Python 2.6 (Pull #1429 and Pull #1430)\n\n* Fixed bug where responses with header Content-Type: message/* erroneously\n raised HeaderParsingError, resulting in a warning being logged. (Pull #1439)\n\n* Move urllib3 to src/urllib3 (Pull #1409)\n\n\n1.23 (2018-06-04)\n-----------------\n\n* Allow providing a list of headers to strip from requests when redirecting\n to a different host. Defaults to the ``Authorization`` header. Different\n headers can be set via ``Retry.remove_headers_on_redirect``. (Issue #1316)\n\n* Fix ``util.selectors._fileobj_to_fd`` to accept ``long`` (Issue #1247).\n\n* Dropped Python 3.3 support. (Pull #1242)\n\n* Put the connection back in the pool when calling stream() or read_chunked() on\n a chunked HEAD response. (Issue #1234)\n\n* Fixed pyOpenSSL-specific ssl client authentication issue when clients\n attempted to auth via certificate + chain (Issue #1060)\n\n* Add the port to the connectionpool connect print (Pull #1251)\n\n* Don't use the ``uuid`` module to create multipart data boundaries. (Pull #1380)\n\n* ``read_chunked()`` on a closed response returns no chunks. (Issue #1088)\n\n* Add Python 2.6 support to ``contrib.securetransport`` (Pull #1359)\n\n* Added support for auth info in url for SOCKS proxy (Pull #1363)\n\n\n1.22 (2017-07-20)\n-----------------\n\n* Fixed missing brackets in ``HTTP CONNECT`` when connecting to IPv6 address via\n IPv6 proxy. (Issue #1222)\n\n* Made the connection pool retry on ``SSLError``. The original ``SSLError``\n is available on ``MaxRetryError.reason``. (Issue #1112)\n\n* Drain and release connection before recursing on retry/redirect. Fixes\n deadlocks with a blocking connectionpool. (Issue #1167)\n\n* Fixed compatibility for cookiejar. (Issue #1229)\n\n* pyopenssl: Use vendored version of ``six``. (Issue #1231)\n\n\n1.21.1 (2017-05-02)\n-------------------\n\n* Fixed SecureTransport issue that would cause long delays in response body\n delivery. (Pull #1154)\n\n* Fixed regression in 1.21 that threw exceptions when users passed the\n ``socket_options`` flag to the ``PoolManager``. (Issue #1165)\n\n* Fixed regression in 1.21 that threw exceptions when users passed the\n ``assert_hostname`` or ``assert_fingerprint`` flag to the ``PoolManager``.\n (Pull #1157)\n\n\n1.21 (2017-04-25)\n-----------------\n\n* Improved performance of certain selector system calls on Python 3.5 and\n later. (Pull #1095)\n\n* Resolved issue where the PyOpenSSL backend would not wrap SysCallError\n exceptions appropriately when sending data. (Pull #1125)\n\n* Selectors now detects a monkey-patched select module after import for modules\n that patch the select module like eventlet, greenlet. (Pull #1128)\n\n* Reduced memory consumption when streaming zlib-compressed responses\n (as opposed to raw deflate streams). (Pull #1129)\n\n* Connection pools now use the entire request context when constructing the\n pool key. (Pull #1016)\n\n* ``PoolManager.connection_from_*`` methods now accept a new keyword argument,\n ``pool_kwargs``, which are merged with the existing ``connection_pool_kw``.\n (Pull #1016)\n\n* Add retry counter for ``status_forcelist``. (Issue #1147)\n\n* Added ``contrib`` module for using SecureTransport on macOS:\n ``urllib3.contrib.securetransport``. (Pull #1122)\n\n* urllib3 now only normalizes the case of ``http://`` and ``https://`` schemes:\n for schemes it does not recognise, it assumes they are case-sensitive and\n leaves them unchanged.\n (Issue #1080)\n\n\n1.20 (2017-01-19)\n-----------------\n\n* Added support for waiting for I/O using selectors other than select,\n improving urllib3's behaviour with large numbers of concurrent connections.\n (Pull #1001)\n\n* Updated the date for the system clock check. (Issue #1005)\n\n* ConnectionPools now correctly consider hostnames to be case-insensitive.\n (Issue #1032)\n\n* Outdated versions of PyOpenSSL now cause the PyOpenSSL contrib module\n to fail when it is injected, rather than at first use. (Pull #1063)\n\n* Outdated versions of cryptography now cause the PyOpenSSL contrib module\n to fail when it is injected, rather than at first use. (Issue #1044)\n\n* Automatically attempt to rewind a file-like body object when a request is\n retried or redirected. (Pull #1039)\n\n* Fix some bugs that occur when modules incautiously patch the queue module.\n (Pull #1061)\n\n* Prevent retries from occurring on read timeouts for which the request method\n was not in the method whitelist. (Issue #1059)\n\n* Changed the PyOpenSSL contrib module to lazily load idna to avoid\n unnecessarily bloating the memory of programs that don't need it. (Pull\n #1076)\n\n* Add support for IPv6 literals with zone identifiers. (Pull #1013)\n\n* Added support for socks5h:// and socks4a:// schemes when working with SOCKS\n proxies, and controlled remote DNS appropriately. (Issue #1035)\n\n\n1.19.1 (2016-11-16)\n-------------------\n\n* Fixed AppEngine import that didn't function on Python 3.5. (Pull #1025)\n\n\n1.19 (2016-11-03)\n-----------------\n\n* urllib3 now respects Retry-After headers on 413, 429, and 503 responses when\n using the default retry logic. (Pull #955)\n\n* Remove markers from setup.py to assist ancient setuptools versions. (Issue\n #986)\n\n* Disallow superscripts and other integerish things in URL ports. (Issue #989)\n\n* Allow urllib3's HTTPResponse.stream() method to continue to work with\n non-httplib underlying FPs. (Pull #990)\n\n* Empty filenames in multipart headers are now emitted as such, rather than\n being suppressed. (Issue #1015)\n\n* Prefer user-supplied Host headers on chunked uploads. (Issue #1009)\n\n\n1.18.1 (2016-10-27)\n-------------------\n\n* CVE-2016-9015. Users who are using urllib3 version 1.17 or 1.18 along with\n PyOpenSSL injection and OpenSSL 1.1.0 *must* upgrade to this version. This\n release fixes a vulnerability whereby urllib3 in the above configuration\n would silently fail to validate TLS certificates due to erroneously setting\n invalid flags in OpenSSL's ``SSL_CTX_set_verify`` function. These erroneous\n flags do not cause a problem in OpenSSL versions before 1.1.0, which\n interprets the presence of any flag as requesting certificate validation.\n\n There is no PR for this patch, as it was prepared for simultaneous disclosure\n and release. The master branch received the same fix in Pull #1010.\n\n\n1.18 (2016-09-26)\n-----------------\n\n* Fixed incorrect message for IncompleteRead exception. (Pull #973)\n\n* Accept ``iPAddress`` subject alternative name fields in TLS certificates.\n (Issue #258)\n\n* Fixed consistency of ``HTTPResponse.closed`` between Python 2 and 3.\n (Issue #977)\n\n* Fixed handling of wildcard certificates when using PyOpenSSL. (Issue #979)\n\n\n1.17 (2016-09-06)\n-----------------\n\n* Accept ``SSLContext`` objects for use in SSL/TLS negotiation. (Issue #835)\n\n* ConnectionPool debug log now includes scheme, host, and port. (Issue #897)\n\n* Substantially refactored documentation. (Issue #887)\n\n* Used URLFetch default timeout on AppEngine, rather than hardcoding our own.\n (Issue #858)\n\n* Normalize the scheme and host in the URL parser (Issue #833)\n\n* ``HTTPResponse`` contains the last ``Retry`` object, which now also\n contains retries history. (Issue #848)\n\n* Timeout can no longer be set as boolean, and must be greater than zero.\n (Pull #924)\n\n* Removed pyasn1 and ndg-httpsclient from dependencies used for PyOpenSSL. We\n now use cryptography and idna, both of which are already dependencies of\n PyOpenSSL. (Pull #930)\n\n* Fixed infinite loop in ``stream`` when amt=None. (Issue #928)\n\n* Try to use the operating system's certificates when we are using an\n ``SSLContext``. (Pull #941)\n\n* Updated cipher suite list to allow ChaCha20+Poly1305. AES-GCM is preferred to\n ChaCha20, but ChaCha20 is then preferred to everything else. (Pull #947)\n\n* Updated cipher suite list to remove 3DES-based cipher suites. (Pull #958)\n\n* Removed the cipher suite fallback to allow HIGH ciphers. (Pull #958)\n\n* Implemented ``length_remaining`` to determine remaining content\n to be read. (Pull #949)\n\n* Implemented ``enforce_content_length`` to enable exceptions when\n incomplete data chunks are received. (Pull #949)\n\n* Dropped connection start, dropped connection reset, redirect, forced retry,\n and new HTTPS connection log levels to DEBUG, from INFO. (Pull #967)\n\n\n1.16 (2016-06-11)\n-----------------\n\n* Disable IPv6 DNS when IPv6 connections are not possible. (Issue #840)\n\n* Provide ``key_fn_by_scheme`` pool keying mechanism that can be\n overridden. (Issue #830)\n\n* Normalize scheme and host to lowercase for pool keys, and include\n ``source_address``. (Issue #830)\n\n* Cleaner exception chain in Python 3 for ``_make_request``.\n (Issue #861)\n\n* Fixed installing ``urllib3[socks]`` extra. (Issue #864)\n\n* Fixed signature of ``ConnectionPool.close`` so it can actually safely be\n called by subclasses. (Issue #873)\n\n* Retain ``release_conn`` state across retries. (Issues #651, #866)\n\n* Add customizable ``HTTPConnectionPool.ResponseCls``, which defaults to\n ``HTTPResponse`` but can be replaced with a subclass. (Issue #879)\n\n\n1.15.1 (2016-04-11)\n-------------------\n\n* Fix packaging to include backports module. (Issue #841)\n\n\n1.15 (2016-04-06)\n-----------------\n\n* Added Retry(raise_on_status=False). (Issue #720)\n\n* Always use setuptools, no more distutils fallback. (Issue #785)\n\n* Dropped support for Python 3.2. (Issue #786)\n\n* Chunked transfer encoding when requesting with ``chunked=True``.\n (Issue #790)\n\n* Fixed regression with IPv6 port parsing. (Issue #801)\n\n* Append SNIMissingWarning messages to allow users to specify it in\n the PYTHONWARNINGS environment variable. (Issue #816)\n\n* Handle unicode headers in Py2. (Issue #818)\n\n* Log certificate when there is a hostname mismatch. (Issue #820)\n\n* Preserve order of request/response headers. (Issue #821)\n\n\n1.14 (2015-12-29)\n-----------------\n\n* contrib: SOCKS proxy support! (Issue #762)\n\n* Fixed AppEngine handling of transfer-encoding header and bug\n in Timeout defaults checking. (Issue #763)\n\n\n1.13.1 (2015-12-18)\n-------------------\n\n* Fixed regression in IPv6 + SSL for match_hostname. (Issue #761)\n\n\n1.13 (2015-12-14)\n-----------------\n\n* Fixed ``pip install urllib3[secure]`` on modern pip. (Issue #706)\n\n* pyopenssl: Fixed SSL3_WRITE_PENDING error. (Issue #717)\n\n* pyopenssl: Support for TLSv1.1 and TLSv1.2. (Issue #696)\n\n* Close connections more defensively on exception. (Issue #734)\n\n* Adjusted ``read_chunked`` to handle gzipped, chunk-encoded bodies without\n repeatedly flushing the decoder, to function better on Jython. (Issue #743)\n\n* Accept ``ca_cert_dir`` for SSL-related PoolManager configuration. (Issue #758)\n\n\n1.12 (2015-09-03)\n-----------------\n\n* Rely on ``six`` for importing ``httplib`` to work around\n conflicts with other Python 3 shims. (Issue #688)\n\n* Add support for directories of certificate authorities, as supported by\n OpenSSL. (Issue #701)\n\n* New exception: ``NewConnectionError``, raised when we fail to establish\n a new connection, usually ``ECONNREFUSED`` socket error.\n\n\n1.11 (2015-07-21)\n-----------------\n\n* When ``ca_certs`` is given, ``cert_reqs`` defaults to\n ``'CERT_REQUIRED'``. (Issue #650)\n\n* ``pip install urllib3[secure]`` will install Certifi and\n PyOpenSSL as dependencies. (Issue #678)\n\n* Made ``HTTPHeaderDict`` usable as a ``headers`` input value\n (Issues #632, #679)\n\n* Added `urllib3.contrib.appengine `_\n which has an ``AppEngineManager`` for using ``URLFetch`` in a\n Google AppEngine environment. (Issue #664)\n\n* Dev: Added test suite for AppEngine. (Issue #631)\n\n* Fix performance regression when using PyOpenSSL. (Issue #626)\n\n* Passing incorrect scheme (e.g. ``foo://``) will raise\n ``ValueError`` instead of ``AssertionError`` (backwards\n compatible for now, but please migrate). (Issue #640)\n\n* Fix pools not getting replenished when an error occurs during a\n request using ``release_conn=False``. (Issue #644)\n\n* Fix pool-default headers not applying for url-encoded requests\n like GET. (Issue #657)\n\n* log.warning in Python 3 when headers are skipped due to parsing\n errors. (Issue #642)\n\n* Close and discard connections if an error occurs during read.\n (Issue #660)\n\n* Fix host parsing for IPv6 proxies. (Issue #668)\n\n* Separate warning type SubjectAltNameWarning, now issued once\n per host. (Issue #671)\n\n* Fix ``httplib.IncompleteRead`` not getting converted to\n ``ProtocolError`` when using ``HTTPResponse.stream()``\n (Issue #674)\n\n1.10.4 (2015-05-03)\n-------------------\n\n* Migrate tests to Tornado 4. (Issue #594)\n\n* Append default warning configuration rather than overwrite.\n (Issue #603)\n\n* Fix streaming decoding regression. (Issue #595)\n\n* Fix chunked requests losing state across keep-alive connections.\n (Issue #599)\n\n* Fix hanging when chunked HEAD response has no body. (Issue #605)\n\n\n1.10.3 (2015-04-21)\n-------------------\n\n* Emit ``InsecurePlatformWarning`` when SSLContext object is missing.\n (Issue #558)\n\n* Fix regression of duplicate header keys being discarded.\n (Issue #563)\n\n* ``Response.stream()`` returns a generator for chunked responses.\n (Issue #560)\n\n* Set upper-bound timeout when waiting for a socket in PyOpenSSL.\n (Issue #585)\n\n* Work on platforms without `ssl` module for plain HTTP requests.\n (Issue #587)\n\n* Stop relying on the stdlib's default cipher list. (Issue #588)\n\n\n1.10.2 (2015-02-25)\n-------------------\n\n* Fix file descriptor leakage on retries. (Issue #548)\n\n* Removed RC4 from default cipher list. (Issue #551)\n\n* Header performance improvements. (Issue #544)\n\n* Fix PoolManager not obeying redirect retry settings. (Issue #553)\n\n\n1.10.1 (2015-02-10)\n-------------------\n\n* Pools can be used as context managers. (Issue #545)\n\n* Don't re-use connections which experienced an SSLError. (Issue #529)\n\n* Don't fail when gzip decoding an empty stream. (Issue #535)\n\n* Add sha256 support for fingerprint verification. (Issue #540)\n\n* Fixed handling of header values containing commas. (Issue #533)\n\n\n1.10 (2014-12-14)\n-----------------\n\n* Disabled SSLv3. (Issue #473)\n\n* Add ``Url.url`` property to return the composed url string. (Issue #394)\n\n* Fixed PyOpenSSL + gevent ``WantWriteError``. (Issue #412)\n\n* ``MaxRetryError.reason`` will always be an exception, not string.\n (Issue #481)\n\n* Fixed SSL-related timeouts not being detected as timeouts. (Issue #492)\n\n* Py3: Use ``ssl.create_default_context()`` when available. (Issue #473)\n\n* Emit ``InsecureRequestWarning`` for *every* insecure HTTPS request.\n (Issue #496)\n\n* Emit ``SecurityWarning`` when certificate has no ``subjectAltName``.\n (Issue #499)\n\n* Close and discard sockets which experienced SSL-related errors.\n (Issue #501)\n\n* Handle ``body`` param in ``.request(...)``. (Issue #513)\n\n* Respect timeout with HTTPS proxy. (Issue #505)\n\n* PyOpenSSL: Handle ZeroReturnError exception. (Issue #520)\n\n\n1.9.1 (2014-09-13)\n------------------\n\n* Apply socket arguments before binding. (Issue #427)\n\n* More careful checks if fp-like object is closed. (Issue #435)\n\n* Fixed packaging issues of some development-related files not\n getting included. (Issue #440)\n\n* Allow performing *only* fingerprint verification. (Issue #444)\n\n* Emit ``SecurityWarning`` if system clock is waaay off. (Issue #445)\n\n* Fixed PyOpenSSL compatibility with PyPy. (Issue #450)\n\n* Fixed ``BrokenPipeError`` and ``ConnectionError`` handling in Py3.\n (Issue #443)\n\n\n\n1.9 (2014-07-04)\n----------------\n\n* Shuffled around development-related files. If you're maintaining a distro\n package of urllib3, you may need to tweak things. (Issue #415)\n\n* Unverified HTTPS requests will trigger a warning on the first request. See\n our new `security documentation\n `_ for details.\n (Issue #426)\n\n* New retry logic and ``urllib3.util.retry.Retry`` configuration object.\n (Issue #326)\n\n* All raised exceptions should now wrapped in a\n ``urllib3.exceptions.HTTPException``-extending exception. (Issue #326)\n\n* All errors during a retry-enabled request should be wrapped in\n ``urllib3.exceptions.MaxRetryError``, including timeout-related exceptions\n which were previously exempt. Underlying error is accessible from the\n ``.reason`` property. (Issue #326)\n\n* ``urllib3.exceptions.ConnectionError`` renamed to\n ``urllib3.exceptions.ProtocolError``. (Issue #326)\n\n* Errors during response read (such as IncompleteRead) are now wrapped in\n ``urllib3.exceptions.ProtocolError``. (Issue #418)\n\n* Requesting an empty host will raise ``urllib3.exceptions.LocationValueError``.\n (Issue #417)\n\n* Catch read timeouts over SSL connections as\n ``urllib3.exceptions.ReadTimeoutError``. (Issue #419)\n\n* Apply socket arguments before connecting. (Issue #427)\n\n\n1.8.3 (2014-06-23)\n------------------\n\n* Fix TLS verification when using a proxy in Python 3.4.1. (Issue #385)\n\n* Add ``disable_cache`` option to ``urllib3.util.make_headers``. (Issue #393)\n\n* Wrap ``socket.timeout`` exception with\n ``urllib3.exceptions.ReadTimeoutError``. (Issue #399)\n\n* Fixed proxy-related bug where connections were being reused incorrectly.\n (Issues #366, #369)\n\n* Added ``socket_options`` keyword parameter which allows to define\n ``setsockopt`` configuration of new sockets. (Issue #397)\n\n* Removed ``HTTPConnection.tcp_nodelay`` in favor of\n ``HTTPConnection.default_socket_options``. (Issue #397)\n\n* Fixed ``TypeError`` bug in Python 2.6.4. (Issue #411)\n\n\n1.8.2 (2014-04-17)\n------------------\n\n* Fix ``urllib3.util`` not being included in the package.\n\n\n1.8.1 (2014-04-17)\n------------------\n\n* Fix AppEngine bug of HTTPS requests going out as HTTP. (Issue #356)\n\n* Don't install ``dummyserver`` into ``site-packages`` as it's only needed\n for the test suite. (Issue #362)\n\n* Added support for specifying ``source_address``. (Issue #352)\n\n\n1.8 (2014-03-04)\n----------------\n\n* Improved url parsing in ``urllib3.util.parse_url`` (properly parse '@' in\n username, and blank ports like 'hostname:').\n\n* New ``urllib3.connection`` module which contains all the HTTPConnection\n objects.\n\n* Several ``urllib3.util.Timeout``-related fixes. Also changed constructor\n signature to a more sensible order. [Backwards incompatible]\n (Issues #252, #262, #263)\n\n* Use ``backports.ssl_match_hostname`` if it's installed. (Issue #274)\n\n* Added ``.tell()`` method to ``urllib3.response.HTTPResponse`` which\n returns the number of bytes read so far. (Issue #277)\n\n* Support for platforms without threading. (Issue #289)\n\n* Expand default-port comparison in ``HTTPConnectionPool.is_same_host``\n to allow a pool with no specified port to be considered equal to to an\n HTTP/HTTPS url with port 80/443 explicitly provided. (Issue #305)\n\n* Improved default SSL/TLS settings to avoid vulnerabilities.\n (Issue #309)\n\n* Fixed ``urllib3.poolmanager.ProxyManager`` not retrying on connect errors.\n (Issue #310)\n\n* Disable Nagle's Algorithm on the socket for non-proxies. A subset of requests\n will send the entire HTTP request ~200 milliseconds faster; however, some of\n the resulting TCP packets will be smaller. (Issue #254)\n\n* Increased maximum number of SubjectAltNames in ``urllib3.contrib.pyopenssl``\n from the default 64 to 1024 in a single certificate. (Issue #318)\n\n* Headers are now passed and stored as a custom\n ``urllib3.collections_.HTTPHeaderDict`` object rather than a plain ``dict``.\n (Issue #329, #333)\n\n* Headers no longer lose their case on Python 3. (Issue #236)\n\n* ``urllib3.contrib.pyopenssl`` now uses the operating system's default CA\n certificates on inject. (Issue #332)\n\n* Requests with ``retries=False`` will immediately raise any exceptions without\n wrapping them in ``MaxRetryError``. (Issue #348)\n\n* Fixed open socket leak with SSL-related failures. (Issue #344, #348)\n\n\n1.7.1 (2013-09-25)\n------------------\n\n* Added granular timeout support with new ``urllib3.util.Timeout`` class.\n (Issue #231)\n\n* Fixed Python 3.4 support. (Issue #238)\n\n\n1.7 (2013-08-14)\n----------------\n\n* More exceptions are now pickle-able, with tests. (Issue #174)\n\n* Fixed redirecting with relative URLs in Location header. (Issue #178)\n\n* Support for relative urls in ``Location: ...`` header. (Issue #179)\n\n* ``urllib3.response.HTTPResponse`` now inherits from ``io.IOBase`` for bonus\n file-like functionality. (Issue #187)\n\n* Passing ``assert_hostname=False`` when creating a HTTPSConnectionPool will\n skip hostname verification for SSL connections. (Issue #194)\n\n* New method ``urllib3.response.HTTPResponse.stream(...)`` which acts as a\n generator wrapped around ``.read(...)``. (Issue #198)\n\n* IPv6 url parsing enforces brackets around the hostname. (Issue #199)\n\n* Fixed thread race condition in\n ``urllib3.poolmanager.PoolManager.connection_from_host(...)`` (Issue #204)\n\n* ``ProxyManager`` requests now include non-default port in ``Host: ...``\n header. (Issue #217)\n\n* Added HTTPS proxy support in ``ProxyManager``. (Issue #170 #139)\n\n* New ``RequestField`` object can be passed to the ``fields=...`` param which\n can specify headers. (Issue #220)\n\n* Raise ``urllib3.exceptions.ProxyError`` when connecting to proxy fails.\n (Issue #221)\n\n* Use international headers when posting file names. (Issue #119)\n\n* Improved IPv6 support. (Issue #203)\n\n\n1.6 (2013-04-25)\n----------------\n\n* Contrib: Optional SNI support for Py2 using PyOpenSSL. (Issue #156)\n\n* ``ProxyManager`` automatically adds ``Host: ...`` header if not given.\n\n* Improved SSL-related code. ``cert_req`` now optionally takes a string like\n \"REQUIRED\" or \"NONE\". Same with ``ssl_version`` takes strings like \"SSLv23\"\n The string values reflect the suffix of the respective constant variable.\n (Issue #130)\n\n* Vendored ``socksipy`` now based on Anorov's fork which handles unexpectedly\n closed proxy connections and larger read buffers. (Issue #135)\n\n* Ensure the connection is closed if no data is received, fixes connection leak\n on some platforms. (Issue #133)\n\n* Added SNI support for SSL/TLS connections on Py32+. (Issue #89)\n\n* Tests fixed to be compatible with Py26 again. (Issue #125)\n\n* Added ability to choose SSL version by passing an ``ssl.PROTOCOL_*`` constant\n to the ``ssl_version`` parameter of ``HTTPSConnectionPool``. (Issue #109)\n\n* Allow an explicit content type to be specified when encoding file fields.\n (Issue #126)\n\n* Exceptions are now pickleable, with tests. (Issue #101)\n\n* Fixed default headers not getting passed in some cases. (Issue #99)\n\n* Treat \"content-encoding\" header value as case-insensitive, per RFC 2616\n Section 3.5. (Issue #110)\n\n* \"Connection Refused\" SocketErrors will get retried rather than raised.\n (Issue #92)\n\n* Updated vendored ``six``, no longer overrides the global ``six`` module\n namespace. (Issue #113)\n\n* ``urllib3.exceptions.MaxRetryError`` contains a ``reason`` property holding\n the exception that prompted the final retry. If ``reason is None`` then it\n was due to a redirect. (Issue #92, #114)\n\n* Fixed ``PoolManager.urlopen()`` from not redirecting more than once.\n (Issue #149)\n\n* Don't assume ``Content-Type: text/plain`` for multi-part encoding parameters\n that are not files. (Issue #111)\n\n* Pass `strict` param down to ``httplib.HTTPConnection``. (Issue #122)\n\n* Added mechanism to verify SSL certificates by fingerprint (md5, sha1) or\n against an arbitrary hostname (when connecting by IP or for misconfigured\n servers). (Issue #140)\n\n* Streaming decompression support. (Issue #159)\n\n\n1.5 (2012-08-02)\n----------------\n\n* Added ``urllib3.add_stderr_logger()`` for quickly enabling STDERR debug\n logging in urllib3.\n\n* Native full URL parsing (including auth, path, query, fragment) available in\n ``urllib3.util.parse_url(url)``.\n\n* Built-in redirect will switch method to 'GET' if status code is 303.\n (Issue #11)\n\n* ``urllib3.PoolManager`` strips the scheme and host before sending the request\n uri. (Issue #8)\n\n* New ``urllib3.exceptions.DecodeError`` exception for when automatic decoding,\n based on the Content-Type header, fails.\n\n* Fixed bug with pool depletion and leaking connections (Issue #76). Added\n explicit connection closing on pool eviction. Added\n ``urllib3.PoolManager.clear()``.\n\n* 99% -> 100% unit test coverage.\n\n\n1.4 (2012-06-16)\n----------------\n\n* Minor AppEngine-related fixes.\n\n* Switched from ``mimetools.choose_boundary`` to ``uuid.uuid4()``.\n\n* Improved url parsing. (Issue #73)\n\n* IPv6 url support. (Issue #72)\n\n\n1.3 (2012-03-25)\n----------------\n\n* Removed pre-1.0 deprecated API.\n\n* Refactored helpers into a ``urllib3.util`` submodule.\n\n* Fixed multipart encoding to support list-of-tuples for keys with multiple\n values. (Issue #48)\n\n* Fixed multiple Set-Cookie headers in response not getting merged properly in\n Python 3. (Issue #53)\n\n* AppEngine support with Py27. (Issue #61)\n\n* Minor ``encode_multipart_formdata`` fixes related to Python 3 strings vs\n bytes.\n\n\n1.2.2 (2012-02-06)\n------------------\n\n* Fixed packaging bug of not shipping ``test-requirements.txt``. (Issue #47)\n\n\n1.2.1 (2012-02-05)\n------------------\n\n* Fixed another bug related to when ``ssl`` module is not available. (Issue #41)\n\n* Location parsing errors now raise ``urllib3.exceptions.LocationParseError``\n which inherits from ``ValueError``.\n\n\n1.2 (2012-01-29)\n----------------\n\n* Added Python 3 support (tested on 3.2.2)\n\n* Dropped Python 2.5 support (tested on 2.6.7, 2.7.2)\n\n* Use ``select.poll`` instead of ``select.select`` for platforms that support\n it.\n\n* Use ``Queue.LifoQueue`` instead of ``Queue.Queue`` for more aggressive\n connection reusing. Configurable by overriding ``ConnectionPool.QueueCls``.\n\n* Fixed ``ImportError`` during install when ``ssl`` module is not available.\n (Issue #41)\n\n* Fixed ``PoolManager`` redirects between schemes (such as HTTP -> HTTPS) not\n completing properly. (Issue #28, uncovered by Issue #10 in v1.1)\n\n* Ported ``dummyserver`` to use ``tornado`` instead of ``webob`` +\n ``eventlet``. Removed extraneous unsupported dummyserver testing backends.\n Added socket-level tests.\n\n* More tests. Achievement Unlocked: 99% Coverage.\n\n\n1.1 (2012-01-07)\n----------------\n\n* Refactored ``dummyserver`` to its own root namespace module (used for\n testing).\n\n* Added hostname verification for ``VerifiedHTTPSConnection`` by vendoring in\n Py32's ``ssl_match_hostname``. (Issue #25)\n\n* Fixed cross-host HTTP redirects when using ``PoolManager``. (Issue #10)\n\n* Fixed ``decode_content`` being ignored when set through ``urlopen``. (Issue\n #27)\n\n* Fixed timeout-related bugs. (Issues #17, #23)\n\n\n1.0.2 (2011-11-04)\n------------------\n\n* Fixed typo in ``VerifiedHTTPSConnection`` which would only present as a bug if\n you're using the object manually. (Thanks pyos)\n\n* Made RecentlyUsedContainer (and consequently PoolManager) more thread-safe by\n wrapping the access log in a mutex. (Thanks @christer)\n\n* Made RecentlyUsedContainer more dict-like (corrected ``__delitem__`` and\n ``__getitem__`` behaviour), with tests. Shouldn't affect core urllib3 code.\n\n\n1.0.1 (2011-10-10)\n------------------\n\n* Fixed a bug where the same connection would get returned into the pool twice,\n causing extraneous \"HttpConnectionPool is full\" log warnings.\n\n\n1.0 (2011-10-08)\n----------------\n\n* Added ``PoolManager`` with LRU expiration of connections (tested and\n documented).\n* Added ``ProxyManager`` (needs tests, docs, and confirmation that it works\n with HTTPS proxies).\n* Added optional partial-read support for responses when\n ``preload_content=False``. You can now make requests and just read the headers\n without loading the content.\n* Made response decoding optional (default on, same as before).\n* Added optional explicit boundary string for ``encode_multipart_formdata``.\n* Convenience request methods are now inherited from ``RequestMethods``. Old\n helpers like ``get_url`` and ``post_url`` should be abandoned in favour of\n the new ``request(method, url, ...)``.\n* Refactored code to be even more decoupled, reusable, and extendable.\n* License header added to ``.py`` files.\n* Embiggened the documentation: Lots of Sphinx-friendly docstrings in the code\n and docs in ``docs/`` and on https://urllib3.readthedocs.io/.\n* Embettered all the things!\n* Started writing this file.\n\n\n0.4.1 (2011-07-17)\n------------------\n\n* Minor bug fixes, code cleanup.\n\n\n0.4 (2011-03-01)\n----------------\n\n* Better unicode support.\n* Added ``VerifiedHTTPSConnection``.\n* Added ``NTLMConnectionPool`` in contrib.\n* Minor improvements.\n\n\n0.3.1 (2010-07-13)\n------------------\n\n* Added ``assert_host_name`` optional parameter. Now compatible with proxies.\n\n\n0.3 (2009-12-10)\n----------------\n\n* Added HTTPS support.\n* Minor bug fixes.\n* Refactored, broken backwards compatibility with 0.2.\n* API to be treated as stable from this version forward.\n\n\n0.2 (2008-11-17)\n----------------\n\n* Added unit tests.\n* Bug fixes.\n\n\n0.1 (2008-11-16)\n----------------\n\n* First release.", - "release_date": "2022-03-16T13:28:19", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Andrey Petrov", - "email": "andrey.petrov@shazow.net", - "url": null - } - ], - "keywords": [ - "urllib httplib threadsafe filepost http https ssl pooling", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Software Development :: Libraries" - ], - "homepage_url": "https://urllib3.readthedocs.io/", - "download_url": "https://files.pythonhosted.org/packages/1b/a5/4eab74853625505725cefdf168f48661b2cd04e7843ab836f3f63abf81da/urllib3-1.26.9.tar.gz", - "size": 295258, - "sha1": null, - "md5": "d4b58522821a33c5e421191b83e0dbac", - "sha256": "aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/urllib3/urllib3", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/urllib3/1.26.9/json", - "datasource_id": null, - "purl": "pkg:pypi/urllib3@1.26.9" - }, { "type": "pypi", "namespace": null, @@ -10145,70 +5905,6 @@ "datasource_id": null, "purl": "pkg:pypi/webencodings@0.5.1" }, - { - "type": "pypi", - "namespace": null, - "name": "webencodings", - "version": "0.5.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Character encoding aliases for legacy web content\npython-webencodings\n===================\n\nThis is a Python implementation of the `WHATWG Encoding standard\n`_.\n\n* Latest documentation: http://packages.python.org/webencodings/\n* Source code and issue tracker:\n https://github.com/gsnedders/python-webencodings\n* PyPI releases: http://pypi.python.org/pypi/webencodings\n* License: BSD\n* Python 2.6+ and 3.3+\n\nIn order to be compatible with legacy web content\nwhen interpreting something like ``Content-Type: text/html; charset=latin1``,\ntools need to use a particular set of aliases for encoding labels\nas well as some overriding rules.\nFor example, ``US-ASCII`` and ``iso-8859-1`` on the web are actually\naliases for ``windows-1252``, and an UTF-8 or UTF-16 BOM takes precedence\nover any other encoding declaration.\nThe Encoding standard defines all such details so that implementations do\nnot have to reverse-engineer each other.\n\nThis module has encoding labels and BOM detection,\nbut the actual implementation for encoders and decoders is Python\u2019s.", - "release_date": "2017-04-05T20:21:34", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Geoffrey Sneddon", - "email": "me@gsnedders.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "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 :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Internet :: WWW/HTTP" - ], - "homepage_url": "https://github.com/SimonSapin/python-webencodings", - "download_url": "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", - "size": 9721, - "sha1": null, - "md5": "32f6e261d52e57bf7e1c4d41546d15b8", - "sha256": "b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/webencodings/0.5.1/json", - "datasource_id": null, - "purl": "pkg:pypi/webencodings@0.5.1" - }, { "type": "pypi", "namespace": null, @@ -10276,73 +5972,6 @@ "datasource_id": null, "purl": "pkg:pypi/werkzeug@2.1.2" }, - { - "type": "pypi", - "namespace": null, - "name": "werkzeug", - "version": "2.1.2", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "The comprehensive WSGI web application library.\nWerkzeug\n========\n\n*werkzeug* German noun: \"tool\". Etymology: *werk* (\"work\"), *zeug* (\"stuff\")\n\nWerkzeug is a comprehensive `WSGI`_ web application library. It began as\na simple collection of various utilities for WSGI applications and has\nbecome one of the most advanced WSGI utility libraries.\n\nIt includes:\n\n- An interactive debugger that allows inspecting stack traces and\n source code in the browser with an interactive interpreter for any\n frame in the stack.\n- A full-featured request object with objects to interact with\n headers, query args, form data, files, and cookies.\n- A response object that can wrap other WSGI applications and handle\n streaming data.\n- A routing system for matching URLs to endpoints and generating URLs\n for endpoints, with an extensible system for capturing variables\n from URLs.\n- HTTP utilities to handle entity tags, cache control, dates, user\n agents, cookies, files, and more.\n- A threaded WSGI server for use while developing applications\n locally.\n- A test client for simulating HTTP requests during testing without\n requiring running a server.\n\nWerkzeug doesn't enforce any dependencies. It is up to the developer to\nchoose a template engine, database adapter, and even how to handle\nrequests. It can be used to build all sorts of end user applications\nsuch as blogs, wikis, or bulletin boards.\n\n`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while\nproviding more structure and patterns for defining powerful\napplications.\n\n.. _WSGI: https://wsgi.readthedocs.io/en/latest/\n.. _Flask: https://www.palletsprojects.com/p/flask/\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U Werkzeug\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n from werkzeug.wrappers import Request, Response\n\n @Request.application\n def application(request):\n return Response('Hello, World!')\n\n if __name__ == '__main__':\n from werkzeug.serving import run_simple\n run_simple('localhost', 4000, application)\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Werkzeug and other\npopular packages. In order to grow the community of contributors and\nusers, and allow the maintainers to devote more time to the projects,\n`please donate today`_.\n\n.. _please donate today: https://palletsprojects.com/donate\n\n\nLinks\n-----\n\n- Documentation: https://werkzeug.palletsprojects.com/\n- Changes: https://werkzeug.palletsprojects.com/changes/\n- PyPI Releases: https://pypi.org/project/Werkzeug/\n- Source Code: https://github.com/pallets/werkzeug/\n- Issue Tracker: https://github.com/pallets/werkzeug/issues/\n- Website: https://palletsprojects.com/p/werkzeug/\n- Twitter: https://twitter.com/PalletsTeam\n- Chat: https://discord.gg/pallets", - "release_date": "2022-04-28T17:39:37", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Internet :: WWW/HTTP :: WSGI", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware", - "Topic :: Software Development :: Libraries :: Application Frameworks" - ], - "homepage_url": "https://palletsprojects.com/p/werkzeug/", - "download_url": "https://files.pythonhosted.org/packages/10/cf/97eb1a3847c01ae53e8376bc21145555ac95279523a935963dc8ff96c50b/Werkzeug-2.1.2.tar.gz", - "size": 835169, - "sha1": null, - "md5": "5835c8738b8081c53367cbcc5db8784c", - "sha256": "1ce08e8093ed67d638d63879fd1ba3735817f7a80de3674d293f5984f25fb6e6", - "sha512": null, - "bug_tracking_url": "https://github.com/pallets/werkzeug/issues/", - "code_view_url": "https://github.com/pallets/werkzeug/", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/werkzeug/2.1.2/json", - "datasource_id": null, - "purl": "pkg:pypi/werkzeug@2.1.2" - }, { "type": "pypi", "namespace": null, @@ -10395,59 +6024,6 @@ "api_data_url": "https://pypi.org/pypi/zipp/3.6.0/json", "datasource_id": null, "purl": "pkg:pypi/zipp@3.6.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "zipp", - "version": "3.6.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Backport of pathlib-compatible object wrapper for zip files\n.. image:: https://img.shields.io/pypi/v/zipp.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/zipp.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/zipp\n\n.. image:: https://github.com/jaraco/zipp/workflows/tests/badge.svg\n :target: https://github.com/jaraco/zipp/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest\n.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2021-informational\n :target: https://blog.jaraco.com/skeleton\n\n\nA pathlib-compatible Zipfile object wrapper. Official backport of the standard library\n`Path object `_.", - "release_date": "2021-09-29T15:34:01", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Jason R. Coombs", - "email": "jaraco@jaraco.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only" - ], - "homepage_url": "https://github.com/jaraco/zipp", - "download_url": "https://files.pythonhosted.org/packages/02/bf/0d03dbdedb83afec081fefe86cae3a2447250ef1a81ac601a9a56e785401/zipp-3.6.0.tar.gz", - "size": 13047, - "sha1": null, - "md5": "8d5cf6eb3270384ae13a6440797ea564", - "sha256": "71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/zipp/3.6.0/json", - "datasource_id": null, - "purl": "pkg:pypi/zipp@3.6.0" } ], "resolution": [ @@ -10830,4 +6406,4 @@ "dependencies": [] } ] -} \ No newline at end of file +} From bf95262a7be1496b03f898047ca08fbc1432f158 Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Thu, 30 Nov 2023 20:27:33 +0100 Subject: [PATCH 11/15] Further unit test fixes. --- ...marker-test-requirements.txt-expected.json | 275 ------------------ .../insecure-setup/setup.py-expected.json | 186 ------------ tests/data/pdt-requirements.txt-expected.json | 275 ------------------ tests/data/setup/spdx-setup.py-expected.json | 235 --------------- tests/data/single-url-expected.json | 53 ---- tests/data/tilde_req-expected.json | 53 ---- 6 files changed, 1077 deletions(-) diff --git a/tests/data/environment-marker-test-requirements.txt-expected.json b/tests/data/environment-marker-test-requirements.txt-expected.json index 1aaae2f..3ac044c 100644 --- a/tests/data/environment-marker-test-requirements.txt-expected.json +++ b/tests/data/environment-marker-test-requirements.txt-expected.json @@ -257,57 +257,6 @@ "datasource_id": null, "purl": "pkg:pypi/click@6.7" }, - { - "type": "pypi", - "namespace": null, - "name": "click", - "version": "6.7", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A simple wrapper around optparse for powerful command line utilities.", - "release_date": "2017-01-06T22:41:13", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - } - ], - "keywords": [ - "Programming Language :: Python", - "Programming Language :: Python :: 3" - ], - "homepage_url": "http://github.com/mitsuhiko/click", - "download_url": "https://files.pythonhosted.org/packages/95/d9/c3336b6b5711c3ab9d1d3a80f1a3e2afeb9d8c02a7166462f6cc96570897/click-6.7.tar.gz", - "size": 279019, - "sha1": null, - "md5": "fc4cc00c4863833230d3af92af48abd4", - "sha256": "f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/click/6.7/json", - "datasource_id": null, - "purl": "pkg:pypi/click@6.7" - }, { "type": "pypi", "namespace": null, @@ -381,79 +330,6 @@ "datasource_id": null, "purl": "pkg:pypi/flask@1.0" }, - { - "type": "pypi", - "namespace": null, - "name": "flask", - "version": "1.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A simple framework for building complex web applications.\nFlask\n=====\n\nFlask is a lightweight `WSGI`_ web application framework. It is designed\nto make getting started quick and easy, with the ability to scale up to\ncomplex applications. It began as a simple wrapper around `Werkzeug`_\nand `Jinja`_ and has become one of the most popular Python web\napplication frameworks.\n\nFlask offers suggestions, but doesn't enforce any dependencies or\nproject layout. It is up to the developer to choose the tools and\nlibraries they want to use. There are many extensions provided by the\ncommunity that make adding new functionality easy.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U Flask\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n from flask import Flask\n\n app = Flask(__name__)\n\n @app.route('/')\n def hello():\n return 'Hello, World!'\n\n.. code-block:: text\n\n $ FLASK_APP=hello.py flask run\n * Serving Flask app \"hello\"\n * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Flask and the libraries\nit uses. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://psfmember.org/civicrm/contribute/transact?reset=1&id=20\n\n\nLinks\n-----\n\n* Website: https://www.palletsprojects.com/p/flask/\n* Documentation: http://flask.pocoo.org/docs/\n* License: `BSD `_\n* Releases: https://pypi.org/project/Flask/\n* Code: https://github.com/pallets/flask\n* Issue tracker: https://github.com/pallets/flask/issues\n* Test status:\n\n * Linux, Mac: https://travis-ci.org/pallets/flask\n * Windows: https://ci.appveyor.com/project/pallets/flask\n\n* Test coverage: https://codecov.io/gh/pallets/flask\n\n.. _WSGI: https://wsgi.readthedocs.io\n.. _Werkzeug: https://www.palletsprojects.com/p/werkzeug/\n.. _Jinja: https://www.palletsprojects.com/p/jinja/\n.. _pip: https://pip.pypa.io/en/stable/quickstart/", - "release_date": "2018-04-26T20:12:54", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets team", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Framework :: Flask", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - "Topic :: Software Development :: Libraries :: Application Frameworks", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "https://www.palletsprojects.com/p/flask/", - "download_url": "https://files.pythonhosted.org/packages/99/ab/eedb921f26adf7057ade1291f9c1bfa35a506d64894f58546457ef658772/Flask-1.0.tar.gz", - "size": 643442, - "sha1": null, - "md5": "7140df3116386c7af0f389800a91817b", - "sha256": "7fab1062d11dd0038434e790d18c5b9133fd9e6b7257d707c4578ccc1e38b67c", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/pallets/flask", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/flask/1.0/json", - "datasource_id": null, - "purl": "pkg:pypi/flask@1.0" - }, { "type": "pypi", "namespace": null, @@ -579,80 +455,6 @@ "datasource_id": null, "purl": "pkg:pypi/jinja2@2.11.3" }, - { - "type": "pypi", - "namespace": null, - "name": "jinja2", - "version": "2.11.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A very fast and expressive template engine.\nJinja\n=====\n\nJinja is a fast, expressive, extensible templating engine. Special\nplaceholders in the template allow writing code similar to Python\nsyntax. Then the template is passed data to render the final document.\n\nIt includes:\n\n- Template inheritance and inclusion.\n- Define and import macros within templates.\n- HTML templates can use autoescaping to prevent XSS from untrusted\n user input.\n- A sandboxed environment can safely render untrusted templates.\n- AsyncIO support for generating templates and calling async\n functions.\n- I18N support with Babel.\n- Templates are compiled to optimized Python code just-in-time and\n cached, or can be compiled ahead-of-time.\n- Exceptions point to the correct line in templates to make debugging\n easier.\n- Extensible filters, tests, functions, and even syntax.\n\nJinja's philosophy is that while application logic belongs in Python if\npossible, it shouldn't make the template designer's job difficult by\nrestricting functionality too much.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U Jinja2\n\n.. _pip: https://pip.pypa.io/en/stable/quickstart/\n\n\nIn A Nutshell\n-------------\n\n.. code-block:: jinja\n\n {% extends \"base.html\" %}\n {% block title %}Members{% endblock %}\n {% block content %}\n \n {% endblock %}\n\n\nLinks\n-----\n\n- Website: https://palletsprojects.com/p/jinja/\n- Documentation: https://jinja.palletsprojects.com/\n- Releases: https://pypi.org/project/Jinja2/\n- Code: https://github.com/pallets/jinja\n- Issue tracker: https://github.com/pallets/jinja/issues\n- Test status: https://dev.azure.com/pallets/jinja/_build\n- Official chat: https://discord.gg/t6rrQZH", - "release_date": "2021-01-31T16:33:09", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "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", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Text Processing :: Markup :: HTML" - ], - "homepage_url": "https://palletsprojects.com/p/jinja/", - "download_url": "https://files.pythonhosted.org/packages/4f/e7/65300e6b32e69768ded990494809106f87da1d436418d5f1367ed3966fd7/Jinja2-2.11.3.tar.gz", - "size": 257589, - "sha1": null, - "md5": "231dc00d34afb2672c497713fa9cdaaa", - "sha256": "a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/pallets/jinja", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/jinja2/2.11.3/json", - "datasource_id": null, - "purl": "pkg:pypi/jinja2@2.11.3" - }, { "type": "pypi", "namespace": null, @@ -788,83 +590,6 @@ "api_data_url": "https://pypi.org/pypi/werkzeug/0.15.3/json", "datasource_id": null, "purl": "pkg:pypi/werkzeug@0.15.3" - }, - { - "type": "pypi", - "namespace": null, - "name": "werkzeug", - "version": "0.15.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "The comprehensive WSGI web application library.\nWerkzeug\n========\n\n*werkzeug* German noun: \"tool\". Etymology: *werk* (\"work\"), *zeug* (\"stuff\")\n\nWerkzeug is a comprehensive `WSGI`_ web application library. It began as\na simple collection of various utilities for WSGI applications and has\nbecome one of the most advanced WSGI utility libraries.\n\nIt includes:\n\n- An interactive debugger that allows inspecting stack traces and\n source code in the browser with an interactive interpreter for any\n frame in the stack.\n- A full-featured request object with objects to interact with\n headers, query args, form data, files, and cookies.\n- A response object that can wrap other WSGI applications and handle\n streaming data.\n- A routing system for matching URLs to endpoints and generating URLs\n for endpoints, with an extensible system for capturing variables\n from URLs.\n- HTTP utilities to handle entity tags, cache control, dates, user\n agents, cookies, files, and more.\n- A threaded WSGI server for use while developing applications\n locally.\n- A test client for simulating HTTP requests during testing without\n requiring running a server.\n\nWerkzeug is Unicode aware and doesn't enforce any dependencies. It is up\nto the developer to choose a template engine, database adapter, and even\nhow to handle requests. It can be used to build all sorts of end user\napplications such as blogs, wikis, or bulletin boards.\n\n`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while\nproviding more structure and patterns for defining powerful\napplications.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U Werkzeug\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n from werkzeug.wrappers import Request, Response\n\n @Request.application\n def application(request):\n return Response('Hello, World!')\n\n if __name__ == '__main__':\n from werkzeug.serving import run_simple\n run_simple('localhost', 4000, application)\n\n\nLinks\n-----\n\n- Website: https://www.palletsprojects.com/p/werkzeug/\n- Documentation: https://werkzeug.palletsprojects.com/\n- Releases: https://pypi.org/project/Werkzeug/\n- Code: https://github.com/pallets/werkzeug\n- Issue tracker: https://github.com/pallets/werkzeug/issues\n- Test status:\n\n - Linux, Mac: https://travis-ci.org/pallets/werkzeug\n - Windows: https://ci.appveyor.com/project/pallets/werkzeug\n\n- Test coverage: https://codecov.io/gh/pallets/werkzeug\n- Official chat: https://discord.gg/t6rrQZH\n\n.. _WSGI: https://wsgi.readthedocs.io/en/latest/\n.. _Flask: https://www.palletsprojects.com/p/flask/\n.. _pip: https://pip.pypa.io/en/stable/quickstart/", - "release_date": "2019-05-14T21:10:49", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "The Pallets Team", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "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 :: 3.7", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Internet :: WWW/HTTP :: WSGI", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware", - "Topic :: Software Development :: Libraries :: Application Frameworks", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "https://palletsprojects.com/p/werkzeug/", - "download_url": "https://files.pythonhosted.org/packages/9c/6d/854f2aa124dcfeb901815492b7fa7f026d114a18784c1c679fbdea36c809/Werkzeug-0.15.3.tar.gz", - "size": 925615, - "sha1": null, - "md5": "2da857b57e7e4c5b6403369a9d1c15a9", - "sha256": "cfd1281b1748288e59762c0e174d64d8bcb2b70e7c57bc4a1203c8825af24ac3", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/pallets/werkzeug", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/werkzeug/0.15.3/json", - "datasource_id": null, - "purl": "pkg:pypi/werkzeug@0.15.3" } ], "resolved_dependencies_graph": [ diff --git a/tests/data/insecure-setup/setup.py-expected.json b/tests/data/insecure-setup/setup.py-expected.json index dbff6d7..852ef2b 100644 --- a/tests/data/insecure-setup/setup.py-expected.json +++ b/tests/data/insecure-setup/setup.py-expected.json @@ -187,71 +187,6 @@ "datasource_id": null, "purl": "pkg:pypi/isodate@0.6.1" }, - { - "type": "pypi", - "namespace": null, - "name": "isodate", - "version": "0.6.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "An ISO 8601 date/time/duration parser and formatter\nISO 8601 date/time parser\n=========================\n\n.. image:: https://travis-ci.org/gweis/isodate.svg?branch=master\n :target: https://travis-ci.org/gweis/isodate\n :alt: Travis-CI\n.. image:: https://coveralls.io/repos/gweis/isodate/badge.svg?branch=master\n :target: https://coveralls.io/r/gweis/isodate?branch=master\n :alt: Coveralls\n.. image:: https://img.shields.io/pypi/v/isodate.svg\n :target: https://pypi.python.org/pypi/isodate/ \n :alt: Latest Version\n.. image:: https://img.shields.io/pypi/l/isodate.svg\n :target: https://pypi.python.org/pypi/isodate/ \n :alt: License\n\n\nThis module implements ISO 8601 date, time and duration parsing.\nThe implementation follows ISO8601:2004 standard, and implements only\ndate/time representations mentioned in the standard. If something is not\nmentioned there, then it is treated as non existent, and not as an allowed\noption.\n\nFor instance, ISO8601:2004 never mentions 2 digit years. So, it is not\nintended by this module to support 2 digit years. (while it may still\nbe valid as ISO date, because it is not explicitly forbidden.)\nAnother example is, when no time zone information is given for a time,\nthen it should be interpreted as local time, and not UTC.\n\nAs this module maps ISO 8601 dates/times to standard Python data types, like\n*date*, *time*, *datetime* and *timedelta*, it is not possible to convert\nall possible ISO 8601 dates/times. For instance, dates before 0001-01-01 are\nnot allowed by the Python *date* and *datetime* classes. Additionally\nfractional seconds are limited to microseconds. That means if the parser finds\nfor instance nanoseconds it will round it to microseconds.\n\nDocumentation\n-------------\n\nCurrently there are four parsing methods available.\n * parse_time:\n parses an ISO 8601 time string into a *time* object\n * parse_date:\n parses an ISO 8601 date string into a *date* object\n * parse_datetime:\n parses an ISO 8601 date-time string into a *datetime* object\n * parse_duration:\n parses an ISO 8601 duration string into a *timedelta* or *Duration*\n object.\n * parse_tzinfo:\n parses the time zone info part of an ISO 8601 string into a\n *tzinfo* object.\n\nAs ISO 8601 allows to define durations in years and months, and *timedelta*\ndoes not handle years and months, this module provides a *Duration* class,\nwhich can be used almost like a *timedelta* object (with some limitations).\nHowever, a *Duration* object can be converted into a *timedelta* object.\n\nThere are also ISO formatting methods for all supported data types. Each\n*xxx_isoformat* method accepts a format parameter. The default format is\nalways the ISO 8601 expanded format. This is the same format used by\n*datetime.isoformat*:\n\n * time_isoformat:\n Intended to create ISO time strings with default format\n *hh:mm:ssZ*.\n * date_isoformat:\n Intended to create ISO date strings with default format\n *yyyy-mm-dd*.\n * datetime_isoformat:\n Intended to create ISO date-time strings with default format\n *yyyy-mm-ddThh:mm:ssZ*.\n * duration_isoformat:\n Intended to create ISO duration strings with default format\n *PnnYnnMnnDTnnHnnMnnS*.\n * tz_isoformat:\n Intended to create ISO time zone strings with default format\n *hh:mm*.\n * strftime:\n A re-implementation mostly compatible with Python's *strftime*, but\n supports only those format strings, which can also be used for dates\n prior 1900. This method also understands how to format *datetime* and\n *Duration* instances.\n\nInstallation:\n-------------\n\nThis module can easily be installed with Python standard installation methods.\n\nEither use *python setup.py install* or in case you have *setuptools* or\n*distribute* available, you can also use *easy_install*.\n\nLimitations:\n------------\n\n * The parser accepts several date/time representation which should be invalid\n according to ISO 8601 standard.\n\n 1. for date and time together, this parser accepts a mixture of basic and extended format.\n e.g. the date could be in basic format, while the time is accepted in extended format.\n It also allows short dates and times in date-time strings.\n 2. For incomplete dates, the first day is chosen. e.g. 19th century results in a date of\n 1901-01-01.\n 3. negative *Duration* and *timedelta* value are not fully supported yet.\n\nFurther information:\n--------------------\n\nThe doc strings and unit tests should provide rather detailed information about\nthe methods and their limitations.\n\nThe source release provides a *setup.py* script,\nwhich can be used to run the unit tests included.\n\nSource code is available at ``_.\n\nCHANGES\n=======\n\n0.6.1 (2021-12-13)\n------------------\n\n- support python 3.10 ()\n- last version to support py 2.7\n\n\n0.6.0 (2017-10-13)\n------------------\n\n- support incomplete month date (Fabien Loffredo)\n- rely on duck typing when doing duration maths\n- support ':' as separator in fractional time zones (usrenmae)\n\n\n0.5.4 (2015-08-06)\n------------------\n\n- Fix parsing of Periods (Fabien Bochu)\n- Make Duration objects hashable (Geoffrey Fairchild)\n- Add multiplication to duration (Reinoud Elhorst)\n\n\n0.5.1 (2014-11-07)\n------------------\n\n- fixed pickling of Duration objects\n- raise ISO8601Error when there is no 'T' separator in datetime strings (Adrian Coveney)\n\n\n0.5.0 (2014-02-23)\n------------------\n\n- ISO8601Error are subclasses of ValueError now (Michael Hrivnak)\n- improve compatibility across various python variants and versions\n- raise exceptions when using fractional years and months in date\n maths with durations\n- renamed method todatetime on Duraction objects to totimedelta\n\n\n0.4.9 (2012-10-30)\n------------------\n\n- support pickling FixedOffset instances\n- make sure parsed fractional seconds are in microseconds\n- add leading zeros when formattig microseconds (Jarom Loveridge)\n\n\n0.4.8 (2012-05-04)\n------------------\n\n- fixed incompatibility of unittests with python 2.5 and 2.6 (runs fine on 2.7\n and 3.2)\n\n\n0.4.7 (2012-01-26)\n------------------\n\n- fixed tzinfo formatting (never pass None into tzinfo.utcoffset())\n\n\n0.4.6 (2012-01-06)\n------------------\n\n- added Python 3 compatibility via 2to3\n\n0.4.5 (2012-01-06)\n------------------\n\n- made setuptools dependency optional\n\n0.4.4 (2011-04-16)\n------------------\n\n- Fixed formatting of microseconds for datetime objects\n\n0.4.3 (2010-10-29)\n------------------\n\n- Fixed problem with %P formating and fractions (supplied by David Brooks)\n\n0.4.2 (2010-10-28)\n------------------\n\n- Implemented unary - for Duration (supplied by David Brooks)\n- Output fractional seconds with '%P' format. (partly supplied by David Brooks)\n\n0.4.1 (2010-10-13)\n------------------\n\n- fixed bug in comparison between timedelta and Duration.\n- fixed precision problem with microseconds (reported by Tommi Virtanen)\n\n0.4.0 (2009-02-09)\n------------------\n\n- added method to parse ISO 8601 time zone strings\n- added methods to create ISO 8601 conforming strings\n\n0.3.0 (2009-1-05)\n------------------\n\n- Initial release\n\nTODOs\n=====\n\nThis to do list contains some thoughts and ideas about missing features, and\nparts to think about, whether to implement them or not. This list is probably\nnot complete.\n\nMissing features:\n-----------------\n\n * time formating does not allow to create fractional representations.\n * parser for ISO intervals.\n * currently microseconds are always padded to a length of 6 characters.\n trailing 0s should be optional\n\nDocumentation:\n--------------\n\n * parse_datetime:\n - complete documentation to show what this function allows, but ISO forbids.\n and vice verse.\n - support other separators between date and time than 'T'\n\n * parse_date:\n - yeardigits should be always greater than 4\n - dates before 0001-01-01 are not supported\n\n * parse_duration:\n - alternative formats are not fully supported due to parse_date restrictions\n - standard duration format is fully supported but not very restrictive.\n\n * Duration:\n - support fractional years and month in calculations\n - implement w3c order relation? (``_)\n - refactor to have duration mathematics only at one place.\n - localize __str__ method (does timedelta do this?)\n - when is a Duration negative?\n - normalize Durations. months [00-12] and years ]-inf,+inf[", - "release_date": "2021-12-13T20:28:31", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Gerhard Weis", - "email": "gerhard.weis@proclos.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Internet", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "https://github.com/gweis/isodate/", - "download_url": "https://files.pythonhosted.org/packages/db/7a/c0a56c7d56c7fa723988f122fa1f1ccf8c5c4ccc48efad0d214b49e5b1af/isodate-0.6.1.tar.gz", - "size": 28443, - "sha1": null, - "md5": "1a310658b30a48641bafb5652ad91c40", - "sha256": "48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/isodate/0.6.1/json", - "datasource_id": null, - "purl": "pkg:pypi/isodate@0.6.1" - }, { "type": "pypi", "namespace": null, @@ -317,71 +252,6 @@ "datasource_id": null, "purl": "pkg:pypi/pyparsing@2.4.7" }, - { - "type": "pypi", - "namespace": null, - "name": "pyparsing", - "version": "2.4.7", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Python parsing module\nPyParsing -- A Python Parsing Module\n====================================\n\n|Build Status|\n\nIntroduction\n============\n\nThe pyparsing module is an alternative approach to creating and\nexecuting simple grammars, vs. the traditional lex/yacc approach, or the\nuse of regular expressions. The pyparsing module provides a library of\nclasses that client code uses to construct the grammar directly in\nPython code.\n\n*[Since first writing this description of pyparsing in late 2003, this\ntechnique for developing parsers has become more widespread, under the\nname Parsing Expression Grammars - PEGs. See more information on PEGs at*\nhttps://en.wikipedia.org/wiki/Parsing_expression_grammar *.]*\n\nHere is a program to parse ``\"Hello, World!\"`` (or any greeting of the form\n``\"salutation, addressee!\"``):\n\n.. code:: python\n\n from pyparsing import Word, alphas\n greet = Word(alphas) + \",\" + Word(alphas) + \"!\"\n hello = \"Hello, World!\"\n print(hello, \"->\", greet.parseString(hello))\n\nThe program outputs the following::\n\n Hello, World! -> ['Hello', ',', 'World', '!']\n\nThe Python representation of the grammar is quite readable, owing to the\nself-explanatory class names, and the use of '+', '|' and '^' operator\ndefinitions.\n\nThe parsed results returned from ``parseString()`` can be accessed as a\nnested list, a dictionary, or an object with named attributes.\n\nThe pyparsing module handles some of the problems that are typically\nvexing when writing text parsers:\n\n- extra or missing whitespace (the above program will also handle ``\"Hello,World!\"``, ``\"Hello , World !\"``, etc.)\n- quoted strings\n- embedded comments\n\nThe examples directory includes a simple SQL parser, simple CORBA IDL\nparser, a config file parser, a chemical formula parser, and a four-\nfunction algebraic notation parser, among many others.\n\nDocumentation\n=============\n\nThere are many examples in the online docstrings of the classes\nand methods in pyparsing. You can find them compiled into online docs\nat https://pyparsing-docs.readthedocs.io/en/latest/. Additional\ndocumentation resources and project info are listed in the online\nGitHub wiki, at https://github.com/pyparsing/pyparsing/wiki. An\nentire directory of examples is at\nhttps://github.com/pyparsing/pyparsing/tree/master/examples.\n\nLicense\n=======\n\nMIT License. See header of pyparsing.py\n\nHistory\n=======\n\nSee CHANGES file.\n\n.. |Build Status| image:: https://travis-ci.org/pyparsing/pyparsing.svg?branch=master\n :target: https://travis-ci.org/pyparsing/pyparsing", - "release_date": "2020-04-05T22:21:25", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Paul McGuire", - "email": "ptmcg@users.sourceforge.net", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Intended Audience :: Information Technology", - "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" - ], - "homepage_url": "https://github.com/pyparsing/pyparsing/", - "download_url": "https://files.pythonhosted.org/packages/c1/47/dfc9c342c9842bbe0036c7f763d2d6686bcf5eb1808ba3e170afdb282210/pyparsing-2.4.7.tar.gz", - "size": 649718, - "sha1": null, - "md5": "f0953e47a0112f7a65aec2305ffdf7b4", - "sha256": "c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT License", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pyparsing/2.4.7/json", - "datasource_id": null, - "purl": "pkg:pypi/pyparsing@2.4.7" - }, { "type": "pypi", "namespace": null, @@ -437,62 +307,6 @@ "api_data_url": "https://pypi.org/pypi/six/1.16.0/json", "datasource_id": null, "purl": "pkg:pypi/six@1.16.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "six", - "version": "1.16.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Python 2 and 3 compatibility utilities\n.. image:: https://img.shields.io/pypi/v/six.svg\n :target: https://pypi.org/project/six/\n :alt: six on PyPI\n\n.. image:: https://travis-ci.org/benjaminp/six.svg?branch=master\n :target: https://travis-ci.org/benjaminp/six\n :alt: six on TravisCI\n\n.. image:: https://readthedocs.org/projects/six/badge/?version=latest\n :target: https://six.readthedocs.io/\n :alt: six's documentation on Read the Docs\n\n.. image:: https://img.shields.io/badge/license-MIT-green.svg\n :target: https://github.com/benjaminp/six/blob/master/LICENSE\n :alt: MIT License badge\n\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 Python 2.7 and 3.3+. 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://six.readthedocs.io/.\n\nBugs can be reported to https://github.com/benjaminp/six. The code can also\nbe found there.", - "release_date": "2021-05-05T14:18:18", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Benjamin Peterson", - "email": "benjamin@python.org", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/benjaminp/six", - "download_url": "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", - "size": 34041, - "sha1": null, - "md5": "a7c927740e4964dd29b72cebfc1429bb", - "sha256": "1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/six/1.16.0/json", - "datasource_id": null, - "purl": "pkg:pypi/six@1.16.0" } ], "resolved_dependencies_graph": [ diff --git a/tests/data/pdt-requirements.txt-expected.json b/tests/data/pdt-requirements.txt-expected.json index 9d870c8..e0a0bcf 100644 --- a/tests/data/pdt-requirements.txt-expected.json +++ b/tests/data/pdt-requirements.txt-expected.json @@ -236,57 +236,6 @@ "datasource_id": null, "purl": "pkg:pypi/click@6.7" }, - { - "type": "pypi", - "namespace": null, - "name": "click", - "version": "6.7", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A simple wrapper around optparse for powerful command line utilities.", - "release_date": "2017-01-06T22:41:13", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - } - ], - "keywords": [ - "Programming Language :: Python", - "Programming Language :: Python :: 3" - ], - "homepage_url": "http://github.com/mitsuhiko/click", - "download_url": "https://files.pythonhosted.org/packages/95/d9/c3336b6b5711c3ab9d1d3a80f1a3e2afeb9d8c02a7166462f6cc96570897/click-6.7.tar.gz", - "size": 279019, - "sha1": null, - "md5": "fc4cc00c4863833230d3af92af48abd4", - "sha256": "f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/click/6.7/json", - "datasource_id": null, - "purl": "pkg:pypi/click@6.7" - }, { "type": "pypi", "namespace": null, @@ -360,79 +309,6 @@ "datasource_id": null, "purl": "pkg:pypi/flask@1.0" }, - { - "type": "pypi", - "namespace": null, - "name": "flask", - "version": "1.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A simple framework for building complex web applications.\nFlask\n=====\n\nFlask is a lightweight `WSGI`_ web application framework. It is designed\nto make getting started quick and easy, with the ability to scale up to\ncomplex applications. It began as a simple wrapper around `Werkzeug`_\nand `Jinja`_ and has become one of the most popular Python web\napplication frameworks.\n\nFlask offers suggestions, but doesn't enforce any dependencies or\nproject layout. It is up to the developer to choose the tools and\nlibraries they want to use. There are many extensions provided by the\ncommunity that make adding new functionality easy.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U Flask\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n from flask import Flask\n\n app = Flask(__name__)\n\n @app.route('/')\n def hello():\n return 'Hello, World!'\n\n.. code-block:: text\n\n $ FLASK_APP=hello.py flask run\n * Serving Flask app \"hello\"\n * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)\n\n\nDonate\n------\n\nThe Pallets organization develops and supports Flask and the libraries\nit uses. In order to grow the community of contributors and users, and\nallow the maintainers to devote more time to the projects, `please\ndonate today`_.\n\n.. _please donate today: https://psfmember.org/civicrm/contribute/transact?reset=1&id=20\n\n\nLinks\n-----\n\n* Website: https://www.palletsprojects.com/p/flask/\n* Documentation: http://flask.pocoo.org/docs/\n* License: `BSD `_\n* Releases: https://pypi.org/project/Flask/\n* Code: https://github.com/pallets/flask\n* Issue tracker: https://github.com/pallets/flask/issues\n* Test status:\n\n * Linux, Mac: https://travis-ci.org/pallets/flask\n * Windows: https://ci.appveyor.com/project/pallets/flask\n\n* Test coverage: https://codecov.io/gh/pallets/flask\n\n.. _WSGI: https://wsgi.readthedocs.io\n.. _Werkzeug: https://www.palletsprojects.com/p/werkzeug/\n.. _Jinja: https://www.palletsprojects.com/p/jinja/\n.. _pip: https://pip.pypa.io/en/stable/quickstart/", - "release_date": "2018-04-26T20:12:54", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets team", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Framework :: Flask", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - "Topic :: Software Development :: Libraries :: Application Frameworks", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "https://www.palletsprojects.com/p/flask/", - "download_url": "https://files.pythonhosted.org/packages/99/ab/eedb921f26adf7057ade1291f9c1bfa35a506d64894f58546457ef658772/Flask-1.0.tar.gz", - "size": 643442, - "sha1": null, - "md5": "7140df3116386c7af0f389800a91817b", - "sha256": "7fab1062d11dd0038434e790d18c5b9133fd9e6b7257d707c4578ccc1e38b67c", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/pallets/flask", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/flask/1.0/json", - "datasource_id": null, - "purl": "pkg:pypi/flask@1.0" - }, { "type": "pypi", "namespace": null, @@ -558,80 +434,6 @@ "datasource_id": null, "purl": "pkg:pypi/jinja2@2.11.3" }, - { - "type": "pypi", - "namespace": null, - "name": "jinja2", - "version": "2.11.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "A very fast and expressive template engine.\nJinja\n=====\n\nJinja is a fast, expressive, extensible templating engine. Special\nplaceholders in the template allow writing code similar to Python\nsyntax. Then the template is passed data to render the final document.\n\nIt includes:\n\n- Template inheritance and inclusion.\n- Define and import macros within templates.\n- HTML templates can use autoescaping to prevent XSS from untrusted\n user input.\n- A sandboxed environment can safely render untrusted templates.\n- AsyncIO support for generating templates and calling async\n functions.\n- I18N support with Babel.\n- Templates are compiled to optimized Python code just-in-time and\n cached, or can be compiled ahead-of-time.\n- Exceptions point to the correct line in templates to make debugging\n easier.\n- Extensible filters, tests, functions, and even syntax.\n\nJinja's philosophy is that while application logic belongs in Python if\npossible, it shouldn't make the template designer's job difficult by\nrestricting functionality too much.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n $ pip install -U Jinja2\n\n.. _pip: https://pip.pypa.io/en/stable/quickstart/\n\n\nIn A Nutshell\n-------------\n\n.. code-block:: jinja\n\n {% extends \"base.html\" %}\n {% block title %}Members{% endblock %}\n {% block content %}\n \n {% endblock %}\n\n\nLinks\n-----\n\n- Website: https://palletsprojects.com/p/jinja/\n- Documentation: https://jinja.palletsprojects.com/\n- Releases: https://pypi.org/project/Jinja2/\n- Code: https://github.com/pallets/jinja\n- Issue tracker: https://github.com/pallets/jinja/issues\n- Test status: https://dev.azure.com/pallets/jinja/_build\n- Official chat: https://discord.gg/t6rrQZH", - "release_date": "2021-01-31T16:33:09", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Pallets", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "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", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Text Processing :: Markup :: HTML" - ], - "homepage_url": "https://palletsprojects.com/p/jinja/", - "download_url": "https://files.pythonhosted.org/packages/4f/e7/65300e6b32e69768ded990494809106f87da1d436418d5f1367ed3966fd7/Jinja2-2.11.3.tar.gz", - "size": 257589, - "sha1": null, - "md5": "231dc00d34afb2672c497713fa9cdaaa", - "sha256": "a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/pallets/jinja", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/jinja2/2.11.3/json", - "datasource_id": null, - "purl": "pkg:pypi/jinja2@2.11.3" - }, { "type": "pypi", "namespace": null, @@ -767,83 +569,6 @@ "api_data_url": "https://pypi.org/pypi/werkzeug/0.15.3/json", "datasource_id": null, "purl": "pkg:pypi/werkzeug@0.15.3" - }, - { - "type": "pypi", - "namespace": null, - "name": "werkzeug", - "version": "0.15.3", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "The comprehensive WSGI web application library.\nWerkzeug\n========\n\n*werkzeug* German noun: \"tool\". Etymology: *werk* (\"work\"), *zeug* (\"stuff\")\n\nWerkzeug is a comprehensive `WSGI`_ web application library. It began as\na simple collection of various utilities for WSGI applications and has\nbecome one of the most advanced WSGI utility libraries.\n\nIt includes:\n\n- An interactive debugger that allows inspecting stack traces and\n source code in the browser with an interactive interpreter for any\n frame in the stack.\n- A full-featured request object with objects to interact with\n headers, query args, form data, files, and cookies.\n- A response object that can wrap other WSGI applications and handle\n streaming data.\n- A routing system for matching URLs to endpoints and generating URLs\n for endpoints, with an extensible system for capturing variables\n from URLs.\n- HTTP utilities to handle entity tags, cache control, dates, user\n agents, cookies, files, and more.\n- A threaded WSGI server for use while developing applications\n locally.\n- A test client for simulating HTTP requests during testing without\n requiring running a server.\n\nWerkzeug is Unicode aware and doesn't enforce any dependencies. It is up\nto the developer to choose a template engine, database adapter, and even\nhow to handle requests. It can be used to build all sorts of end user\napplications such as blogs, wikis, or bulletin boards.\n\n`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while\nproviding more structure and patterns for defining powerful\napplications.\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: text\n\n pip install -U Werkzeug\n\n\nA Simple Example\n----------------\n\n.. code-block:: python\n\n from werkzeug.wrappers import Request, Response\n\n @Request.application\n def application(request):\n return Response('Hello, World!')\n\n if __name__ == '__main__':\n from werkzeug.serving import run_simple\n run_simple('localhost', 4000, application)\n\n\nLinks\n-----\n\n- Website: https://www.palletsprojects.com/p/werkzeug/\n- Documentation: https://werkzeug.palletsprojects.com/\n- Releases: https://pypi.org/project/Werkzeug/\n- Code: https://github.com/pallets/werkzeug\n- Issue tracker: https://github.com/pallets/werkzeug/issues\n- Test status:\n\n - Linux, Mac: https://travis-ci.org/pallets/werkzeug\n - Windows: https://ci.appveyor.com/project/pallets/werkzeug\n\n- Test coverage: https://codecov.io/gh/pallets/werkzeug\n- Official chat: https://discord.gg/t6rrQZH\n\n.. _WSGI: https://wsgi.readthedocs.io/en/latest/\n.. _Flask: https://www.palletsprojects.com/p/flask/\n.. _pip: https://pip.pypa.io/en/stable/quickstart/", - "release_date": "2019-05-14T21:10:49", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "The Pallets Team", - "email": "contact@palletsprojects.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "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 :: 3.7", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Internet :: WWW/HTTP :: WSGI", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware", - "Topic :: Software Development :: Libraries :: Application Frameworks", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "https://palletsprojects.com/p/werkzeug/", - "download_url": "https://files.pythonhosted.org/packages/9c/6d/854f2aa124dcfeb901815492b7fa7f026d114a18784c1c679fbdea36c809/Werkzeug-0.15.3.tar.gz", - "size": 925615, - "sha1": null, - "md5": "2da857b57e7e4c5b6403369a9d1c15a9", - "sha256": "cfd1281b1748288e59762c0e174d64d8bcb2b70e7c57bc4a1203c8825af24ac3", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/pallets/werkzeug", - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD-3-Clause", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/werkzeug/0.15.3/json", - "datasource_id": null, - "purl": "pkg:pypi/werkzeug@0.15.3" } ], "resolved_dependencies_graph": [ diff --git a/tests/data/setup/spdx-setup.py-expected.json b/tests/data/setup/spdx-setup.py-expected.json index f00f689..c495d6d 100644 --- a/tests/data/setup/spdx-setup.py-expected.json +++ b/tests/data/setup/spdx-setup.py-expected.json @@ -178,71 +178,6 @@ "datasource_id": null, "purl": "pkg:pypi/isodate@0.6.1" }, - { - "type": "pypi", - "namespace": null, - "name": "isodate", - "version": "0.6.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "An ISO 8601 date/time/duration parser and formatter\nISO 8601 date/time parser\n=========================\n\n.. image:: https://travis-ci.org/gweis/isodate.svg?branch=master\n :target: https://travis-ci.org/gweis/isodate\n :alt: Travis-CI\n.. image:: https://coveralls.io/repos/gweis/isodate/badge.svg?branch=master\n :target: https://coveralls.io/r/gweis/isodate?branch=master\n :alt: Coveralls\n.. image:: https://img.shields.io/pypi/v/isodate.svg\n :target: https://pypi.python.org/pypi/isodate/ \n :alt: Latest Version\n.. image:: https://img.shields.io/pypi/l/isodate.svg\n :target: https://pypi.python.org/pypi/isodate/ \n :alt: License\n\n\nThis module implements ISO 8601 date, time and duration parsing.\nThe implementation follows ISO8601:2004 standard, and implements only\ndate/time representations mentioned in the standard. If something is not\nmentioned there, then it is treated as non existent, and not as an allowed\noption.\n\nFor instance, ISO8601:2004 never mentions 2 digit years. So, it is not\nintended by this module to support 2 digit years. (while it may still\nbe valid as ISO date, because it is not explicitly forbidden.)\nAnother example is, when no time zone information is given for a time,\nthen it should be interpreted as local time, and not UTC.\n\nAs this module maps ISO 8601 dates/times to standard Python data types, like\n*date*, *time*, *datetime* and *timedelta*, it is not possible to convert\nall possible ISO 8601 dates/times. For instance, dates before 0001-01-01 are\nnot allowed by the Python *date* and *datetime* classes. Additionally\nfractional seconds are limited to microseconds. That means if the parser finds\nfor instance nanoseconds it will round it to microseconds.\n\nDocumentation\n-------------\n\nCurrently there are four parsing methods available.\n * parse_time:\n parses an ISO 8601 time string into a *time* object\n * parse_date:\n parses an ISO 8601 date string into a *date* object\n * parse_datetime:\n parses an ISO 8601 date-time string into a *datetime* object\n * parse_duration:\n parses an ISO 8601 duration string into a *timedelta* or *Duration*\n object.\n * parse_tzinfo:\n parses the time zone info part of an ISO 8601 string into a\n *tzinfo* object.\n\nAs ISO 8601 allows to define durations in years and months, and *timedelta*\ndoes not handle years and months, this module provides a *Duration* class,\nwhich can be used almost like a *timedelta* object (with some limitations).\nHowever, a *Duration* object can be converted into a *timedelta* object.\n\nThere are also ISO formatting methods for all supported data types. Each\n*xxx_isoformat* method accepts a format parameter. The default format is\nalways the ISO 8601 expanded format. This is the same format used by\n*datetime.isoformat*:\n\n * time_isoformat:\n Intended to create ISO time strings with default format\n *hh:mm:ssZ*.\n * date_isoformat:\n Intended to create ISO date strings with default format\n *yyyy-mm-dd*.\n * datetime_isoformat:\n Intended to create ISO date-time strings with default format\n *yyyy-mm-ddThh:mm:ssZ*.\n * duration_isoformat:\n Intended to create ISO duration strings with default format\n *PnnYnnMnnDTnnHnnMnnS*.\n * tz_isoformat:\n Intended to create ISO time zone strings with default format\n *hh:mm*.\n * strftime:\n A re-implementation mostly compatible with Python's *strftime*, but\n supports only those format strings, which can also be used for dates\n prior 1900. This method also understands how to format *datetime* and\n *Duration* instances.\n\nInstallation:\n-------------\n\nThis module can easily be installed with Python standard installation methods.\n\nEither use *python setup.py install* or in case you have *setuptools* or\n*distribute* available, you can also use *easy_install*.\n\nLimitations:\n------------\n\n * The parser accepts several date/time representation which should be invalid\n according to ISO 8601 standard.\n\n 1. for date and time together, this parser accepts a mixture of basic and extended format.\n e.g. the date could be in basic format, while the time is accepted in extended format.\n It also allows short dates and times in date-time strings.\n 2. For incomplete dates, the first day is chosen. e.g. 19th century results in a date of\n 1901-01-01.\n 3. negative *Duration* and *timedelta* value are not fully supported yet.\n\nFurther information:\n--------------------\n\nThe doc strings and unit tests should provide rather detailed information about\nthe methods and their limitations.\n\nThe source release provides a *setup.py* script,\nwhich can be used to run the unit tests included.\n\nSource code is available at ``_.\n\nCHANGES\n=======\n\n0.6.1 (2021-12-13)\n------------------\n\n- support python 3.10 ()\n- last version to support py 2.7\n\n\n0.6.0 (2017-10-13)\n------------------\n\n- support incomplete month date (Fabien Loffredo)\n- rely on duck typing when doing duration maths\n- support ':' as separator in fractional time zones (usrenmae)\n\n\n0.5.4 (2015-08-06)\n------------------\n\n- Fix parsing of Periods (Fabien Bochu)\n- Make Duration objects hashable (Geoffrey Fairchild)\n- Add multiplication to duration (Reinoud Elhorst)\n\n\n0.5.1 (2014-11-07)\n------------------\n\n- fixed pickling of Duration objects\n- raise ISO8601Error when there is no 'T' separator in datetime strings (Adrian Coveney)\n\n\n0.5.0 (2014-02-23)\n------------------\n\n- ISO8601Error are subclasses of ValueError now (Michael Hrivnak)\n- improve compatibility across various python variants and versions\n- raise exceptions when using fractional years and months in date\n maths with durations\n- renamed method todatetime on Duraction objects to totimedelta\n\n\n0.4.9 (2012-10-30)\n------------------\n\n- support pickling FixedOffset instances\n- make sure parsed fractional seconds are in microseconds\n- add leading zeros when formattig microseconds (Jarom Loveridge)\n\n\n0.4.8 (2012-05-04)\n------------------\n\n- fixed incompatibility of unittests with python 2.5 and 2.6 (runs fine on 2.7\n and 3.2)\n\n\n0.4.7 (2012-01-26)\n------------------\n\n- fixed tzinfo formatting (never pass None into tzinfo.utcoffset())\n\n\n0.4.6 (2012-01-06)\n------------------\n\n- added Python 3 compatibility via 2to3\n\n0.4.5 (2012-01-06)\n------------------\n\n- made setuptools dependency optional\n\n0.4.4 (2011-04-16)\n------------------\n\n- Fixed formatting of microseconds for datetime objects\n\n0.4.3 (2010-10-29)\n------------------\n\n- Fixed problem with %P formating and fractions (supplied by David Brooks)\n\n0.4.2 (2010-10-28)\n------------------\n\n- Implemented unary - for Duration (supplied by David Brooks)\n- Output fractional seconds with '%P' format. (partly supplied by David Brooks)\n\n0.4.1 (2010-10-13)\n------------------\n\n- fixed bug in comparison between timedelta and Duration.\n- fixed precision problem with microseconds (reported by Tommi Virtanen)\n\n0.4.0 (2009-02-09)\n------------------\n\n- added method to parse ISO 8601 time zone strings\n- added methods to create ISO 8601 conforming strings\n\n0.3.0 (2009-1-05)\n------------------\n\n- Initial release\n\nTODOs\n=====\n\nThis to do list contains some thoughts and ideas about missing features, and\nparts to think about, whether to implement them or not. This list is probably\nnot complete.\n\nMissing features:\n-----------------\n\n * time formating does not allow to create fractional representations.\n * parser for ISO intervals.\n * currently microseconds are always padded to a length of 6 characters.\n trailing 0s should be optional\n\nDocumentation:\n--------------\n\n * parse_datetime:\n - complete documentation to show what this function allows, but ISO forbids.\n and vice verse.\n - support other separators between date and time than 'T'\n\n * parse_date:\n - yeardigits should be always greater than 4\n - dates before 0001-01-01 are not supported\n\n * parse_duration:\n - alternative formats are not fully supported due to parse_date restrictions\n - standard duration format is fully supported but not very restrictive.\n\n * Duration:\n - support fractional years and month in calculations\n - implement w3c order relation? (``_)\n - refactor to have duration mathematics only at one place.\n - localize __str__ method (does timedelta do this?)\n - when is a Duration negative?\n - normalize Durations. months [00-12] and years ]-inf,+inf[", - "release_date": "2021-12-13T20:28:31", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Gerhard Weis", - "email": "gerhard.weis@proclos.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Internet", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "https://github.com/gweis/isodate/", - "download_url": "https://files.pythonhosted.org/packages/db/7a/c0a56c7d56c7fa723988f122fa1f1ccf8c5c4ccc48efad0d214b49e5b1af/isodate-0.6.1.tar.gz", - "size": 28443, - "sha1": null, - "md5": "1a310658b30a48641bafb5652ad91c40", - "sha256": "48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD", - "classifiers": [ - "License :: OSI Approved :: BSD License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/isodate/0.6.1/json", - "datasource_id": null, - "purl": "pkg:pypi/isodate@0.6.1" - }, { "type": "pypi", "namespace": null, @@ -292,55 +227,6 @@ "datasource_id": null, "purl": "pkg:pypi/ply@3.11" }, - { - "type": "pypi", - "namespace": null, - "name": "ply", - "version": "3.11", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Python Lex & Yacc\nPLY is yet another implementation of lex and yacc for Python. Some notable\nfeatures include the fact that its implemented entirely in Python and it\nuses LALR(1) parsing which is efficient and well suited for larger grammars.\n\nPLY provides most of the standard lex/yacc features including support for empty \nproductions, precedence rules, error recovery, and support for ambiguous grammars. \n\nPLY is extremely easy to use and provides very extensive error checking. \nIt is compatible with both Python 2 and Python 3.", - "release_date": "2018-02-15T19:01:31", - "parties": [ - { - "type": "person", - "role": "author", - "name": "David Beazley", - "email": "dave@dabeaz.com", - "url": null - } - ], - "keywords": [ - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3" - ], - "homepage_url": "http://www.dabeaz.com/ply/", - "download_url": "https://files.pythonhosted.org/packages/e5/69/882ee5c9d017149285cab114ebeab373308ef0f874fcdac9beb90e0ac4da/ply-3.11.tar.gz", - "size": 159130, - "sha1": null, - "md5": "6465f602e656455affcd7c5734c638f8", - "sha256": "00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "BSD" - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/ply/3.11/json", - "datasource_id": null, - "purl": "pkg:pypi/ply@3.11" - }, { "type": "pypi", "namespace": null, @@ -406,71 +292,6 @@ "datasource_id": null, "purl": "pkg:pypi/pyparsing@2.4.7" }, - { - "type": "pypi", - "namespace": null, - "name": "pyparsing", - "version": "2.4.7", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Python parsing module\nPyParsing -- A Python Parsing Module\n====================================\n\n|Build Status|\n\nIntroduction\n============\n\nThe pyparsing module is an alternative approach to creating and\nexecuting simple grammars, vs. the traditional lex/yacc approach, or the\nuse of regular expressions. The pyparsing module provides a library of\nclasses that client code uses to construct the grammar directly in\nPython code.\n\n*[Since first writing this description of pyparsing in late 2003, this\ntechnique for developing parsers has become more widespread, under the\nname Parsing Expression Grammars - PEGs. See more information on PEGs at*\nhttps://en.wikipedia.org/wiki/Parsing_expression_grammar *.]*\n\nHere is a program to parse ``\"Hello, World!\"`` (or any greeting of the form\n``\"salutation, addressee!\"``):\n\n.. code:: python\n\n from pyparsing import Word, alphas\n greet = Word(alphas) + \",\" + Word(alphas) + \"!\"\n hello = \"Hello, World!\"\n print(hello, \"->\", greet.parseString(hello))\n\nThe program outputs the following::\n\n Hello, World! -> ['Hello', ',', 'World', '!']\n\nThe Python representation of the grammar is quite readable, owing to the\nself-explanatory class names, and the use of '+', '|' and '^' operator\ndefinitions.\n\nThe parsed results returned from ``parseString()`` can be accessed as a\nnested list, a dictionary, or an object with named attributes.\n\nThe pyparsing module handles some of the problems that are typically\nvexing when writing text parsers:\n\n- extra or missing whitespace (the above program will also handle ``\"Hello,World!\"``, ``\"Hello , World !\"``, etc.)\n- quoted strings\n- embedded comments\n\nThe examples directory includes a simple SQL parser, simple CORBA IDL\nparser, a config file parser, a chemical formula parser, and a four-\nfunction algebraic notation parser, among many others.\n\nDocumentation\n=============\n\nThere are many examples in the online docstrings of the classes\nand methods in pyparsing. You can find them compiled into online docs\nat https://pyparsing-docs.readthedocs.io/en/latest/. Additional\ndocumentation resources and project info are listed in the online\nGitHub wiki, at https://github.com/pyparsing/pyparsing/wiki. An\nentire directory of examples is at\nhttps://github.com/pyparsing/pyparsing/tree/master/examples.\n\nLicense\n=======\n\nMIT License. See header of pyparsing.py\n\nHistory\n=======\n\nSee CHANGES file.\n\n.. |Build Status| image:: https://travis-ci.org/pyparsing/pyparsing.svg?branch=master\n :target: https://travis-ci.org/pyparsing/pyparsing", - "release_date": "2020-04-05T22:21:25", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Paul McGuire", - "email": "ptmcg@users.sourceforge.net", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Intended Audience :: Information Technology", - "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" - ], - "homepage_url": "https://github.com/pyparsing/pyparsing/", - "download_url": "https://files.pythonhosted.org/packages/c1/47/dfc9c342c9842bbe0036c7f763d2d6686bcf5eb1808ba3e170afdb282210/pyparsing-2.4.7.tar.gz", - "size": 649718, - "sha1": null, - "md5": "f0953e47a0112f7a65aec2305ffdf7b4", - "sha256": "c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT License", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/pyparsing/2.4.7/json", - "datasource_id": null, - "purl": "pkg:pypi/pyparsing@2.4.7" - }, { "type": "pypi", "namespace": null, @@ -594,62 +415,6 @@ "api_data_url": "https://pypi.org/pypi/six/1.16.0/json", "datasource_id": null, "purl": "pkg:pypi/six@1.16.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "six", - "version": "1.16.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Python 2 and 3 compatibility utilities\n.. image:: https://img.shields.io/pypi/v/six.svg\n :target: https://pypi.org/project/six/\n :alt: six on PyPI\n\n.. image:: https://travis-ci.org/benjaminp/six.svg?branch=master\n :target: https://travis-ci.org/benjaminp/six\n :alt: six on TravisCI\n\n.. image:: https://readthedocs.org/projects/six/badge/?version=latest\n :target: https://six.readthedocs.io/\n :alt: six's documentation on Read the Docs\n\n.. image:: https://img.shields.io/badge/license-MIT-green.svg\n :target: https://github.com/benjaminp/six/blob/master/LICENSE\n :alt: MIT License badge\n\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 Python 2.7 and 3.3+. 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://six.readthedocs.io/.\n\nBugs can be reported to https://github.com/benjaminp/six. The code can also\nbe found there.", - "release_date": "2021-05-05T14:18:18", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Benjamin Peterson", - "email": "benjamin@python.org", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities" - ], - "homepage_url": "https://github.com/benjaminp/six", - "download_url": "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", - "size": 34041, - "sha1": null, - "md5": "a7c927740e4964dd29b72cebfc1429bb", - "sha256": "1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "license": "MIT", - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/six/1.16.0/json", - "datasource_id": null, - "purl": "pkg:pypi/six@1.16.0" } ], "resolved_dependencies_graph": [ diff --git a/tests/data/single-url-expected.json b/tests/data/single-url-expected.json index fd2d896..69bb08f 100644 --- a/tests/data/single-url-expected.json +++ b/tests/data/single-url-expected.json @@ -67,59 +67,6 @@ "api_data_url": "https://pypi.org/pypi/zipp/3.8.0/json", "datasource_id": null, "purl": "pkg:pypi/zipp@3.8.0" - }, - { - "type": "pypi", - "namespace": null, - "name": "zipp", - "version": "3.8.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Backport of pathlib-compatible object wrapper for zip files\n.. image:: https://img.shields.io/pypi/v/zipp.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/zipp.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/zipp\n\n.. image:: https://github.com/jaraco/zipp/workflows/tests/badge.svg\n :target: https://github.com/jaraco/zipp/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest\n.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2022-informational\n :target: https://blog.jaraco.com/skeleton\n\n\nA pathlib-compatible Zipfile object wrapper. Official backport of the standard library\n`Path object `_.\n\n\nCompatibility\n=============\n\nNew features are introduced in this third-party library and later merged\ninto CPython. The following table indicates which versions of this library\nwere contributed to different versions in the standard library:\n\n.. list-table::\n :header-rows: 1\n\n * - zipp\n - stdlib\n * - 3.5\n - 3.11\n * - 3.3\n - 3.9\n * - 1.0\n - 3.8\n\n\nUsage\n=====\n\nUse ``zipp.Path`` in place of ``zipfile.Path`` on any Python.", - "release_date": "2022-04-03T15:07:28", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Jason R. Coombs", - "email": "jaraco@jaraco.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only" - ], - "homepage_url": "https://github.com/jaraco/zipp", - "download_url": "https://files.pythonhosted.org/packages/cc/3c/3e8c69cd493297003da83f26ccf1faea5dd7da7892a0a7c965ac3bcba7bf/zipp-3.8.0.tar.gz", - "size": 13344, - "sha1": null, - "md5": "8864ff5ed01cd28755cc87f1443dbc67", - "sha256": "56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/zipp/3.8.0/json", - "datasource_id": null, - "purl": "pkg:pypi/zipp@3.8.0" } ], "resolved_dependencies_graph": [ diff --git a/tests/data/tilde_req-expected.json b/tests/data/tilde_req-expected.json index 68856bd..25f44dc 100644 --- a/tests/data/tilde_req-expected.json +++ b/tests/data/tilde_req-expected.json @@ -69,59 +69,6 @@ "api_data_url": "https://pypi.org/pypi/zipp/3.8.1/json", "datasource_id": null, "purl": "pkg:pypi/zipp@3.8.1" - }, - { - "type": "pypi", - "namespace": null, - "name": "zipp", - "version": "3.8.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Backport of pathlib-compatible object wrapper for zip files\n.. image:: https://img.shields.io/pypi/v/zipp.svg\n :target: `PyPI link`_\n\n.. image:: https://img.shields.io/pypi/pyversions/zipp.svg\n :target: `PyPI link`_\n\n.. _PyPI link: https://pypi.org/project/zipp\n\n.. image:: https://github.com/jaraco/zipp/workflows/tests/badge.svg\n :target: https://github.com/jaraco/zipp/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Code style: Black\n\n.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest\n.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest\n\n.. image:: https://img.shields.io/badge/skeleton-2022-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. image:: https://tidelift.com/badges/package/pypi/zipp\n :target: https://tidelift.com/subscription/pkg/pypi-zipp?utm_source=pypi-zipp&utm_medium=readme\n\n\nA pathlib-compatible Zipfile object wrapper. Official backport of the standard library\n`Path object `_.\n\n\nCompatibility\n=============\n\nNew features are introduced in this third-party library and later merged\ninto CPython. The following table indicates which versions of this library\nwere contributed to different versions in the standard library:\n\n.. list-table::\n :header-rows: 1\n\n * - zipp\n - stdlib\n * - 3.5\n - 3.11\n * - 3.3\n - 3.9\n * - 1.0\n - 3.8\n\n\nUsage\n=====\n\nUse ``zipp.Path`` in place of ``zipfile.Path`` on any Python.\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nThis project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more `_.\n\nSecurity Contact\n================\n\nTo report a security vulnerability, please use the\n`Tidelift security contact `_.\nTidelift will coordinate the fix and disclosure.", - "release_date": "2022-07-12T14:21:21", - "parties": [ - { - "type": "person", - "role": "author", - "name": "Jason R. Coombs", - "email": "jaraco@jaraco.com", - "url": null - } - ], - "keywords": [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only" - ], - "homepage_url": "https://github.com/jaraco/zipp", - "download_url": "https://files.pythonhosted.org/packages/3b/e3/fb79a1ea5f3a7e9745f688855d3c673f2ef7921639a380ec76f7d4d83a85/zipp-3.8.1.tar.gz", - "size": 14189, - "sha1": null, - "md5": "6f15c3e3c78919f8936749b0033e0cea", - "sha256": "05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2", - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "license_expression": null, - "declared_license": { - "classifiers": [ - "License :: OSI Approved :: MIT License" - ] - }, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": "https://pypi.org/pypi/zipp/3.8.1/json", - "datasource_id": null, - "purl": "pkg:pypi/zipp@3.8.1" } ], "resolved_dependencies_graph": [ From a3140250fd72f74eb24350509221facbb487de97 Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Thu, 30 Nov 2023 21:22:25 +0100 Subject: [PATCH 12/15] Fix import sorting. --- src/python_inspector/api.py | 6 ++++-- src/python_inspector/dependencies.py | 3 ++- src/python_inspector/package_data.py | 5 ++++- src/python_inspector/resolution.py | 5 ++++- src/python_inspector/utils.py | 3 ++- src/python_inspector/utils_pypi.py | 9 ++++++--- 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/python_inspector/api.py b/src/python_inspector/api.py index 1955828..2d89f6e 100644 --- a/src/python_inspector/api.py +++ b/src/python_inspector/api.py @@ -11,10 +11,11 @@ import asyncio import os from netrc import netrc -from typing import Dict, Tuple +from typing import Dict from typing import List from typing import NamedTuple from typing import Sequence +from typing import Tuple from packageurl import PackageURL from packvers.requirements import Requirement @@ -23,9 +24,10 @@ from _packagedcode.models import DependentPackage from _packagedcode.models import PackageData -from _packagedcode.pypi import PipRequirementsFileHandler, get_resolved_purl +from _packagedcode.pypi import PipRequirementsFileHandler from _packagedcode.pypi import PythonSetupPyHandler from _packagedcode.pypi import can_process_dependent_package +from _packagedcode.pypi import get_resolved_purl from python_inspector import dependencies from python_inspector import utils from python_inspector import utils_pypi diff --git a/src/python_inspector/dependencies.py b/src/python_inspector/dependencies.py index 3db30bc..0c49130 100644 --- a/src/python_inspector/dependencies.py +++ b/src/python_inspector/dependencies.py @@ -8,7 +8,8 @@ # See https://github.com/nexB/skeleton for support or download. # See https://aboutcode.org for more information about nexB OSS projects. # -from typing import Iterable, Mapping +from typing import Iterable +from typing import Mapping from packageurl import PackageURL from packvers.requirements import Requirement diff --git a/src/python_inspector/package_data.py b/src/python_inspector/package_data.py index 19ce5a6..905c085 100644 --- a/src/python_inspector/package_data.py +++ b/src/python_inspector/package_data.py @@ -9,7 +9,10 @@ # See https://aboutcode.org for more information about nexB OSS projects. # -from typing import List, Iterable, Optional, Dict +from typing import Dict +from typing import Iterable +from typing import List +from typing import Optional from packageurl import PackageURL diff --git a/src/python_inspector/resolution.py b/src/python_inspector/resolution.py index 9dbbf55..7a1a646 100644 --- a/src/python_inspector/resolution.py +++ b/src/python_inspector/resolution.py @@ -12,11 +12,14 @@ import operator import os import tarfile -from typing import Dict, Iterable, Mapping, Type +from typing import Dict from typing import Generator +from typing import Iterable from typing import List +from typing import Mapping from typing import NamedTuple from typing import Tuple +from typing import Type from typing import Union from zipfile import ZipFile diff --git a/src/python_inspector/utils.py b/src/python_inspector/utils.py index 4dbfcce..a7df84b 100644 --- a/src/python_inspector/utils.py +++ b/src/python_inspector/utils.py @@ -11,9 +11,10 @@ import json import os -from typing import Dict, Optional +from typing import Dict from typing import List from typing import NamedTuple +from typing import Optional import aiohttp import requests diff --git a/src/python_inspector/utils_pypi.py b/src/python_inspector/utils_pypi.py index 3020057..990a001 100644 --- a/src/python_inspector/utils_pypi.py +++ b/src/python_inspector/utils_pypi.py @@ -8,7 +8,7 @@ # See https://github.com/nexB/skeleton for support or download. # See https://aboutcode.org for more information about nexB OSS projects. # - +import asyncio import email import itertools import os @@ -18,8 +18,11 @@ import tempfile import time from collections import defaultdict -from typing import List, Dict, Union, Tuple +from typing import Dict +from typing import List from typing import NamedTuple +from typing import Tuple +from typing import Union from urllib.parse import quote_plus from urllib.parse import unquote from urllib.parse import urlparse @@ -1305,7 +1308,7 @@ async def dists_from_links(cls, links: List[Link]): ... Link(url="https://example.com/bar/bitarray-0.8.1.tar.gz",python_requires= ">=3.7"), ... Link(url="bitarray-0.8.1.tar.gz.ABOUT",python_requires= ">=3.7"), ... Link(url="bit.LICENSE", python_requires=">=3.7")] - >>> results = list(PypiPackage.dists_from_links(links)) + >>> results = list(asyncio.run(PypiPackage.dists_from_links(links))) >>> for r in results: ... print(r.__class__.__name__, r.name, r.version) ... if isinstance(r, Wheel): From 1f7ca90e6bf3946274d6aa617d4f94795fd95d9a Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Thu, 30 Nov 2023 21:25:41 +0100 Subject: [PATCH 13/15] Fix error in setup.cfg. --- tests/data/setup.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/data/setup.cfg b/tests/data/setup.cfg index c9d6a7b..62a0642 100644 --- a/tests/data/setup.cfg +++ b/tests/data/setup.cfg @@ -10,7 +10,6 @@ install_requires = requests >= 2.7.0 saneyaml >= 0.5.2 text_unidecode >= 1.0 - pure-eval; black; tox; typing >=3.6, < 3.7; python_version < "3.7" [options.extras_require] From da79c1d8f809c94d689cd0b28b5736f2cb72152c Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Thu, 30 Nov 2023 21:30:53 +0100 Subject: [PATCH 14/15] Add skip to failing test. --- tests/test_utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_utils.py b/tests/test_utils.py index 34b45a8..00ff4d5 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -11,6 +11,7 @@ import collections import json import os +import sys from netrc import netrc from unittest import mock @@ -49,6 +50,7 @@ def test_get_netrc_auth_with_no_matching_url(): @pytest.mark.asyncio +@pytest.mark.skipif(sys.version_info < (3, 8), reason="requires python3.8 or higher") @mock.patch("python_inspector.utils_pypi.CACHE.get") async def test_fetch_links(mock_get): file_name = test_env.get_test_loc("psycopg2.html") From f3bd8b033e09f9f6e478d70ec925da094622e3cc Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Sat, 2 Dec 2023 21:00:59 +0100 Subject: [PATCH 15/15] Some more cleanups. --- src/python_inspector/api.py | 2 +- src/python_inspector/package_data.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/python_inspector/api.py b/src/python_inspector/api.py index 2d89f6e..70b547c 100644 --- a/src/python_inspector/api.py +++ b/src/python_inspector/api.py @@ -56,7 +56,7 @@ class Resolution(NamedTuple): ``files`` is a parsed list of input file data. """ - resolution: Dict + resolution: List[Dict] packages: List[PackageData] files: List[Dict] diff --git a/src/python_inspector/package_data.py b/src/python_inspector/package_data.py index 905c085..1a045c0 100644 --- a/src/python_inspector/package_data.py +++ b/src/python_inspector/package_data.py @@ -10,7 +10,6 @@ # from typing import Dict -from typing import Iterable from typing import List from typing import Optional