From 6140a8038d6363ca793c6b355b5a8bba179f21d3 Mon Sep 17 00:00:00 2001 From: yamagen0915 Date: Thu, 23 Jan 2020 15:04:58 +0900 Subject: [PATCH 01/80] Fix error on invalid author --- poetry/packages/package.py | 6 ++++++ tests/packages/test_package.py | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/poetry/packages/package.py b/poetry/packages/package.py index 5b7dfea09d1..56e01f34741 100644 --- a/poetry/packages/package.py +++ b/poetry/packages/package.py @@ -162,6 +162,9 @@ def _get_author(self): # type: () -> dict m = AUTHOR_REGEX.match(self._authors[0]) + if m is None: + return {"name": None, "email": None} + name = m.group("name") email = m.group("email") @@ -173,6 +176,9 @@ def _get_maintainer(self): # type: () -> dict m = AUTHOR_REGEX.match(self._maintainers[0]) + if m is None: + return {"name": None, "email": None} + name = m.group("name") email = m.group("email") diff --git a/tests/packages/test_package.py b/tests/packages/test_package.py index b61de86e540..c25e15cde48 100644 --- a/tests/packages/test_package.py +++ b/tests/packages/test_package.py @@ -17,6 +17,10 @@ def test_package_authors(): assert package.author_name == "John Doe" assert package.author_email is None + package.authors.insert(0, " Date: Thu, 23 Jan 2020 16:32:21 +0900 Subject: [PATCH 02/80] Add a friendly warning message --- poetry/packages/package.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/poetry/packages/package.py b/poetry/packages/package.py index 56e01f34741..4b39bb9eb5c 100644 --- a/poetry/packages/package.py +++ b/poetry/packages/package.py @@ -163,6 +163,10 @@ def _get_author(self): # type: () -> dict m = AUTHOR_REGEX.match(self._authors[0]) if m is None: + logger.warning( + "Invalid author string. Must be in the format: " + "John Smith " + ) return {"name": None, "email": None} name = m.group("name") @@ -177,6 +181,10 @@ def _get_maintainer(self): # type: () -> dict m = AUTHOR_REGEX.match(self._maintainers[0]) if m is None: + logger.warning( + "Invalid maintainer string. Must be in the format: " + "John Smith " + ) return {"name": None, "email": None} name = m.group("name") From 29c1125c5d8631c30d1d3583964adee30b94c410 Mon Sep 17 00:00:00 2001 From: Alex Triaca Date: Sun, 8 Mar 2020 12:06:32 +0000 Subject: [PATCH 03/80] Changed indirect access to more direct access methods to improve performance --- poetry/packages/dependency_package.py | 20 ++++++++++++++++++++ poetry/packages/package.py | 14 +++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/poetry/packages/dependency_package.py b/poetry/packages/dependency_package.py index f38892488d9..6285cf29ae4 100644 --- a/poetry/packages/dependency_package.py +++ b/poetry/packages/dependency_package.py @@ -3,6 +3,26 @@ def __init__(self, dependency, package): self._dependency = dependency self._package = package + @property + def name(self): + return self._package.name + + @property + def version(self): + return self._package.version + + @property + def constraint(self): + return self._package.constraint + + @property + def all_requires(self): + return self._package.all_requires + + @property + def marker(self): + return self._package.marker + @property def dependency(self): return self._dependency diff --git a/poetry/packages/package.py b/poetry/packages/package.py index cb28ef70c7f..c98544852e9 100644 --- a/poetry/packages/package.py +++ b/poetry/packages/package.py @@ -40,7 +40,7 @@ def __init__(self, name, version, pretty_version=None): Creates a new in memory package. """ self._pretty_name = name - self._name = canonicalize_name(name) + self.name = canonicalize_name(name) if not isinstance(version, Version): self._version = Version.parse(version) @@ -88,10 +88,6 @@ def __init__(self, name, version, pretty_version=None): self.develop = True - @property - def name(self): - return self._name - @property def pretty_name(self): return self._pretty_name @@ -107,7 +103,7 @@ def pretty_version(self): @property def unique_name(self): if self.is_root(): - return self._name + return self.name return self.name + "-" + self._version.text @@ -388,7 +384,7 @@ def add_dependency( def to_dependency(self): from . import dependency_from_pep_508 - name = "{} (=={})".format(self._name, self._version) + name = "{} (=={})".format(self.name, self._version) if not self.marker.is_any(): name += " ; {}".format(str(self.marker)) @@ -425,13 +421,13 @@ def clone(self): # type: () -> Package return clone def __hash__(self): - return hash((self._name, self._version)) + return hash((self.name, self._version)) def __eq__(self, other): if not isinstance(other, Package): return NotImplemented - return self._name == other.name and self._version == other.version + return self.name == other.name and self._version == other.version def __str__(self): return self.unique_name From bf07ceff6cd625fb53c9b711321a4e319defd800 Mon Sep 17 00:00:00 2001 From: Alex Povel <48824213+alexpovel@users.noreply.github.com> Date: Tue, 10 Mar 2020 10:16:38 +0100 Subject: [PATCH 04/80] Update managing-environments.md --- docs/docs/managing-environments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/managing-environments.md b/docs/docs/managing-environments.md index 51e2a68e7a0..47e8ede4047 100644 --- a/docs/docs/managing-environments.md +++ b/docs/docs/managing-environments.md @@ -1,6 +1,6 @@ # Managing environments -Poetry makes project environment isolation one of its core feature. +Poetry makes project environment isolation one of its core features. What this means is that it will always work isolated from your global Python installation. To achieve this, it will first check if it's currently running inside a virtual environment. From bf12e427aea2eb5d7f11f0480c57508ae4f7326b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 20 Mar 2020 14:06:30 +0100 Subject: [PATCH 05/80] Merge master into develop (#2206) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * export: fix exporting extras sub-dependencies (#1294) * Support POETRY_HOME for install (#794) Allow the `POETRY_HOME` environment variable to be passed during installation to change the default installation directory of `~/.poetry`: ``` POETRY_HOME=/etc/poetry python get-poetry.py ``` * * check if relative filename is in excluded file list (#1459) * * check if relative filename is in excluded file list * removed find_excluded_files() method from wheel.py * added test for excluding files in wheels * creating an own test data folder, for testing excluding files by pyproject.toml * use as_posix() to respect windows file path delimiters * Exclude nested items (#784) (#1464) * This PR impliments the feature request #784. When a folder is explicit defined in `pyproject.toml` as excluded, all nested data, including subfolder, are excluded. It is no longer neccessary to use the glob `folder/**/*` * use `Path` instead of `os.path.join` to create string for globbing * try to fix linting error * create glob pattern string by concatenating and not using Path * using `os.path.isdir()`` for checking of explicit excluded name is a folder, because pathlib's `is_dir()` raises in exception under windows of name contains globing characters * Remove nested data when wildcards where used. Steps to do this are: 1. expand any wildcard used 2. if expanded path is a folder append **/* and expand again * fix linting * only glob a second time if path is dir * implement @sdispater 's suggestion for better readability * fix glob for windows? * On Windows, testing if a path with a glob is a directory will raise an OSError * pathlibs glob function doesn't return the correct case (https://bugs.python.org/issue26655). So switching back to glob.glob() * removing obsolete imports * Update dependencies * Deprecate allows-prereleases in favor of allow-prereleases for consistency * Fix tests for Python 2.7 * Fix linting * Fix linting * Fix linting * Fix typing import * Correct a couple typos in get-poetry.py (#573) * Docs: `self:update` changed to `self update` (#1588) * Fix GitHub actions cache issues on develop (#1918) * Fix Github actions cache issues * Fix Github Actions cache issues (#1928) * Add --source option to "poetry add" (#1912) * Add --source option to 'poetry add' * Add tests for 'poetry add --source' * Merge master into develop (#2070) * Fix Github actions cache issues (#1908) * Fix case of `-f` flag * Make it clearer what options to pass to `--format` * fix (masonry.api): `get_requires_for_build_wheel` must return additional list of requirements for building a package, not listed in `pyproject.toml` and not dependencies for the package itself (#1875) fix (tests): adopted tests * Lazy Keyring intialization for PasswordManager (#1892) * Fix Github Actions cache issues (#1928) * Avoid nested quantifiers with overlapping character space on git url parsing (#1902 (#1913) * fix (git): match for `\w` instead of `.` for getting user * change (vcs.git): hold pattern of the regex parts in a dictionary to be consistent over all regexs * new (vcs.git): test for `parse_url` and some fixes for the regex pattern * new (vcs.git): test for `parse_url` with string that should fail * fix (test.vcs.git): make flake8 happy * fix: correct parsing of wheel version with regex. (#1932) The previous regexp was only taking the first integer of the version number, this presented problems when the major version number reached double digits. Poetry would determine that the version of the dependency is '1', rather than, ie: '14'. This caused failures to solve versions. * Fix errors when using the --help option (#1910) * Fix how repository credentials are retrieved from env vars (#1909) # Conflicts: # poetry/utils/password_manager.py * Fix downloading packages from Simplepypi (#1851) * fix downloading packages from simplepypi * unused code removed * remove unused imports * Upgrade dependencies for the 1.0.3 release (#1965) * Bump version to 1.0.3 (#1966) * Fix non-compliant Git URL matching RFC 3986 § 2.3 permits more characters in a URL than were matched. This corrects that, though there may be other deficiencies. This was a regression from v1.0.2, where at least “.” was matched without error. * Update README.md "Updating Poetry" Currently the note in "Updating Poetry" is different from the one below in "Enable tab completion for Bash, Fish, or Zsh". This MR is to make them more consistent. * init: change dev dependency prompt * Fix CI issues (#2069) Co-authored-by: brandonaut Co-authored-by: finswimmer Co-authored-by: Yannick PÉROUX Co-authored-by: Edward George Co-authored-by: Jan Škoda Co-authored-by: Andrew Marshall Co-authored-by: Andrew Selzer Co-authored-by: Andrii Maletskyi * pre-commit: replace isort mirror with isort upstream (#2118) The isort pre-commit mirror has been deprecated. This change updates configuration to use the upstream package repository instead of the mirror. * Add cache list command (#1187) * Add poetry.locations.REPOSITORY_CACHE_DIR The repository cache directory is used in multiple places in the codebase. This change ensures that the value is reused. * Add cache list command This introduces a new cache sub-command that lists all available caches. Relates-to: #1162 Co-authored-by: Tom Milligan Co-authored-by: David Cramer Co-authored-by: finswimmer Co-authored-by: Kyle Altendorf Co-authored-by: Justin Mayer Co-authored-by: Yannick PÉROUX Co-authored-by: brandonaut Co-authored-by: Edward George Co-authored-by: Jan Škoda Co-authored-by: Andrew Marshall Co-authored-by: Andrew Selzer Co-authored-by: Andrii Maletskyi Co-authored-by: Arun Babu Neelicattu --- .pre-commit-config.yaml | 4 +- CHANGELOG.md | 1 - docs/docs/cli.md | 12 +++++ poetry/console/commands/add.py | 13 ++++- poetry/console/commands/cache/cache.py | 4 +- poetry/console/commands/cache/clear.py | 8 ++- poetry/console/commands/cache/list.py | 21 ++++++++ poetry/console/commands/init.py | 11 ++-- poetry/locations.py | 3 ++ poetry/repositories/legacy_repository.py | 4 +- poetry/repositories/pypi_repository.py | 4 +- poetry/version/version_selector.py | 3 +- tests/console/commands/test_add.py | 68 ++++++++++++++++++++++++ tests/console/commands/test_cache.py | 60 +++++++++++++++++++++ 14 files changed, 197 insertions(+), 19 deletions(-) create mode 100644 poetry/console/commands/cache/list.py create mode 100644 tests/console/commands/test_cache.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b296497d29f..426692139b4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,8 +9,8 @@ repos: hooks: - id: flake8 - - repo: https://github.com/pre-commit/mirrors-isort - rev: v4.3.21 + - repo: https://github.com/timothycrosley/isort + rev: 4.3.21 hooks: - id: isort additional_dependencies: [toml] diff --git a/CHANGELOG.md b/CHANGELOG.md index d196bd38d52..2a49380e6be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,6 @@ - Fixed an error when parsing some git URLs ([#2018](https://github.com/python-poetry/poetry/pull/2018)). - ## [1.0.3] - 2020-01-31 ### Fixed diff --git a/docs/docs/cli.md b/docs/docs/cli.md index 89d19a8cc18..63d63fbc990 100644 --- a/docs/docs/cli.md +++ b/docs/docs/cli.md @@ -452,3 +452,15 @@ The `env` command regroups sub commands to interact with the virtualenvs associated with a specific project. See [Managing environments](./managing-environments.md) for more information about these commands. + +## cache + +The `cache` command regroups sub commands to interact with Poetry's cache. + +### cache list + +The `cache list` command lists Poetry's available caches. + +```bash +poetry cache list +``` diff --git a/poetry/console/commands/add.py b/poetry/console/commands/add.py index 275fc44f5f1..bb210265703 100644 --- a/poetry/console/commands/add.py +++ b/poetry/console/commands/add.py @@ -33,6 +33,12 @@ class AddCommand(EnvCommand, InitCommand): "Platforms for which the dependency must be installed.", flag=False, ), + option( + "source", + None, + "Name of the source to use to install the package.", + flag=False, + ), option("allow-prereleases", None, "Accept prereleases."), option( "dry-run", @@ -86,7 +92,9 @@ def handle(self): raise ValueError("Package {} is already present".format(name)) requirements = self._determine_requirements( - packages, allow_prereleases=self.option("allow-prereleases") + packages, + allow_prereleases=self.option("allow-prereleases"), + source=self.option("source"), ) for _constraint in requirements: @@ -123,6 +131,9 @@ def handle(self): if self.option("platform"): constraint["platform"] = self.option("platform") + if self.option("source"): + constraint["source"] = self.option("source") + if len(constraint) == 1 and "version" in constraint: constraint = constraint["version"] diff --git a/poetry/console/commands/cache/cache.py b/poetry/console/commands/cache/cache.py index 469eb56be05..695e27e0af7 100644 --- a/poetry/console/commands/cache/cache.py +++ b/poetry/console/commands/cache/cache.py @@ -1,3 +1,5 @@ +from poetry.console.commands.cache.list import CacheListCommand + from ..command import Command from .clear import CacheClearCommand @@ -7,7 +9,7 @@ class CacheCommand(Command): name = "cache" description = "Interact with Poetry's cache" - commands = [CacheClearCommand()] + commands = [CacheClearCommand(), CacheListCommand()] def handle(self): return self.call("help", self._config.name) diff --git a/poetry/console/commands/cache/clear.py b/poetry/console/commands/cache/clear.py index 347f534afc0..c46dab01281 100644 --- a/poetry/console/commands/cache/clear.py +++ b/poetry/console/commands/cache/clear.py @@ -16,19 +16,17 @@ class CacheClearCommand(Command): def handle(self): from cachy import CacheManager - from poetry.locations import CACHE_DIR - from poetry.utils._compat import Path + from poetry.locations import REPOSITORY_CACHE_DIR cache = self.argument("cache") parts = cache.split(":") root = parts[0] - base_cache = Path(CACHE_DIR) / "cache" / "repositories" - cache_dir = base_cache / root + cache_dir = REPOSITORY_CACHE_DIR / root try: - cache_dir.relative_to(base_cache) + cache_dir.relative_to(REPOSITORY_CACHE_DIR) except ValueError: raise ValueError("{} is not a valid repository cache".format(root)) diff --git a/poetry/console/commands/cache/list.py b/poetry/console/commands/cache/list.py new file mode 100644 index 00000000000..6a030fa2eba --- /dev/null +++ b/poetry/console/commands/cache/list.py @@ -0,0 +1,21 @@ +import os + +from ..command import Command + + +class CacheListCommand(Command): + + name = "list" + description = "List Poetry's caches." + + def handle(self): + from poetry.locations import REPOSITORY_CACHE_DIR + + if os.path.exists(str(REPOSITORY_CACHE_DIR)): + caches = list(sorted(REPOSITORY_CACHE_DIR.iterdir())) + if caches: + for cache in caches: + self.line("{}".format(cache.name)) + return 0 + + self.line("No caches found") diff --git a/poetry/console/commands/init.py b/poetry/console/commands/init.py index 825f8c68e2a..40ed33a17f1 100644 --- a/poetry/console/commands/init.py +++ b/poetry/console/commands/init.py @@ -203,7 +203,7 @@ def handle(self): f.write(content) def _determine_requirements( - self, requires, allow_prereleases=False + self, requires, allow_prereleases=False, source=None ): # type: (List[str], bool) -> List[Dict[str, str]] if not requires: requires = [] @@ -299,7 +299,9 @@ def _determine_requirements( elif "version" not in requirement: # determine the best version automatically name, version = self._find_best_version_for_package( - requirement["name"], allow_prereleases=allow_prereleases + requirement["name"], + allow_prereleases=allow_prereleases, + source=source, ) requirement["version"] = version requirement["name"] = name @@ -314,6 +316,7 @@ def _determine_requirements( requirement["name"], requirement["version"], allow_prereleases=allow_prereleases, + source=source, ) requirement["name"] = name @@ -323,13 +326,13 @@ def _determine_requirements( return result def _find_best_version_for_package( - self, name, required_version=None, allow_prereleases=False + self, name, required_version=None, allow_prereleases=False, source=None ): # type: (...) -> Tuple[str, str] from poetry.version.version_selector import VersionSelector selector = VersionSelector(self._get_pool()) package = selector.find_best_candidate( - name, required_version, allow_prereleases=allow_prereleases + name, required_version, allow_prereleases=allow_prereleases, source=source ) if not package: diff --git a/poetry/locations.py b/poetry/locations.py index 17fb4d42a99..003950d500d 100644 --- a/poetry/locations.py +++ b/poetry/locations.py @@ -1,6 +1,9 @@ +from .utils._compat import Path from .utils.appdirs import user_cache_dir from .utils.appdirs import user_config_dir CACHE_DIR = user_cache_dir("pypoetry") CONFIG_DIR = user_config_dir("pypoetry") + +REPOSITORY_CACHE_DIR = Path(CACHE_DIR) / "cache" / "repositories" diff --git a/poetry/repositories/legacy_repository.py b/poetry/repositories/legacy_repository.py index 4bb0496eb29..c2eac509ae8 100644 --- a/poetry/repositories/legacy_repository.py +++ b/poetry/repositories/legacy_repository.py @@ -15,7 +15,7 @@ import poetry.packages -from poetry.locations import CACHE_DIR +from poetry.locations import REPOSITORY_CACHE_DIR from poetry.packages import Package from poetry.packages import dependency_from_pep_508 from poetry.packages.utils.link import Link @@ -174,7 +174,7 @@ def __init__( self._client_cert = client_cert self._cert = cert self._inspector = Inspector() - self._cache_dir = Path(CACHE_DIR) / "cache" / "repositories" / name + self._cache_dir = REPOSITORY_CACHE_DIR / name self._cache = CacheManager( { "default": "releases", diff --git a/poetry/repositories/pypi_repository.py b/poetry/repositories/pypi_repository.py index 767a7353b3c..0f1ac5208ed 100644 --- a/poetry/repositories/pypi_repository.py +++ b/poetry/repositories/pypi_repository.py @@ -15,7 +15,7 @@ from requests import session from requests.exceptions import TooManyRedirects -from poetry.locations import CACHE_DIR +from poetry.locations import REPOSITORY_CACHE_DIR from poetry.packages import Package from poetry.packages import dependency_from_pep_508 from poetry.packages.utils.link import Link @@ -57,7 +57,7 @@ def __init__(self, url="https://pypi.org/", disable_cache=False, fallback=True): self._disable_cache = disable_cache self._fallback = fallback - release_cache_dir = Path(CACHE_DIR) / "cache" / "repositories" / "pypi" + release_cache_dir = REPOSITORY_CACHE_DIR / "pypi" self._cache = CacheManager( { "default": "releases", diff --git a/poetry/version/version_selector.py b/poetry/version/version_selector.py index 8c71daec87b..2077e322699 100644 --- a/poetry/version/version_selector.py +++ b/poetry/version/version_selector.py @@ -15,6 +15,7 @@ def find_best_candidate( package_name, # type: str target_package_version=None, # type: Union[str, None] allow_prereleases=False, # type: bool + source=None, # type: str ): # type: (...) -> Union[Package, bool] """ Given a package name and optional version, @@ -26,7 +27,7 @@ def find_best_candidate( constraint = parse_constraint("*") candidates = self._pool.find_packages( - package_name, constraint, allow_prereleases=True + package_name, constraint, allow_prereleases=True, repository=source ) only_prereleases = all([c.version.is_prerelease() for c in candidates]) diff --git a/tests/console/commands/test_add.py b/tests/console/commands/test_add.py index 6a64ba7e4eb..8e7f4a870c8 100644 --- a/tests/console/commands/test_add.py +++ b/tests/console/commands/test_add.py @@ -4,6 +4,8 @@ from cleo.testers import CommandTester +from poetry.repositories.legacy_repository import LegacyRepository +from poetry.semver import Version from poetry.utils._compat import Path from tests.helpers import get_dependency from tests.helpers import get_package @@ -634,6 +636,72 @@ def test_add_constraint_with_platform(app, repo, installer): } +def test_add_constraint_with_source(app, poetry, installer): + repo = LegacyRepository(name="my-index", url="https://my-index.fake") + repo.add_package(get_package("cachy", "0.2.0")) + repo._cache.store("matches").put("cachy:0.2.0", [Version.parse("0.2.0")], 5) + + poetry.pool.add_repository(repo) + + command = app.find("add") + tester = CommandTester(command) + + tester.execute("cachy=0.2.0 --source my-index") + + expected = """\ + +Updating dependencies +Resolving dependencies... + +Writing lock file + + +Package operations: 1 install, 0 updates, 0 removals + + - Installing cachy (0.2.0) +""" + + assert expected == tester.io.fetch_output() + + assert len(installer.installs) == 1 + + content = app.poetry.file.read()["tool"]["poetry"] + + assert "cachy" in content["dependencies"] + assert content["dependencies"]["cachy"] == { + "version": "0.2.0", + "source": "my-index", + } + + +def test_add_constraint_with_source_that_does_not_exist(app): + command = app.find("add") + tester = CommandTester(command) + + with pytest.raises(ValueError) as e: + tester.execute("foo --source i-dont-exist") + + assert 'Repository "i-dont-exist" does not exist.' == str(e.value) + + +def test_add_constraint_not_found_with_source(app, poetry, mocker): + repo = LegacyRepository(name="my-index", url="https://my-index.fake") + mocker.patch.object(repo, "find_packages", return_value=[]) + + poetry.pool.add_repository(repo) + + pypi = poetry.pool.repositories[0] + pypi.add_package(get_package("cachy", "0.2.0")) + + command = app.find("add") + tester = CommandTester(command) + + with pytest.raises(ValueError) as e: + tester.execute("cachy --source my-index") + + assert "Could not find a matching version of package cachy" == str(e.value) + + def test_add_to_section_that_does_no_exist_yet(app, repo, installer): command = app.find("add") tester = CommandTester(command) diff --git a/tests/console/commands/test_cache.py b/tests/console/commands/test_cache.py new file mode 100644 index 00000000000..8a22eee7f1b --- /dev/null +++ b/tests/console/commands/test_cache.py @@ -0,0 +1,60 @@ +import uuid + +import pytest + +from cleo.testers import CommandTester + + +@pytest.fixture +def repository_cache_dir(monkeypatch, tmpdir): + import poetry.locations + from poetry.utils._compat import Path + + path = Path(str(tmpdir)) + monkeypatch.setattr(poetry.locations, "REPOSITORY_CACHE_DIR", path) + return path + + +@pytest.fixture +def repository_one(): + return "01_{}".format(uuid.uuid4()) + + +@pytest.fixture +def repository_two(): + return "02_{}".format(uuid.uuid4()) + + +@pytest.fixture +def mock_caches(repository_cache_dir, repository_one, repository_two): + (repository_cache_dir / repository_one).mkdir() + (repository_cache_dir / repository_two).mkdir() + + +def test_cache_list(app, mock_caches, repository_one, repository_two): + command = app.find("cache list") + tester = CommandTester(command) + + tester.execute() + + expected = """\ +{} +{} +""".format( + repository_one, repository_two + ) + + assert expected == tester.io.fetch_output() + + +def test_cache_list_empty(app, repository_cache_dir): + command = app.find("cache list") + tester = CommandTester(command) + + tester.execute() + + expected = """\ +No caches found +""" + + assert expected == tester.io.fetch_output() From 9ab25813f9de1019910549dc92d30bbad427a838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 20 Mar 2020 14:25:26 +0100 Subject: [PATCH 06/80] Revert "Merge master into develop (#2206)" (#2208) This reverts commit bf12e427aea2eb5d7f11f0480c57508ae4f7326b. --- .pre-commit-config.yaml | 4 +- CHANGELOG.md | 1 + docs/docs/cli.md | 12 ----- poetry/console/commands/add.py | 13 +---- poetry/console/commands/cache/cache.py | 4 +- poetry/console/commands/cache/clear.py | 8 +-- poetry/console/commands/cache/list.py | 21 -------- poetry/console/commands/init.py | 11 ++-- poetry/locations.py | 3 -- poetry/repositories/legacy_repository.py | 4 +- poetry/repositories/pypi_repository.py | 4 +- poetry/version/version_selector.py | 3 +- tests/console/commands/test_add.py | 68 ------------------------ tests/console/commands/test_cache.py | 60 --------------------- 14 files changed, 19 insertions(+), 197 deletions(-) delete mode 100644 poetry/console/commands/cache/list.py delete mode 100644 tests/console/commands/test_cache.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 426692139b4..b296497d29f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,8 +9,8 @@ repos: hooks: - id: flake8 - - repo: https://github.com/timothycrosley/isort - rev: 4.3.21 + - repo: https://github.com/pre-commit/mirrors-isort + rev: v4.3.21 hooks: - id: isort additional_dependencies: [toml] diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a49380e6be..d196bd38d52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ - Fixed an error when parsing some git URLs ([#2018](https://github.com/python-poetry/poetry/pull/2018)). + ## [1.0.3] - 2020-01-31 ### Fixed diff --git a/docs/docs/cli.md b/docs/docs/cli.md index 63d63fbc990..89d19a8cc18 100644 --- a/docs/docs/cli.md +++ b/docs/docs/cli.md @@ -452,15 +452,3 @@ The `env` command regroups sub commands to interact with the virtualenvs associated with a specific project. See [Managing environments](./managing-environments.md) for more information about these commands. - -## cache - -The `cache` command regroups sub commands to interact with Poetry's cache. - -### cache list - -The `cache list` command lists Poetry's available caches. - -```bash -poetry cache list -``` diff --git a/poetry/console/commands/add.py b/poetry/console/commands/add.py index bb210265703..275fc44f5f1 100644 --- a/poetry/console/commands/add.py +++ b/poetry/console/commands/add.py @@ -33,12 +33,6 @@ class AddCommand(EnvCommand, InitCommand): "Platforms for which the dependency must be installed.", flag=False, ), - option( - "source", - None, - "Name of the source to use to install the package.", - flag=False, - ), option("allow-prereleases", None, "Accept prereleases."), option( "dry-run", @@ -92,9 +86,7 @@ def handle(self): raise ValueError("Package {} is already present".format(name)) requirements = self._determine_requirements( - packages, - allow_prereleases=self.option("allow-prereleases"), - source=self.option("source"), + packages, allow_prereleases=self.option("allow-prereleases") ) for _constraint in requirements: @@ -131,9 +123,6 @@ def handle(self): if self.option("platform"): constraint["platform"] = self.option("platform") - if self.option("source"): - constraint["source"] = self.option("source") - if len(constraint) == 1 and "version" in constraint: constraint = constraint["version"] diff --git a/poetry/console/commands/cache/cache.py b/poetry/console/commands/cache/cache.py index 695e27e0af7..469eb56be05 100644 --- a/poetry/console/commands/cache/cache.py +++ b/poetry/console/commands/cache/cache.py @@ -1,5 +1,3 @@ -from poetry.console.commands.cache.list import CacheListCommand - from ..command import Command from .clear import CacheClearCommand @@ -9,7 +7,7 @@ class CacheCommand(Command): name = "cache" description = "Interact with Poetry's cache" - commands = [CacheClearCommand(), CacheListCommand()] + commands = [CacheClearCommand()] def handle(self): return self.call("help", self._config.name) diff --git a/poetry/console/commands/cache/clear.py b/poetry/console/commands/cache/clear.py index c46dab01281..347f534afc0 100644 --- a/poetry/console/commands/cache/clear.py +++ b/poetry/console/commands/cache/clear.py @@ -16,17 +16,19 @@ class CacheClearCommand(Command): def handle(self): from cachy import CacheManager - from poetry.locations import REPOSITORY_CACHE_DIR + from poetry.locations import CACHE_DIR + from poetry.utils._compat import Path cache = self.argument("cache") parts = cache.split(":") root = parts[0] - cache_dir = REPOSITORY_CACHE_DIR / root + base_cache = Path(CACHE_DIR) / "cache" / "repositories" + cache_dir = base_cache / root try: - cache_dir.relative_to(REPOSITORY_CACHE_DIR) + cache_dir.relative_to(base_cache) except ValueError: raise ValueError("{} is not a valid repository cache".format(root)) diff --git a/poetry/console/commands/cache/list.py b/poetry/console/commands/cache/list.py deleted file mode 100644 index 6a030fa2eba..00000000000 --- a/poetry/console/commands/cache/list.py +++ /dev/null @@ -1,21 +0,0 @@ -import os - -from ..command import Command - - -class CacheListCommand(Command): - - name = "list" - description = "List Poetry's caches." - - def handle(self): - from poetry.locations import REPOSITORY_CACHE_DIR - - if os.path.exists(str(REPOSITORY_CACHE_DIR)): - caches = list(sorted(REPOSITORY_CACHE_DIR.iterdir())) - if caches: - for cache in caches: - self.line("{}".format(cache.name)) - return 0 - - self.line("No caches found") diff --git a/poetry/console/commands/init.py b/poetry/console/commands/init.py index 40ed33a17f1..825f8c68e2a 100644 --- a/poetry/console/commands/init.py +++ b/poetry/console/commands/init.py @@ -203,7 +203,7 @@ def handle(self): f.write(content) def _determine_requirements( - self, requires, allow_prereleases=False, source=None + self, requires, allow_prereleases=False ): # type: (List[str], bool) -> List[Dict[str, str]] if not requires: requires = [] @@ -299,9 +299,7 @@ def _determine_requirements( elif "version" not in requirement: # determine the best version automatically name, version = self._find_best_version_for_package( - requirement["name"], - allow_prereleases=allow_prereleases, - source=source, + requirement["name"], allow_prereleases=allow_prereleases ) requirement["version"] = version requirement["name"] = name @@ -316,7 +314,6 @@ def _determine_requirements( requirement["name"], requirement["version"], allow_prereleases=allow_prereleases, - source=source, ) requirement["name"] = name @@ -326,13 +323,13 @@ def _determine_requirements( return result def _find_best_version_for_package( - self, name, required_version=None, allow_prereleases=False, source=None + self, name, required_version=None, allow_prereleases=False ): # type: (...) -> Tuple[str, str] from poetry.version.version_selector import VersionSelector selector = VersionSelector(self._get_pool()) package = selector.find_best_candidate( - name, required_version, allow_prereleases=allow_prereleases, source=source + name, required_version, allow_prereleases=allow_prereleases ) if not package: diff --git a/poetry/locations.py b/poetry/locations.py index 003950d500d..17fb4d42a99 100644 --- a/poetry/locations.py +++ b/poetry/locations.py @@ -1,9 +1,6 @@ -from .utils._compat import Path from .utils.appdirs import user_cache_dir from .utils.appdirs import user_config_dir CACHE_DIR = user_cache_dir("pypoetry") CONFIG_DIR = user_config_dir("pypoetry") - -REPOSITORY_CACHE_DIR = Path(CACHE_DIR) / "cache" / "repositories" diff --git a/poetry/repositories/legacy_repository.py b/poetry/repositories/legacy_repository.py index c2eac509ae8..4bb0496eb29 100644 --- a/poetry/repositories/legacy_repository.py +++ b/poetry/repositories/legacy_repository.py @@ -15,7 +15,7 @@ import poetry.packages -from poetry.locations import REPOSITORY_CACHE_DIR +from poetry.locations import CACHE_DIR from poetry.packages import Package from poetry.packages import dependency_from_pep_508 from poetry.packages.utils.link import Link @@ -174,7 +174,7 @@ def __init__( self._client_cert = client_cert self._cert = cert self._inspector = Inspector() - self._cache_dir = REPOSITORY_CACHE_DIR / name + self._cache_dir = Path(CACHE_DIR) / "cache" / "repositories" / name self._cache = CacheManager( { "default": "releases", diff --git a/poetry/repositories/pypi_repository.py b/poetry/repositories/pypi_repository.py index 0f1ac5208ed..767a7353b3c 100644 --- a/poetry/repositories/pypi_repository.py +++ b/poetry/repositories/pypi_repository.py @@ -15,7 +15,7 @@ from requests import session from requests.exceptions import TooManyRedirects -from poetry.locations import REPOSITORY_CACHE_DIR +from poetry.locations import CACHE_DIR from poetry.packages import Package from poetry.packages import dependency_from_pep_508 from poetry.packages.utils.link import Link @@ -57,7 +57,7 @@ def __init__(self, url="https://pypi.org/", disable_cache=False, fallback=True): self._disable_cache = disable_cache self._fallback = fallback - release_cache_dir = REPOSITORY_CACHE_DIR / "pypi" + release_cache_dir = Path(CACHE_DIR) / "cache" / "repositories" / "pypi" self._cache = CacheManager( { "default": "releases", diff --git a/poetry/version/version_selector.py b/poetry/version/version_selector.py index 2077e322699..8c71daec87b 100644 --- a/poetry/version/version_selector.py +++ b/poetry/version/version_selector.py @@ -15,7 +15,6 @@ def find_best_candidate( package_name, # type: str target_package_version=None, # type: Union[str, None] allow_prereleases=False, # type: bool - source=None, # type: str ): # type: (...) -> Union[Package, bool] """ Given a package name and optional version, @@ -27,7 +26,7 @@ def find_best_candidate( constraint = parse_constraint("*") candidates = self._pool.find_packages( - package_name, constraint, allow_prereleases=True, repository=source + package_name, constraint, allow_prereleases=True ) only_prereleases = all([c.version.is_prerelease() for c in candidates]) diff --git a/tests/console/commands/test_add.py b/tests/console/commands/test_add.py index 8e7f4a870c8..6a64ba7e4eb 100644 --- a/tests/console/commands/test_add.py +++ b/tests/console/commands/test_add.py @@ -4,8 +4,6 @@ from cleo.testers import CommandTester -from poetry.repositories.legacy_repository import LegacyRepository -from poetry.semver import Version from poetry.utils._compat import Path from tests.helpers import get_dependency from tests.helpers import get_package @@ -636,72 +634,6 @@ def test_add_constraint_with_platform(app, repo, installer): } -def test_add_constraint_with_source(app, poetry, installer): - repo = LegacyRepository(name="my-index", url="https://my-index.fake") - repo.add_package(get_package("cachy", "0.2.0")) - repo._cache.store("matches").put("cachy:0.2.0", [Version.parse("0.2.0")], 5) - - poetry.pool.add_repository(repo) - - command = app.find("add") - tester = CommandTester(command) - - tester.execute("cachy=0.2.0 --source my-index") - - expected = """\ - -Updating dependencies -Resolving dependencies... - -Writing lock file - - -Package operations: 1 install, 0 updates, 0 removals - - - Installing cachy (0.2.0) -""" - - assert expected == tester.io.fetch_output() - - assert len(installer.installs) == 1 - - content = app.poetry.file.read()["tool"]["poetry"] - - assert "cachy" in content["dependencies"] - assert content["dependencies"]["cachy"] == { - "version": "0.2.0", - "source": "my-index", - } - - -def test_add_constraint_with_source_that_does_not_exist(app): - command = app.find("add") - tester = CommandTester(command) - - with pytest.raises(ValueError) as e: - tester.execute("foo --source i-dont-exist") - - assert 'Repository "i-dont-exist" does not exist.' == str(e.value) - - -def test_add_constraint_not_found_with_source(app, poetry, mocker): - repo = LegacyRepository(name="my-index", url="https://my-index.fake") - mocker.patch.object(repo, "find_packages", return_value=[]) - - poetry.pool.add_repository(repo) - - pypi = poetry.pool.repositories[0] - pypi.add_package(get_package("cachy", "0.2.0")) - - command = app.find("add") - tester = CommandTester(command) - - with pytest.raises(ValueError) as e: - tester.execute("cachy --source my-index") - - assert "Could not find a matching version of package cachy" == str(e.value) - - def test_add_to_section_that_does_no_exist_yet(app, repo, installer): command = app.find("add") tester = CommandTester(command) diff --git a/tests/console/commands/test_cache.py b/tests/console/commands/test_cache.py deleted file mode 100644 index 8a22eee7f1b..00000000000 --- a/tests/console/commands/test_cache.py +++ /dev/null @@ -1,60 +0,0 @@ -import uuid - -import pytest - -from cleo.testers import CommandTester - - -@pytest.fixture -def repository_cache_dir(monkeypatch, tmpdir): - import poetry.locations - from poetry.utils._compat import Path - - path = Path(str(tmpdir)) - monkeypatch.setattr(poetry.locations, "REPOSITORY_CACHE_DIR", path) - return path - - -@pytest.fixture -def repository_one(): - return "01_{}".format(uuid.uuid4()) - - -@pytest.fixture -def repository_two(): - return "02_{}".format(uuid.uuid4()) - - -@pytest.fixture -def mock_caches(repository_cache_dir, repository_one, repository_two): - (repository_cache_dir / repository_one).mkdir() - (repository_cache_dir / repository_two).mkdir() - - -def test_cache_list(app, mock_caches, repository_one, repository_two): - command = app.find("cache list") - tester = CommandTester(command) - - tester.execute() - - expected = """\ -{} -{} -""".format( - repository_one, repository_two - ) - - assert expected == tester.io.fetch_output() - - -def test_cache_list_empty(app, repository_cache_dir): - command = app.find("cache list") - tester = CommandTester(command) - - tester.execute() - - expected = """\ -No caches found -""" - - assert expected == tester.io.fetch_output() From 94152a1e0181d6205a362606d8ce9c170cfcfe6d Mon Sep 17 00:00:00 2001 From: stephsamson Date: Fri, 10 Jan 2020 13:22:34 +0100 Subject: [PATCH 07/80] Add a subsection on documenting the --no-root option in the Basic Usage section and also in the CLI. Resolves #1848. --- docs/docs/basic-usage.md | 9 +++++++++ poetry/console/commands/install.py | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/docs/docs/basic-usage.md b/docs/docs/basic-usage.md index dad1ef9b9b4..7a8fef02695 100644 --- a/docs/docs/basic-usage.md +++ b/docs/docs/basic-usage.md @@ -134,6 +134,15 @@ the dependencies installed are still working even if your dependencies released For libraries it is not necessary to commit the lock file. +### Installing dependencies only + +The current project is installed in [editable](https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs) mode by default. + +If you want to install the dependencies only, run the `install` command with the `--no-root` flag: + +```bash +poetry install --no-root +``` ## Updating dependencies to their latest versions diff --git a/poetry/console/commands/install.py b/poetry/console/commands/install.py index fabffec4a24..f69e4e5873c 100644 --- a/poetry/console/commands/install.py +++ b/poetry/console/commands/install.py @@ -34,6 +34,12 @@ class InstallCommand(EnvCommand): exist it will look for pyproject.toml and do the same. poetry install + +By default, the above command will also install the current project. To install only the +dependencies and not including the current project, run the command with the +--no-root option like below: + + poetry install --no-root """ _loggers = ["poetry.repositories.pypi_repository"] From 9e18519a26e50538e5b2f2dc446e49ef72a8de15 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Thu, 26 Mar 2020 19:19:39 +0100 Subject: [PATCH 08/80] Add contact links when choosing issue template (#2226) Configuring the template chooser to include discord community server. --- .github/ISSUE_TEMPLATE/config.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000000..82577fb2a8a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,7 @@ +# Ref: https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository#configuring-the-template-chooser +blank_issues_enabled: true +contact_links: +- name: '💬 Discord Server' + url: https://discordapp.com/invite/awxPgve + about: | + Chat with the community, ask questions and learn about best practices. From 1d413c0de47fefc54766e5fecfe6cdc1a65da947 Mon Sep 17 00:00:00 2001 From: Harun Yasar Date: Thu, 26 Mar 2020 19:36:59 +0000 Subject: [PATCH 09/80] Add a new line after path info written on the screen #2195 (#2196) --- poetry/console/commands/env/info.py | 2 +- tests/console/commands/env/test_info.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/poetry/console/commands/env/info.py b/poetry/console/commands/env/info.py index d66baa56408..301d88f9520 100644 --- a/poetry/console/commands/env/info.py +++ b/poetry/console/commands/env/info.py @@ -19,7 +19,7 @@ def handle(self): if not env.is_venv(): return 1 - self.write(str(env.path)) + self.line(str(env.path)) return diff --git a/tests/console/commands/env/test_info.py b/tests/console/commands/env/test_info.py index 77001ead3c3..775680f13dc 100644 --- a/tests/console/commands/env/test_info.py +++ b/tests/console/commands/env/test_info.py @@ -48,4 +48,4 @@ def test_env_info_displays_path_only(app): expected = str(Path("/prefix")) - assert expected == tester.io.fetch_output() + assert expected + "\n" == tester.io.fetch_output() From 2f8b67e7a8cc778820554c550e8ff707f42077dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 27 Mar 2020 20:10:20 +0100 Subject: [PATCH 10/80] Update the installer script to handle future releases (#2233) --- get-poetry.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/get-poetry.py b/get-poetry.py index 7a2b18d3997..b8085ca3c7c 100644 --- a/get-poetry.py +++ b/get-poetry.py @@ -204,8 +204,12 @@ def expanduser(path): import os lib = os.path.normpath(os.path.join(os.path.realpath(__file__), "../..", "lib")) - +vendors = os.path.join(lib, "poetry", "_vendor") +current_vendors = os.path.join( + vendors, "py{}".format(".".join(str(v) for v in sys.version_info[:2])) +) sys.path.insert(0, lib) +sys.path.insert(0, current_vendors) if __name__ == "__main__": from poetry.console import main From 8e5d46f1ec2c873640a701ab37214d2a768e183e Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Sun, 29 Mar 2020 18:52:55 +0200 Subject: [PATCH 11/80] Add documentation for use of proprietary licence (#2231) Resolves: #2198 --- docs/docs/pyproject.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/docs/pyproject.md b/docs/docs/pyproject.md index b6bcbe318f1..cde6c463d3e 100644 --- a/docs/docs/pyproject.md +++ b/docs/docs/pyproject.md @@ -40,6 +40,10 @@ The recommended notation for the most common licenses is (alphabetical): Optional, but it is highly recommended to supply this. More identifiers are listed at the [SPDX Open Source License Registry](https://www.spdx.org/licenses/). +!!!note + + If your project is proprietary and does not use a specific licence, you can set this value as `Proprietary`. + ## authors The authors of the package. **Required** From fb4628c3612beb942381deb024d0dc6924b7ee30 Mon Sep 17 00:00:00 2001 From: bynare <1852531+bynare@users.noreply.github.com> Date: Mon, 30 Mar 2020 05:53:19 +1300 Subject: [PATCH 12/80] clarify wildcard dependency specification (#2229) --- docs/docs/dependency-specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/dependency-specification.md b/docs/docs/dependency-specification.md index 8ae0044f8b6..f826332eb71 100644 --- a/docs/docs/dependency-specification.md +++ b/docs/docs/dependency-specification.md @@ -42,7 +42,7 @@ If you only specify a major version, then minor- and patch-level changes are all ### Wildcard requirements -**Wildcard requirements** allow for any version where the wildcard is positioned. +**Wildcard requirements** allow for the latest (dependency dependent) version where the wildcard is positioned. `*`, `1.*` and `1.2.*` are examples of wildcard requirements. From 7555d6dcf26bc618e9885aa249fc2dedc08ae9e7 Mon Sep 17 00:00:00 2001 From: jtrakk <43392409+jtrakk@users.noreply.github.com> Date: Sun, 29 Mar 2020 16:14:04 -0700 Subject: [PATCH 13/80] Rename secondary "tests" package in doc example (#2122) If multiple distributions have `tests` as a top-level package, they'll conflict whenever both are installed. (Examples [here]((https://github.com/python-poetry/poetry/issues/1905) and [here](https://github.com/NixOS/nixpkgs/issues/81482). Two common alternative strategies are: 1. not distributing tests (as [here](https://github.com/pypa/sampleproject)), or 2. placing tests in a subdirectory of the main package, rather than adjacent (as [here](http://blog.habnab.it/blog/2013/07/21/python-packages-and-you/) and [here](http://as.ynchrono.us/2007/12/filesystem-structure-of-python-project_21.html)). Each of these strategies will avoid this issue. Users may fall into this trap because of the [package documentation](https://python-poetry.org/docs/pyproject/#packages) page, which gives an example: ``` packages = [ { include = "my_package" }, { include = "tests", format = "sdist" }, ] ``` Having two top-level packages in a distribution is relatively unusual, but does have some use cases. Using `"tests"` as a top-level package name in the example is likely to lead to conflicts, however. The alternate package in the documentation example could have a unique name like `"my_other_package"`, which would reduce the likelihood of this kind of overlap. --- docs/docs/pyproject.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/pyproject.md b/docs/docs/pyproject.md index cde6c463d3e..a3c75526d7a 100644 --- a/docs/docs/pyproject.md +++ b/docs/docs/pyproject.md @@ -131,11 +131,11 @@ it by using `format`: # ... packages = [ { include = "my_package" }, - { include = "tests", format = "sdist" }, + { include = "my_other_package", format = "sdist" }, ] ``` -From now on, only the `sdist` build archive will include the `tests` package. +From now on, only the `sdist` build archive will include the `my_other_package` package. !!!note From 1bcee9200fc48daa97af857c8da36bca33d465fb Mon Sep 17 00:00:00 2001 From: chenrui Date: Sun, 29 Mar 2020 19:24:58 -0400 Subject: [PATCH 14/80] Add fish shell tab completion for mac (#1830) * Add fish shell tab completion for mac * Remove macOS ref as brew should work linux as well --- README.md | 7 +++++-- docs/docs/index.md | 5 ++++- .../python3.7/site-packages/cleo-0.7.6.dist-info/METADATA | 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ea0df8ded25..9339381d5f7 100644 --- a/README.md +++ b/README.md @@ -79,16 +79,19 @@ See `poetry help completions` for full details, but the gist is as simple as usi # Bash poetry completions bash > /etc/bash_completion.d/poetry.bash-completion -# Bash (macOS/Homebrew) +# Bash (Homebrew) poetry completions bash > $(brew --prefix)/etc/bash_completion.d/poetry.bash-completion # Fish poetry completions fish > ~/.config/fish/completions/poetry.fish +# Fish (Homebrew) +poetry completions fish > $(brew --prefix)/share/fish/vendor_completions.d/poetry.fish + # Zsh poetry completions zsh > ~/.zfunc/_poetry -# Zsh (macOS/Homebrew) +# Zsh (Homebrew) poetry completions zsh > $(brew --prefix)/share/zsh/site-functions/_poetry ``` diff --git a/docs/docs/index.md b/docs/docs/index.md index e768cc19124..003ba210533 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -161,12 +161,15 @@ See `poetry help completions` for full details, but the gist is as simple as usi # Bash poetry completions bash > /etc/bash_completion.d/poetry.bash-completion -# Bash (macOS/Homebrew) +# Bash (Homebrew) poetry completions bash > $(brew --prefix)/etc/bash_completion.d/poetry.bash-completion # Fish poetry completions fish > ~/.config/fish/completions/poetry.fish +# Fish (Homebrew) +poetry completions fish > $(brew --prefix)/share/fish/vendor_completions.d/poetry.fish + # Zsh poetry completions zsh > ~/.zfunc/_poetry diff --git a/tests/repositories/fixtures/installed/lib/python3.7/site-packages/cleo-0.7.6.dist-info/METADATA b/tests/repositories/fixtures/installed/lib/python3.7/site-packages/cleo-0.7.6.dist-info/METADATA index 2a4c1439cf2..261c036ecda 100644 --- a/tests/repositories/fixtures/installed/lib/python3.7/site-packages/cleo-0.7.6.dist-info/METADATA +++ b/tests/repositories/fixtures/installed/lib/python3.7/site-packages/cleo-0.7.6.dist-info/METADATA @@ -521,3 +521,5 @@ replacing ``[program]`` with the command you use to run your application: # FISH [program] completions fish > ~/.config/fish/completions/[program].fish + # FISH - Mac OSX (with Homebrew "fish") + [program] completions fish > $(brew --prefix)/share/fish/vendor_completions.d/[program].fish From 9e1324e1fbf4d42141dce959d877571d424ee8aa Mon Sep 17 00:00:00 2001 From: finswimmer Date: Mon, 30 Mar 2020 01:28:05 +0200 Subject: [PATCH 15/80] fix: Add information about valid export formats to help page (#1653) Co-authored-by: finswimmer77@gmail.com --- poetry/console/commands/export.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/poetry/console/commands/export.py b/poetry/console/commands/export.py index 37cfc1394e8..5e2d450e011 100644 --- a/poetry/console/commands/export.py +++ b/poetry/console/commands/export.py @@ -11,7 +11,12 @@ class ExportCommand(Command): description = "Exports the lock file to alternative formats." options = [ - option("format", "f", "Format to export to.", flag=False), + option( + "format", + "f", + "Format to export to. Currently, only requirements.txt is supported.", + flag=False, + ), option("output", "o", "The name of the output file.", flag=False), option("without-hashes", None, "Exclude hashes from the exported file."), option("dev", None, "Include development dependencies."), From 655f58252d4cc6a77def7d890c43288b1534664e Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Wed, 1 Apr 2020 14:14:08 +0100 Subject: [PATCH 16/80] package: allow url dependencies to be optional --- poetry/packages/package.py | 4 +++- tests/packages/test_package.py | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/poetry/packages/package.py b/poetry/packages/package.py index cb28ef70c7f..4940d6f027a 100644 --- a/poetry/packages/package.py +++ b/poetry/packages/package.py @@ -333,7 +333,9 @@ def add_dependency( develop=constraint.get("develop", True), ) elif "url" in constraint: - dependency = URLDependency(name, constraint["url"], category=category) + dependency = URLDependency( + name, constraint["url"], category=category, optional=optional + ) else: version = constraint["version"] diff --git a/tests/packages/test_package.py b/tests/packages/test_package.py index 510f542f222..54221eca4c8 100644 --- a/tests/packages/test_package.py +++ b/tests/packages/test_package.py @@ -49,3 +49,20 @@ def test_package_add_dependency_vcs_category_default_main(): "poetry", constraint={"git": "https://github.com/python-poetry/poetry.git"} ) assert dependency.category == "main" + + +@pytest.mark.parametrize("category", ["main", "dev"]) +@pytest.mark.parametrize("optional", [True, False]) +def test_package_url_category_optional(category, optional): + package = Package("foo", "0.1.0") + + dependency = package.add_dependency( + "poetry", + constraint={ + "url": "https://github.com/python-poetry/poetry/releases/download/1.0.5/poetry-1.0.5-linux.tar.gz", + "optional": optional, + }, + category=category, + ) + assert dependency.category == category + assert dependency.is_optional() == optional From bf331a54fa8823d51763ffea1fa0791ced20f0d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Thu, 2 Apr 2020 18:43:39 +0200 Subject: [PATCH 17/80] Speed up tests (#2257) When testing the behavior for git packages with a setup.py file, the Provider class would create a temporary virtual environment and execute python setup.py egg_info. Both actions are costly and take time. By mocking them, we can reduce the tests time by a factor of 4 or 5. --- .gitignore | 1 - poetry/puzzle/provider.py | 11 ++++++---- pyproject.toml | 20 +++++++++++++++++++ tests/conftest.py | 5 +++++ .../demo/demo/demo.egg-info/PKG-INFO | 12 +++++++++++ .../demo/demo/demo.egg-info/SOURCES.txt | 7 +++++++ .../demo/demo.egg-info/dependency_links.txt | 0 .../demo/demo/demo.egg-info/requires.txt | 7 +++++++ .../demo/demo/demo.egg-info/top_level.txt | 1 + .../no-dependencies/demo.egg-info/PKG-INFO | 10 ++++++++++ .../no-dependencies/demo.egg-info/SOURCES.txt | 6 ++++++ .../demo.egg-info/dependency_links.txt | 0 .../demo.egg-info/top_level.txt | 1 + .../non-canonical-name/Demo.egg-info/PKG-INFO | 12 +++++++++++ .../Demo.egg-info/SOURCES.txt | 7 +++++++ .../Demo.egg-info/dependency_links.txt | 0 .../Demo.egg-info/requires.txt | 7 +++++++ .../Demo.egg-info/top_level.txt | 1 + .../my_package.egg-info/PKG-INFO | 10 ++++++++++ .../my_package.egg-info/SOURCES.txt | 7 +++++++ .../my_package.egg-info/dependency_links.txt | 0 .../my_package.egg-info/requires.txt | 2 ++ .../my_package.egg-info/top_level.txt | 1 + .../fixtures/excluded_subpackage/README.rst | 2 +- tests/puzzle/test_provider.py | 2 +- .../py3.7/attrs-19.3.0.dist-info/METADATA | 2 -- 26 files changed, 125 insertions(+), 9 deletions(-) create mode 100755 tests/fixtures/git/github.com/demo/demo/demo.egg-info/PKG-INFO create mode 100755 tests/fixtures/git/github.com/demo/demo/demo.egg-info/SOURCES.txt create mode 100755 tests/fixtures/git/github.com/demo/demo/demo.egg-info/dependency_links.txt create mode 100755 tests/fixtures/git/github.com/demo/demo/demo.egg-info/requires.txt create mode 100755 tests/fixtures/git/github.com/demo/demo/demo.egg-info/top_level.txt create mode 100644 tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/PKG-INFO create mode 100644 tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/SOURCES.txt create mode 100644 tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/dependency_links.txt create mode 100644 tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/top_level.txt create mode 100644 tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/PKG-INFO create mode 100644 tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/SOURCES.txt create mode 100644 tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/dependency_links.txt create mode 100644 tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/requires.txt create mode 100644 tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/top_level.txt create mode 100644 tests/fixtures/project_with_setup/my_package.egg-info/PKG-INFO create mode 100644 tests/fixtures/project_with_setup/my_package.egg-info/SOURCES.txt create mode 100644 tests/fixtures/project_with_setup/my_package.egg-info/dependency_links.txt create mode 100644 tests/fixtures/project_with_setup/my_package.egg-info/requires.txt create mode 100644 tests/fixtures/project_with_setup/my_package.egg-info/top_level.txt diff --git a/.gitignore b/.gitignore index c2d2a72090e..fcbd92e97a3 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ *.egg !/tests/**/*.egg /*.egg-info -/tests/fixtures/**/*.egg-info /dist/* build _build diff --git a/poetry/puzzle/provider.py b/poetry/puzzle/provider.py index 989a592912b..4888b9828b1 100644 --- a/poetry/puzzle/provider.py +++ b/poetry/puzzle/provider.py @@ -326,10 +326,7 @@ def get_package_from_directory( os.chdir(str(directory)) try: - with temporary_directory() as tmp_dir: - EnvManager.build_venv(tmp_dir) - venv = VirtualEnv(Path(tmp_dir), Path(tmp_dir)) - venv.run("python", "setup.py", "egg_info") + cls._execute_setup() except EnvCommandError: result = SetupReader.read_from_directory(directory) if not result["name"]: @@ -817,3 +814,9 @@ def progress(self): yield self._in_progress = False + + def _execute_setup(self): + with temporary_directory() as tmp_dir: + EnvManager.build_venv(tmp_dir) + venv = VirtualEnv(Path(tmp_dir), Path(tmp_dir)) + venv.run("python", "setup.py", "egg_info") diff --git a/pyproject.toml b/pyproject.toml index 938b89fe422..519fb373ca6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -116,3 +116,23 @@ known_third_party = [ "shellingham", "tomlkit", ] + + +[tool.black] +line-length = 88 +include = '\.pyi?$' +exclude = ''' +/( + \.eggs + | \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | _build + | buck-out + | build + | dist + | tests/.*/setup.py +)/ +''' diff --git a/tests/conftest.py b/tests/conftest.py index d5ff7f488c9..8386ad35f57 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -74,6 +74,11 @@ def download_mock(mocker): mocker.patch("poetry.utils.inspector.Inspector.download", new=mock_download) +@pytest.fixture(autouse=True) +def execute_setup_mock(mocker): + mocker.patch("poetry.puzzle.provider.Provider._execute_setup") + + @pytest.fixture def environ(): original_environ = dict(os.environ) diff --git a/tests/fixtures/git/github.com/demo/demo/demo.egg-info/PKG-INFO b/tests/fixtures/git/github.com/demo/demo/demo.egg-info/PKG-INFO new file mode 100755 index 00000000000..7f543c49cb3 --- /dev/null +++ b/tests/fixtures/git/github.com/demo/demo/demo.egg-info/PKG-INFO @@ -0,0 +1,12 @@ +Metadata-Version: 2.1 +Name: demo +Version: 0.1.2 +Summary: Demo project. +Home-page: https://github.com/demo/demo +Author: Sébastien Eustace +Author-email: sebastien@eustace.io +License: MIT +Description: UNKNOWN +Platform: UNKNOWN +Provides-Extra: bar +Provides-Extra: foo diff --git a/tests/fixtures/git/github.com/demo/demo/demo.egg-info/SOURCES.txt b/tests/fixtures/git/github.com/demo/demo/demo.egg-info/SOURCES.txt new file mode 100755 index 00000000000..6eb8a3ef3e3 --- /dev/null +++ b/tests/fixtures/git/github.com/demo/demo/demo.egg-info/SOURCES.txt @@ -0,0 +1,7 @@ +setup.py +demo/__init__.py +demo.egg-info/PKG-INFO +demo.egg-info/SOURCES.txt +demo.egg-info/dependency_links.txt +demo.egg-info/requires.txt +demo.egg-info/top_level.txt diff --git a/tests/fixtures/git/github.com/demo/demo/demo.egg-info/dependency_links.txt b/tests/fixtures/git/github.com/demo/demo/demo.egg-info/dependency_links.txt new file mode 100755 index 00000000000..e69de29bb2d diff --git a/tests/fixtures/git/github.com/demo/demo/demo.egg-info/requires.txt b/tests/fixtures/git/github.com/demo/demo/demo.egg-info/requires.txt new file mode 100755 index 00000000000..e05a65d3c93 --- /dev/null +++ b/tests/fixtures/git/github.com/demo/demo/demo.egg-info/requires.txt @@ -0,0 +1,7 @@ +pendulum>=1.4.4 + +[bar] +tomlkit + +[foo] +cleo diff --git a/tests/fixtures/git/github.com/demo/demo/demo.egg-info/top_level.txt b/tests/fixtures/git/github.com/demo/demo/demo.egg-info/top_level.txt new file mode 100755 index 00000000000..1549b67ca59 --- /dev/null +++ b/tests/fixtures/git/github.com/demo/demo/demo.egg-info/top_level.txt @@ -0,0 +1 @@ +demo diff --git a/tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/PKG-INFO b/tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/PKG-INFO new file mode 100644 index 00000000000..7ba97897a10 --- /dev/null +++ b/tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/PKG-INFO @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: demo +Version: 0.1.2 +Summary: Demo project. +Home-page: https://github.com/demo/demo +Author: Sébastien Eustace +Author-email: sebastien@eustace.io +License: MIT +Description: UNKNOWN +Platform: UNKNOWN diff --git a/tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/SOURCES.txt b/tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/SOURCES.txt new file mode 100644 index 00000000000..e19f4a4eb57 --- /dev/null +++ b/tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/SOURCES.txt @@ -0,0 +1,6 @@ +setup.py +demo/__init__.py +demo.egg-info/PKG-INFO +demo.egg-info/SOURCES.txt +demo.egg-info/dependency_links.txt +demo.egg-info/top_level.txt diff --git a/tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/dependency_links.txt b/tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/dependency_links.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/top_level.txt b/tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/top_level.txt new file mode 100644 index 00000000000..1549b67ca59 --- /dev/null +++ b/tests/fixtures/git/github.com/demo/no-dependencies/demo.egg-info/top_level.txt @@ -0,0 +1 @@ +demo diff --git a/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/PKG-INFO b/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/PKG-INFO new file mode 100644 index 00000000000..996589ec257 --- /dev/null +++ b/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/PKG-INFO @@ -0,0 +1,12 @@ +Metadata-Version: 2.1 +Name: Demo +Version: 0.1.2 +Summary: Demo project. +Home-page: https://github.com/demo/demo +Author: Sébastien Eustace +Author-email: sebastien@eustace.io +License: MIT +Description: UNKNOWN +Platform: UNKNOWN +Provides-Extra: foo +Provides-Extra: bar diff --git a/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/SOURCES.txt b/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/SOURCES.txt new file mode 100644 index 00000000000..8134b008da5 --- /dev/null +++ b/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/SOURCES.txt @@ -0,0 +1,7 @@ +setup.py +Demo.egg-info/PKG-INFO +Demo.egg-info/SOURCES.txt +Demo.egg-info/dependency_links.txt +Demo.egg-info/requires.txt +Demo.egg-info/top_level.txt +demo/__init__.py diff --git a/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/dependency_links.txt b/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/dependency_links.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/requires.txt b/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/requires.txt new file mode 100644 index 00000000000..e05a65d3c93 --- /dev/null +++ b/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/requires.txt @@ -0,0 +1,7 @@ +pendulum>=1.4.4 + +[bar] +tomlkit + +[foo] +cleo diff --git a/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/top_level.txt b/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/top_level.txt new file mode 100644 index 00000000000..1549b67ca59 --- /dev/null +++ b/tests/fixtures/git/github.com/demo/non-canonical-name/Demo.egg-info/top_level.txt @@ -0,0 +1 @@ +demo diff --git a/tests/fixtures/project_with_setup/my_package.egg-info/PKG-INFO b/tests/fixtures/project_with_setup/my_package.egg-info/PKG-INFO new file mode 100644 index 00000000000..71ba645751f --- /dev/null +++ b/tests/fixtures/project_with_setup/my_package.egg-info/PKG-INFO @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: my-package +Version: 0.1.2 +Summary: Demo project. +Home-page: https://github.com/demo/demo +Author: Sébastien Eustace +Author-email: sebastien@eustace.io +License: MIT +Description: UNKNOWN +Platform: UNKNOWN diff --git a/tests/fixtures/project_with_setup/my_package.egg-info/SOURCES.txt b/tests/fixtures/project_with_setup/my_package.egg-info/SOURCES.txt new file mode 100644 index 00000000000..f5255dc9dad --- /dev/null +++ b/tests/fixtures/project_with_setup/my_package.egg-info/SOURCES.txt @@ -0,0 +1,7 @@ +setup.py +my_package/__init__.py +my_package.egg-info/PKG-INFO +my_package.egg-info/SOURCES.txt +my_package.egg-info/dependency_links.txt +my_package.egg-info/requires.txt +my_package.egg-info/top_level.txt diff --git a/tests/fixtures/project_with_setup/my_package.egg-info/dependency_links.txt b/tests/fixtures/project_with_setup/my_package.egg-info/dependency_links.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/fixtures/project_with_setup/my_package.egg-info/requires.txt b/tests/fixtures/project_with_setup/my_package.egg-info/requires.txt new file mode 100644 index 00000000000..eeb0a4815ce --- /dev/null +++ b/tests/fixtures/project_with_setup/my_package.egg-info/requires.txt @@ -0,0 +1,2 @@ +pendulum>=1.4.4 +cachy[msgpack]>=0.2.0 diff --git a/tests/fixtures/project_with_setup/my_package.egg-info/top_level.txt b/tests/fixtures/project_with_setup/my_package.egg-info/top_level.txt new file mode 100644 index 00000000000..5d04b540bc9 --- /dev/null +++ b/tests/fixtures/project_with_setup/my_package.egg-info/top_level.txt @@ -0,0 +1 @@ +my_package diff --git a/tests/masonry/builders/fixtures/excluded_subpackage/README.rst b/tests/masonry/builders/fixtures/excluded_subpackage/README.rst index b00640203c5..f7fe15470f9 100644 --- a/tests/masonry/builders/fixtures/excluded_subpackage/README.rst +++ b/tests/masonry/builders/fixtures/excluded_subpackage/README.rst @@ -1,2 +1,2 @@ My Package -========== \ No newline at end of file +========== diff --git a/tests/puzzle/test_provider.py b/tests/puzzle/test_provider.py index d3bcba65688..4d4463b3b73 100644 --- a/tests/puzzle/test_provider.py +++ b/tests/puzzle/test_provider.py @@ -118,7 +118,7 @@ def test_search_for_vcs_read_setup_with_extras(provider, mocker): def test_search_for_vcs_read_setup_raises_error_if_no_version(provider, mocker): mocker.patch( - "poetry.utils.env.VirtualEnv.run", + "poetry.puzzle.provider.Provider._execute_setup", side_effect=EnvCommandError(CalledProcessError(1, "python", output="")), ) diff --git a/tests/repositories/fixtures/installed/vendor/py3.7/attrs-19.3.0.dist-info/METADATA b/tests/repositories/fixtures/installed/vendor/py3.7/attrs-19.3.0.dist-info/METADATA index a1064151030..6c8d9f7d6eb 100644 --- a/tests/repositories/fixtures/installed/vendor/py3.7/attrs-19.3.0.dist-info/METADATA +++ b/tests/repositories/fixtures/installed/vendor/py3.7/attrs-19.3.0.dist-info/METADATA @@ -225,5 +225,3 @@ A full list of contributors can be found in `GitHub's overview `_ and aspires to fix some of it clunkiness and unfortunate decisions. Both were inspired by Twisted’s `FancyEqMixin `_ but both are implemented using class decorators because `subclassing is bad for you `_, m’kay? - - From 511d753c8115c39e4d32227ae2dbeeaf3ada01ee Mon Sep 17 00:00:00 2001 From: Xavier Francisco Date: Sun, 5 Apr 2020 23:36:16 +0100 Subject: [PATCH 18/80] Ensure list access is performed after the length check (#2265) --- poetry/masonry/utils/package_include.py | 3 +-- tests/masonry/utils/test_package_include.py | 9 +++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/poetry/masonry/utils/package_include.py b/poetry/masonry/utils/package_include.py index 42ecbbc1fd0..512c6c48f63 100644 --- a/poetry/masonry/utils/package_include.py +++ b/poetry/masonry/utils/package_include.py @@ -34,13 +34,12 @@ def refresh(self): # type: () -> PackageInclude return self.check_elements() def check_elements(self): # type: () -> PackageInclude - root = self._elements[0] - if not self._elements: raise ValueError( "{} does not contain any element".format(self._base / self._include) ) + root = self._elements[0] if len(self._elements) > 1: # Probably glob self._is_package = True diff --git a/tests/masonry/utils/test_package_include.py b/tests/masonry/utils/test_package_include.py index a79ff96f03c..36b5985800b 100644 --- a/tests/masonry/utils/test_package_include.py +++ b/tests/masonry/utils/test_package_include.py @@ -41,3 +41,12 @@ def test_package_include_with_no_python_files_in_dir(): PackageInclude(base=with_includes, include="not_a_python_pkg") assert str(e.value) == "not_a_python_pkg is not a package." + + +def test_package_include_with_non_existent_directory(): + with pytest.raises(ValueError) as e: + PackageInclude(base=with_includes, include="not_a_dir") + + err_str = str(with_includes / "not_a_dir") + " does not contain any element" + + assert str(e.value) == err_str From f98b6d224c801fabb22fcb91820fc291603b4992 Mon Sep 17 00:00:00 2001 From: Eyal Levin Date: Mon, 6 Apr 2020 16:14:39 +0300 Subject: [PATCH 19/80] doc: update "An" to "A" (#2274) 'An' should come before a vowel sound. Reference: https://english.stackexchange.com/a/164/198117 --- poetry/console/commands/init.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/poetry/console/commands/init.py b/poetry/console/commands/init.py index 825f8c68e2a..b74d191fa5c 100644 --- a/poetry/console/commands/init.py +++ b/poetry/console/commands/init.py @@ -151,7 +151,7 @@ def handle(self): " - A git url with a revision (git+https://github.com/python-poetry/poetry.git#develop)\n" " - A file path (../my-package/my-package.whl)\n" " - A directory (../my-package/)\n" - " - An url (https://example.com/packages/my-package-0.1.0.tar.gz)\n" + " - A url (https://example.com/packages/my-package-0.1.0.tar.gz)\n" ) help_displayed = False if self.confirm(question, True): From f76ceee06b9d96d6ce7a9c7d9bf5e24e27df8917 Mon Sep 17 00:00:00 2001 From: Daniel <61800298+ffe4@users.noreply.github.com> Date: Mon, 6 Apr 2020 15:16:37 +0200 Subject: [PATCH 20/80] doc: fix typo in basic-usage.md (#2273) --- docs/docs/basic-usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/basic-usage.md b/docs/docs/basic-usage.md index 7a8fef02695..48fc8f480e7 100644 --- a/docs/docs/basic-usage.md +++ b/docs/docs/basic-usage.md @@ -77,7 +77,7 @@ how versions relate to each other, and on the different ways you can specify dep **How does Poetry download the right files?** - When you specify a dependency in `pyproject.toml`, Poetry first take the name of the package + When you specify a dependency in `pyproject.toml`, Poetry first takes the name of the package that you have requested and searches for it in any repository you have registered using the `repositories` key. If you have not registered any extra repositories, or it does not find a package with that name in the repositories you have specified, it falls back on PyPI. From 518b6993f356a18cb032bacce37078a276d41d50 Mon Sep 17 00:00:00 2001 From: finswimmer Date: Mon, 6 Apr 2020 17:43:43 +0200 Subject: [PATCH 21/80] utils: fallback to env var when detecting shell (#2147) Resolves: #2115 --- poetry/utils/shell.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/poetry/utils/shell.py b/poetry/utils/shell.py index e883c80fc6e..b18bda0dd20 100644 --- a/poetry/utils/shell.py +++ b/poetry/utils/shell.py @@ -9,6 +9,7 @@ from shellingham import detect_shell from ._compat import WINDOWS +from ._compat import Path from .env import VirtualEnv @@ -42,7 +43,17 @@ def get(cls): # type: () -> Shell try: name, path = detect_shell(os.getpid()) except (RuntimeError, ShellDetectionFailure): - raise RuntimeError("Unable to detect the current shell.") + shell = None + + if os.name == "posix": + shell = os.environ.get("SHELL") + elif os.name == "nt": + shell = os.environ.get("COMSPEC") + + if not shell: + raise RuntimeError("Unable to detect the current shell.") + + name, path = Path(shell).stem, shell cls._shell = cls(name, path) From 9b56bdd53aa9900ca7a95964ee55f1b3b1a6465d Mon Sep 17 00:00:00 2001 From: Dimitri Merejkowsky Date: Tue, 7 Apr 2020 13:35:52 +0200 Subject: [PATCH 22/80] doc: explain why `update` sometimes causes a no-op --- docs/docs/cli.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/docs/cli.md b/docs/docs/cli.md index 89d19a8cc18..d8906f26d77 100644 --- a/docs/docs/cli.md +++ b/docs/docs/cli.md @@ -165,6 +165,11 @@ If you just want to update a few packages and not all, you can list them as such poetry update requests toml ``` +Note that this will not update versions for dependencies outside their version constraints specified +in the `pyproject.toml` file. In other terms, `poetry update foo` will be a no-op if the version constraint +specified for `foo` is `~2.3` or `2.3` and `2.4` is available. In order for `foo` to be updated, you must +update the constraint, for example `^2.3`. You can do this using the `add` command. + ### Options * `--dry-run` : Outputs the operations but will not execute anything (implicitly enables --verbose). From d47b52855bdc226e4ada58173d6eef9d23b23be5 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Sat, 28 Mar 2020 15:01:49 +0100 Subject: [PATCH 23/80] pip: ensure vcs source is removed after package removal Relates-to: #2238 --- poetry/installation/pip_installer.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry/installation/pip_installer.py b/poetry/installation/pip_installer.py index aada0cd0190..e335c1a8b33 100644 --- a/poetry/installation/pip_installer.py +++ b/poetry/installation/pip_installer.py @@ -105,12 +105,6 @@ def update(self, package, target): self.install(target, update=True) def remove(self, package): - # If we have a VCS package, remove its source directory - if package.source_type == "git": - src_dir = self._env.path / "src" / package.name - if src_dir.exists(): - safe_rmtree(str(src_dir)) - try: self.run("uninstall", package.name, "-y") except CalledProcessError as e: @@ -119,6 +113,12 @@ def remove(self, package): raise + # If we have a VCS package, remove its source directory + if package.source_type == "git": + src_dir = self._env.path / "src" / package.name + if src_dir.exists(): + safe_rmtree(str(src_dir)) + def run(self, *args, **kwargs): # type: (...) -> str return self._env.run_pip(*args, **kwargs) From a0904f95ab0b2d837e19d6725655e4bec9c88865 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Fri, 10 Apr 2020 18:11:27 +0200 Subject: [PATCH 24/80] tests: move tmp_venv fixture to conftest --- tests/conftest.py | 14 ++++++++++++++ tests/utils/test_env.py | 12 ------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 8386ad35f57..7cda645c303 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -11,6 +11,8 @@ from poetry.config.config import Config as BaseConfig from poetry.config.dict_config_source import DictConfigSource from poetry.utils._compat import Path +from poetry.utils.env import EnvManager +from poetry.utils.env import VirtualEnv from tests.helpers import mock_clone from tests.helpers import mock_download @@ -122,3 +124,15 @@ def tmp_dir(): yield dir_ shutil.rmtree(dir_) + + +@pytest.fixture +def tmp_venv(tmp_dir): + venv_path = Path(tmp_dir) / "venv" + + EnvManager.build_venv(str(venv_path)) + + venv = VirtualEnv(venv_path) + yield venv + + shutil.rmtree(str(venv.path)) diff --git a/tests/utils/test_env.py b/tests/utils/test_env.py index e5926e68862..9ed47c87b56 100644 --- a/tests/utils/test_env.py +++ b/tests/utils/test_env.py @@ -60,18 +60,6 @@ def manager(poetry): return EnvManager(poetry) -@pytest.fixture -def tmp_venv(tmp_dir, manager): - venv_path = Path(tmp_dir) / "venv" - - manager.build_venv(str(venv_path)) - - venv = VirtualEnv(venv_path) - yield venv - - shutil.rmtree(str(venv.path)) - - def test_virtualenvs_with_spaces_in_their_path_work_as_expected(tmp_dir, manager): venv_path = Path(tmp_dir) / "Virtual Env" From cdd7c77e8f8be77106fd2c39623ffbf88ba7c4ea Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Sat, 28 Mar 2020 15:03:01 +0100 Subject: [PATCH 25/80] pip: remove orphaned nspkg.pth files manually Relates-to: #2238 --- poetry/installation/pip_installer.py | 5 +++ .../namespace_package/__init__.py | 1 + .../namespace_package/one/__init__.py | 1 + .../demo/namespace-package-one/setup.py | 15 +++++++ tests/installation/test_pip_installer.py | 41 +++++++++++++++++++ 5 files changed, 63 insertions(+) create mode 100644 tests/fixtures/git/github.com/demo/namespace-package-one/namespace_package/__init__.py create mode 100644 tests/fixtures/git/github.com/demo/namespace-package-one/namespace_package/one/__init__.py create mode 100644 tests/fixtures/git/github.com/demo/namespace-package-one/setup.py diff --git a/poetry/installation/pip_installer.py b/poetry/installation/pip_installer.py index e335c1a8b33..5a3e8df7852 100644 --- a/poetry/installation/pip_installer.py +++ b/poetry/installation/pip_installer.py @@ -113,6 +113,11 @@ def remove(self, package): raise + # This is a workaround for https://github.com/pypa/pip/issues/4176 + nspkg_pth_file = self._env.site_packages / "{}-nspkg.pth".format(package.name) + if nspkg_pth_file.exists(): + nspkg_pth_file.unlink() + # If we have a VCS package, remove its source directory if package.source_type == "git": src_dir = self._env.path / "src" / package.name diff --git a/tests/fixtures/git/github.com/demo/namespace-package-one/namespace_package/__init__.py b/tests/fixtures/git/github.com/demo/namespace-package-one/namespace_package/__init__.py new file mode 100644 index 00000000000..5284146ebf2 --- /dev/null +++ b/tests/fixtures/git/github.com/demo/namespace-package-one/namespace_package/__init__.py @@ -0,0 +1 @@ +__import__("pkg_resources").declare_namespace(__name__) diff --git a/tests/fixtures/git/github.com/demo/namespace-package-one/namespace_package/one/__init__.py b/tests/fixtures/git/github.com/demo/namespace-package-one/namespace_package/one/__init__.py new file mode 100644 index 00000000000..1ac9243c76f --- /dev/null +++ b/tests/fixtures/git/github.com/demo/namespace-package-one/namespace_package/one/__init__.py @@ -0,0 +1 @@ +name = "one" diff --git a/tests/fixtures/git/github.com/demo/namespace-package-one/setup.py b/tests/fixtures/git/github.com/demo/namespace-package-one/setup.py new file mode 100644 index 00000000000..871fae6cf69 --- /dev/null +++ b/tests/fixtures/git/github.com/demo/namespace-package-one/setup.py @@ -0,0 +1,15 @@ +from setuptools import setup, find_packages + + +setup( + name="namespace_package_one", + version="1.0.0", + description="", + long_description="", + author="Python Poetry", + author_email="noreply@python-poetry.org", + license="MIT", + packages=find_packages(), + namespace_packages=["namespace_package"], + zip_safe=False, +) diff --git a/tests/installation/test_pip_installer.py b/tests/installation/test_pip_installer.py index fe40328aa1a..702dfe9c0e6 100644 --- a/tests/installation/test_pip_installer.py +++ b/tests/installation/test_pip_installer.py @@ -1,3 +1,5 @@ +import shutil + import pytest from poetry.installation.pip_installer import PipInstaller @@ -152,3 +154,42 @@ def test_requirement_git_develop_true(installer, package_git): expected = ["-e", "git+git@github.com:demo/demo.git@master#egg=demo"] assert expected == result + + +def test_uninstall_git_package_nspkg_pth_cleanup(mocker, tmp_venv, pool): + # this test scenario requires a real installation using the pip installer + installer = PipInstaller(tmp_venv, NullIO(), pool) + + # use a namepspace package + package = Package("namespace-package-one", "1.0.0") + package.source_type = "git" + package.source_url = "https://github.com/demo/namespace-package-one.git" + package.source_reference = "master" + package.develop = True + + # we do this here because the virtual env might not be usable if failure case is triggered + pth_file_candidate = tmp_venv.site_packages / "{}-nspkg.pth".format(package.name) + + # in order to reproduce the scenario where the git source is removed prior to proper + # clean up of nspkg.pth file, we need to make sure the fixture is copied and not + # symlinked into the git src directory + def copy_only(source, dest): + if dest.exists(): + dest.unlink() + + if source.is_dir(): + shutil.copytree(str(source), str(dest)) + else: + shutil.copyfile(str(source), str(dest)) + + mocker.patch("tests.helpers.copy_or_symlink", new=copy_only) + + # install package and then remove it + installer.install(package) + installer.remove(package) + + assert not Path(pth_file_candidate).exists() + + # any command in the virtual environment should trigger the error message + output = tmp_venv.run("python", "-m", "site") + assert "Error processing line 1 of {}".format(pth_file_candidate) not in output From 370d325680e00a7745b3e39949914b566db99310 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Fri, 10 Apr 2020 19:37:53 +0200 Subject: [PATCH 26/80] deps: general update --- poetry.lock | 353 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 234 insertions(+), 119 deletions(-) diff --git a/poetry.lock b/poetry.lock index 68b195a47b1..165be3bd167 100644 --- a/poetry.lock +++ b/poetry.lock @@ -99,7 +99,7 @@ description = "Python package for providing Mozilla's CA Bundle." name = "certifi" optional = false python-versions = "*" -version = "2019.11.28" +version = "2020.4.5.1" [[package]] category = "main" @@ -146,19 +146,28 @@ clikit = ">=0.4.0,<0.5.0" [[package]] category = "dev" description = "Composable command line interface toolkit" -marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_version >= \"3.4\" and python_version < \"4.0\" or python_version >= \"3.6\" and python_version < \"4.0\"" +marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_version >= \"3.4\" and python_version < \"4.0\"" name = "click" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "7.0" +[[package]] +category = "dev" +description = "Composable command line interface toolkit" +marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_version >= \"3.4\" and python_version < \"4.0\" or python_version >= \"3.6\" and python_version < \"4.0\"" +name = "click" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "7.1.1" + [[package]] category = "main" description = "CliKit is a group of utilities to build beautiful and testable command line interfaces." name = "clikit" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "0.4.2" +version = "0.4.3" [package.dependencies] pastel = ">=0.2.0,<0.3.0" @@ -230,7 +239,7 @@ description = "Code coverage measurement for Python" name = "coverage" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" -version = "5.0.3" +version = "5.0.4" [package.extras] toml = ["toml"] @@ -238,7 +247,7 @@ toml = ["toml"] [[package]] category = "main" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -marker = "python_version >= \"2.7\" and python_version < \"2.8\" and (sys_platform == \"linux2\" or sys_platform == \"linux\") or python_version >= \"3.4\" and python_version < \"3.5\" and (sys_platform == \"linux2\" or sys_platform == \"linux\") or python_version >= \"3.5\" and python_version < \"4.0\" and sys_platform == \"linux\"" +marker = "python_version >= \"2.7\" and python_version < \"2.8\" and (sys_platform == \"linux2\" or sys_platform == \"linux\") or python_version >= \"3.4\" and python_version < \"3.5\" and (sys_platform == \"linux2\" or sys_platform == \"linux\")" name = "cryptography" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" @@ -248,6 +257,26 @@ version = "2.8" cffi = ">=1.8,<1.11.3 || >1.11.3" six = ">=1.4.1" +[package.extras] +docs = ["sphinx (>=1.6.5,<1.8.0 || >1.8.0)", "sphinx-rtd-theme"] +docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] +idna = ["idna (>=2.1)"] +pep8test = ["flake8", "flake8-import-order", "pep8-naming"] +test = ["pytest (>=3.6.0,<3.9.0 || >3.9.0,<3.9.1 || >3.9.1,<3.9.2 || >3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,<3.79.2 || >3.79.2)"] + +[[package]] +category = "main" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +marker = "python_version >= \"2.7\" and python_version < \"2.8\" and (sys_platform == \"linux2\" or sys_platform == \"linux\") or python_version >= \"3.4\" and python_version < \"3.5\" and (sys_platform == \"linux2\" or sys_platform == \"linux\") or python_version >= \"3.5\" and python_version < \"4.0\" and sys_platform == \"linux\"" +name = "cryptography" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" +version = "2.9" + +[package.dependencies] +cffi = ">=1.8,<1.11.3 || >1.11.3" +six = ">=1.4.1" + [package.dependencies.enum34] python = "<3" version = "*" @@ -292,7 +321,7 @@ marker = "python_version >= \"2.7\" and python_version < \"2.8\" or python_versi name = "enum34" optional = false python-versions = "*" -version = "1.1.9" +version = "1.1.10" [[package]] category = "dev" @@ -383,7 +412,7 @@ description = "File identification library for Python" name = "identify" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "1.4.11" +version = "1.4.14" [package.extras] license = ["editdistance"] @@ -437,14 +466,47 @@ python-versions = ">=2.7,!=3.0,!=3.1,!=3.2,!=3.3" version = "1.0.2" [package.dependencies] +[package.dependencies.typing] +python = "<3.5" +version = "*" + +[[package]] +category = "dev" +description = "Read resources from Python packages" +marker = "python_version < \"3.7\"" +name = "importlib-resources" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +version = "1.4.0" + +[package.dependencies] +[package.dependencies.contextlib2] +python = "<3" +version = "*" + +[package.dependencies.importlib-metadata] +python = "<3.8" +version = "*" + [package.dependencies.pathlib2] python = "<3" version = "*" +[package.dependencies.singledispatch] +python = "<3.4" +version = "*" + [package.dependencies.typing] python = "<3.5" version = "*" +[package.dependencies.zipp] +python = "<3.8" +version = ">=0.4" + +[package.extras] +docs = ["sphinx", "rst.linker", "jaraco.packaging"] + [[package]] category = "main" description = "IPv4/IPv6 manipulation library" @@ -461,7 +523,7 @@ marker = "python_version >= \"3.5\" and python_version < \"4.0\" and sys_platfor name = "jeepney" optional = false python-versions = ">=3.5" -version = "0.4.2" +version = "0.4.3" [package.extras] dev = ["testpath"] @@ -792,7 +854,7 @@ description = "Core utilities for Python packages" name = "packaging" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "20.1" +version = "20.3" [package.dependencies] pyparsing = ">=2.0.2" @@ -829,7 +891,7 @@ marker = "python_version >= \"3.6\" and python_version < \"4.0\"" name = "pathspec" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "0.7.0" +version = "0.8.0" [[package]] category = "dev" @@ -953,7 +1015,7 @@ marker = "python_version >= \"2.7\" and python_version < \"2.8\" and (sys_platfo name = "pycparser" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.19" +version = "2.20" [[package]] category = "dev" @@ -971,6 +1033,14 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" version = "2.5.2" +[[package]] +category = "dev" +description = "Pygments is a syntax highlighting package written in Python." +name = "pygments" +optional = false +python-versions = ">=3.5" +version = "2.6.1" + [[package]] category = "dev" description = "Pygments Github custom lexers." @@ -1030,7 +1100,7 @@ description = "Python parsing module" name = "pyparsing" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -version = "2.4.6" +version = "2.4.7" [[package]] category = "main" @@ -1160,7 +1230,7 @@ description = "YAML parser and emitter for Python" name = "pyyaml" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "5.3" +version = "5.3.1" [[package]] category = "dev" @@ -1169,7 +1239,7 @@ marker = "python_version >= \"3.6\" and python_version < \"4.0\"" name = "regex" optional = false python-versions = "*" -version = "2020.2.20" +version = "2020.4.4" [[package]] category = "main" @@ -1221,7 +1291,7 @@ requests = ">=2.0.1,<3.0.0" [[package]] category = "main" description = "scandir, a better directory iterator and faster os.walk()" -marker = "python_version >= \"2.7\" and python_version < \"2.8\" or python_version >= \"3.4\" and python_version < \"3.5\" or python_version < \"3.5\"" +marker = "python_version >= \"2.7\" and python_version < \"2.8\" or python_version >= \"3.4\" and python_version < \"3.5\"" name = "scandir" optional = false python-versions = "*" @@ -1263,6 +1333,18 @@ optional = false python-versions = "!=3.0,!=3.1,!=3.2,!=3.3,>=2.6" version = "1.3.2" +[[package]] +category = "dev" +description = "This library brings functools.singledispatch from Python 3.4 to Python 2.6-3.3." +marker = "python_version < \"3.4\"" +name = "singledispatch" +optional = false +python-versions = "*" +version = "3.4.0.3" + +[package.dependencies] +six = "*" + [[package]] category = "main" description = "Python 2 and 3 compatibility utilities" @@ -1333,7 +1415,7 @@ marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_v name = "tornado" optional = false python-versions = ">= 3.5" -version = "6.0.3" +version = "6.0.4" [[package]] category = "dev" @@ -1362,7 +1444,7 @@ description = "tox is a generic virtualenv management and test command line tool name = "tox" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -version = "3.14.5" +version = "3.14.6" [package.dependencies] colorama = ">=0.4.1" @@ -1372,7 +1454,7 @@ pluggy = ">=0.12.0,<1" py = ">=1.4.17,<2" six = ">=1.14.0,<2" toml = ">=0.9.4" -virtualenv = ">=16.0.0" +virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7" [package.dependencies.importlib-metadata] python = "<3.8" @@ -1407,7 +1489,7 @@ marker = "python_version >= \"3.5.0\" and python_version < \"3.5.4\"" name = "typing-extensions" optional = false python-versions = "*" -version = "3.7.4.1" +version = "3.7.4.2" [[package]] category = "main" @@ -1452,7 +1534,7 @@ description = "Virtual Python Environment builder" name = "virtualenv" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "20.0.7" +version = "20.0.17" [package.dependencies] appdirs = ">=1.4.3,<2" @@ -1470,7 +1552,7 @@ version = ">=1.0,<2" [package.extras] docs = ["sphinx (>=2.0.0,<3)", "sphinx-argparse (>=0.2.5,<1)", "sphinx-rtd-theme (>=0.4.3,<1)", "towncrier (>=19.9.0rc1)", "proselint (>=0.10.2,<1)"] -testing = ["pytest (>=4.0.0,<6)", "coverage (>=4.5.1,<6)", "pytest-mock (>=2.0.0,<3)", "pytest-env (>=0.6.2,<1)", "packaging (>=20.0)", "xonsh (>=0.9.13,<1)"] +testing = ["pytest (>=4.0.0,<6)", "coverage (>=4.5.1,<6)", "pytest-mock (>=2.0.0,<3)", "pytest-env (>=0.6.2,<1)", "pytest-timeout (>=1.3.4,<2)", "packaging (>=20.0)", "xonsh (>=0.9.16,<1)"] [[package]] category = "dev" @@ -1478,7 +1560,7 @@ description = "Measures number of Terminal column cells of wide-character codes" name = "wcwidth" optional = false python-versions = "*" -version = "0.1.8" +version = "0.1.9" [[package]] category = "main" @@ -1491,6 +1573,7 @@ version = "0.5.1" [[package]] category = "main" description = "Backport of pathlib-compatible object wrapper for zip files" +marker = "python_version < \"3.8\" or python_version >= \"3.5\" and python_version < \"3.8\"" name = "zipp" optional = false python-versions = ">=2.7" @@ -1539,8 +1622,8 @@ cachy = [ {file = "cachy-0.3.0.tar.gz", hash = "sha256:186581f4ceb42a0bbe040c407da73c14092379b1e4c0e327fdb72ae4a9b269b1"}, ] certifi = [ - {file = "certifi-2019.11.28-py2.py3-none-any.whl", hash = "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3"}, - {file = "certifi-2019.11.28.tar.gz", hash = "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f"}, + {file = "certifi-2020.4.5.1-py2.py3-none-any.whl", hash = "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304"}, + {file = "certifi-2020.4.5.1.tar.gz", hash = "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519"}, ] cffi = [ {file = "cffi-1.14.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1cae98a7054b5c9391eb3249b86e0e99ab1e02bb0cc0575da191aedadbdf4384"}, @@ -1587,10 +1670,12 @@ cleo = [ click = [ {file = "Click-7.0-py2.py3-none-any.whl", hash = "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13"}, {file = "Click-7.0.tar.gz", hash = "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"}, + {file = "click-7.1.1-py2.py3-none-any.whl", hash = "sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a"}, + {file = "click-7.1.1.tar.gz", hash = "sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc"}, ] clikit = [ - {file = "clikit-0.4.2-py2.py3-none-any.whl", hash = "sha256:95394982cfa460a77ded2f173380a958e5f90c16972307c19d79b96f6e335326"}, - {file = "clikit-0.4.2.tar.gz", hash = "sha256:f67336462800078e0896cf6ecfa3b460dfea4dfa01de659388a4ff0d83c8d6ca"}, + {file = "clikit-0.4.3-py2.py3-none-any.whl", hash = "sha256:71e321b7795a2a6c4888629f43365d52db071737e668ab16861121d7dd3ada09"}, + {file = "clikit-0.4.3.tar.gz", hash = "sha256:6e2d7e115e7c7b35bceb0209109935ab2f9ab50910e9ff2293f7fa0b7abf973e"}, ] colorama = [ {file = "colorama-0.4.1-py2.py3-none-any.whl", hash = "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"}, @@ -1639,37 +1724,37 @@ coverage = [ {file = "coverage-4.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351"}, {file = "coverage-4.5.4-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5"}, {file = "coverage-4.5.4.tar.gz", hash = "sha256:e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c"}, - {file = "coverage-5.0.3-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:cc1109f54a14d940b8512ee9f1c3975c181bbb200306c6d8b87d93376538782f"}, - {file = "coverage-5.0.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:be18f4ae5a9e46edae3f329de2191747966a34a3d93046dbdf897319923923bc"}, - {file = "coverage-5.0.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:3230d1003eec018ad4a472d254991e34241e0bbd513e97a29727c7c2f637bd2a"}, - {file = "coverage-5.0.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:e69215621707119c6baf99bda014a45b999d37602cb7043d943c76a59b05bf52"}, - {file = "coverage-5.0.3-cp27-cp27m-win32.whl", hash = "sha256:1daa3eceed220f9fdb80d5ff950dd95112cd27f70d004c7918ca6dfc6c47054c"}, - {file = "coverage-5.0.3-cp27-cp27m-win_amd64.whl", hash = "sha256:51bc7710b13a2ae0c726f69756cf7ffd4362f4ac36546e243136187cfcc8aa73"}, - {file = "coverage-5.0.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:9bea19ac2f08672636350f203db89382121c9c2ade85d945953ef3c8cf9d2a68"}, - {file = "coverage-5.0.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:5012d3b8d5a500834783689a5d2292fe06ec75dc86ee1ccdad04b6f5bf231691"}, - {file = "coverage-5.0.3-cp35-cp35m-macosx_10_12_x86_64.whl", hash = "sha256:d513cc3db248e566e07a0da99c230aca3556d9b09ed02f420664e2da97eac301"}, - {file = "coverage-5.0.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3dbb72eaeea5763676a1a1efd9b427a048c97c39ed92e13336e726117d0b72bf"}, - {file = "coverage-5.0.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:15cf13a6896048d6d947bf7d222f36e4809ab926894beb748fc9caa14605d9c3"}, - {file = "coverage-5.0.3-cp35-cp35m-win32.whl", hash = "sha256:fca1669d464f0c9831fd10be2eef6b86f5ebd76c724d1e0706ebdff86bb4adf0"}, - {file = "coverage-5.0.3-cp35-cp35m-win_amd64.whl", hash = "sha256:1e44a022500d944d42f94df76727ba3fc0a5c0b672c358b61067abb88caee7a0"}, - {file = "coverage-5.0.3-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:b26aaf69713e5674efbde4d728fb7124e429c9466aeaf5f4a7e9e699b12c9fe2"}, - {file = "coverage-5.0.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:722e4557c8039aad9592c6a4213db75da08c2cd9945320220634f637251c3894"}, - {file = "coverage-5.0.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:7afad9835e7a651d3551eab18cbc0fdb888f0a6136169fbef0662d9cdc9987cf"}, - {file = "coverage-5.0.3-cp36-cp36m-win32.whl", hash = "sha256:25dbf1110d70bab68a74b4b9d74f30e99b177cde3388e07cc7272f2168bd1477"}, - {file = "coverage-5.0.3-cp36-cp36m-win_amd64.whl", hash = "sha256:c312e57847db2526bc92b9bfa78266bfbaabac3fdcd751df4d062cd4c23e46dc"}, - {file = "coverage-5.0.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:a8b8ac7876bc3598e43e2603f772d2353d9931709345ad6c1149009fd1bc81b8"}, - {file = "coverage-5.0.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:527b4f316e6bf7755082a783726da20671a0cc388b786a64417780b90565b987"}, - {file = "coverage-5.0.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d649dc0bcace6fcdb446ae02b98798a856593b19b637c1b9af8edadf2b150bea"}, - {file = "coverage-5.0.3-cp37-cp37m-win32.whl", hash = "sha256:cd60f507c125ac0ad83f05803063bed27e50fa903b9c2cfee3f8a6867ca600fc"}, - {file = "coverage-5.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c60097190fe9dc2b329a0eb03393e2e0829156a589bd732e70794c0dd804258e"}, - {file = "coverage-5.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:d7008a6796095a79544f4da1ee49418901961c97ca9e9d44904205ff7d6aa8cb"}, - {file = "coverage-5.0.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:ea9525e0fef2de9208250d6c5aeeee0138921057cd67fcef90fbed49c4d62d37"}, - {file = "coverage-5.0.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c62a2143e1313944bf4a5ab34fd3b4be15367a02e9478b0ce800cb510e3bbb9d"}, - {file = "coverage-5.0.3-cp38-cp38m-win32.whl", hash = "sha256:b0840b45187699affd4c6588286d429cd79a99d509fe3de0f209594669bb0954"}, - {file = "coverage-5.0.3-cp38-cp38m-win_amd64.whl", hash = "sha256:76e2057e8ffba5472fd28a3a010431fd9e928885ff480cb278877c6e9943cc2e"}, - {file = "coverage-5.0.3-cp39-cp39m-win32.whl", hash = "sha256:b63dd43f455ba878e5e9f80ba4f748c0a2156dde6e0e6e690310e24d6e8caf40"}, - {file = "coverage-5.0.3-cp39-cp39m-win_amd64.whl", hash = "sha256:da93027835164b8223e8e5af2cf902a4c80ed93cb0909417234f4a9df3bcd9af"}, - {file = "coverage-5.0.3.tar.gz", hash = "sha256:77afca04240c40450c331fa796b3eab6f1e15c5ecf8bf2b8bee9706cd5452fef"}, + {file = "coverage-5.0.4-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:8a620767b8209f3446197c0e29ba895d75a1e272a36af0786ec70fe7834e4307"}, + {file = "coverage-5.0.4-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:73aa6e86034dad9f00f4bbf5a666a889d17d79db73bc5af04abd6c20a014d9c8"}, + {file = "coverage-5.0.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:408ce64078398b2ee2ec08199ea3fcf382828d2f8a19c5a5ba2946fe5ddc6c31"}, + {file = "coverage-5.0.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:cda33311cb9fb9323958a69499a667bd728a39a7aa4718d7622597a44c4f1441"}, + {file = "coverage-5.0.4-cp27-cp27m-win32.whl", hash = "sha256:5f587dfd83cb669933186661a351ad6fc7166273bc3e3a1531ec5c783d997aac"}, + {file = "coverage-5.0.4-cp27-cp27m-win_amd64.whl", hash = "sha256:9fad78c13e71546a76c2f8789623eec8e499f8d2d799f4b4547162ce0a4df435"}, + {file = "coverage-5.0.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:2e08c32cbede4a29e2a701822291ae2bc9b5220a971bba9d1e7615312efd3037"}, + {file = "coverage-5.0.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:922fb9ef2c67c3ab20e22948dcfd783397e4c043a5c5fa5ff5e9df5529074b0a"}, + {file = "coverage-5.0.4-cp35-cp35m-macosx_10_12_x86_64.whl", hash = "sha256:c3fc325ce4cbf902d05a80daa47b645d07e796a80682c1c5800d6ac5045193e5"}, + {file = "coverage-5.0.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:046a1a742e66d065d16fb564a26c2a15867f17695e7f3d358d7b1ad8a61bca30"}, + {file = "coverage-5.0.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6ad6ca45e9e92c05295f638e78cd42bfaaf8ee07878c9ed73e93190b26c125f7"}, + {file = "coverage-5.0.4-cp35-cp35m-win32.whl", hash = "sha256:eda55e6e9ea258f5e4add23bcf33dc53b2c319e70806e180aecbff8d90ea24de"}, + {file = "coverage-5.0.4-cp35-cp35m-win_amd64.whl", hash = "sha256:4a8a259bf990044351baf69d3b23e575699dd60b18460c71e81dc565f5819ac1"}, + {file = "coverage-5.0.4-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:f372cdbb240e09ee855735b9d85e7f50730dcfb6296b74b95a3e5dea0615c4c1"}, + {file = "coverage-5.0.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a37c6233b28e5bc340054cf6170e7090a4e85069513320275a4dc929144dccf0"}, + {file = "coverage-5.0.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:443be7602c790960b9514567917af538cac7807a7c0c0727c4d2bbd4014920fd"}, + {file = "coverage-5.0.4-cp36-cp36m-win32.whl", hash = "sha256:165a48268bfb5a77e2d9dbb80de7ea917332a79c7adb747bd005b3a07ff8caf0"}, + {file = "coverage-5.0.4-cp36-cp36m-win_amd64.whl", hash = "sha256:0a907199566269e1cfa304325cc3b45c72ae341fbb3253ddde19fa820ded7a8b"}, + {file = "coverage-5.0.4-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:513e6526e0082c59a984448f4104c9bf346c2da9961779ede1fc458e8e8a1f78"}, + {file = "coverage-5.0.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:3844c3dab800ca8536f75ae89f3cf566848a3eb2af4d9f7b1103b4f4f7a5dad6"}, + {file = "coverage-5.0.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:641e329e7f2c01531c45c687efcec8aeca2a78a4ff26d49184dce3d53fc35014"}, + {file = "coverage-5.0.4-cp37-cp37m-win32.whl", hash = "sha256:db1d4e38c9b15be1521722e946ee24f6db95b189d1447fa9ff18dd16ba89f732"}, + {file = "coverage-5.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:62061e87071497951155cbccee487980524d7abea647a1b2a6eb6b9647df9006"}, + {file = "coverage-5.0.4-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:65a7e00c00472cd0f59ae09d2fb8a8aaae7f4a0cf54b2b74f3138d9f9ceb9cb2"}, + {file = "coverage-5.0.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1f66cf263ec77af5b8fe14ef14c5e46e2eb4a795ac495ad7c03adc72ae43fafe"}, + {file = "coverage-5.0.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:85596aa5d9aac1bf39fe39d9fa1051b0f00823982a1de5766e35d495b4a36ca9"}, + {file = "coverage-5.0.4-cp38-cp38-win32.whl", hash = "sha256:86a0ea78fd851b313b2e712266f663e13b6bc78c2fb260b079e8b67d970474b1"}, + {file = "coverage-5.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:03f630aba2b9b0d69871c2e8d23a69b7fe94a1e2f5f10df5049c0df99db639a0"}, + {file = "coverage-5.0.4-cp39-cp39-win32.whl", hash = "sha256:7c9762f80a25d8d0e4ab3cb1af5d9dffbddb3ee5d21c43e3474c84bf5ff941f7"}, + {file = "coverage-5.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:4482f69e0701139d0f2c44f3c395d1d1d37abd81bfafbf9b6efbe2542679d892"}, + {file = "coverage-5.0.4.tar.gz", hash = "sha256:1b60a95fc995649464e0cd48cecc8288bac5f4198f21d04b8229dc4097d76823"}, ] cryptography = [ {file = "cryptography-2.8-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8"}, @@ -1693,6 +1778,25 @@ cryptography = [ {file = "cryptography-2.8-cp38-cp38-win32.whl", hash = "sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e"}, {file = "cryptography-2.8-cp38-cp38-win_amd64.whl", hash = "sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13"}, {file = "cryptography-2.8.tar.gz", hash = "sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651"}, + {file = "cryptography-2.9-cp27-cp27m-macosx_10_9_intel.whl", hash = "sha256:ef9a55013676907df6c9d7dd943eb1770d014f68beaa7e73250fb43c759f4585"}, + {file = "cryptography-2.9-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:2a2ad24d43398d89f92209289f15265107928f22a8d10385f70def7a698d6a02"}, + {file = "cryptography-2.9-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:95e1296e0157361fe2f5f0ed307fd31f94b0ca13372e3673fa95095a627636a1"}, + {file = "cryptography-2.9-cp27-cp27m-win32.whl", hash = "sha256:192ca04a36852a994ef21df13cca4d822adbbdc9d5009c0f96f1d2929e375d4f"}, + {file = "cryptography-2.9-cp27-cp27m-win_amd64.whl", hash = "sha256:ed1d0760c7e46436ec90834d6f10477ff09475c692ed1695329d324b2c5cd547"}, + {file = "cryptography-2.9-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:19ae795137682a9778892fb4390c07811828b173741bce91e30f899424b3934d"}, + {file = "cryptography-2.9-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d1bf5a1a0d60c7f9a78e448adcb99aa101f3f9588b16708044638881be15d6bc"}, + {file = "cryptography-2.9-cp35-abi3-macosx_10_9_intel.whl", hash = "sha256:1b9b535d6b55936a79dbe4990b64bb16048f48747c76c29713fea8c50eca2acf"}, + {file = "cryptography-2.9-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:7a279f33a081d436e90e91d1a7c338553c04e464de1c9302311a5e7e4b746088"}, + {file = "cryptography-2.9-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:49870684da168b90110bbaf86140d4681032c5e6a2461adc7afdd93be5634216"}, + {file = "cryptography-2.9-cp35-cp35m-win32.whl", hash = "sha256:6b91cab3841b4c7cb70e4db1697c69f036c8bc0a253edc0baa6783154f1301e4"}, + {file = "cryptography-2.9-cp35-cp35m-win_amd64.whl", hash = "sha256:587f98ce27ac4547177a0c6fe0986b8736058daffe9160dcf5f1bd411b7fbaa1"}, + {file = "cryptography-2.9-cp36-cp36m-win32.whl", hash = "sha256:cc20316e3f5a6b582fc3b029d8dc03aabeb645acfcb7fc1d9848841a33265748"}, + {file = "cryptography-2.9-cp36-cp36m-win_amd64.whl", hash = "sha256:3be7a5722d5bfe69894d3f7bbed15547b17619f3a88a318aab2e37f457524164"}, + {file = "cryptography-2.9-cp37-cp37m-win32.whl", hash = "sha256:7598974f6879a338c785c513e7c5a4329fbc58b9f6b9a6305035fca5b1076552"}, + {file = "cryptography-2.9-cp37-cp37m-win_amd64.whl", hash = "sha256:5aca6f00b2f42546b9bdf11a69f248d1881212ce5b9e2618b04935b87f6f82a1"}, + {file = "cryptography-2.9-cp38-cp38-win32.whl", hash = "sha256:9fc9da390e98cb6975eadf251b6e5fa088820141061bf041cd5c72deba1dc526"}, + {file = "cryptography-2.9-cp38-cp38-win_amd64.whl", hash = "sha256:6b744039b55988519cc183149cceb573189b3e46e16ccf6f8c46798bb767c9dc"}, + {file = "cryptography-2.9.tar.gz", hash = "sha256:0cacd3ef5c604b8e5f59bf2582c076c98a37fe206b31430d0cd08138aff0986e"}, ] distlib = [ {file = "distlib-0.3.0.zip", hash = "sha256:2e166e231a26b36d6dfe35a48c4464346620f8645ed0ace01ee31822b288de21"}, @@ -1702,9 +1806,9 @@ entrypoints = [ {file = "entrypoints-0.3.tar.gz", hash = "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"}, ] enum34 = [ - {file = "enum34-1.1.9-py2-none-any.whl", hash = "sha256:98df1f1937840b7d8012fea7f0b36392a3e6fd8a2f429c48a3ff4b1aad907f3f"}, - {file = "enum34-1.1.9-py3-none-any.whl", hash = "sha256:708aabfb3d5898f99674c390d360d59efdd08547019763622365f19e84a7fef4"}, - {file = "enum34-1.1.9.tar.gz", hash = "sha256:13ef9a1c478203252107f66c25b99b45b1865693ca1284aab40dafa7e1e7ac17"}, + {file = "enum34-1.1.10-py2-none-any.whl", hash = "sha256:a98a201d6de3f2ab3db284e70a33b0f896fbf35f8086594e8c9e74b909058d53"}, + {file = "enum34-1.1.10-py3-none-any.whl", hash = "sha256:c3858660960c984d6ab0ebad691265180da2b43f07e061c0f8dca9ef3cffd328"}, + {file = "enum34-1.1.10.tar.gz", hash = "sha256:cce6a7477ed816bd2542d03d53db9f0db935dd013b70f336a95c73979289f248"}, ] filelock = [ {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"}, @@ -1736,8 +1840,8 @@ httpretty = [ {file = "httpretty-0.9.7.tar.gz", hash = "sha256:66216f26b9d2c52e81808f3e674a6fb65d4bf719721394a1a9be926177e55fbe"}, ] identify = [ - {file = "identify-1.4.11-py2.py3-none-any.whl", hash = "sha256:1222b648251bdcb8deb240b294f450fbf704c7984e08baa92507e4ea10b436d5"}, - {file = "identify-1.4.11.tar.gz", hash = "sha256:d824ebe21f38325c771c41b08a95a761db1982f1fc0eee37c6c97df3f1636b96"}, + {file = "identify-1.4.14-py2.py3-none-any.whl", hash = "sha256:2bb8760d97d8df4408f4e805883dad26a2d076f04be92a10a3e43f09c6060742"}, + {file = "identify-1.4.14.tar.gz", hash = "sha256:faffea0fd8ec86bb146ac538ac350ed0c73908326426d387eded0bcc9d077522"}, ] idna = [ {file = "idna-2.8-py2.py3-none-any.whl", hash = "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"}, @@ -1752,14 +1856,16 @@ importlib-metadata = [ importlib-resources = [ {file = "importlib_resources-1.0.2-py2.py3-none-any.whl", hash = "sha256:6e2783b2538bd5a14678284a3962b0660c715e5a0f10243fd5e00a4b5974f50b"}, {file = "importlib_resources-1.0.2.tar.gz", hash = "sha256:d3279fd0f6f847cced9f7acc19bd3e5df54d34f93a2e7bb5f238f81545787078"}, + {file = "importlib_resources-1.4.0-py2.py3-none-any.whl", hash = "sha256:dd98ceeef3f5ad2ef4cc287b8586da4ebad15877f351e9688987ad663a0a29b8"}, + {file = "importlib_resources-1.4.0.tar.gz", hash = "sha256:4019b6a9082d8ada9def02bece4a76b131518866790d58fdda0b5f8c603b36c2"}, ] ipaddress = [ {file = "ipaddress-1.0.23-py2.py3-none-any.whl", hash = "sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc"}, {file = "ipaddress-1.0.23.tar.gz", hash = "sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2"}, ] jeepney = [ - {file = "jeepney-0.4.2-py3-none-any.whl", hash = "sha256:6f45dce1125cf6c58a1c88123d3831f36a789f9204fbad3172eac15f8ccd08d0"}, - {file = "jeepney-0.4.2.tar.gz", hash = "sha256:0ba6d8c597e9bef1ebd18aaec595f942a264e25c1a48f164d46120eacaa2e9bb"}, + {file = "jeepney-0.4.3-py3-none-any.whl", hash = "sha256:d6c6b49683446d2407d2fe3acb7a368a77ff063f9182fe427da15d622adc24cf"}, + {file = "jeepney-0.4.3.tar.gz", hash = "sha256:3479b861cc2b6407de5188695fa1a8d57e5072d7059322469b62628869b8e36e"}, ] jinja2 = [ {file = "Jinja2-2.10.3-py2.py3-none-any.whl", hash = "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f"}, @@ -1882,8 +1988,8 @@ nodeenv = [ {file = "nodeenv-1.3.5-py2.py3-none-any.whl", hash = "sha256:5b2438f2e42af54ca968dd1b374d14a1194848955187b0e5e4be1f73813a5212"}, ] packaging = [ - {file = "packaging-20.1-py2.py3-none-any.whl", hash = "sha256:170748228214b70b672c581a3dd610ee51f733018650740e98c7df862a583f73"}, - {file = "packaging-20.1.tar.gz", hash = "sha256:e665345f9eef0c621aa0bf2f8d78cf6d21904eef16a93f020240b704a57f1334"}, + {file = "packaging-20.3-py2.py3-none-any.whl", hash = "sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752"}, + {file = "packaging-20.3.tar.gz", hash = "sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3"}, ] pastel = [ {file = "pastel-0.2.0-py2.py3-none-any.whl", hash = "sha256:18b559dc3ad4ba9b8bd5baebe6503f25f36d21460f021cf27a8d889cb5d17840"}, @@ -1894,8 +2000,8 @@ pathlib2 = [ {file = "pathlib2-2.3.5.tar.gz", hash = "sha256:6cd9a47b597b37cc57de1c05e56fb1a1c9cc9fab04fe78c29acd090418529868"}, ] pathspec = [ - {file = "pathspec-0.7.0-py2.py3-none-any.whl", hash = "sha256:163b0632d4e31cef212976cf57b43d9fd6b0bac6e67c26015d611a647d5e7424"}, - {file = "pathspec-0.7.0.tar.gz", hash = "sha256:562aa70af2e0d434367d9790ad37aed893de47f1693e4201fd1d3dca15d19b96"}, + {file = "pathspec-0.8.0-py2.py3-none-any.whl", hash = "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0"}, + {file = "pathspec-0.8.0.tar.gz", hash = "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"}, ] pep562 = [ {file = "pep562-1.0-py2.py3-none-any.whl", hash = "sha256:d2a48b178ebf5f8dd31709cc26a19808ef794561fa2fe50ea01ea2bad4d667ef"}, @@ -1928,13 +2034,16 @@ py = [ {file = "py-1.8.1.tar.gz", hash = "sha256:5e27081401262157467ad6e7f851b7aa402c5852dbcb3dae06768434de5752aa"}, ] pycparser = [ - {file = "pycparser-2.19.tar.gz", hash = "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"}, + {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"}, + {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, ] pygments = [ {file = "Pygments-2.3.1-py2.py3-none-any.whl", hash = "sha256:e8218dd399a61674745138520d0d4cf2621d7e032439341bc3f647bff125818d"}, {file = "Pygments-2.3.1.tar.gz", hash = "sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a"}, {file = "Pygments-2.5.2-py2.py3-none-any.whl", hash = "sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b"}, {file = "Pygments-2.5.2.tar.gz", hash = "sha256:98c8aa5a9f778fcd1026a17361ddaf7330d1b7c62ae97c3bb0ae73e0b9b6b0fe"}, + {file = "Pygments-2.6.1-py3-none-any.whl", hash = "sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324"}, + {file = "Pygments-2.6.1.tar.gz", hash = "sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44"}, ] pygments-github-lexers = [ {file = "pygments-github-lexers-0.0.5.tar.gz", hash = "sha256:aaca57e77cd6fcfce8d6ee97a998962eebf7fbb810519a8ebde427c62823e133"}, @@ -1953,8 +2062,8 @@ pymdown-extensions = [ {file = "pymdown_extensions-6.3-py2.py3-none-any.whl", hash = "sha256:66fae2683c7a1dac53184f7de57f51f8dad73f9ead2f453e94e85096cb811335"}, ] pyparsing = [ - {file = "pyparsing-2.4.6-py2.py3-none-any.whl", hash = "sha256:c342dccb5250c08d45fd6f8b4a559613ca603b57498511740e65cd11a2e7dcec"}, - {file = "pyparsing-2.4.6.tar.gz", hash = "sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f"}, + {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, + {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pyrsistent = [ {file = "pyrsistent-0.14.11.tar.gz", hash = "sha256:3ca82748918eb65e2d89f222b702277099aca77e34843c5eb9d52451173970e2"}, @@ -1991,40 +2100,40 @@ pyyaml = [ {file = "PyYAML-5.2-cp38-cp38-win32.whl", hash = "sha256:8100c896ecb361794d8bfdb9c11fce618c7cf83d624d73d5ab38aef3bc82d43f"}, {file = "PyYAML-5.2-cp38-cp38-win_amd64.whl", hash = "sha256:2e9f0b7c5914367b0916c3c104a024bb68f269a486b9d04a2e8ac6f6597b7803"}, {file = "PyYAML-5.2.tar.gz", hash = "sha256:c0ee8eca2c582d29c3c2ec6e2c4f703d1b7f1fb10bc72317355a746057e7346c"}, - {file = "PyYAML-5.3-cp27-cp27m-win32.whl", hash = "sha256:940532b111b1952befd7db542c370887a8611660d2b9becff75d39355303d82d"}, - {file = "PyYAML-5.3-cp27-cp27m-win_amd64.whl", hash = "sha256:059b2ee3194d718896c0ad077dd8c043e5e909d9180f387ce42012662a4946d6"}, - {file = "PyYAML-5.3-cp35-cp35m-win32.whl", hash = "sha256:4fee71aa5bc6ed9d5f116327c04273e25ae31a3020386916905767ec4fc5317e"}, - {file = "PyYAML-5.3-cp35-cp35m-win_amd64.whl", hash = "sha256:dbbb2379c19ed6042e8f11f2a2c66d39cceb8aeace421bfc29d085d93eda3689"}, - {file = "PyYAML-5.3-cp36-cp36m-win32.whl", hash = "sha256:e3a057b7a64f1222b56e47bcff5e4b94c4f61faac04c7c4ecb1985e18caa3994"}, - {file = "PyYAML-5.3-cp36-cp36m-win_amd64.whl", hash = "sha256:74782fbd4d4f87ff04159e986886931456a1894c61229be9eaf4de6f6e44b99e"}, - {file = "PyYAML-5.3-cp37-cp37m-win32.whl", hash = "sha256:24521fa2890642614558b492b473bee0ac1f8057a7263156b02e8b14c88ce6f5"}, - {file = "PyYAML-5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:1cf708e2ac57f3aabc87405f04b86354f66799c8e62c28c5fc5f88b5521b2dbf"}, - {file = "PyYAML-5.3-cp38-cp38-win32.whl", hash = "sha256:70024e02197337533eef7b85b068212420f950319cc8c580261963aefc75f811"}, - {file = "PyYAML-5.3-cp38-cp38-win_amd64.whl", hash = "sha256:cb1f2f5e426dc9f07a7681419fe39cee823bb74f723f36f70399123f439e9b20"}, - {file = "PyYAML-5.3.tar.gz", hash = "sha256:e9f45bd5b92c7974e59bcd2dcc8631a6b6cc380a904725fce7bc08872e691615"}, + {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, + {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, + {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, + {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, + {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, ] regex = [ - {file = "regex-2020.2.20-cp27-cp27m-win32.whl", hash = "sha256:99272d6b6a68c7ae4391908fc15f6b8c9a6c345a46b632d7fdb7ef6c883a2bbb"}, - {file = "regex-2020.2.20-cp27-cp27m-win_amd64.whl", hash = "sha256:974535648f31c2b712a6b2595969f8ab370834080e00ab24e5dbb9d19b8bfb74"}, - {file = "regex-2020.2.20-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5de40649d4f88a15c9489ed37f88f053c15400257eeb18425ac7ed0a4e119400"}, - {file = "regex-2020.2.20-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:82469a0c1330a4beb3d42568f82dffa32226ced006e0b063719468dcd40ffdf0"}, - {file = "regex-2020.2.20-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d58a4fa7910102500722defbde6e2816b0372a4fcc85c7e239323767c74f5cbc"}, - {file = "regex-2020.2.20-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:f1ac2dc65105a53c1c2d72b1d3e98c2464a133b4067a51a3d2477b28449709a0"}, - {file = "regex-2020.2.20-cp36-cp36m-win32.whl", hash = "sha256:8c2b7fa4d72781577ac45ab658da44c7518e6d96e2a50d04ecb0fd8f28b21d69"}, - {file = "regex-2020.2.20-cp36-cp36m-win_amd64.whl", hash = "sha256:269f0c5ff23639316b29f31df199f401e4cb87529eafff0c76828071635d417b"}, - {file = "regex-2020.2.20-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:bed7986547ce54d230fd8721aba6fd19459cdc6d315497b98686d0416efaff4e"}, - {file = "regex-2020.2.20-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:046e83a8b160aff37e7034139a336b660b01dbfe58706f9d73f5cdc6b3460242"}, - {file = "regex-2020.2.20-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:b33ebcd0222c1d77e61dbcd04a9fd139359bded86803063d3d2d197b796c63ce"}, - {file = "regex-2020.2.20-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bba52d72e16a554d1894a0cc74041da50eea99a8483e591a9edf1025a66843ab"}, - {file = "regex-2020.2.20-cp37-cp37m-win32.whl", hash = "sha256:01b2d70cbaed11f72e57c1cfbaca71b02e3b98f739ce33f5f26f71859ad90431"}, - {file = "regex-2020.2.20-cp37-cp37m-win_amd64.whl", hash = "sha256:113309e819634f499d0006f6200700c8209a2a8bf6bd1bdc863a4d9d6776a5d1"}, - {file = "regex-2020.2.20-cp38-cp38-manylinux1_i686.whl", hash = "sha256:25f4ce26b68425b80a233ce7b6218743c71cf7297dbe02feab1d711a2bf90045"}, - {file = "regex-2020.2.20-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:9b64a4cc825ec4df262050c17e18f60252cdd94742b4ba1286bcfe481f1c0f26"}, - {file = "regex-2020.2.20-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:9ff16d994309b26a1cdf666a6309c1ef51ad4f72f99d3392bcd7b7139577a1f2"}, - {file = "regex-2020.2.20-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:c7f58a0e0e13fb44623b65b01052dae8e820ed9b8b654bb6296bc9c41f571b70"}, - {file = "regex-2020.2.20-cp38-cp38-win32.whl", hash = "sha256:200539b5124bc4721247a823a47d116a7a23e62cc6695744e3eb5454a8888e6d"}, - {file = "regex-2020.2.20-cp38-cp38-win_amd64.whl", hash = "sha256:7f78f963e62a61e294adb6ff5db901b629ef78cb2a1cfce3cf4eeba80c1c67aa"}, - {file = "regex-2020.2.20.tar.gz", hash = "sha256:9e9624440d754733eddbcd4614378c18713d2d9d0dc647cf9c72f64e39671be5"}, + {file = "regex-2020.4.4-cp27-cp27m-win32.whl", hash = "sha256:90742c6ff121a9c5b261b9b215cb476eea97df98ea82037ec8ac95d1be7a034f"}, + {file = "regex-2020.4.4-cp27-cp27m-win_amd64.whl", hash = "sha256:24f4f4062eb16c5bbfff6a22312e8eab92c2c99c51a02e39b4eae54ce8255cd1"}, + {file = "regex-2020.4.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:08119f707f0ebf2da60d2f24c2f39ca616277bb67ef6c92b72cbf90cbe3a556b"}, + {file = "regex-2020.4.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c9423a150d3a4fc0f3f2aae897a59919acd293f4cb397429b120a5fcd96ea3db"}, + {file = "regex-2020.4.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:c087bff162158536387c53647411db09b6ee3f9603c334c90943e97b1052a156"}, + {file = "regex-2020.4.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:1cbe0fa0b7f673400eb29e9ef41d4f53638f65f9a2143854de6b1ce2899185c3"}, + {file = "regex-2020.4.4-cp36-cp36m-win32.whl", hash = "sha256:0ce9537396d8f556bcfc317c65b6a0705320701e5ce511f05fc04421ba05b8a8"}, + {file = "regex-2020.4.4-cp36-cp36m-win_amd64.whl", hash = "sha256:7e1037073b1b7053ee74c3c6c0ada80f3501ec29d5f46e42669378eae6d4405a"}, + {file = "regex-2020.4.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4385f12aa289d79419fede43f979e372f527892ac44a541b5446617e4406c468"}, + {file = "regex-2020.4.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a58dd45cb865be0ce1d5ecc4cfc85cd8c6867bea66733623e54bd95131f473b6"}, + {file = "regex-2020.4.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ccccdd84912875e34c5ad2d06e1989d890d43af6c2242c6fcfa51556997af6cd"}, + {file = "regex-2020.4.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:ea4adf02d23b437684cd388d557bf76e3afa72f7fed5bbc013482cc00c816948"}, + {file = "regex-2020.4.4-cp37-cp37m-win32.whl", hash = "sha256:2294f8b70e058a2553cd009df003a20802ef75b3c629506be20687df0908177e"}, + {file = "regex-2020.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:e91ba11da11cf770f389e47c3f5c30473e6d85e06d7fd9dcba0017d2867aab4a"}, + {file = "regex-2020.4.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5635cd1ed0a12b4c42cce18a8d2fb53ff13ff537f09de5fd791e97de27b6400e"}, + {file = "regex-2020.4.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:23069d9c07e115537f37270d1d5faea3e0bdded8279081c4d4d607a2ad393683"}, + {file = "regex-2020.4.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:c162a21e0da33eb3d31a3ac17a51db5e634fc347f650d271f0305d96601dc15b"}, + {file = "regex-2020.4.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:fb95debbd1a824b2c4376932f2216cc186912e389bdb0e27147778cf6acb3f89"}, + {file = "regex-2020.4.4-cp38-cp38-win32.whl", hash = "sha256:2a3bf8b48f8e37c3a40bb3f854bf0121c194e69a650b209628d951190b862de3"}, + {file = "regex-2020.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bfed051dbff32fd8945eccca70f5e22b55e4148d2a8a45141a3b053d6455ae3"}, + {file = "regex-2020.4.4.tar.gz", hash = "sha256:295badf61a51add2d428a46b8580309c520d8b26e769868b922750cf3ce67142"}, ] requests = [ {file = "requests-2.21.0-py2.py3-none-any.whl", hash = "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b"}, @@ -2058,6 +2167,10 @@ shellingham = [ {file = "shellingham-1.3.2-py2.py3-none-any.whl", hash = "sha256:7f6206ae169dc1a03af8a138681b3f962ae61cc93ade84d0585cca3aaf770044"}, {file = "shellingham-1.3.2.tar.gz", hash = "sha256:576c1982bea0ba82fb46c36feb951319d7f42214a82634233f58b40d858a751e"}, ] +singledispatch = [ + {file = "singledispatch-3.4.0.3-py2.py3-none-any.whl", hash = "sha256:833b46966687b3de7f438c761ac475213e53b306740f1abfaa86e1d1aae56aa8"}, + {file = "singledispatch-3.4.0.3.tar.gz", hash = "sha256:5b06af87df13818d14f08a028e42f566640aef80805c3b50c5056b086e3c2b9c"}, +] six = [ {file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"}, {file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"}, @@ -2086,19 +2199,21 @@ tornado = [ {file = "tornado-5.1.1-cp37-cp37m-win32.whl", hash = "sha256:e5f2585afccbff22390cddac29849df463b252b711aa2ce7c5f3f342a5b3b444"}, {file = "tornado-5.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:8e9d728c4579682e837c92fdd98036bd5cdefa1da2aaf6acf26947e6dd0c01c5"}, {file = "tornado-5.1.1.tar.gz", hash = "sha256:4e5158d97583502a7e2739951553cbd88a72076f152b4b11b64b9a10c4c49409"}, - {file = "tornado-6.0.3-cp35-cp35m-win32.whl", hash = "sha256:c9399267c926a4e7c418baa5cbe91c7d1cf362d505a1ef898fde44a07c9dd8a5"}, - {file = "tornado-6.0.3-cp35-cp35m-win_amd64.whl", hash = "sha256:398e0d35e086ba38a0427c3b37f4337327231942e731edaa6e9fd1865bbd6f60"}, - {file = "tornado-6.0.3-cp36-cp36m-win32.whl", hash = "sha256:4e73ef678b1a859f0cb29e1d895526a20ea64b5ffd510a2307b5998c7df24281"}, - {file = "tornado-6.0.3-cp36-cp36m-win_amd64.whl", hash = "sha256:349884248c36801afa19e342a77cc4458caca694b0eda633f5878e458a44cb2c"}, - {file = "tornado-6.0.3-cp37-cp37m-win32.whl", hash = "sha256:559bce3d31484b665259f50cd94c5c28b961b09315ccd838f284687245f416e5"}, - {file = "tornado-6.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:abbe53a39734ef4aba061fca54e30c6b4639d3e1f59653f0da37a0003de148c7"}, - {file = "tornado-6.0.3.tar.gz", hash = "sha256:c845db36ba616912074c5b1ee897f8e0124df269468f25e4fe21fe72f6edd7a9"}, + {file = "tornado-6.0.4-cp35-cp35m-win32.whl", hash = "sha256:5217e601700f24e966ddab689f90b7ea4bd91ff3357c3600fa1045e26d68e55d"}, + {file = "tornado-6.0.4-cp35-cp35m-win_amd64.whl", hash = "sha256:c98232a3ac391f5faea6821b53db8db461157baa788f5d6222a193e9456e1740"}, + {file = "tornado-6.0.4-cp36-cp36m-win32.whl", hash = "sha256:5f6a07e62e799be5d2330e68d808c8ac41d4a259b9cea61da4101b83cb5dc673"}, + {file = "tornado-6.0.4-cp36-cp36m-win_amd64.whl", hash = "sha256:c952975c8ba74f546ae6de2e226ab3cc3cc11ae47baf607459a6728585bb542a"}, + {file = "tornado-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:2c027eb2a393d964b22b5c154d1a23a5f8727db6fda837118a776b29e2b8ebc6"}, + {file = "tornado-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:5618f72e947533832cbc3dec54e1dffc1747a5cb17d1fd91577ed14fa0dc081b"}, + {file = "tornado-6.0.4-cp38-cp38-win32.whl", hash = "sha256:22aed82c2ea340c3771e3babc5ef220272f6fd06b5108a53b4976d0d722bcd52"}, + {file = "tornado-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:c58d56003daf1b616336781b26d184023ea4af13ae143d9dda65e31e534940b9"}, + {file = "tornado-6.0.4.tar.gz", hash = "sha256:0fe2d45ba43b00a41cd73f8be321a44936dc1aba233dee979f17a042b83eb6dc"}, ] tox = [ {file = "tox-3.12.1-py2.py3-none-any.whl", hash = "sha256:f5c8e446b51edd2ea97df31d4ded8c8b72e7d6c619519da6bb6084b9dd5770f9"}, {file = "tox-3.12.1.tar.gz", hash = "sha256:f87fd33892a2df0950e5e034def9468988b8d008c7e9416be665fcc0dd45b14f"}, - {file = "tox-3.14.5-py2.py3-none-any.whl", hash = "sha256:0cbe98369081fa16bd6f1163d3d0b2a62afa29d402ccfad2bd09fb2668be0956"}, - {file = "tox-3.14.5.tar.gz", hash = "sha256:676f1e3e7de245ad870f956436b84ea226210587d1f72c8dfb8cd5ac7b6f0e70"}, + {file = "tox-3.14.6-py2.py3-none-any.whl", hash = "sha256:b2c4b91c975ea5c11463d9ca00bebf82654439c5df0f614807b9bdec62cc9471"}, + {file = "tox-3.14.6.tar.gz", hash = "sha256:a4a6689045d93c208d77230853b28058b7513f5123647b67bf012f82fa168303"}, ] typed-ast = [ {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, @@ -2129,9 +2244,9 @@ typing = [ {file = "typing-3.7.4.1.tar.gz", hash = "sha256:91dfe6f3f706ee8cc32d38edbbf304e9b7583fb37108fef38229617f8b3eba23"}, ] typing-extensions = [ - {file = "typing_extensions-3.7.4.1-py2-none-any.whl", hash = "sha256:910f4656f54de5993ad9304959ce9bb903f90aadc7c67a0bef07e678014e892d"}, - {file = "typing_extensions-3.7.4.1-py3-none-any.whl", hash = "sha256:cf8b63fedea4d89bab840ecbb93e75578af28f76f66c35889bd7065f5af88575"}, - {file = "typing_extensions-3.7.4.1.tar.gz", hash = "sha256:091ecc894d5e908ac75209f10d5b4f118fbdb2eb1ede6a63544054bb1edb41f2"}, + {file = "typing_extensions-3.7.4.2-py2-none-any.whl", hash = "sha256:f8d2bd89d25bc39dabe7d23df520442fa1d8969b82544370e03d88b5a591c392"}, + {file = "typing_extensions-3.7.4.2-py3-none-any.whl", hash = "sha256:6e95524d8a547a91e08f404ae485bbb71962de46967e1b71a0cb89af24e761c5"}, + {file = "typing_extensions-3.7.4.2.tar.gz", hash = "sha256:79ee589a3caca649a9bfd2a8de4709837400dfa00b6cc81962a1e6a1815969ae"}, ] urllib3 = [ {file = "urllib3-1.24.3-py2.py3-none-any.whl", hash = "sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb"}, @@ -2142,12 +2257,12 @@ urllib3 = [ virtualenv = [ {file = "virtualenv-16.7.10-py2.py3-none-any.whl", hash = "sha256:105893c8dc66b7817691c7371439ec18e3b6c5e323a304b5ed96cdd2e75cc1ec"}, {file = "virtualenv-16.7.10.tar.gz", hash = "sha256:e88fdcb08b0ecb11da97868f463dd06275923f50d87f4b9c8b2fc0994eec40f4"}, - {file = "virtualenv-20.0.7-py2.py3-none-any.whl", hash = "sha256:30ea90b21dabd11da5f509710ad3be2ae47d40ccbc717dfdd2efe4367c10f598"}, - {file = "virtualenv-20.0.7.tar.gz", hash = "sha256:4a36a96d785428278edd389d9c36d763c5755844beb7509279194647b1ef47f1"}, + {file = "virtualenv-20.0.17-py2.py3-none-any.whl", hash = "sha256:00cfe8605fb97f5a59d52baab78e6070e72c12ca64f51151695407cc0eb8a431"}, + {file = "virtualenv-20.0.17.tar.gz", hash = "sha256:c8364ec469084046c779c9a11ae6340094e8a0bf1d844330fc55c1cefe67c172"}, ] wcwidth = [ - {file = "wcwidth-0.1.8-py2.py3-none-any.whl", hash = "sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603"}, - {file = "wcwidth-0.1.8.tar.gz", hash = "sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8"}, + {file = "wcwidth-0.1.9-py2.py3-none-any.whl", hash = "sha256:cafe2186b3c009a04067022ce1dcd79cb38d8d65ee4f4791b8888d6599d1bbe1"}, + {file = "wcwidth-0.1.9.tar.gz", hash = "sha256:ee73862862a156bf77ff92b09034fc4825dd3af9cf81bc5b360668d425f3c5f1"}, ] webencodings = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, From 10685f40c25c9db989f6f8f0c65a33ad604e89f2 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Sun, 12 Apr 2020 13:26:35 +0200 Subject: [PATCH 27/80] github: simplify main workflow (#2293) Co-Authored-By: Pradyun Gedam Co-authored-by: Pradyun Gedam --- .github/workflows/main.yml | 145 +++++++++++-------------------------- 1 file changed, 44 insertions(+), 101 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5ec42d4c608..63a8fb7918f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,120 +8,63 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up Python 3.7 + - name: Set up Python 3.8 uses: actions/setup-python@v1 with: - python-version: 3.7 + python-version: 3.8 - name: Linting run: | pip install pre-commit pre-commit run --all-files - Linux: + Tests: needs: Linting - runs-on: ubuntu-latest + name: ${{ matrix.os }} / ${{ matrix.python-version }} + runs-on: ${{ matrix.os }}-latest strategy: matrix: + os: [Ubuntu, MacOS, Windows] python-version: [2.7, 3.5, 3.6, 3.7, 3.8] - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - name: Get full python version - id: full-python-version - run: | - echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") - - name: Install and set up Poetry - run: | - python get-poetry.py --preview -y - source $HOME/.poetry/env - poetry config virtualenvs.in-project true - - name: Set up cache - uses: actions/cache@v1 - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }} - - name: Install dependencies - run: | - source $HOME/.poetry/env - poetry install - - name: Test - run: | - source $HOME/.poetry/env - poetry run pytest -q tests + - uses: actions/checkout@v2 - MacOS: - needs: Linting - runs-on: macos-latest - strategy: - matrix: - python-version: [2.7, 3.5, 3.6, 3.7, 3.8] + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - name: Get full python version - id: full-python-version - run: | - echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") - - name: Install and set up Poetry - run: | - python get-poetry.py --preview -y - source $HOME/.poetry/env - poetry config virtualenvs.in-project true - - name: Set up cache - uses: actions/cache@v1 - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }} - - name: Install dependencies - run: | - source $HOME/.poetry/env - poetry install - - name: Test - run: | - source $HOME/.poetry/env - .venv/bin/pytest -q tests + - name: Get full python version + id: full-python-version + shell: bash + run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") - Windows: - needs: Linting - runs-on: windows-latest - strategy: - matrix: - python-version: [2.7, 3.5, 3.6, 3.7, 3.8] + - name: Install poetry + shell: bash + run: | + curl -fsS -o get-poetry.py https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py + python get-poetry.py --preview -y + echo "::set-env name=PATH::$HOME/.poetry/bin:$PATH" - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - name: Get full python version - id: full-python-version - shell: bash - run: | - echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") - - name: Install and setup Poetry - run: | - python get-poetry.py --preview -y - $env:Path += ";$env:Userprofile\.poetry\bin" - poetry config virtualenvs.in-project true - - name: Set up cache - uses: actions/cache@v1 - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }} - - name: Install dependencies - run: | - $env:Path += ";$env:Userprofile\.poetry\bin" - poetry install - - name: Test - run: | - $env:Path += ";$env:Userprofile\.poetry\bin" - poetry run pytest -q tests + - name: Configure poetry + shell: bash + run: poetry config virtualenvs.in-project true + + - name: Set up cache + uses: actions/cache@v1 + id: cache + with: + path: .venv + key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }} + + - name: Ensure cache is healthy + if: steps.cache.outputs.cache-hit == 'true' + shell: bash + run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv + + - name: Install dependencies + shell: bash + run: poetry install + + - name: Run pytest + shell: bash + run: poetry run pytest -q tests From 32e457b78e79a93563f9c4b7802cd90d8344fe4b Mon Sep 17 00:00:00 2001 From: stephsamson Date: Mon, 13 Apr 2020 10:36:01 +0200 Subject: [PATCH 28/80] Add Triage label to new issues and clean the PR template. --- .github/ISSUE_TEMPLATE/---bug-report.md | 2 +- .github/ISSUE_TEMPLATE/---documentation.md | 2 +- .github/ISSUE_TEMPLATE/---feature-request.md | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 10 ++++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/---bug-report.md b/.github/ISSUE_TEMPLATE/---bug-report.md index caf8db9a353..05288e74fef 100644 --- a/.github/ISSUE_TEMPLATE/---bug-report.md +++ b/.github/ISSUE_TEMPLATE/---bug-report.md @@ -2,7 +2,7 @@ name: "\U0001F41E Bug Report" about: Did you find a bug? title: '' -labels: 'Bug' +labels: Bug, Triage assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/---documentation.md b/.github/ISSUE_TEMPLATE/---documentation.md index 1e6737d6067..4ded4f67949 100644 --- a/.github/ISSUE_TEMPLATE/---documentation.md +++ b/.github/ISSUE_TEMPLATE/---documentation.md @@ -2,7 +2,7 @@ name: "\U0001F4DA Documentation" about: Did you find errors, problems, or anything unintelligible in the docs (https://python-poetry.org/docs)? title: '' -labels: 'Documentation' +labels: Documentation, Triage assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/---feature-request.md b/.github/ISSUE_TEMPLATE/---feature-request.md index f486d4abbdf..6a984e925c5 100644 --- a/.github/ISSUE_TEMPLATE/---feature-request.md +++ b/.github/ISSUE_TEMPLATE/---feature-request.md @@ -2,7 +2,7 @@ name: "\U0001F381 Feature Request" about: Do you have ideas for new features and improvements? title: '' -labels: 'Feature' +labels: Feature, Triage assignees: '' --- diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3b8acacb709..bdba9f27880 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,11 +1,13 @@ # Pull Request Check List -This is just a reminder about the most common mistakes. Please make sure that you tick all *appropriate* boxes. But please read our [contribution guide](https://python-poetry.org/docs/contributing/) at least once, it will save you unnecessary review cycles! +Resolves: #issue-number-here + + - [ ] Added **tests** for changed code. - [ ] Updated **documentation** for changed code. -**Note**: If your Pull Request introduces a new feature or changes the current behavior, it should be based -on the `develop` branch. If it's a bug fix or only a documentation update, it should be based on the `master` branch. + -If you have *any* questions to *any* of the points above, just **submit and ask**! This checklist is here to *help* you, not to deter you from contributing! + From f6759c7bdda12fbfc74793381f0773c162c6a9a0 Mon Sep 17 00:00:00 2001 From: Maximilian Roos <5635139+max-sixty@users.noreply.github.com> Date: Tue, 14 Apr 2020 08:43:31 -0700 Subject: [PATCH 29/80] doc: fix instructions for fish completion --- README.md | 2 +- docs/docs/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9339381d5f7..487307ea5cf 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ poetry completions bash > $(brew --prefix)/etc/bash_completion.d/poetry.bash-com poetry completions fish > ~/.config/fish/completions/poetry.fish # Fish (Homebrew) -poetry completions fish > $(brew --prefix)/share/fish/vendor_completions.d/poetry.fish +poetry completions fish > (brew --prefix)/share/fish/vendor_completions.d/poetry.fish # Zsh poetry completions zsh > ~/.zfunc/_poetry diff --git a/docs/docs/index.md b/docs/docs/index.md index 003ba210533..86cb861a5e1 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -168,7 +168,7 @@ poetry completions bash > $(brew --prefix)/etc/bash_completion.d/poetry.bash-com poetry completions fish > ~/.config/fish/completions/poetry.fish # Fish (Homebrew) -poetry completions fish > $(brew --prefix)/share/fish/vendor_completions.d/poetry.fish +poetry completions fish > (brew --prefix)/share/fish/vendor_completions.d/poetry.fish # Zsh poetry completions zsh > ~/.zfunc/_poetry From 288d99739fba4425def7c567d71537ce5bd2a0f9 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 14 Apr 2020 23:45:14 +0800 Subject: [PATCH 30/80] pre-commit: use official isort repo Co-Authored-By: Pradyun Gedam --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b296497d29f..79b09408ed4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,8 +9,8 @@ repos: hooks: - id: flake8 - - repo: https://github.com/pre-commit/mirrors-isort - rev: v4.3.21 + - repo: https://github.com/timothycrosley/isort + rev: 4.3.21-2 hooks: - id: isort additional_dependencies: [toml] From 54870697d921ae6efdbba0bc86f6b54c86d6896a Mon Sep 17 00:00:00 2001 From: Ryan Butler Date: Sat, 21 Mar 2020 18:07:15 -0400 Subject: [PATCH 31/80] remove_venv will empty folder contents if it can't delete folder itself --- poetry/utils/env.py | 49 +++++++++---- tests/console/commands/env/test_use.py | 14 ++-- tests/utils/test_env.py | 97 ++++++++++++++++++-------- 3 files changed, 110 insertions(+), 50 deletions(-) diff --git a/poetry/utils/env.py b/poetry/utils/env.py index 0c326880ba1..1bc00f32af0 100644 --- a/poetry/utils/env.py +++ b/poetry/utils/env.py @@ -15,6 +15,7 @@ from typing import List from typing import Optional from typing import Tuple +from typing import Union import tomlkit @@ -403,7 +404,7 @@ def remove(self, python): # type: (str) -> Env if venv.path.name == python: # Exact virtualenv name if not envs_file.exists(): - self.remove_venv(str(venv.path)) + self.remove_venv(venv.path) return venv @@ -413,7 +414,7 @@ def remove(self, python): # type: (str) -> Env current_env = envs.get(base_env_name) if not current_env: - self.remove_venv(str(venv.path)) + self.remove_venv(venv.path) return venv @@ -421,7 +422,7 @@ def remove(self, python): # type: (str) -> Env del envs[base_env_name] envs_file.write(envs) - self.remove_venv(str(venv.path)) + self.remove_venv(venv.path) return venv @@ -475,7 +476,7 @@ def remove(self, python): # type: (str) -> Env del envs[base_env_name] envs_file.write(envs) - self.remove_venv(str(venv)) + self.remove_venv(venv) return VirtualEnv(venv) @@ -621,7 +622,7 @@ def create_venv( "Creating virtualenv {} in {}".format(name, str(venv_path)) ) - self.build_venv(str(venv), executable=executable) + self.build_venv(venv, executable=executable) else: if force: if not env.is_sane(): @@ -633,8 +634,8 @@ def create_venv( io.write_line( "Recreating virtualenv {} in {}".format(name, str(venv)) ) - self.remove_venv(str(venv)) - self.build_venv(str(venv), executable=executable) + self.remove_venv(venv) + self.build_venv(venv, executable=executable) elif io.is_very_verbose(): io.write_line("Virtualenv {} already exists.".format(name)) @@ -657,7 +658,9 @@ def create_venv( return VirtualEnv(venv) @classmethod - def build_venv(cls, path, executable=None): + def build_venv( + cls, path, executable=None + ): # type: (Union[Path,str], Optional[str]) -> () if executable is not None: # Create virtualenv by using an external executable try: @@ -682,21 +685,41 @@ def build_venv(cls, path, executable=None): use_symlinks = True builder = EnvBuilder(with_pip=True, symlinks=use_symlinks) - builder.create(path) + builder.create(str(path)) except ImportError: try: # We fallback on virtualenv for Python 2.7 from virtualenv import create_environment - create_environment(path) + create_environment(str(path)) except ImportError: # since virtualenv>20 we have to use cli_run from virtualenv import cli_run - cli_run([path]) + cli_run([str(path)]) - def remove_venv(self, path): # type: (str) -> None - shutil.rmtree(path) + @classmethod + def remove_venv(cls, path): # type: (Union[Path,str]) -> None + if isinstance(path, str): + path = Path(path) + assert path.is_dir() + try: + shutil.rmtree(str(path)) + return + except OSError as e: + # Continue only if e.errno == 16 + if e.errno != 16: # ERRNO 16: Device or resource busy + raise e + + # Delete all files and folders but the toplevel one. This is because sometimes + # the venv folder is mounted by the OS, such as in a docker volume. In such + # cases, an attempt to delete the folder itself will result in an `OSError`. + # See https://github.com/python-poetry/poetry/pull/2064 + for file_path in path.iterdir(): + if file_path.is_file() or file_path.is_symlink(): + file_path.unlink() + elif file_path.is_dir(): + shutil.rmtree(str(file_path)) def get_base_prefix(self): # type: () -> Path if hasattr(sys, "real_prefix"): diff --git a/tests/console/commands/env/test_use.py b/tests/console/commands/env/test_use.py index 2b1967bf3b1..0029ee00854 100644 --- a/tests/console/commands/env/test_use.py +++ b/tests/console/commands/env/test_use.py @@ -1,7 +1,9 @@ import os -import shutil import sys +from typing import Optional +from typing import Union + import tomlkit from cleo.testers import CommandTester @@ -16,12 +18,8 @@ CWD = Path(__file__).parent.parent / "fixtures" / "simple_project" -def build_venv(path, executable=None): - os.mkdir(path) - - -def remove_venv(path): - shutil.rmtree(path) +def build_venv(path, executable=None): # type: (Union[Path,str], Optional[str]) -> () + os.mkdir(str(path)) def check_output_wrapper(version=Version.parse("3.7.1")): @@ -62,7 +60,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(app, tmp_dir, m ) m.assert_called_with( - os.path.join(tmp_dir, "{}-py3.7".format(venv_name)), executable="python3.7" + Path(tmp_dir) / "{}-py3.7".format(venv_name), executable="python3.7" ) envs_file = TomlFile(Path(tmp_dir) / "envs.toml") diff --git a/tests/utils/test_env.py b/tests/utils/test_env.py index 9ed47c87b56..04bb4f8808e 100644 --- a/tests/utils/test_env.py +++ b/tests/utils/test_env.py @@ -2,6 +2,9 @@ import shutil import sys +from typing import Optional +from typing import Union + import pytest import tomlkit @@ -83,12 +86,8 @@ def test_env_get_in_project_venv(manager, poetry): shutil.rmtree(str(venv.path)) -def build_venv(path, executable=None): - os.mkdir(path) - - -def remove_venv(path): - shutil.rmtree(path) +def build_venv(path, executable=None): # type: (Union[Path,str], Optional[str]) -> () + os.mkdir(str(path)) def check_output_wrapper(version=Version.parse("3.7.1")): @@ -125,7 +124,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file( venv_name = EnvManager.generate_env_name("simple-project", str(poetry.file.parent)) m.assert_called_with( - os.path.join(tmp_dir, "{}-py3.7".format(venv_name)), executable="python3.7" + Path(tmp_dir) / "{}-py3.7".format(venv_name), executable="python3.7" ) envs_file = TomlFile(Path(tmp_dir) / "envs.toml") @@ -243,7 +242,7 @@ def test_activate_activates_different_virtualenv_with_envs_file( env = manager.activate("python3.6", NullIO()) m.assert_called_with( - os.path.join(tmp_dir, "{}-py3.6".format(venv_name)), executable="python3.6" + Path(tmp_dir) / "{}-py3.6".format(venv_name), executable="python3.6" ) assert envs_file.exists() @@ -289,17 +288,15 @@ def test_activate_activates_recreates_for_different_patch( "poetry.utils.env.EnvManager.build_venv", side_effect=build_venv ) remove_venv_m = mocker.patch( - "poetry.utils.env.EnvManager.remove_venv", side_effect=remove_venv + "poetry.utils.env.EnvManager.remove_venv", side_effect=EnvManager.remove_venv ) env = manager.activate("python3.7", NullIO()) build_venv_m.assert_called_with( - os.path.join(tmp_dir, "{}-py3.7".format(venv_name)), executable="python3.7" - ) - remove_venv_m.assert_called_with( - os.path.join(tmp_dir, "{}-py3.7".format(venv_name)) + Path(tmp_dir) / "{}-py3.7".format(venv_name), executable="python3.7" ) + remove_venv_m.assert_called_with(Path(tmp_dir) / "{}-py3.7".format(venv_name)) assert envs_file.exists() envs = envs_file.read() @@ -340,7 +337,7 @@ def test_activate_does_not_recreate_when_switching_minor( "poetry.utils.env.EnvManager.build_venv", side_effect=build_venv ) remove_venv_m = mocker.patch( - "poetry.utils.env.EnvManager.remove_venv", side_effect=remove_venv + "poetry.utils.env.EnvManager.remove_venv", side_effect=EnvManager.remove_venv ) env = manager.activate("python3.6", NullIO()) @@ -535,6 +532,54 @@ def test_remove_also_deactivates(tmp_dir, manager, poetry, config, mocker): assert venv_name not in envs +def test_remove_keeps_dir_if_not_deleteable(tmp_dir, manager, poetry, config, mocker): + # Ensure we empty rather than delete folder if its is an active mount point. + # See https://github.com/python-poetry/poetry/pull/2064 + config.merge({"virtualenvs": {"path": str(tmp_dir)}}) + + venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) + venv_path = Path(tmp_dir) / "{}-py3.6".format(venv_name) + venv_path.mkdir() + + folder1_path = venv_path / "folder1" + folder1_path.mkdir() + + file1_path = folder1_path / "file1" + file1_path.touch(exist_ok=False) + + file2_path = venv_path / "file2" + file2_path.touch(exist_ok=False) + + mocker.patch( + "poetry.utils._compat.subprocess.check_output", + side_effect=check_output_wrapper(Version.parse("3.6.6")), + ) + + original_rmtree = shutil.rmtree + + def err_on_rm_venv_only(path, *args, **kwargs): + print(path) + if path == str(venv_path): + raise OSError(16, "Test error") # ERRNO 16: Device or resource busy + else: + original_rmtree(path) + + m = mocker.patch("shutil.rmtree", side_effect=err_on_rm_venv_only) + + venv = manager.remove("{}-py3.6".format(venv_name)) + + m.assert_any_call(str(venv_path)) + + assert venv_path == venv.path + assert venv_path.exists() + + assert not folder1_path.exists() + assert not file1_path.exists() + assert not file2_path.exists() + + m.side_effect = original_rmtree # Avoid teardown using `err_on_rm_venv_only` + + def test_env_has_symlinks_on_nix(tmp_dir, tmp_venv): venv_available = False try: @@ -584,7 +629,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_generic_ manager.create_venv(NullIO()) m.assert_called_with( - str(Path("/foo/virtualenvs/{}-py3.7".format(venv_name))), executable="python3" + Path("/foo/virtualenvs/{}-py3.7".format(venv_name)), executable="python3" ) @@ -608,7 +653,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_specific manager.create_venv(NullIO()) m.assert_called_with( - str(Path("/foo/virtualenvs/{}-py3.8".format(venv_name))), executable="python3.8" + Path("/foo/virtualenvs/{}-py3.8".format(venv_name)), executable="python3.8" ) @@ -691,11 +736,9 @@ def test_create_venv_uses_patch_version_to_detect_compatibility( assert not check_output.called m.assert_called_with( - str( - Path( - "/foo/virtualenvs/{}-py{}.{}".format( - venv_name, version.major, version.minor - ) + Path( + "/foo/virtualenvs/{}-py{}.{}".format( + venv_name, version.major, version.minor ) ), executable=None, @@ -730,11 +773,9 @@ def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable( assert check_output.called m.assert_called_with( - str( - Path( - "/foo/virtualenvs/{}-py{}.{}".format( - venv_name, version.major, version.minor - 1 - ) + Path( + "/foo/virtualenvs/{}-py{}.{}".format( + venv_name, version.major, version.minor - 1 ) ), executable="python{}.{}".format(version.major, version.minor - 1), @@ -768,9 +809,7 @@ def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir( manager.activate("python3.7", NullIO()) - m.assert_called_with( - os.path.join(str(poetry.file.parent), ".venv"), executable="python3.7" - ) + m.assert_called_with(poetry.file.parent / ".venv", executable="python3.7") envs_file = TomlFile(Path(tmp_dir) / "virtualenvs" / "envs.toml") assert not envs_file.exists() From dad6b0841b997000ef017c6738064f57b60bb8f9 Mon Sep 17 00:00:00 2001 From: George Hawkins Date: Mon, 20 Apr 2020 23:32:38 +0200 Subject: [PATCH 32/80] doc: update incorrect "create virtualenv" link --- docs/docs/cli.md | 2 +- docs/docs/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/cli.md b/docs/docs/cli.md index d8906f26d77..a5b7df3cd6b 100644 --- a/docs/docs/cli.md +++ b/docs/docs/cli.md @@ -456,4 +456,4 @@ poetry export -f requirements.txt > requirements.txt The `env` command regroups sub commands to interact with the virtualenvs associated with a specific project. -See [Managing environments](./managing-environments.md) for more information about these commands. +See [Managing environments](/docs/managing-environments.md) for more information about these commands. diff --git a/docs/docs/index.md b/docs/docs/index.md index 86cb861a5e1..0ba5a1840db 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -28,7 +28,7 @@ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poet !!! note You only need to install Poetry once. It will automatically pick up the current - Python version and use it to [create virtualenvs](/docs/basic-usage/#poetry-and-virtualenvs) accordingly. + Python version and use it to [create virtualenvs](/docs/managing-environments.md) accordingly. The installer installs the `poetry` tool to Poetry's `bin` directory. On Unix it is located at `$HOME/.poetry/bin` and on Windows at `%USERPROFILE%\.poetry\bin`. From dbc1e1b932794d7a06fa12589ebc82972bb7317e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6hl?= Date: Tue, 21 Apr 2020 19:25:28 +0200 Subject: [PATCH 33/80] build: remove 'm' and 'd' ABI tags for Python 3.8 wheels --- poetry/masonry/utils/tags.py | 25 +++++----- poetry/utils/env.py | 11 +++++ tests/masonry/utils/test_tags.py | 79 ++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 tests/masonry/utils/test_tags.py diff --git a/poetry/masonry/utils/tags.py b/poetry/masonry/utils/tags.py index 175cdd8b73b..88dc33f5b53 100644 --- a/poetry/masonry/utils/tags.py +++ b/poetry/masonry/utils/tags.py @@ -76,19 +76,22 @@ def get_abi_tag(env): env, "Py_DEBUG", lambda: hasattr(sys, "gettotalrefcount"), - warn=(impl == "cp"), + warn=(impl == "cp" and env.version_info < (3, 8)), ): d = "d" - if get_flag(env, "WITH_PYMALLOC", lambda: impl == "cp", warn=(impl == "cp")): - m = "m" - if get_flag( - env, - "Py_UNICODE_SIZE", - lambda: sys.maxunicode == 0x10FFFF, - expected=4, - warn=(impl == "cp" and env.version_info < (3, 3)), - ) and env.version_info < (3, 3): - u = "u" + if env.version_info < (3, 8): + if get_flag( + env, "WITH_PYMALLOC", lambda: impl == "cp", warn=(impl == "cp") + ): + m = "m" + if get_flag( + env, + "Py_UNICODE_SIZE", + lambda: sys.maxunicode == 0x10FFFF, + expected=4, + warn=(impl == "cp" and env.version_info < (3, 3)), + ) and env.version_info < (3, 3): + u = "u" abi = "%s%s%s%s%s" % (impl, get_impl_ver(env), d, m, u) elif soabi and soabi.startswith("cpython-"): abi = "cp" + soabi.split("-")[1] diff --git a/poetry/utils/env.py b/poetry/utils/env.py index 0c326880ba1..5b18878df5f 100644 --- a/poetry/utils/env.py +++ b/poetry/utils/env.py @@ -1151,6 +1151,7 @@ def __init__( is_venv=False, pip_version="19.1", sys_path=None, + config_vars=None, **kwargs ): super(MockEnv, self).__init__(**kwargs) @@ -1162,6 +1163,7 @@ def __init__( self._is_venv = is_venv self._pip_version = Version.parse(pip_version) self._sys_path = sys_path + self._config_vars = config_vars @property def version_info(self): # type: () -> Tuple[int] @@ -1192,3 +1194,12 @@ def sys_path(self): def is_venv(self): # type: () -> bool return self._is_venv + + def config_var(self, var): # type: (str) -> Any + if self._config_vars is None: + return super().config_var(var) + else: + try: + return self._config_vars[var] + except KeyError: + return None diff --git a/tests/masonry/utils/test_tags.py b/tests/masonry/utils/test_tags.py new file mode 100644 index 00000000000..50193f509a2 --- /dev/null +++ b/tests/masonry/utils/test_tags.py @@ -0,0 +1,79 @@ +import pytest + +from poetry.masonry.utils.tags import get_abi_tag +from poetry.utils.env import MockEnv + + +def test_tags_cpython38(): + assert ( + get_abi_tag( + MockEnv( + version_info=(3, 8, 0), + python_implementation="CPython", + config_vars={"Py_DEBUG": True}, + ) + ) + == "cp38d" + ) + assert ( + get_abi_tag( + MockEnv( + version_info=(3, 8, 0), python_implementation="CPython", config_vars={}, + ) + ) + == "cp38" + ) + + +def test_tags_cpython37(): + assert ( + get_abi_tag( + MockEnv( + version_info=(3, 7, 3), + python_implementation="CPython", + config_vars={"Py_DEBUG": True, "WITH_PYMALLOC": True}, + ) + ) + == "cp37dm" + ) + assert ( + get_abi_tag( + MockEnv( + version_info=(3, 7, 3), + python_implementation="CPython", + config_vars={"Py_DEBUG": True, "WITH_PYMALLOC": False}, + ) + ) + == "cp37d" + ) + assert ( + get_abi_tag( + MockEnv( + version_info=(3, 7, 3), + python_implementation="CPython", + config_vars={"Py_DEBUG": False, "WITH_PYMALLOC": True}, + ) + ) + == "cp37m" + ) + assert ( + get_abi_tag( + MockEnv( + version_info=(3, 7, 3), + python_implementation="CPython", + config_vars={"Py_DEBUG": False, "WITH_PYMALLOC": False}, + ) + ) + == "cp37" + ) + with pytest.warns(RuntimeWarning): + assert ( + get_abi_tag( + MockEnv( + version_info=(3, 7, 3), + python_implementation="CPython", + config_vars={"Py_DEBUG": False}, + ) + ) + == "cp37m" + ) From 9a283965cb6cc5ddf228c73b6f7c3df1a4392d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oleg=20H=C3=B6fling?= Date: Wed, 22 Apr 2020 20:38:28 +0200 Subject: [PATCH 34/80] Fix regression in stub-only package (PEP-561) support Signed-off-by: oleg.hoefling --- poetry/masonry/utils/package_include.py | 23 ++++++++++---- .../pep_561_stub_only/pkg-stubs/__init__.pyi | 0 .../pep_561_stub_only/pkg-stubs/module.pyi | 4 +++ .../pkg-stubs/subpkg/__init__.pyi | 0 .../fixtures/pep_561_stub_only/pyproject.toml | 14 +++++++++ .../pkg-stubs/__init__.pyi | 0 .../pkg-stubs/module.pyi | 4 +++ .../pkg-stubs/py.typed | 1 + .../pkg-stubs/subpkg/__init__.pyi | 0 .../pep_561_stub_only_partial/pyproject.toml | 14 +++++++++ .../pep_561_stub_only_src/pyproject.toml | 14 +++++++++ .../src/pkg-stubs/__init__.pyi | 0 .../src/pkg-stubs/module.pyi | 4 +++ .../src/pkg-stubs/subpkg/__init__.pyi | 0 tests/masonry/builders/test_sdist.py | 18 +++++++++++ tests/masonry/builders/test_wheel.py | 30 +++++++++++++++++++ .../pep_561_stub_only/bad/__init__.pyi | 0 .../fixtures/pep_561_stub_only/bad/module.pyi | 5 ++++ .../pep_561_stub_only/good-stubs/__init__.pyi | 0 .../pep_561_stub_only/good-stubs/module.pyi | 5 ++++ tests/masonry/utils/test_package_include.py | 17 +++++++++++ 21 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only/pkg-stubs/__init__.pyi create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only/pkg-stubs/module.pyi create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only/pkg-stubs/subpkg/__init__.pyi create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only/pyproject.toml create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/__init__.pyi create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/module.pyi create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/py.typed create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/subpkg/__init__.pyi create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only_partial/pyproject.toml create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only_src/pyproject.toml create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only_src/src/pkg-stubs/__init__.pyi create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only_src/src/pkg-stubs/module.pyi create mode 100644 tests/masonry/builders/fixtures/pep_561_stub_only_src/src/pkg-stubs/subpkg/__init__.pyi create mode 100644 tests/masonry/utils/fixtures/pep_561_stub_only/bad/__init__.pyi create mode 100644 tests/masonry/utils/fixtures/pep_561_stub_only/bad/module.pyi create mode 100644 tests/masonry/utils/fixtures/pep_561_stub_only/good-stubs/__init__.pyi create mode 100644 tests/masonry/utils/fixtures/pep_561_stub_only/good-stubs/module.pyi diff --git a/poetry/masonry/utils/package_include.py b/poetry/masonry/utils/package_include.py index 512c6c48f63..47345765f07 100644 --- a/poetry/masonry/utils/package_include.py +++ b/poetry/masonry/utils/package_include.py @@ -33,6 +33,21 @@ def refresh(self): # type: () -> PackageInclude return self.check_elements() + def is_stub_only(self): # type: () -> bool + # returns `True` if this a PEP 561 stub-only package, + # see [PEP 561](https://www.python.org/dev/peps/pep-0561/#stub-only-packages) + return self.package.endswith("-stubs") and all( + el.suffix == ".pyi" + or (el.parent.name == self.package and el.name == "py.typed") + for el in self.elements + if el.is_file() + ) + + def has_modules(self): # type: () -> bool + # Packages no longer need an __init__.py in python3, but there must + # at least be one .py file for it to be considered a package + return any(element.suffix == ".py" for element in self.elements) + def check_elements(self): # type: () -> PackageInclude if not self._elements: raise ValueError( @@ -43,20 +58,18 @@ def check_elements(self): # type: () -> PackageInclude if len(self._elements) > 1: # Probably glob self._is_package = True + self._package = root.parent.name - # Packages no longer need an __init__.py in python3, but there must - # at least be one .py file for it to be considered a package - if not any([element.suffix == ".py" for element in self._elements]): + if not self.is_stub_only() and not self.has_modules(): raise ValueError("{} is not a package.".format(root.name)) - self._package = root.parent.name else: if root.is_dir(): # If it's a directory, we include everything inside it self._package = root.name self._elements = sorted(list(root.glob("**/*"))) - if not any([element.suffix == ".py" for element in self._elements]): + if not self.is_stub_only() and not self.has_modules(): raise ValueError("{} is not a package.".format(root.name)) self._is_package = True diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only/pkg-stubs/__init__.pyi b/tests/masonry/builders/fixtures/pep_561_stub_only/pkg-stubs/__init__.pyi new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only/pkg-stubs/module.pyi b/tests/masonry/builders/fixtures/pep_561_stub_only/pkg-stubs/module.pyi new file mode 100644 index 00000000000..d79e6e39ee0 --- /dev/null +++ b/tests/masonry/builders/fixtures/pep_561_stub_only/pkg-stubs/module.pyi @@ -0,0 +1,4 @@ +"""Example module""" +from typing import Tuple + +version_info = Tuple[int, int, int] diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only/pkg-stubs/subpkg/__init__.pyi b/tests/masonry/builders/fixtures/pep_561_stub_only/pkg-stubs/subpkg/__init__.pyi new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only/pyproject.toml b/tests/masonry/builders/fixtures/pep_561_stub_only/pyproject.toml new file mode 100644 index 00000000000..36a077afd95 --- /dev/null +++ b/tests/masonry/builders/fixtures/pep_561_stub_only/pyproject.toml @@ -0,0 +1,14 @@ +[tool.poetry] +name = "pep-561-stubs" +version = "0.1" +description = "PEP 561 stub package example" +authors = [ + "Oleg Höfling " +] +license = "MIT" +packages = [ + {include = "pkg-stubs"} +] + +[tool.poetry.dependencies] +python = "^3.6" diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/__init__.pyi b/tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/__init__.pyi new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/module.pyi b/tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/module.pyi new file mode 100644 index 00000000000..d79e6e39ee0 --- /dev/null +++ b/tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/module.pyi @@ -0,0 +1,4 @@ +"""Example module""" +from typing import Tuple + +version_info = Tuple[int, int, int] diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/py.typed b/tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/py.typed new file mode 100644 index 00000000000..b648ac92333 --- /dev/null +++ b/tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/py.typed @@ -0,0 +1 @@ +partial diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/subpkg/__init__.pyi b/tests/masonry/builders/fixtures/pep_561_stub_only_partial/pkg-stubs/subpkg/__init__.pyi new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only_partial/pyproject.toml b/tests/masonry/builders/fixtures/pep_561_stub_only_partial/pyproject.toml new file mode 100644 index 00000000000..db202c04a1c --- /dev/null +++ b/tests/masonry/builders/fixtures/pep_561_stub_only_partial/pyproject.toml @@ -0,0 +1,14 @@ +[tool.poetry] +name = "pep-561-stubs" +version = "0.1" +description = "PEP 561 stub package example with the py.typed marker file" +authors = [ + "Oleg Höfling " +] +license = "MIT" +packages = [ + {include = "pkg-stubs"} +] + +[tool.poetry.dependencies] +python = "^3.6" diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only_src/pyproject.toml b/tests/masonry/builders/fixtures/pep_561_stub_only_src/pyproject.toml new file mode 100644 index 00000000000..666b2b24f6d --- /dev/null +++ b/tests/masonry/builders/fixtures/pep_561_stub_only_src/pyproject.toml @@ -0,0 +1,14 @@ +[tool.poetry] +name = "pep-561-stubs" +version = "0.1" +description = "PEP 561 stub package example with an src layout" +authors = [ + "Oleg Höfling " +] +license = "MIT" +packages = [ + {include = "pkg-stubs", from = "src"} +] + +[tool.poetry.dependencies] +python = "^3.6" diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only_src/src/pkg-stubs/__init__.pyi b/tests/masonry/builders/fixtures/pep_561_stub_only_src/src/pkg-stubs/__init__.pyi new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only_src/src/pkg-stubs/module.pyi b/tests/masonry/builders/fixtures/pep_561_stub_only_src/src/pkg-stubs/module.pyi new file mode 100644 index 00000000000..d79e6e39ee0 --- /dev/null +++ b/tests/masonry/builders/fixtures/pep_561_stub_only_src/src/pkg-stubs/module.pyi @@ -0,0 +1,4 @@ +"""Example module""" +from typing import Tuple + +version_info = Tuple[int, int, int] diff --git a/tests/masonry/builders/fixtures/pep_561_stub_only_src/src/pkg-stubs/subpkg/__init__.pyi b/tests/masonry/builders/fixtures/pep_561_stub_only_src/src/pkg-stubs/subpkg/__init__.pyi new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/masonry/builders/test_sdist.py b/tests/masonry/builders/test_sdist.py index ed2ded503df..7b55e2acbb2 100644 --- a/tests/masonry/builders/test_sdist.py +++ b/tests/masonry/builders/test_sdist.py @@ -488,3 +488,21 @@ def test_excluded_subpackage(): exec(compile(setup_ast, filename="setup.py", mode="exec"), ns) assert ns["packages"] == ["example"] + + +def test_sdist_package_pep_561_stub_only(): + root = fixtures_dir / "pep_561_stub_only" + poetry = Factory().create_poetry(root) + + builder = SdistBuilder(poetry, NullEnv(), NullIO()) + builder.build() + + sdist = root / "dist" / "pep-561-stubs-0.1.tar.gz" + + assert sdist.exists() + + with tarfile.open(str(sdist), "r") as tar: + names = tar.getnames() + assert "pep-561-stubs-0.1/pkg-stubs/__init__.pyi" in names + assert "pep-561-stubs-0.1/pkg-stubs/module.pyi" in names + assert "pep-561-stubs-0.1/pkg-stubs/subpkg/__init__.pyi" in names diff --git a/tests/masonry/builders/test_wheel.py b/tests/masonry/builders/test_wheel.py index ec3de8f7a60..36f8c27170b 100644 --- a/tests/masonry/builders/test_wheel.py +++ b/tests/masonry/builders/test_wheel.py @@ -162,3 +162,33 @@ def test_dist_info_file_permissions(): z.getinfo("my_package-1.2.3.dist-info/entry_points.txt").external_attr == 0o644 << 16 ) + + +@pytest.mark.parametrize( + "package", + ["pep_561_stub_only", "pep_561_stub_only_partial", "pep_561_stub_only_src"], +) +def test_wheel_package_pep_561_stub_only(package): + root = fixtures_dir / package + WheelBuilder.make(Factory().create_poetry(root), NullEnv(), NullIO()) + + whl = root / "dist" / "pep_561_stubs-0.1-py3-none-any.whl" + + assert whl.exists() + + with zipfile.ZipFile(str(whl)) as z: + assert "pkg-stubs/__init__.pyi" in z.namelist() + assert "pkg-stubs/module.pyi" in z.namelist() + assert "pkg-stubs/subpkg/__init__.pyi" in z.namelist() + + +def test_wheel_package_pep_561_stub_only_includes_typed_marker(): + root = fixtures_dir / "pep_561_stub_only_partial" + WheelBuilder.make(Factory().create_poetry(root), NullEnv(), NullIO()) + + whl = root / "dist" / "pep_561_stubs-0.1-py3-none-any.whl" + + assert whl.exists() + + with zipfile.ZipFile(str(whl)) as z: + assert "pkg-stubs/py.typed" in z.namelist() diff --git a/tests/masonry/utils/fixtures/pep_561_stub_only/bad/__init__.pyi b/tests/masonry/utils/fixtures/pep_561_stub_only/bad/__init__.pyi new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/masonry/utils/fixtures/pep_561_stub_only/bad/module.pyi b/tests/masonry/utils/fixtures/pep_561_stub_only/bad/module.pyi new file mode 100644 index 00000000000..f85a07d465a --- /dev/null +++ b/tests/masonry/utils/fixtures/pep_561_stub_only/bad/module.pyi @@ -0,0 +1,5 @@ +"""Example module""" +from typing import Tuple + + +version_info = Tuple[int, int, int] diff --git a/tests/masonry/utils/fixtures/pep_561_stub_only/good-stubs/__init__.pyi b/tests/masonry/utils/fixtures/pep_561_stub_only/good-stubs/__init__.pyi new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/masonry/utils/fixtures/pep_561_stub_only/good-stubs/module.pyi b/tests/masonry/utils/fixtures/pep_561_stub_only/good-stubs/module.pyi new file mode 100644 index 00000000000..f85a07d465a --- /dev/null +++ b/tests/masonry/utils/fixtures/pep_561_stub_only/good-stubs/module.pyi @@ -0,0 +1,5 @@ +"""Example module""" +from typing import Tuple + + +version_info = Tuple[int, int, int] diff --git a/tests/masonry/utils/test_package_include.py b/tests/masonry/utils/test_package_include.py index 36b5985800b..88ce75101d9 100644 --- a/tests/masonry/utils/test_package_include.py +++ b/tests/masonry/utils/test_package_include.py @@ -50,3 +50,20 @@ def test_package_include_with_non_existent_directory(): err_str = str(with_includes / "not_a_dir") + " does not contain any element" assert str(e.value) == err_str + + +def test_pep_561_stub_only_package_good_name_suffix(): + pkg_include = PackageInclude( + base=fixtures_dir / "pep_561_stub_only", include="good-stubs" + ) + assert pkg_include.elements == [ + fixtures_dir / "pep_561_stub_only/good-stubs/__init__.pyi", + fixtures_dir / "pep_561_stub_only/good-stubs/module.pyi", + ] + + +def test_pep_561_stub_only_package_bad_name_suffix(): + with pytest.raises(ValueError) as e: + PackageInclude(base=fixtures_dir / "pep_561_stub_only", include="bad") + + assert str(e.value) == "bad is not a package." From 9f93df1140efd44f37d07fc04fe5eb9abdc105db Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Sat, 25 Apr 2020 13:49:28 +0200 Subject: [PATCH 35/80] Handle whitespaces for PEP-440 constraints * fix incorrect parsing of spaces when parsing version constraints * add tests for `parse_constraint` --- poetry/semver/__init__.py | 2 +- poetry/semver/patterns.py | 4 +- tests/semver/test_parse_constraint.py | 86 +++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 tests/semver/test_parse_constraint.py diff --git a/poetry/semver/__init__.py b/poetry/semver/__init__.py index 725b7d43f58..39ab433d670 100644 --- a/poetry/semver/__init__.py +++ b/poetry/semver/__init__.py @@ -20,7 +20,7 @@ def parse_constraint(constraints): # type: (str) -> VersionConstraint or_groups = [] for constraints in or_constraints: and_constraints = re.split( - "(?< ,]) *(?< ,]) *(?|!=|>=?|<=?|==?)?\s*({}|dev)".format(_COMPLETE_VERSION) diff --git a/tests/semver/test_parse_constraint.py b/tests/semver/test_parse_constraint.py new file mode 100644 index 00000000000..e950168f17a --- /dev/null +++ b/tests/semver/test_parse_constraint.py @@ -0,0 +1,86 @@ +import pytest + +from poetry.semver import Version +from poetry.semver import VersionRange +from poetry.semver import VersionUnion +from poetry.semver import parse_constraint + + +@pytest.mark.parametrize( + "constraint,version", + [ + ("~=3.8", VersionRange(min=Version(3, 8), max=Version(4, 0), include_min=True)), + ( + "~= 3.8", + VersionRange(min=Version(3, 8), max=Version(4, 0), include_min=True), + ), + ("~3.8", VersionRange(min=Version(3, 8), max=Version(3, 9), include_min=True)), + ("~ 3.8", VersionRange(min=Version(3, 8), max=Version(3, 9), include_min=True)), + (">3.8", VersionRange(min=Version(3, 8))), + (">=3.8", VersionRange(min=Version(3, 8), include_min=True)), + (">= 3.8", VersionRange(min=Version(3, 8), include_min=True)), + ( + ">3.8,<=6.5", + VersionRange(min=Version(3, 8), max=Version(6, 5), include_max=True), + ), + ( + ">3.8,<= 6.5", + VersionRange(min=Version(3, 8), max=Version(6, 5), include_max=True), + ), + ( + "> 3.8,<= 6.5", + VersionRange(min=Version(3, 8), max=Version(6, 5), include_max=True), + ), + ( + "> 3.8,<=6.5", + VersionRange(min=Version(3, 8), max=Version(6, 5), include_max=True), + ), + ( + ">3.8 ,<=6.5", + VersionRange(min=Version(3, 8), max=Version(6, 5), include_max=True), + ), + ( + ">3.8, <=6.5", + VersionRange(min=Version(3, 8), max=Version(6, 5), include_max=True), + ), + ( + ">3.8 , <=6.5", + VersionRange(min=Version(3, 8), max=Version(6, 5), include_max=True), + ), + ( + "==3.8", + VersionRange( + min=Version(3, 8), max=Version(3, 8), include_min=True, include_max=True + ), + ), + ( + "== 3.8", + VersionRange( + min=Version(3, 8), max=Version(3, 8), include_min=True, include_max=True + ), + ), + ( + "~2.7 || ~3.8", + VersionUnion( + VersionRange(min=Version(2, 7), max=Version(2, 8), include_min=True), + VersionRange(min=Version(3, 8), max=Version(3, 9), include_min=True), + ), + ), + ( + "~2.7||~3.8", + VersionUnion( + VersionRange(min=Version(2, 7), max=Version(2, 8), include_min=True), + VersionRange(min=Version(3, 8), max=Version(3, 9), include_min=True), + ), + ), + ( + "~ 2.7||~ 3.8", + VersionUnion( + VersionRange(min=Version(2, 7), max=Version(2, 8), include_min=True), + VersionRange(min=Version(3, 8), max=Version(3, 9), include_min=True), + ), + ), + ], +) +def test_parse_constraint(constraint, version): + assert parse_constraint(constraint) == version From 7fac3ef00d843884391ebcda29ec7218a5441715 Mon Sep 17 00:00:00 2001 From: Artem Kolichenkov Date: Sat, 9 May 2020 14:05:22 +0300 Subject: [PATCH 36/80] Fix typo in docs Your -> you --- docs/docs/managing-environments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/managing-environments.md b/docs/docs/managing-environments.md index 47e8ede4047..8a1475f7c45 100644 --- a/docs/docs/managing-environments.md +++ b/docs/docs/managing-environments.md @@ -118,4 +118,4 @@ poetry env remove 3.7 poetry env remove test-O3eWbxRl-py3.7 ``` -If your remove the currently activated virtual environment, it will be automatically deactivated. +If you remove the currently activated virtual environment, it will be automatically deactivated. From c945890eece4e7471d485f33876eb920bed983d9 Mon Sep 17 00:00:00 2001 From: finswimmer Date: Sat, 9 May 2020 20:32:09 +0200 Subject: [PATCH 37/80] remove hint in the docs for using short names for commands as this is not supported anymore (#2379) --- docs/docs/cli.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/docs/docs/cli.md b/docs/docs/cli.md index a5b7df3cd6b..27745d25fb2 100644 --- a/docs/docs/cli.md +++ b/docs/docs/cli.md @@ -6,15 +6,6 @@ This chapter documents all the available commands. To get help from the command-line, simply call `poetry` to see the complete list of commands, then `--help` combined with any of those can give you more information. -As `Poetry` uses [cleo](https://github.com/sdispater/cleo) you can call commands by short name if it's not ambiguous. - -```bash -poetry up -``` - -calls `poetry update`. - - ## Global options * `--verbose (-v|vv|vvv)`: Increase the verbosity of messages: "-v" for normal output, "-vv" for more verbose output and "-vvv" for debug. From 0e9e9944d26d817786df6fa8acb7221ce9361855 Mon Sep 17 00:00:00 2001 From: Simone Primarosa Date: Sun, 10 May 2020 23:53:41 +0100 Subject: [PATCH 38/80] pep508: ensure whitespace prefix for quoted marker Prior to this fix, when formatting PEP 508 dependency specification for remote url references, the quoted marker was not prefixed with required whitespace. This change ensures that the format adheres to the specified grammar. Resolves: python-poetry/poetry#2326 --- poetry/packages/__init__.py | 4 ++-- poetry/utils/helpers.py | 2 +- tests/packages/test_main.py | 16 ++++++++++++++++ tests/utils/test_helpers.py | 12 ++++++++---- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/poetry/packages/__init__.py b/poetry/packages/__init__.py index e0a2203c9d3..a829858deb2 100644 --- a/poetry/packages/__init__.py +++ b/poetry/packages/__init__.py @@ -33,8 +33,8 @@ def dependency_from_pep_508(name): name = parts[0].strip() if len(parts) > 1: rest = parts[1] - if ";" in rest: - name += ";" + rest.split(";", 1)[1] + if " ;" in rest: + name += " ;" + rest.split(" ;", 1)[1] req = Requirement(name) diff --git a/poetry/utils/helpers.py b/poetry/utils/helpers.py index 3ecef0c391e..85d18a71d44 100644 --- a/poetry/utils/helpers.py +++ b/poetry/utils/helpers.py @@ -83,7 +83,7 @@ def parse_requires(requires): # type: (str) -> List[str] continue if current_marker: - line = "{}; {}".format(line, current_marker) + line = "{} ; {}".format(line, current_marker) requires_dist.append(line) diff --git a/tests/packages/test_main.py b/tests/packages/test_main.py index 586be5a31b8..5559057e4e9 100644 --- a/tests/packages/test_main.py +++ b/tests/packages/test_main.py @@ -183,6 +183,22 @@ def test_dependency_from_pep_508_with_git_url(): assert "1.2" == dep.reference +def test_dependency_from_pep_508_with_git_url_and_comment_and_extra(): + name = ( + "poetry @ git+https://github.com/python-poetry/poetry.git@b;ar;#egg=poetry" + ' ; extra == "foo;"' + ) + + dep = dependency_from_pep_508(name) + + assert "poetry" == dep.name + assert dep.is_vcs() + assert "git" == dep.vcs + assert "https://github.com/python-poetry/poetry.git" == dep.source + assert "b;ar;" == dep.reference + assert dep.in_extras == ["foo;"] + + def test_dependency_from_pep_508_with_url(): name = "django-utils @ https://example.com/django-utils-1.0.0.tar.gz" diff --git a/tests/utils/test_helpers.py b/tests/utils/test_helpers.py index d34061c88d6..eb7ce191f18 100644 --- a/tests/utils/test_helpers.py +++ b/tests/utils/test_helpers.py @@ -29,6 +29,9 @@ def test_parse_requires(): [:python_version >= "3.4.0.0" and python_version < "3.6.0.0"] zipfile36>=0.1.0.0,<0.2.0.0 + +[dev] +isort@ git+git://github.com/timothycrosley/isort.git@e63ae06ec7d70b06df9e528357650281a3d3ec22#egg=isort """ result = parse_requires(requires) expected = [ @@ -45,10 +48,11 @@ def test_parse_requires(): "msgpack-python>=0.5.0.0,<0.6.0.0", "pyparsing>=2.2.0.0,<3.0.0.0", "requests-toolbelt>=0.8.0.0,<0.9.0.0", - 'typing>=3.6.0.0,<4.0.0.0; (python_version >= "2.7.0.0" and python_version < "2.8.0.0") or (python_version >= "3.4.0.0" and python_version < "3.5.0.0")', - 'virtualenv>=15.2.0.0,<16.0.0.0; python_version >= "2.7.0.0" and python_version < "2.8.0.0"', - 'pathlib2>=2.3.0.0,<3.0.0.0; python_version >= "2.7.0.0" and python_version < "2.8.0.0"', - 'zipfile36>=0.1.0.0,<0.2.0.0; python_version >= "3.4.0.0" and python_version < "3.6.0.0"', + 'typing>=3.6.0.0,<4.0.0.0 ; (python_version >= "2.7.0.0" and python_version < "2.8.0.0") or (python_version >= "3.4.0.0" and python_version < "3.5.0.0")', + 'virtualenv>=15.2.0.0,<16.0.0.0 ; python_version >= "2.7.0.0" and python_version < "2.8.0.0"', + 'pathlib2>=2.3.0.0,<3.0.0.0 ; python_version >= "2.7.0.0" and python_version < "2.8.0.0"', + 'zipfile36>=0.1.0.0,<0.2.0.0 ; python_version >= "3.4.0.0" and python_version < "3.6.0.0"', + 'isort@ git+git://github.com/timothycrosley/isort.git@e63ae06ec7d70b06df9e528357650281a3d3ec22#egg=isort ; extra == "dev"', ] assert result == expected From 621f698ab7fa46b4109a6812a11c325dd2222746 Mon Sep 17 00:00:00 2001 From: finswimmer Date: Mon, 11 May 2020 00:59:54 +0200 Subject: [PATCH 39/80] utils: add missing comma in list of valid url schemes --- poetry/packages/utils/utils.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/poetry/packages/utils/utils.py b/poetry/packages/utils/utils.py index 03dfb84fda6..a219c36c416 100644 --- a/poetry/packages/utils/utils.py +++ b/poetry/packages/utils/utils.py @@ -22,13 +22,11 @@ except ImportError: import urlparse - try: import urllib.request as urllib2 except ImportError: import urllib2 - BZ2_EXTENSIONS = (".tar.bz2", ".tbz") XZ_EXTENSIONS = (".tar.xz", ".txz", ".tlz", ".tar.lz", ".tar.lzma") ZIP_EXTENSIONS = (".zip", ".whl") @@ -77,7 +75,8 @@ def is_url(name): "hg", "bzr", "sftp", - "svn" "ssh", + "svn", + "ssh", ] From 6b7615d316125c8182bd14628ee4c640434038b8 Mon Sep 17 00:00:00 2001 From: Ilia Kurenkov Date: Wed, 13 May 2020 21:44:38 +0200 Subject: [PATCH 40/80] Add link to SemVer and examples for bump rules --- docs/docs/cli.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/docs/cli.md b/docs/docs/cli.md index 27745d25fb2..b8124adb480 100644 --- a/docs/docs/cli.md +++ b/docs/docs/cli.md @@ -415,9 +415,23 @@ This command shows the current version of the project or bumps the version of the project and writes the new version back to `pyproject.toml` if a valid bump rule is provided. -The new version should ideally be a valid semver string or a valid bump rule: +The new version should ideally be a valid [semver](https://semver.org/) string or a valid bump rule: `patch`, `minor`, `major`, `prepatch`, `preminor`, `premajor`, `prerelease`. +The table below illustrates the effect of these rules with concrete examples. + +| rule | before | after | +|------------|---------------|---------------| +| major | 1.3.0 | 2.0.0 | +| minor | 2.1.4 | 2.2.0 | +| patch | 4.1.1 | 4.1.2 | +| premajor | 1.0.2 | 2.0.0-alpha.0 | +| preminor | 1.0.2 | 1.1.0-alpha.0 | +| prepatch | 1.0.2 | 1.0.3-alpha.0 | +| prerelease | 1.0.2 | 1.0.3-alpha.0 | +| prerelease | 1.0.3-alpha.0 | 1.0.3-alpha.1 | +| prerelease | 1.0.3-beta.0 | 1.0.3-beta.1 | + ## export From d5414b8b931b2b87d03e90b63478e4fdb0ebbc14 Mon Sep 17 00:00:00 2001 From: matemax Date: Fri, 15 May 2020 13:14:22 +0300 Subject: [PATCH 41/80] recurse-submodules --- poetry/vcs/git.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/poetry/vcs/git.py b/poetry/vcs/git.py index 28b8de74c2b..8992c410b76 100644 --- a/poetry/vcs/git.py +++ b/poetry/vcs/git.py @@ -197,7 +197,7 @@ def config(self): # type: () -> GitConfig return self._config def clone(self, repository, dest): # type: (...) -> str - return self.run("clone", repository, str(dest)) + return self.run("clone", "--recurse-submodules", repository, str(dest)) def checkout(self, rev, folder=None): # type: (...) -> str args = [] From 474104998aee429806a420103372fcd927bcad44 Mon Sep 17 00:00:00 2001 From: Sanket Dasgupta Date: Wed, 20 May 2020 03:19:27 +0530 Subject: [PATCH 42/80] Update shell completion docs for prezto Fixes https://github.com/python-poetry/poetry/issues/2048 --- README.md | 7 +++++++ docs/docs/index.md | 3 +++ 2 files changed, 10 insertions(+) diff --git a/README.md b/README.md index 487307ea5cf..44145cba57c 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,13 @@ poetry completions zsh > ~/.zfunc/_poetry # Zsh (Homebrew) poetry completions zsh > $(brew --prefix)/share/zsh/site-functions/_poetry + +# Zsh (Oh-My-Zsh) +mkdir $ZSH/plugins/poetry +poetry completions zsh > $ZSH/plugins/poetry/_poetry + +# Zsh (prezto) +poetry completions zsh > ~/.zprezto/modules/completion/external/src/_poetry ``` *Note:* you may need to restart your shell in order for the changes to take diff --git a/docs/docs/index.md b/docs/docs/index.md index 0ba5a1840db..9fe5b372c61 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -177,6 +177,9 @@ poetry completions zsh > ~/.zfunc/_poetry mkdir $ZSH/plugins/poetry poetry completions zsh > $ZSH/plugins/poetry/_poetry +# prezto +poetry completions zsh > ~/.zprezto/modules/completion/external/src/_poetry + ``` !!! note From 6cd3645d889f47c10425961661b8193b23f0ed79 Mon Sep 17 00:00:00 2001 From: Dominik Moritz Date: Thu, 21 May 2020 15:10:38 -0700 Subject: [PATCH 43/80] ci: Capitalize Python consistently --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 63a8fb7918f..565b05cae5d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -33,7 +33,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Get full python version + - name: Get full Python version id: full-python-version shell: bash run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") From 1d8e28471ea629f4defc17ca552d7d0bc6866d04 Mon Sep 17 00:00:00 2001 From: Sora Morimoto Date: Wed, 27 May 2020 06:49:05 +0900 Subject: [PATCH 44/80] Bump actions/cache from v1 to v2 --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 565b05cae5d..c7cea8e9120 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -50,7 +50,7 @@ jobs: run: poetry config virtualenvs.in-project true - name: Set up cache - uses: actions/cache@v1 + uses: actions/cache@v2 id: cache with: path: .venv From 720c47f3389ccc7151f94202d9c9847eeb1cf0ef Mon Sep 17 00:00:00 2001 From: Ilia Kurenkov Date: Fri, 29 May 2020 10:53:44 +0200 Subject: [PATCH 45/80] trivial change to retrigger the CI --- docs/docs/cli.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs/cli.md b/docs/docs/cli.md index b8124adb480..2b98b5f0371 100644 --- a/docs/docs/cli.md +++ b/docs/docs/cli.md @@ -433,6 +433,7 @@ The table below illustrates the effect of these rules with concrete examples. | prerelease | 1.0.3-beta.0 | 1.0.3-beta.1 | + ## export This command exports the lock file to other formats. From d22afa9d933529c01b74a6127fa41ce49bf0182b Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 30 May 2019 16:46:03 -0500 Subject: [PATCH 46/80] fix: Gracefully handle read-only sdists For a package without dependencies in pypi's database, like p4python, the sdist is required. The problem is p4python was developed in perforce where all files are read-only by default and deleting the temp directory fails. So we need to use the custom-built temp directory and specially handle read-only files to be able to use p4python in poetry. Fixes #520 --- poetry/utils/helpers.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/poetry/utils/helpers.py b/poetry/utils/helpers.py index 85d18a71d44..af68a6d0105 100644 --- a/poetry/utils/helpers.py +++ b/poetry/utils/helpers.py @@ -34,19 +34,18 @@ def normalize_version(version): # type: (str) -> str return str(Version(version)) +def _del_ro(action, name, exc): + os.chmod(name, stat.S_IWRITE) + os.remove(name) + + @contextmanager def temporary_directory(*args, **kwargs): - try: - from tempfile import TemporaryDirectory - - with TemporaryDirectory(*args, **kwargs) as name: - yield name - except ImportError: - name = tempfile.mkdtemp(*args, **kwargs) + name = tempfile.mkdtemp(*args, **kwargs) - yield name + yield name - shutil.rmtree(name) + shutil.rmtree(name, onerror=_del_ro) def parse_requires(requires): # type: (str) -> List[str] From afefd58b774caee2e62e377ef566a2510e989dd8 Mon Sep 17 00:00:00 2001 From: Nat Noordanus Date: Fri, 29 May 2020 19:53:22 +0200 Subject: [PATCH 47/80] doc: fix issue template links in CONTRIBUTING.md --- CONTRIBUTING.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d03da34c186..0b184a286ee 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,7 @@ The following is a set of guidelines for contributing to Poetry on GitHub. These This section guides you through submitting a bug report for Poetry. Following these guidelines helps maintainers and the community understand your report, reproduce the behavior, and find related reports. -Before creating bug reports, please check [this list](#before-submitting-a-bug-report) to be sure that you need to create one. When you are creating a bug report, please include as many details as possible. Fill out the [required template](https://github.com/python-poetry/poetry/blob/master/.github/ISSUE_TEMPLATE/1_Bug_report.md), the information it asks helps the maintainers resolve the issue faster. +Before creating bug reports, please check [this list](#before-submitting-a-bug-report) to be sure that you need to create one. When you are creating a bug report, please include as many details as possible. Fill out the [required template](https://github.com/python-poetry/poetry/blob/master/.github/ISSUE_TEMPLATE/---bug-report.md), the information it asks helps the maintainers resolve the issue faster. > **Note:** If you find a **Closed** issue that seems like it is the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one. @@ -31,7 +31,7 @@ Before creating bug reports, please check [this list](#before-submitting-a-bug-r #### How do I submit a bug report? -Bugs are tracked on the [official issue tracker](https://github.com/python-poetry/poetry/issues) where you can create a new one and provide the following information by filling in [the template](https://github.com/python-poetry/poetry/blob/master/.github/ISSUE_TEMPLATE/1_Bug_report.md). +Bugs are tracked on the [official issue tracker](https://github.com/python-poetry/poetry/issues) where you can create a new one and provide the following information by filling in [the template](https://github.com/python-poetry/poetry/blob/master/.github/ISSUE_TEMPLATE/---bug-report.md). Explain the problem and include additional details to help maintainers reproduce the problem: @@ -60,14 +60,13 @@ Include details about your configuration and environment: This section guides you through submitting an enhancement suggestion for Poetry, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the community understand your suggestion and find related suggestions. -Before creating enhancement suggestions, please check [this list](#before-submitting-an-enhancement-suggestion) as you might find out that you don't need to create one. When you are creating an enhancement suggestion, please [include as many details as possible](#how-do-i-submit-an-enhancement-suggestion). Fill in [the template](https://github.com/python-poetry/poetry/blob/master/.github/ISSUE_TEMPLATE/2_Feature_request.md), including the steps that you imagine you would take if the feature you're requesting existed. +Before creating enhancement suggestions, please check [this list](#before-submitting-an-enhancement-suggestion) as you might find out that you don't need to create one. When you are creating an enhancement suggestion, please [include as many details as possible](#how-do-i-submit-an-enhancement-suggestion). Fill in [the template](https://github.com/python-poetry/poetry/blob/master/.github/ISSUE_TEMPLATE/---feature-request.md), including the steps that you imagine you would take if the feature you're requesting existed. #### Before submitting an enhancement suggestion * **Check the [FAQs on the official website](https://python-poetry.org/docs/faq)** for a list of common questions and problems. * **Check that your issue does not already exist in the [issue tracker](https://github.com/python-poetry/poetry/issues)**. - #### How do I submit an Enhancement suggestion? Enhancement suggestions are tracked on the [official issue tracker](https://github.com/python-poetry/poetry/issues) where you can create a new one and provide the following information: From c94c34c813060abfaebc2632c58abe063e40efd3 Mon Sep 17 00:00:00 2001 From: Joey Wilhelm Date: Fri, 5 Jun 2020 05:13:09 -0400 Subject: [PATCH 48/80] Document expanded table syntax for dependencies (#2392) --- docs/docs/dependency-specification.md | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/docs/dependency-specification.md b/docs/docs/dependency-specification.md index f826332eb71..257b585b5a3 100644 --- a/docs/docs/dependency-specification.md +++ b/docs/docs/dependency-specification.md @@ -179,6 +179,34 @@ foo = [ ] ``` +## Expanded dependency specification syntax + +In the case of more complex dependency specifications, you may find that you +end up with lines which are very long and difficult to read. In these cases, +you can shift from using "inline table" syntax, to the "standard table" syntax. + +An example where this might be useful is the following: + +```toml +[tool.poetry.dev-dependencies] +black = {version = "19.10b0", allow-prereleases = true, python = "^3.6", markers = "platform_python_implementation == 'CPython'} +``` + +As a single line, this is a lot to digest. To make this a little bit easier to +work with, you can do the following: + +```toml +[tool.poetry.dev-dependencies.black] +version = "19.10b0" +allow-prereleases = true +python = "^3.6" +markers = "platform_python_implementation == 'CPython'" +``` + +All of the same information is still present, and ends up providing the exact +same specification. It's simply split into multiple, slightly more readable, +lines. + !!!note The constraints **must** have different requirements (like `python`) From 0ac9e5c5fe11c5afc3523d355bb20e81aa5f0c37 Mon Sep 17 00:00:00 2001 From: Radu Suciu Date: Fri, 5 Jun 2020 02:14:36 -0700 Subject: [PATCH 49/80] Fix mispelled content-type in release action (#2378) --- .github/workflows/release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f0b3b27925f..2828853eb49 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -205,7 +205,7 @@ jobs: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-linux.sha256sum/poetry-${{ steps.tag.outputs.tag }}-linux.sha256sum asset_name: poetry-${{ steps.tag.outputs.tag }}-linux.sha256sum - asset_content_type: text/pain + asset_content_type: text/plain - name: Upload MacOS release file asset uses: actions/upload-release-asset@v1.0.1 env: @@ -223,7 +223,7 @@ jobs: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-darwin.sha256sum/poetry-${{ steps.tag.outputs.tag }}-darwin.sha256sum asset_name: poetry-${{ steps.tag.outputs.tag }}-darwin.sha256sum - asset_content_type: text/pain + asset_content_type: text/plain - name: Upload Windows release file asset uses: actions/upload-release-asset@v1.0.1 env: @@ -241,7 +241,7 @@ jobs: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-win32.sha256sum/poetry-${{ steps.tag.outputs.tag }}-win32.sha256sum asset_name: poetry-${{ steps.tag.outputs.tag }}-win32.sha256sum - asset_content_type: text/pain + asset_content_type: text/plain - name: Install Poetry run: | python get-poetry.py --preview -y From 7ee66c0a77d8f3a7413dadbbbfa765e61438bd0b Mon Sep 17 00:00:00 2001 From: Hemanta Date: Fri, 5 Jun 2020 15:08:28 +0545 Subject: [PATCH 50/80] Removes unnecessary paths nesting in release workflow file (#2128) --- .github/workflows/release.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2828853eb49..b422419bb98 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -152,32 +152,32 @@ jobs: uses: actions/download-artifact@master with: name: poetry-${{ steps.tag.outputs.tag }}-linux.tar.gz - path: releases/poetry-${{ steps.tag.outputs.tag }}-linux.tar.gz + path: releases/ - name: Download Linux checksum file uses: actions/download-artifact@master with: name: poetry-${{ steps.tag.outputs.tag }}-linux.sha256sum - path: releases/poetry-${{ steps.tag.outputs.tag }}-linux.sha256sum + path: releases/ - name: Download MacOS release file uses: actions/download-artifact@master with: name: poetry-${{ steps.tag.outputs.tag }}-darwin.tar.gz - path: releases/poetry-${{ steps.tag.outputs.tag }}-darwin.tar.gz + path: releases/ - name: Download MacOS checksum file uses: actions/download-artifact@master with: name: poetry-${{ steps.tag.outputs.tag }}-darwin.sha256sum - path: releases/poetry-${{ steps.tag.outputs.tag }}-darwin.sha256sum + path: releases/ - name: Download Windows release file uses: actions/download-artifact@master with: name: poetry-${{ steps.tag.outputs.tag }}-win32.tar.gz - path: releases/poetry-${{ steps.tag.outputs.tag }}-win32.tar.gz + path: releases/ - name: Download Windows checksum file uses: actions/download-artifact@master with: name: poetry-${{ steps.tag.outputs.tag }}-win32.sha256sum - path: releases/poetry-${{ steps.tag.outputs.tag }}-win32.sha256sum + path: releases/ - name: Create Release id: create_release uses: actions/create-release@v1 @@ -194,7 +194,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-linux.tar.gz/poetry-${{ steps.tag.outputs.tag }}-linux.tar.gz + asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-linux.tar.gz asset_name: poetry-${{ steps.tag.outputs.tag }}-linux.tar.gz asset_content_type: application/gzip - name: Upload Linux checksum file asset @@ -203,7 +203,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-linux.sha256sum/poetry-${{ steps.tag.outputs.tag }}-linux.sha256sum + asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-linux.sha256sum asset_name: poetry-${{ steps.tag.outputs.tag }}-linux.sha256sum asset_content_type: text/plain - name: Upload MacOS release file asset @@ -212,7 +212,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-darwin.tar.gz/poetry-${{ steps.tag.outputs.tag }}-darwin.tar.gz + asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-darwin.tar.gz asset_name: poetry-${{ steps.tag.outputs.tag }}-darwin.tar.gz asset_content_type: application/gzip - name: Upload MacOS checksum file asset @@ -221,7 +221,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-darwin.sha256sum/poetry-${{ steps.tag.outputs.tag }}-darwin.sha256sum + asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-darwin.sha256sum asset_name: poetry-${{ steps.tag.outputs.tag }}-darwin.sha256sum asset_content_type: text/plain - name: Upload Windows release file asset @@ -230,7 +230,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-win32.tar.gz/poetry-${{ steps.tag.outputs.tag }}-win32.tar.gz + asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-win32.tar.gz asset_name: poetry-${{ steps.tag.outputs.tag }}-win32.tar.gz asset_content_type: application/gzip - name: Upload Windows checksum file asset @@ -239,7 +239,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-win32.sha256sum/poetry-${{ steps.tag.outputs.tag }}-win32.sha256sum + asset_path: releases/poetry-${{ steps.tag.outputs.tag }}-win32.sha256sum asset_name: poetry-${{ steps.tag.outputs.tag }}-win32.sha256sum asset_content_type: text/plain - name: Install Poetry From e4e8e3cb960849c793deaf72ece9c7096623e418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 5 Jun 2020 12:24:46 +0200 Subject: [PATCH 51/80] Fix resolution of path, url and VCS dependencies (#2398) * Fix resolution of path, url and VCS dependencies * Fix editable installation of Poetry packages --- poetry/installation/pip_installer.py | 14 +-- poetry/mixology/version_solver.py | 10 ++ poetry/packages/directory_dependency.py | 11 ++ poetry/packages/file_dependency.py | 15 +++ poetry/packages/package.py | 1 + poetry/packages/url_dependency.py | 6 + poetry/packages/vcs_dependency.py | 8 ++ poetry/puzzle/provider.py | 73 ++++++++++-- .../pyproject.toml | 1 + .../inner-directory-project/pyproject.toml | 11 ++ .../pyproject.toml | 1 + ...irectory-dependency-poetry-transitive.test | 73 +++++++++++- .../with-file-dependency-transitive.test | 22 +++- tests/installation/test_installer.py | 20 ++-- tests/puzzle/test_provider.py | 17 ++- tests/puzzle/test_solver.py | 111 ++++++++++++++++++ 16 files changed, 353 insertions(+), 41 deletions(-) create mode 100644 tests/fixtures/directory/project_with_transitive_file_dependencies/inner-directory-project/pyproject.toml diff --git a/poetry/installation/pip_installer.py b/poetry/installation/pip_installer.py index 5a3e8df7852..331a69b580e 100644 --- a/poetry/installation/pip_installer.py +++ b/poetry/installation/pip_installer.py @@ -1,7 +1,6 @@ import os import tempfile -from io import open from subprocess import CalledProcessError from clikit.api.io import IO @@ -181,9 +180,7 @@ def create_temporary_requirement(self, package): return name def install_directory(self, package): - from poetry.masonry.builder import SdistBuilder from poetry.factory import Factory - from poetry.utils._compat import decode from poetry.utils.env import NullEnv from poetry.utils.toml_file import TomlFile @@ -210,17 +207,20 @@ def install_directory(self, package): setup = os.path.join(req, "setup.py") has_setup = os.path.exists(setup) - if not has_setup and has_poetry and (package.develop or not has_build_system): + if has_poetry and (package.develop or not has_build_system): # We actually need to rely on creating a temporary setup.py # file since pip, as of this comment, does not support # build-system for editable packages # We also need it for non-PEP-517 packages - builder = SdistBuilder( + from poetry.masonry.builders.editable import EditableBuilder + + builder = EditableBuilder( Factory().create_poetry(pyproject.parent), NullEnv(), NullIO() ) - with open(setup, "w", encoding="utf-8") as f: - f.write(decode(builder.build_setup())) + builder.build() + + return if package.develop: args.append("-e") diff --git a/poetry/mixology/version_solver.py b/poetry/mixology/version_solver.py index d1c78ba7661..02b9a74a1d8 100644 --- a/poetry/mixology/version_solver.py +++ b/poetry/mixology/version_solver.py @@ -339,6 +339,16 @@ def _get_min(dependency): if dependency.name in self._locked: return 1 + # VCS, URL, File or Directory dependencies + # represent a single version + if ( + dependency.is_vcs() + or dependency.is_url() + or dependency.is_file() + or dependency.is_directory() + ): + return 1 + try: return len(self._provider.search_for(dependency)) except ValueError: diff --git a/poetry/packages/directory_dependency.py b/poetry/packages/directory_dependency.py index ac4bca8ea82..978300ca689 100644 --- a/poetry/packages/directory_dependency.py +++ b/poetry/packages/directory_dependency.py @@ -79,3 +79,14 @@ def supports_poetry(self): def is_directory(self): return True + + def __str__(self): + if self.is_root: + return self._pretty_name + + return "{} ({} {})".format( + self._pretty_name, self._pretty_constraint, self._path + ) + + def __hash__(self): + return hash((self._name, self._full_path)) diff --git a/poetry/packages/file_dependency.py b/poetry/packages/file_dependency.py index b91d296a512..751e61997f8 100644 --- a/poetry/packages/file_dependency.py +++ b/poetry/packages/file_dependency.py @@ -41,6 +41,10 @@ def __init__( name, "*", category=category, optional=optional, allows_prereleases=True ) + @property + def base(self): + return self._base + @property def path(self): return self._path @@ -59,3 +63,14 @@ def hash(self): h.update(content) return h.hexdigest() + + def __str__(self): + if self.is_root: + return self._pretty_name + + return "{} ({} {})".format( + self._pretty_name, self._pretty_constraint, self._path + ) + + def __hash__(self): + return hash((self._name, self._full_path)) diff --git a/poetry/packages/package.py b/poetry/packages/package.py index 4940d6f027a..680bf31f596 100644 --- a/poetry/packages/package.py +++ b/poetry/packages/package.py @@ -409,6 +409,7 @@ def with_python_versions(self, python_versions): def clone(self): # type: () -> Package clone = self.__class__(self.pretty_name, self.version) + clone.description = self.description clone.category = self.category clone.optional = self.optional clone.python_versions = self.python_versions diff --git a/poetry/packages/url_dependency.py b/poetry/packages/url_dependency.py index f128dc49366..295fea60e6e 100644 --- a/poetry/packages/url_dependency.py +++ b/poetry/packages/url_dependency.py @@ -38,3 +38,9 @@ def base_pep_508_name(self): # type: () -> str def is_url(self): # type: () -> bool return True + + def __str__(self): + return "{} ({} url)".format(self._pretty_name, self._pretty_constraint) + + def __hash__(self): + return hash((self._name, self._url)) diff --git a/poetry/packages/vcs_dependency.py b/poetry/packages/vcs_dependency.py index 7574b8dbac3..b8f2992b92e 100644 --- a/poetry/packages/vcs_dependency.py +++ b/poetry/packages/vcs_dependency.py @@ -94,3 +94,11 @@ def is_vcs(self): # type: () -> bool def accepts_prereleases(self): # type: () -> bool return True + + def __str__(self): + return "{} ({} {})".format( + self._pretty_name, self._pretty_constraint, self._vcs + ) + + def __hash__(self): + return hash((self._name, self._vcs, self._branch, self._tag, self._rev)) diff --git a/poetry/puzzle/provider.py b/poetry/puzzle/provider.py index 4888b9828b1..3157b2a52da 100644 --- a/poetry/puzzle/provider.py +++ b/poetry/puzzle/provider.py @@ -72,6 +72,7 @@ def __init__(self, package, pool, io): # type: (Package, Pool, Any) -> None self._search_for = {} self._is_debugging = self._io.is_debug() or self._io.is_very_verbose() self._in_progress = False + self._deferred_cache = {} @property def pool(self): # type: () -> Pool @@ -164,6 +165,9 @@ def search_for_vcs(self, dependency): # type: (VCSDependency) -> List[Package] Basically, we clone the repository in a temporary directory and get the information we need by checking out the specified reference. """ + if dependency in self._deferred_cache: + return [self._deferred_cache[dependency]] + package = self.get_package_from_vcs( dependency.vcs, dependency.source, @@ -178,6 +182,11 @@ def search_for_vcs(self, dependency): # type: (VCSDependency) -> List[Package] package.requires += package.extras[extra] + dependency._constraint = package.version + dependency._pretty_constraint = package.version.text + + self._deferred_cache[dependency] = package + return [package] @classmethod @@ -214,7 +223,17 @@ def get_package_from_vcs( return package def search_for_file(self, dependency): # type: (FileDependency) -> List[Package] - package = self.get_package_from_file(dependency.full_path) + if dependency in self._deferred_cache: + dependency, _package = self._deferred_cache[dependency] + + package = _package.clone() + else: + package = self.get_package_from_file(dependency.full_path) + + dependency._constraint = package.version + dependency._pretty_constraint = package.version.text + + self._deferred_cache[dependency] = (dependency, package) if dependency.name != package.name: # For now, the dependency's name must match the actual package's name @@ -224,6 +243,9 @@ def search_for_file(self, dependency): # type: (FileDependency) -> List[Package ) ) + if dependency.base is not None: + package.root_dir = dependency.base + package.source_url = dependency.path.as_posix() package.files = [ {"file": dependency.path.name, "hash": "sha256:" + dependency.hash()} @@ -270,15 +292,25 @@ def get_package_from_file(cls, file_path): # type: (Path) -> Package def search_for_directory( self, dependency ): # type: (DirectoryDependency) -> List[Package] - package = self.get_package_from_directory( - dependency.full_path, name=dependency.name - ) + if dependency in self._deferred_cache: + dependency, _package = self._deferred_cache[dependency] + + package = _package.clone() + else: + package = self.get_package_from_directory( + dependency.full_path, name=dependency.name + ) + + dependency._constraint = package.version + dependency._pretty_constraint = package.version.text + + self._deferred_cache[dependency] = (dependency, package) package.source_url = dependency.path.as_posix() package.develop = dependency.develop if dependency.base is not None: - package.root_dir = dependency.base.as_posix() + package.root_dir = dependency.base for extra in dependency.extras: if extra in package.extras: @@ -434,6 +466,9 @@ def get_package_from_directory( return package def search_for_url(self, dependency): # type: (URLDependency) -> List[Package] + if dependency in self._deferred_cache: + return [self._deferred_cache[dependency]] + package = self.get_package_from_url(dependency.url) if dependency.name != package.name: @@ -451,6 +486,11 @@ def search_for_url(self, dependency): # type: (URLDependency) -> List[Package] package.requires += package.extras[extra] + dependency._constraint = package.version + dependency._pretty_constraint = package.version.text + + self._deferred_cache[dependency] = package + return [package] @classmethod @@ -551,6 +591,17 @@ def complete_package( else: requires = package.requires + # Retrieving constraints for deferred dependencies + for r in requires: + if r.is_directory(): + self.search_for_directory(r) + elif r.is_file(): + self.search_for_file(r) + elif r.is_vcs(): + self.search_for_vcs(r) + elif r.is_url(): + self.search_for_url(r) + dependencies = [ r for r in requires @@ -696,15 +747,15 @@ def complete_package( if (package.dependency.is_directory() or package.dependency.is_file()) and ( dep.is_directory() or dep.is_file() ): - if dep.path.as_posix().startswith(package.source_url): - relative = (Path(package.source_url) / dep.path).relative_to( - package.source_url + relative_path = Path( + os.path.relpath( + dep.full_path.as_posix(), package.root_dir.as_posix() ) - else: - relative = Path(package.source_url) / dep.path + ) # TODO: Improve the way we set the correct relative path for dependencies - dep._path = relative + dep._path = relative_path + clean_dependencies.append(dep) package.requires = clean_dependencies diff --git a/tests/fixtures/directory/project_with_transitive_directory_dependencies/pyproject.toml b/tests/fixtures/directory/project_with_transitive_directory_dependencies/pyproject.toml index 0a97ea02c5f..28678e0d0ae 100644 --- a/tests/fixtures/directory/project_with_transitive_directory_dependencies/pyproject.toml +++ b/tests/fixtures/directory/project_with_transitive_directory_dependencies/pyproject.toml @@ -8,5 +8,6 @@ license = "MIT" [tool.poetry.dependencies] python = "*" project-with-extras = {path = "../../project_with_extras/"} +project-with-transitive-file-dependencies = {path = "../project_with_transitive_file_dependencies/"} [tool.poetry.dev-dependencies] diff --git a/tests/fixtures/directory/project_with_transitive_file_dependencies/inner-directory-project/pyproject.toml b/tests/fixtures/directory/project_with_transitive_file_dependencies/inner-directory-project/pyproject.toml new file mode 100644 index 00000000000..a80113675e6 --- /dev/null +++ b/tests/fixtures/directory/project_with_transitive_file_dependencies/inner-directory-project/pyproject.toml @@ -0,0 +1,11 @@ +[tool.poetry] +name = "inner-directory-project" +version = "1.2.4" +description = "This is a description" +authors = ["Your Name "] +license = "MIT" + +[tool.poetry.dependencies] +python = "*" + +[tool.poetry.dev-dependencies] diff --git a/tests/fixtures/directory/project_with_transitive_file_dependencies/pyproject.toml b/tests/fixtures/directory/project_with_transitive_file_dependencies/pyproject.toml index 14512e2746e..678e42f2fa5 100644 --- a/tests/fixtures/directory/project_with_transitive_file_dependencies/pyproject.toml +++ b/tests/fixtures/directory/project_with_transitive_file_dependencies/pyproject.toml @@ -8,5 +8,6 @@ license = "MIT" [tool.poetry.dependencies] python = "*" demo = {path = "../../distributions/demo-0.1.0-py2.py3-none-any.whl"} +inner-directory-project = {path = "./inner-directory-project"} [tool.poetry.dev-dependencies] diff --git a/tests/installation/fixtures/with-directory-dependency-poetry-transitive.test b/tests/installation/fixtures/with-directory-dependency-poetry-transitive.test index 06f262f74e6..ad29dd7abe6 100644 --- a/tests/installation/fixtures/with-directory-dependency-poetry-transitive.test +++ b/tests/installation/fixtures/with-directory-dependency-poetry-transitive.test @@ -1,3 +1,45 @@ +[[package]] +category = "main" +description = "" +name = "demo" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.1.0" + +[package.dependencies] +pendulum = ">=1.4.4" + +[package.extras] +bar = ["tomlkit"] +foo = ["cleo"] + +[package.source] +reference = "" +type = "file" +url = "../../distributions/demo-0.1.0-py2.py3-none-any.whl" + +[[package]] +category = "main" +description = "" +develop = true +name = "inner-directory-project" +optional = false +python-versions = "*" +version = "1.2.4" + +[package.source] +reference = "" +type = "directory" +url = "../project_with_transitive_file_dependencies/inner-directory-project" + +[[package]] +category = "main" +description = "" +name = "pendulum" +optional = false +python-versions = "*" +version = "1.4.4" + [[package]] category = "main" description = "" @@ -14,7 +56,7 @@ extras_b = ["cachy (>=0.2.0)"] [package.source] reference = "" type = "directory" -url = "tests/fixtures/directory/project_with_transitive_directory_dependencies/../../project_with_extras" +url = "../project_with_extras" [[package]] category = "main" @@ -26,17 +68,42 @@ python-versions = "*" version = "1.2.3" [package.dependencies] -project-with-extras = "*" +project-with-extras = "1.2.3" +project-with-transitive-file-dependencies = "1.2.3" + +[package.source] +reference = "" +type = "directory" +url = "project_with_transitive_directory_dependencies" + +[[package]] +category = "main" +description = "" +develop = true +name = "project-with-transitive-file-dependencies" +optional = false +python-versions = "*" +version = "1.2.3" + +[package.dependencies] +demo = "0.1.0" +inner-directory-project = "1.2.4" [package.source] reference = "" type = "directory" -url = "tests/fixtures/directory/project_with_transitive_directory_dependencies" +url = "project_with_transitive_file_dependencies" [metadata] content-hash = "123456789" python-versions = "*" [metadata.files] +demo = [ + {file = "demo-0.1.0-py2.py3-none-any.whl", hash = "sha256:70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a"}, +] +inner-directory-project = [] +pendulum = [] project-with-extras = [] project-with-transitive-directory-dependencies = [] +project-with-transitive-file-dependencies = [] diff --git a/tests/installation/fixtures/with-file-dependency-transitive.test b/tests/installation/fixtures/with-file-dependency-transitive.test index db3b632694a..2cbd16e1a53 100644 --- a/tests/installation/fixtures/with-file-dependency-transitive.test +++ b/tests/installation/fixtures/with-file-dependency-transitive.test @@ -16,7 +16,21 @@ foo = ["cleo"] [package.source] reference = "" type = "file" -url = "tests/fixtures/directory/project_with_transitive_file_dependencies/../../distributions/demo-0.1.0-py2.py3-none-any.whl" +url = "../distributions/demo-0.1.0-py2.py3-none-any.whl" + +[[package]] +category = "main" +description = "" +develop = true +name = "inner-directory-project" +optional = false +python-versions = "*" +version = "1.2.4" + +[package.source] +reference = "" +type = "directory" +url = "project_with_transitive_file_dependencies/inner-directory-project" [[package]] category = "main" @@ -36,12 +50,13 @@ python-versions = "*" version = "1.2.3" [package.dependencies] -demo = "*" +demo = "0.1.0" +inner-directory-project = "1.2.4" [package.source] reference = "" type = "directory" -url = "tests/fixtures/directory/project_with_transitive_file_dependencies" +url = "project_with_transitive_file_dependencies" [metadata] content-hash = "123456789" @@ -51,5 +66,6 @@ python-versions = "*" demo = [ {file = "demo-0.1.0-py2.py3-none-any.whl", hash = "sha256:70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a"}, ] +inner-directory-project = [] pendulum = [] project-with-transitive-file-dependencies = [] diff --git a/tests/installation/test_installer.py b/tests/installation/test_installer.py index c236141be44..ee5318a5a23 100644 --- a/tests/installation/test_installer.py +++ b/tests/installation/test_installer.py @@ -716,11 +716,13 @@ def test_run_installs_with_local_poetry_directory_and_extras( def test_run_installs_with_local_poetry_directory_transitive( installer, locker, repo, package, tmpdir ): - file_path = ( - fixtures_dir / "directory/project_with_transitive_directory_dependencies/" + package.root_dir = fixtures_dir.joinpath("directory") + directory = fixtures_dir.joinpath("directory").joinpath( + "project_with_transitive_directory_dependencies" ) package.add_dependency( - "project-with-transitive-directory-dependencies", {"path": str(file_path)} + "project-with-transitive-directory-dependencies", + {"path": str(directory.relative_to(fixtures_dir.joinpath("directory")))}, ) repo.add_package(get_package("pendulum", "1.4.4")) @@ -732,15 +734,19 @@ def test_run_installs_with_local_poetry_directory_transitive( assert locker.written_data == expected - assert len(installer.installer.installs) == 2 + assert len(installer.installer.installs) == 6 def test_run_installs_with_local_poetry_file_transitive( installer, locker, repo, package, tmpdir ): - file_path = fixtures_dir / "directory/project_with_transitive_file_dependencies/" + package.root_dir = fixtures_dir.joinpath("directory") + directory = fixtures_dir.joinpath("directory").joinpath( + "project_with_transitive_file_dependencies" + ) package.add_dependency( - "project-with-transitive-file-dependencies", {"path": str(file_path)} + "project-with-transitive-file-dependencies", + {"path": str(directory.relative_to(fixtures_dir.joinpath("directory")))}, ) repo.add_package(get_package("pendulum", "1.4.4")) @@ -752,7 +758,7 @@ def test_run_installs_with_local_poetry_file_transitive( assert locker.written_data == expected - assert len(installer.installer.installs) == 3 + assert len(installer.installer.installs) == 4 def test_run_installs_with_local_setuptools_directory( diff --git a/tests/puzzle/test_provider.py b/tests/puzzle/test_provider.py index 4d4463b3b73..3431911866a 100644 --- a/tests/puzzle/test_provider.py +++ b/tests/puzzle/test_provider.py @@ -204,16 +204,13 @@ def test_search_for_directory_setup_with_base(provider, directory): "foo": [get_dependency("cleo")], "bar": [get_dependency("tomlkit")], } - assert ( - package.root_dir - == ( - Path(__file__).parent.parent - / "fixtures" - / "git" - / "github.com" - / "demo" - / directory - ).as_posix() + assert package.root_dir == ( + Path(__file__).parent.parent + / "fixtures" + / "git" + / "github.com" + / "demo" + / directory ) diff --git a/tests/puzzle/test_solver.py b/tests/puzzle/test_solver.py index 415f6bcea09..1c75b59862f 100644 --- a/tests/puzzle/test_solver.py +++ b/tests/puzzle/test_solver.py @@ -1928,3 +1928,114 @@ def test_solver_properly_propagates_markers(solver, repo, package): str(ops[0].package.marker) == 'python_version >= "3.6" and implementation_name != "pypy"' ) + + +def test_solver_cannot_choose_another_version_for_directory_dependencies( + solver, repo, package +): + pendulum = get_package("pendulum", "2.0.3") + demo = get_package("demo", "0.1.0") + foo = get_package("foo", "1.2.3") + foo.add_dependency("demo", "<0.1.2") + repo.add_package(foo) + repo.add_package(demo) + repo.add_package(pendulum) + + path = ( + Path(__file__).parent.parent + / "fixtures" + / "git" + / "github.com" + / "demo" + / "demo" + ).as_posix() + + package.add_dependency("demo", {"path": path}) + package.add_dependency("foo", "^1.2.3") + + # This is not solvable since the demo version is pinned + # via the directory dependency + with pytest.raises(SolverProblemError): + solver.solve() + + +def test_solver_cannot_choose_another_version_for_file_dependencies( + solver, repo, package +): + pendulum = get_package("pendulum", "2.0.3") + demo = get_package("demo", "0.0.8") + foo = get_package("foo", "1.2.3") + foo.add_dependency("demo", "<0.1.0") + repo.add_package(foo) + repo.add_package(demo) + repo.add_package(pendulum) + + path = ( + Path(__file__).parent.parent + / "fixtures" + / "distributions" + / "demo-0.1.0-py2.py3-none-any.whl" + ).as_posix() + + package.add_dependency("demo", {"path": path}) + package.add_dependency("foo", "^1.2.3") + + # This is not solvable since the demo version is pinned + # via the file dependency + with pytest.raises(SolverProblemError): + solver.solve() + + +def test_solver_cannot_choose_another_version_for_git_dependencies( + solver, repo, package +): + pendulum = get_package("pendulum", "2.0.3") + demo = get_package("demo", "0.0.8") + foo = get_package("foo", "1.2.3") + foo.add_dependency("demo", "<0.1.0") + repo.add_package(foo) + repo.add_package(demo) + repo.add_package(pendulum) + + package.add_dependency("demo", {"git": "https://github.com/demo/demo.git"}) + package.add_dependency("foo", "^1.2.3") + + # This is not solvable since the demo version is pinned + # via the file dependency + with pytest.raises(SolverProblemError): + solver.solve() + + +def test_solver_cannot_choose_another_version_for_url_dependencies( + solver, repo, package, http +): + path = ( + Path(__file__).parent.parent + / "fixtures" + / "distributions" + / "demo-0.1.0-py2.py3-none-any.whl" + ) + + http.register_uri( + "GET", + "https://foo.bar/demo-0.1.0-py2.py3-none-any.whl", + body=path.read_bytes(), + streaming=True, + ) + pendulum = get_package("pendulum", "2.0.3") + demo = get_package("demo", "0.0.8") + foo = get_package("foo", "1.2.3") + foo.add_dependency("demo", "<0.1.0") + repo.add_package(foo) + repo.add_package(demo) + repo.add_package(pendulum) + + package.add_dependency( + "demo", {"url": "https://foo.bar/distributions/demo-0.1.0-py2.py3-none-any.whl"} + ) + package.add_dependency("foo", "^1.2.3") + + # This is not solvable since the demo version is pinned + # via the git dependency + with pytest.raises(SolverProblemError): + solver.solve() From 9cd16a93b1443f821453df607fb98f652531b89c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 5 Jun 2020 12:35:13 +0200 Subject: [PATCH 52/80] Update the self update command to be able to handle future versions (#2429) --- poetry/console/commands/self/update.py | 150 +++++++++++++++--- tests/console/commands/self/__init__.py | 0 .../fixtures/poetry-1.0.5-darwin.sha256sum | 1 + .../self/fixtures/poetry-1.0.5-darwin.tar.gz | Bin 0 -> 1041 bytes tests/console/commands/self/test_update.py | 87 ++++++++++ 5 files changed, 214 insertions(+), 24 deletions(-) create mode 100644 tests/console/commands/self/__init__.py create mode 100644 tests/console/commands/self/fixtures/poetry-1.0.5-darwin.sha256sum create mode 100644 tests/console/commands/self/fixtures/poetry-1.0.5-darwin.tar.gz create mode 100644 tests/console/commands/self/test_update.py diff --git a/poetry/console/commands/self/update.py b/poetry/console/commands/self/update.py index 032213ae0ce..5e0433e368c 100644 --- a/poetry/console/commands/self/update.py +++ b/poetry/console/commands/self/update.py @@ -1,6 +1,10 @@ +from __future__ import unicode_literals + import hashlib import os +import re import shutil +import stat import subprocess import sys import tarfile @@ -22,6 +26,27 @@ from urllib2 import urlopen +BIN = """# -*- coding: utf-8 -*- +import glob +import sys +import os + +lib = os.path.normpath(os.path.join(os.path.realpath(__file__), "../..", "lib")) +vendors = os.path.join(lib, "poetry", "_vendor") +current_vendors = os.path.join( + vendors, "py{}".format(".".join(str(v) for v in sys.version_info[:2])) +) +sys.path.insert(0, lib) +sys.path.insert(0, current_vendors) + +if __name__ == "__main__": + from poetry.console import main + main() +""" + +BAT = '@echo off\r\n{python_executable} "{poetry_bin}" %*\r\n' + + class SelfUpdateCommand(Command): name = "update" @@ -32,17 +57,23 @@ class SelfUpdateCommand(Command): REPOSITORY_URL = "https://github.com/python-poetry/poetry" BASE_URL = REPOSITORY_URL + "/releases/download" - FALLBACK_BASE_URL = "https://github.com/sdispater/poetry/releases/download" @property def home(self): from poetry.utils._compat import Path from poetry.utils.appdirs import expanduser + if os.environ.get("POETRY_HOME"): + return Path(expanduser(os.environ["POETRY_HOME"])) + home = Path(expanduser("~")) return home / ".poetry" + @property + def bin(self): + return self.home / "bin" + @property def lib(self): return self.home / "lib" @@ -55,16 +86,8 @@ def handle(self): from poetry.__version__ import __version__ from poetry.repositories.pypi_repository import PyPiRepository from poetry.semver import Version - from poetry.utils._compat import Path - current = Path(__file__) - try: - current.relative_to(self.home) - except ValueError: - raise RuntimeError( - "Poetry was not installed with the recommended installer. " - "Cannot update automatically." - ) + self._check_recommended_installation() version = self.argument("version") if not version: @@ -136,6 +159,8 @@ def update(self, release): if self.lib_backup.exists(): shutil.rmtree(str(self.lib_backup)) + self.make_bin() + self.line("") self.line("") self.line( @@ -147,20 +172,11 @@ def update(self, release): def _update(self, version): from poetry.utils.helpers import temporary_directory - platform = sys.platform - if platform == "linux2": - platform = "linux" + release_name = self._get_release_name(version) - checksum = "poetry-{}-{}.sha256sum".format(version, platform) + checksum = "{}.sha256sum".format(release_name) base_url = self.BASE_URL - try: - urlopen(self.REPOSITORY_URL) - except HTTPError as e: - if e.code == 404: - base_url = self.FALLBACK_BASE_URL - else: - raise try: r = urlopen(base_url + "/{}/{}".format(version, checksum)) @@ -170,10 +186,10 @@ def _update(self, version): raise - checksum = r.read().decode() + checksum = r.read().decode().strip() # We get the payload from the remote host - name = "poetry-{}-{}.tar.gz".format(version, platform) + name = "{}.tar.gz".format(release_name) try: r = urlopen(base_url + "/{}/{}".format(version, name)) except HTTPError as e: @@ -226,8 +242,94 @@ def _update(self, version): def process(self, *args): return subprocess.check_output(list(args), stderr=subprocess.STDOUT) + def _check_recommended_installation(self): + from poetry.utils._compat import Path + + current = Path(__file__) + try: + current.relative_to(self.home) + except ValueError: + raise RuntimeError( + "Poetry was not installed with the recommended installer. " + "Cannot update automatically." + ) + + def _get_release_name(self, version): + platform = sys.platform + if platform == "linux2": + platform = "linux" + + return "poetry-{}-{}".format(version, platform) + def _bin_path(self, base_path, bin): - if sys.platform == "win32": + from poetry.utils._compat import WINDOWS + + if WINDOWS: return (base_path / "Scripts" / bin).with_suffix(".exe") return base_path / "bin" / bin + + def make_bin(self): + from poetry.utils._compat import WINDOWS + + self.bin.mkdir(0o755, parents=True, exist_ok=True) + + python_executable = self._which_python() + + if WINDOWS: + with self.bin.joinpath("poetry.bat").open("w", newline="") as f: + f.write( + BAT.format( + python_executable=python_executable, + poetry_bin=str(self.bin / "poetry").replace( + os.environ["USERPROFILE"], "%USERPROFILE%" + ), + ) + ) + + bin_content = BIN + if not WINDOWS: + bin_content = "#!/usr/bin/env {}\n".format(python_executable) + bin_content + + self.bin.joinpath("poetry").write_text(bin_content, encoding="utf-8") + + if not WINDOWS: + # Making the file executable + st = os.stat(str(self.bin.joinpath("poetry"))) + os.chmod(str(self.bin.joinpath("poetry")), st.st_mode | stat.S_IEXEC) + + def _which_python(self): + """ + Decides which python executable we'll embed in the launcher script. + """ + from poetry.utils._compat import WINDOWS + + allowed_executables = ["python", "python3"] + if WINDOWS: + allowed_executables += ["py.exe -3", "py.exe -2"] + + # \d in regex ensures we can convert to int later + version_matcher = re.compile(r"^Python (?P\d+)\.(?P\d+)\..+$") + fallback = None + for executable in allowed_executables: + try: + raw_version = subprocess.check_output( + executable + " --version", stderr=subprocess.STDOUT, shell=True + ).decode("utf-8") + except subprocess.CalledProcessError: + continue + + match = version_matcher.match(raw_version.strip()) + if match and tuple(map(int, match.groups())) >= (3, 0): + # favor the first py3 executable we can find. + return executable + + if fallback is None: + # keep this one as the fallback; it was the first valid executable we found. + fallback = executable + + if fallback is None: + # Avoid breaking existing scripts + fallback = "python" + + return fallback diff --git a/tests/console/commands/self/__init__.py b/tests/console/commands/self/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/console/commands/self/fixtures/poetry-1.0.5-darwin.sha256sum b/tests/console/commands/self/fixtures/poetry-1.0.5-darwin.sha256sum new file mode 100644 index 00000000000..3229630afad --- /dev/null +++ b/tests/console/commands/self/fixtures/poetry-1.0.5-darwin.sha256sum @@ -0,0 +1 @@ +be3d3b916cb47038899d6ff37e875fd08ba3fed22bcdbf5a92f3f48fd2f15da8 diff --git a/tests/console/commands/self/fixtures/poetry-1.0.5-darwin.tar.gz b/tests/console/commands/self/fixtures/poetry-1.0.5-darwin.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..09bb17bdeb92ccdc331cba93b1337ec9129f355f GIT binary patch literal 1041 zcmV+s1n&DEiwFP)U%p-h1MOJdi`zyJ_p|YCX*_Cv%F2aS{p-ERS`!V0Y+0l+v3#R4q<>Z=A2+w-Go|ti!m@!<$ zcErsvoJ7l2vW}DW66RsFSR|_nNv`QstNWmIDhZh=_AXVLv#KQwMqn$7!QNM}tZn}7 z5Y)$OgoFuR#WvsT=lNeo(Hir=SS5>iu?D^xTVah~R@b`foTEnl+ zX2VgZ*~j!fQ!Vk0$UZVTLflI6fn|DYWf~^QYN5Cmk~0<5LX@qlEzBF9gXX0QXeRb` zsylkBe>Dn(l+woY2t03ZcR&4je@AWr+zty%%2@%M zyyBWt-!P+qVr4P!R%mEW$P1#6HQSIadV^f}lp;$@a2L_*@#H+y9Z!Q?k34|Ksxry| z(jH%faZ7(@rb!UeXPeF*dLLMLZb*xak5SA9JdI}nOfwtM`_TbYfBBpfT(>-UELxYX zFV=CO+R1=wj=~M3OqBl2rsY*FMa`r>8dgjay6>a5UZ9dep;RVYHr_GeCb~xcDV6?= zeDf_C$;OHH79Zo!bMN}dj95825+}O*!ebEt55PL2`i(8c7W1KU%*Tk|2>pmsQCpbN^hJcLQLUyo(gH<_*@YGHZrg>8oC$=n7WElM@S)L!JC)Me%%g8_@4mm^^`t%sUin7VoJ^rX>$N=yH7Mqryf5)Rk*Q3Y*R#;Zd7vRV8J zK0zn&f_#_f#2RNg$yp74uquQ8k!S%u3xwyPxS8=vLC4^Sb29L9=6#OjUBE_H|1BK! z@~?n%^&c))gZfXRFn0BSf%KkL(fc}qQk+IX7$nm#65O4@M1RMhY3W2`? LE~wAj04M+eXZ{jT literal 0 HcmV?d00001 diff --git a/tests/console/commands/self/test_update.py b/tests/console/commands/self/test_update.py new file mode 100644 index 00000000000..7d6914cfd7d --- /dev/null +++ b/tests/console/commands/self/test_update.py @@ -0,0 +1,87 @@ +import os + +from cleo.testers import CommandTester + +from poetry.__version__ import __version__ +from poetry.packages.package import Package +from poetry.semver.version import Version +from poetry.utils._compat import WINDOWS +from poetry.utils._compat import Path + + +FIXTURES = Path(__file__).parent.joinpath("fixtures") + + +def test_self_update_should_install_all_necessary_elements( + app, http, mocker, environ, tmp_dir +): + os.environ["POETRY_HOME"] = tmp_dir + + command = app.find("self update") + + version = Version.parse(__version__).next_minor.text + mocker.patch( + "poetry.repositories.pypi_repository.PyPiRepository.find_packages", + return_value=[Package("poetry", version)], + ) + mocker.patch.object(command, "_check_recommended_installation", return_value=None) + mocker.patch.object( + command, "_get_release_name", return_value="poetry-{}-darwin".format(version) + ) + mocker.patch("subprocess.check_output", return_value=b"Python 3.8.2") + + http.register_uri( + "GET", + command.BASE_URL + "/{}/poetry-{}-darwin.sha256sum".format(version, version), + body=FIXTURES.joinpath("poetry-1.0.5-darwin.sha256sum").read_bytes(), + ) + http.register_uri( + "GET", + command.BASE_URL + "/{}/poetry-{}-darwin.tar.gz".format(version, version), + body=FIXTURES.joinpath("poetry-1.0.5-darwin.tar.gz").read_bytes(), + ) + + tester = CommandTester(command) + tester.execute() + + bin_ = Path(tmp_dir).joinpath("bin") + lib = Path(tmp_dir).joinpath("lib") + assert bin_.exists() + + script = bin_.joinpath("poetry") + assert script.exists() + + expected_script = """\ +# -*- coding: utf-8 -*- +import glob +import sys +import os + +lib = os.path.normpath(os.path.join(os.path.realpath(__file__), "../..", "lib")) +vendors = os.path.join(lib, "poetry", "_vendor") +current_vendors = os.path.join( + vendors, "py{}".format(".".join(str(v) for v in sys.version_info[:2])) +) +sys.path.insert(0, lib) +sys.path.insert(0, current_vendors) + +if __name__ == "__main__": + from poetry.console import main + main() +""" + if not WINDOWS: + expected_script = "#!/usr/bin/env python\n" + expected_script + + assert expected_script == script.read_text() + + if WINDOWS: + bat = bin_.joinpath("poetry.bat") + expected_bat = '@echo off\r\npython "{}" %*\r\n'.format( + str(script).replace(os.environ.get("USERPROFILE", ""), "%USERPROFILE%") + ) + assert bat.exists() + with bat.open(newline="") as f: + assert expected_bat == f.read() + + assert lib.exists() + assert lib.joinpath("poetry").exists() From 0d646e2e30126f5eab1c022e8d71c434805e7153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 5 Jun 2020 12:43:02 +0200 Subject: [PATCH 53/80] Fix legacy repositories information not being set on packages (#2484) --- poetry/repositories/legacy_repository.py | 3 +++ tests/repositories/test_legacy_repository.py | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/poetry/repositories/legacy_repository.py b/poetry/repositories/legacy_repository.py index 4bb0496eb29..f850c29c85a 100644 --- a/poetry/repositories/legacy_repository.py +++ b/poetry/repositories/legacy_repository.py @@ -269,6 +269,8 @@ def find_packages( for version in versions: package = Package(name, version) + package.source_type = "legacy" + package.source_reference = self.name package.source_url = self._url if extras is not None: @@ -313,6 +315,7 @@ def package( if release_info["requires_python"]: package.python_versions = release_info["requires_python"] + package.source_type = "legacy" package.source_url = self._url package.source_reference = self.name diff --git a/tests/repositories/test_legacy_repository.py b/tests/repositories/test_legacy_repository.py index 3803da552ce..43aa8aae028 100644 --- a/tests/repositories/test_legacy_repository.py +++ b/tests/repositories/test_legacy_repository.py @@ -84,6 +84,9 @@ def test_get_package_information_fallback_read_setup(): package = repo.package("jupyter", "1.0.0") + assert package.source_type == "legacy" + assert package.source_reference == repo.name + assert package.source_url == repo.url assert package.name == "jupyter" assert package.version.text == "1.0.0" assert ( @@ -142,6 +145,10 @@ def test_find_packages_no_prereleases(): assert len(packages) == 1 + assert packages[0].source_type == "legacy" + assert packages[0].source_reference == repo.name + assert packages[0].source_url == repo.url + def test_get_package_information_chooses_correct_distribution(): repo = MockRepository() From 5384da7a4b6a9c9f47ae099588a6a3d6d59c2562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 5 Jun 2020 15:27:35 +0200 Subject: [PATCH 54/80] Upgrade dependencies before the 1.0.6 release (#2495) --- poetry.lock | 438 ++++++++++++++++++++++++++++++------------------- pyproject.toml | 5 +- 2 files changed, 273 insertions(+), 170 deletions(-) diff --git a/poetry.lock b/poetry.lock index 165be3bd167..8d423ed68f9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4,7 +4,7 @@ description = "A small Python module for determining appropriate platform-specif name = "appdirs" optional = false python-versions = "*" -version = "1.4.3" +version = "1.4.4" [[package]] category = "dev" @@ -20,10 +20,11 @@ pyyaml = "*" [[package]] category = "dev" description = "Atomic file writes." +marker = "python_version >= \"3.5\" and sys_platform == \"win32\" or python_version < \"3.5\"" name = "atomicwrites" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.3.0" +version = "1.4.0" [[package]] category = "main" @@ -39,6 +40,19 @@ dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.int docs = ["sphinx", "zope.interface"] tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] +[[package]] +category = "dev" +description = "Backport of functools.lru_cache" +marker = "python_version < \"3.2\"" +name = "backports.functools-lru-cache" +optional = false +python-versions = ">=2.6" +version = "1.6.1" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-black-multipy", "pytest-cov"] + [[package]] category = "dev" description = "The uncompromising code formatter." @@ -146,20 +160,20 @@ clikit = ">=0.4.0,<0.5.0" [[package]] category = "dev" description = "Composable command line interface toolkit" -marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_version >= \"3.4\" and python_version < \"4.0\"" +marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_version >= \"3.4\" and python_version < \"4.0\" or python_version >= \"3.6\" and python_version < \"4.0\"" name = "click" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "7.0" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "7.1.2" [[package]] category = "dev" description = "Composable command line interface toolkit" -marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_version >= \"3.4\" and python_version < \"4.0\" or python_version >= \"3.6\" and python_version < \"4.0\"" +marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_version >= \"3.4\" and python_version < \"4.0\"" name = "click" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "7.1.1" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "7.0" [[package]] category = "main" @@ -197,7 +211,7 @@ version = "0.4.1" [[package]] category = "dev" description = "Cross-platform colored terminal text." -marker = "sys_platform == \"win32\" and python_version != \"3.4\" or platform_system == \"Windows\"" +marker = "sys_platform == \"win32\" and python_version != \"3.4\" and python_version < \"3.5\" or platform_system == \"Windows\" or python_version >= \"3.5\" and sys_platform == \"win32\"" name = "colorama" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" @@ -239,7 +253,7 @@ description = "Code coverage measurement for Python" name = "coverage" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" -version = "5.0.4" +version = "5.1" [package.extras] toml = ["toml"] @@ -271,7 +285,7 @@ marker = "python_version >= \"2.7\" and python_version < \"2.8\" and (sys_platfo name = "cryptography" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" -version = "2.9" +version = "2.9.2" [package.dependencies] cffi = ">=1.8,<1.11.3 || >1.11.3" @@ -412,7 +426,7 @@ description = "File identification library for Python" name = "identify" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "1.4.14" +version = "1.4.19" [package.extras] license = ["editdistance"] @@ -477,7 +491,7 @@ marker = "python_version < \"3.7\"" name = "importlib-resources" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -version = "1.4.0" +version = "1.5.0" [package.dependencies] [package.dependencies.contextlib2] @@ -550,7 +564,7 @@ marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_v name = "jinja2" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "2.11.1" +version = "2.11.2" [package.dependencies] MarkupSafe = ">=0.23" @@ -558,6 +572,15 @@ MarkupSafe = ">=0.23" [package.extras] i18n = ["Babel (>=0.8)"] +[[package]] +category = "dev" +description = "Lightweight pipelining: using Python functions as pipeline jobs." +marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_version >= \"3.4\" and python_version < \"4.0\"" +name = "joblib" +optional = false +python-versions = "*" +version = "0.14.1" + [[package]] category = "main" description = "An implementation of JSON Schema validation for Python" @@ -654,7 +677,7 @@ marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_v name = "lunr" optional = false python-versions = "*" -version = "0.5.6" +version = "0.5.8" [package.dependencies] future = ">=0.16.0" @@ -662,10 +685,11 @@ six = ">=1.11.0" [package.dependencies.nltk] optional = true +python = ">=2.8" version = ">=3.2.5" [package.extras] -languages = ["nltk (>=3.2.5)"] +languages = ["nltk (>=3.2.5,<3.5)", "nltk (>=3.2.5)"] [[package]] category = "dev" @@ -695,10 +719,12 @@ description = "Python implementation of Markdown." name = "markdown" optional = false python-versions = ">=3.5" -version = "3.2.1" +version = "3.2.2" [package.dependencies] -setuptools = ">=36" +[package.dependencies.importlib-metadata] +python = "<3.8" +version = "*" [package.extras] testing = ["coverage", "pyyaml"] @@ -747,7 +773,7 @@ marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_v name = "mkdocs" optional = false python-versions = ">=3.5" -version = "1.1" +version = "1.1.2" [package.dependencies] Jinja2 = ">=2.10.1" @@ -759,7 +785,7 @@ tornado = ">=5.0" [package.dependencies.lunr] extras = ["languages"] -version = "0.5.6" +version = "0.5.8" [[package]] category = "dev" @@ -797,7 +823,7 @@ six = ">=1.0.0,<2.0.0" [[package]] category = "dev" description = "More routines for operating on iterables, beyond itertools" -marker = "python_version > \"2.7\"" +marker = "python_version < \"3.5\" and python_version > \"2.7\"" name = "more-itertools" optional = false python-versions = ">=3.4" @@ -806,11 +832,11 @@ version = "7.2.0" [[package]] category = "dev" description = "More routines for operating on iterables, beyond itertools" -marker = "python_version > \"2.7\"" +marker = "python_version >= \"3.5\"" name = "more-itertools" optional = false python-versions = ">=3.5" -version = "8.2.0" +version = "8.3.0" [[package]] category = "main" @@ -827,13 +853,16 @@ marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_v name = "nltk" optional = false python-versions = "*" -version = "3.4.5" +version = "3.5" [package.dependencies] -six = "*" +click = "*" +joblib = "*" +regex = "*" +tqdm = "*" [package.extras] -all = ["pyparsing", "scikit-learn", "python-crfsuite", "matplotlib", "scipy", "gensim", "requests", "twython", "numpy"] +all = ["requests", "numpy", "python-crfsuite", "scikit-learn", "twython", "pyparsing", "scipy", "matplotlib", "gensim"] corenlp = ["requests"] machine_learning = ["gensim", "numpy", "python-crfsuite", "scikit-learn", "scipy"] plot = ["matplotlib"] @@ -846,7 +875,7 @@ description = "Node.js virtual environment builder" name = "nodeenv" optional = false python-versions = "*" -version = "1.3.5" +version = "1.4.0" [[package]] category = "dev" @@ -854,7 +883,7 @@ description = "Core utilities for Python packages" name = "packaging" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "20.3" +version = "20.4" [package.dependencies] pyparsing = ">=2.0.2" @@ -871,7 +900,7 @@ version = "0.2.0" [[package]] category = "main" description = "Object-oriented filesystem paths" -marker = "python_version >= \"2.7\" and python_version < \"2.8\" or python_version >= \"3.4\" and python_version < \"3.5\" or python_version < \"3.6\"" +marker = "python_version >= \"2.7\" and python_version < \"2.8\" or python_version >= \"3.4\" and python_version < \"3.5\" or python_version < \"3.5\" or python_version >= \"3.5\" and python_version < \"3.6\"" name = "pathlib2" optional = false python-versions = "*" @@ -1119,7 +1148,7 @@ description = "pytest: simple powerful testing with Python" name = "pytest" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "4.6.9" +version = "4.6.11" [package.dependencies] atomicwrites = ">=1.0" @@ -1161,6 +1190,36 @@ version = ">=2.2.0" [package.extras] testing = ["argcomplete", "hypothesis (>=3.56)", "nose", "requests", "mock"] +[[package]] +category = "dev" +description = "pytest: simple powerful testing with Python" +name = "pytest" +optional = false +python-versions = ">=3.5" +version = "5.4.3" + +[package.dependencies] +atomicwrites = ">=1.0" +attrs = ">=17.4.0" +colorama = "*" +more-itertools = ">=4.0.0" +packaging = "*" +pluggy = ">=0.12,<1.0" +py = ">=1.5.0" +wcwidth = "*" + +[package.dependencies.importlib-metadata] +python = "<3.8" +version = ">=0.12" + +[package.dependencies.pathlib2] +python = "<3.6" +version = ">=2.2.0" + +[package.extras] +checkqa-mypy = ["mypy (v0.761)"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + [[package]] category = "dev" description = "Pytest plugin for measuring coverage." @@ -1176,6 +1235,21 @@ pytest = ">=3.6" [package.extras] testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "virtualenv"] +[[package]] +category = "dev" +description = "Pytest plugin for measuring coverage." +name = "pytest-cov" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.9.0" + +[package.dependencies] +coverage = ">=4.4" +pytest = ">=3.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "pytest-xdist", "virtualenv"] + [[package]] category = "dev" description = "Thin-wrapper around the mock package for easier use with py.test" @@ -1200,7 +1274,7 @@ description = "pytest-sugar is a plugin for pytest that changes the default look name = "pytest-sugar" optional = false python-versions = "*" -version = "0.9.2" +version = "0.9.3" [package.dependencies] packaging = ">=14.1" @@ -1235,11 +1309,11 @@ version = "5.3.1" [[package]] category = "dev" description = "Alternative regular expression module, to replace re." -marker = "python_version >= \"3.6\" and python_version < \"4.0\"" +marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_version >= \"3.4\" and python_version < \"4.0\" or python_version >= \"3.6\" and python_version < \"4.0\"" name = "regex" optional = false python-versions = "*" -version = "2020.4.4" +version = "2020.5.14" [[package]] category = "main" @@ -1351,7 +1425,7 @@ description = "Python 2 and 3 compatibility utilities" name = "six" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -version = "1.14.0" +version = "1.15.0" [[package]] category = "main" @@ -1376,7 +1450,7 @@ description = "Python Library for Tom's Obvious, Minimal Language" name = "toml" optional = false python-versions = "*" -version = "0.10.0" +version = "0.10.1" [[package]] category = "main" @@ -1444,15 +1518,15 @@ description = "tox is a generic virtualenv management and test command line tool name = "tox" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -version = "3.14.6" +version = "3.15.1" [package.dependencies] colorama = ">=0.4.1" -filelock = ">=3.0.0,<4" +filelock = ">=3.0.0" packaging = ">=14" -pluggy = ">=0.12.0,<1" -py = ">=1.4.17,<2" -six = ">=1.14.0,<2" +pluggy = ">=0.12.0" +py = ">=1.4.17" +six = ">=1.14.0" toml = ">=0.9.4" virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7" @@ -1461,8 +1535,20 @@ python = "<3.8" version = ">=0.12,<2" [package.extras] -docs = ["sphinx (>=2.0.0,<3)", "towncrier (>=18.5.0)", "pygments-github-lexers (>=0.0.5)", "sphinxcontrib-autoprogram (>=0.1.5)"] -testing = ["freezegun (>=0.3.11,<1)", "pathlib2 (>=2.3.3,<3)", "pytest (>=4.0.0,<6)", "pytest-cov (>=2.5.1,<3)", "pytest-mock (>=1.10.0,<2)", "pytest-xdist (>=1.22.2,<2)", "pytest-randomly (>=1.0.0,<4)", "flaky (>=3.4.0,<4)", "psutil (>=5.6.1,<6)"] +docs = ["sphinx (>=2.0.0)", "towncrier (>=18.5.0)", "pygments-github-lexers (>=0.0.5)", "sphinxcontrib-autoprogram (>=0.1.5)"] +testing = ["freezegun (>=0.3.11)", "pathlib2 (>=2.3.3)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-xdist (>=1.22.2)", "pytest-randomly (>=1.0.0)", "flaky (>=3.4.0)", "psutil (>=5.6.1)"] + +[[package]] +category = "dev" +description = "Fast, Extensible Progress Meter" +marker = "python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_version >= \"3.4\" and python_version < \"4.0\"" +name = "tqdm" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*" +version = "4.46.1" + +[package.extras] +dev = ["py-make (>=0.1.0)", "twine", "argopt", "pydoc-markdown"] [[package]] category = "dev" @@ -1509,11 +1595,11 @@ description = "HTTP library with thread-safe connection pooling, file post, and name = "urllib3" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" -version = "1.25.8" +version = "1.25.9" [package.extras] brotli = ["brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"] socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] [[package]] @@ -1534,7 +1620,7 @@ description = "Virtual Python Environment builder" name = "virtualenv" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "20.0.17" +version = "20.0.21" [package.dependencies] appdirs = ">=1.4.3,<2" @@ -1551,16 +1637,22 @@ python = "<3.7" version = ">=1.0,<2" [package.extras] -docs = ["sphinx (>=2.0.0,<3)", "sphinx-argparse (>=0.2.5,<1)", "sphinx-rtd-theme (>=0.4.3,<1)", "towncrier (>=19.9.0rc1)", "proselint (>=0.10.2,<1)"] -testing = ["pytest (>=4.0.0,<6)", "coverage (>=4.5.1,<6)", "pytest-mock (>=2.0.0,<3)", "pytest-env (>=0.6.2,<1)", "pytest-timeout (>=1.3.4,<2)", "packaging (>=20.0)", "xonsh (>=0.9.16,<1)"] +docs = ["sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)", "proselint (>=0.10.2)"] +testing = ["pytest (>=4)", "coverage (>=5)", "coverage-enable-subprocess (>=1)", "pytest-xdist (>=1.31.0)", "pytest-mock (>=2)", "pytest-env (>=0.6.2)", "pytest-randomly (>=1)", "pytest-timeout", "packaging (>=20.0)", "xonsh (>=0.9.16)"] [[package]] category = "dev" -description = "Measures number of Terminal column cells of wide-character codes" +description = "Measures the displayed width of unicode strings in a terminal" +marker = "python_version < \"3.5\" or python_version >= \"3.5\"" name = "wcwidth" optional = false python-versions = "*" -version = "0.1.9" +version = "0.2.3" + +[package.dependencies] +[package.dependencies."backports.functools-lru-cache"] +python = "<3.2" +version = ">=1.2.1" [[package]] category = "main" @@ -1573,7 +1665,7 @@ version = "0.5.1" [[package]] category = "main" description = "Backport of pathlib-compatible object wrapper for zip files" -marker = "python_version < \"3.8\" or python_version >= \"3.5\" and python_version < \"3.8\"" +marker = "python_version < \"3.8\" or python_version >= \"3.5\" and python_version < \"3.8\" or python_version >= \"2.7.9\" and python_version < \"2.8.0\" or python_version >= \"3.4\" and python_version < \"3.8\"" name = "zipp" optional = false python-versions = ">=2.7" @@ -1589,26 +1681,30 @@ docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] testing = ["pathlib2", "unittest2", "jaraco.itertools", "func-timeout"] [metadata] -content-hash = "70609fddc0d3768b1003fc24207951ab7ad8bfad4c6cb326d6217c52f5a92e3d" +content-hash = "f585f9479c9551e48768249cc80ec8f217539b42fcc3822543fdd0789f9f9d87" python-versions = "~2.7 || ^3.4" [metadata.files] appdirs = [ - {file = "appdirs-1.4.3-py2.py3-none-any.whl", hash = "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"}, - {file = "appdirs-1.4.3.tar.gz", hash = "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92"}, + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, ] "aspy.yaml" = [ {file = "aspy.yaml-1.3.0-py2.py3-none-any.whl", hash = "sha256:463372c043f70160a9ec950c3f1e4c3a82db5fca01d334b6bc89c7164d744bdc"}, {file = "aspy.yaml-1.3.0.tar.gz", hash = "sha256:e7c742382eff2caed61f87a39d13f99109088e5e93f04d76eb8d4b28aa143f45"}, ] atomicwrites = [ - {file = "atomicwrites-1.3.0-py2.py3-none-any.whl", hash = "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4"}, - {file = "atomicwrites-1.3.0.tar.gz", hash = "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"}, + {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, + {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ {file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"}, {file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"}, ] +"backports.functools-lru-cache" = [ + {file = "backports.functools_lru_cache-1.6.1-py2.py3-none-any.whl", hash = "sha256:0bada4c2f8a43d533e4ecb7a12214d9420e66eb206d54bf2d682581ca4b80848"}, + {file = "backports.functools_lru_cache-1.6.1.tar.gz", hash = "sha256:8fde5f188da2d593bd5bc0be98d9abc46c95bb8a9dde93429570192ee6cc2d4a"}, +] black = [ {file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"}, {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"}, @@ -1668,10 +1764,10 @@ cleo = [ {file = "cleo-0.7.6.tar.gz", hash = "sha256:99cf342406f3499cec43270fcfaf93c126c5164092eca201dfef0f623360b409"}, ] click = [ + {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, + {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, {file = "Click-7.0-py2.py3-none-any.whl", hash = "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13"}, {file = "Click-7.0.tar.gz", hash = "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"}, - {file = "click-7.1.1-py2.py3-none-any.whl", hash = "sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a"}, - {file = "click-7.1.1.tar.gz", hash = "sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc"}, ] clikit = [ {file = "clikit-0.4.3-py2.py3-none-any.whl", hash = "sha256:71e321b7795a2a6c4888629f43365d52db071737e668ab16861121d7dd3ada09"}, @@ -1724,37 +1820,37 @@ coverage = [ {file = "coverage-4.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351"}, {file = "coverage-4.5.4-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5"}, {file = "coverage-4.5.4.tar.gz", hash = "sha256:e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c"}, - {file = "coverage-5.0.4-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:8a620767b8209f3446197c0e29ba895d75a1e272a36af0786ec70fe7834e4307"}, - {file = "coverage-5.0.4-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:73aa6e86034dad9f00f4bbf5a666a889d17d79db73bc5af04abd6c20a014d9c8"}, - {file = "coverage-5.0.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:408ce64078398b2ee2ec08199ea3fcf382828d2f8a19c5a5ba2946fe5ddc6c31"}, - {file = "coverage-5.0.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:cda33311cb9fb9323958a69499a667bd728a39a7aa4718d7622597a44c4f1441"}, - {file = "coverage-5.0.4-cp27-cp27m-win32.whl", hash = "sha256:5f587dfd83cb669933186661a351ad6fc7166273bc3e3a1531ec5c783d997aac"}, - {file = "coverage-5.0.4-cp27-cp27m-win_amd64.whl", hash = "sha256:9fad78c13e71546a76c2f8789623eec8e499f8d2d799f4b4547162ce0a4df435"}, - {file = "coverage-5.0.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:2e08c32cbede4a29e2a701822291ae2bc9b5220a971bba9d1e7615312efd3037"}, - {file = "coverage-5.0.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:922fb9ef2c67c3ab20e22948dcfd783397e4c043a5c5fa5ff5e9df5529074b0a"}, - {file = "coverage-5.0.4-cp35-cp35m-macosx_10_12_x86_64.whl", hash = "sha256:c3fc325ce4cbf902d05a80daa47b645d07e796a80682c1c5800d6ac5045193e5"}, - {file = "coverage-5.0.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:046a1a742e66d065d16fb564a26c2a15867f17695e7f3d358d7b1ad8a61bca30"}, - {file = "coverage-5.0.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6ad6ca45e9e92c05295f638e78cd42bfaaf8ee07878c9ed73e93190b26c125f7"}, - {file = "coverage-5.0.4-cp35-cp35m-win32.whl", hash = "sha256:eda55e6e9ea258f5e4add23bcf33dc53b2c319e70806e180aecbff8d90ea24de"}, - {file = "coverage-5.0.4-cp35-cp35m-win_amd64.whl", hash = "sha256:4a8a259bf990044351baf69d3b23e575699dd60b18460c71e81dc565f5819ac1"}, - {file = "coverage-5.0.4-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:f372cdbb240e09ee855735b9d85e7f50730dcfb6296b74b95a3e5dea0615c4c1"}, - {file = "coverage-5.0.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a37c6233b28e5bc340054cf6170e7090a4e85069513320275a4dc929144dccf0"}, - {file = "coverage-5.0.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:443be7602c790960b9514567917af538cac7807a7c0c0727c4d2bbd4014920fd"}, - {file = "coverage-5.0.4-cp36-cp36m-win32.whl", hash = "sha256:165a48268bfb5a77e2d9dbb80de7ea917332a79c7adb747bd005b3a07ff8caf0"}, - {file = "coverage-5.0.4-cp36-cp36m-win_amd64.whl", hash = "sha256:0a907199566269e1cfa304325cc3b45c72ae341fbb3253ddde19fa820ded7a8b"}, - {file = "coverage-5.0.4-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:513e6526e0082c59a984448f4104c9bf346c2da9961779ede1fc458e8e8a1f78"}, - {file = "coverage-5.0.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:3844c3dab800ca8536f75ae89f3cf566848a3eb2af4d9f7b1103b4f4f7a5dad6"}, - {file = "coverage-5.0.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:641e329e7f2c01531c45c687efcec8aeca2a78a4ff26d49184dce3d53fc35014"}, - {file = "coverage-5.0.4-cp37-cp37m-win32.whl", hash = "sha256:db1d4e38c9b15be1521722e946ee24f6db95b189d1447fa9ff18dd16ba89f732"}, - {file = "coverage-5.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:62061e87071497951155cbccee487980524d7abea647a1b2a6eb6b9647df9006"}, - {file = "coverage-5.0.4-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:65a7e00c00472cd0f59ae09d2fb8a8aaae7f4a0cf54b2b74f3138d9f9ceb9cb2"}, - {file = "coverage-5.0.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1f66cf263ec77af5b8fe14ef14c5e46e2eb4a795ac495ad7c03adc72ae43fafe"}, - {file = "coverage-5.0.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:85596aa5d9aac1bf39fe39d9fa1051b0f00823982a1de5766e35d495b4a36ca9"}, - {file = "coverage-5.0.4-cp38-cp38-win32.whl", hash = "sha256:86a0ea78fd851b313b2e712266f663e13b6bc78c2fb260b079e8b67d970474b1"}, - {file = "coverage-5.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:03f630aba2b9b0d69871c2e8d23a69b7fe94a1e2f5f10df5049c0df99db639a0"}, - {file = "coverage-5.0.4-cp39-cp39-win32.whl", hash = "sha256:7c9762f80a25d8d0e4ab3cb1af5d9dffbddb3ee5d21c43e3474c84bf5ff941f7"}, - {file = "coverage-5.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:4482f69e0701139d0f2c44f3c395d1d1d37abd81bfafbf9b6efbe2542679d892"}, - {file = "coverage-5.0.4.tar.gz", hash = "sha256:1b60a95fc995649464e0cd48cecc8288bac5f4198f21d04b8229dc4097d76823"}, + {file = "coverage-5.1-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:0cb4be7e784dcdc050fc58ef05b71aa8e89b7e6636b99967fadbdba694cf2b65"}, + {file = "coverage-5.1-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:c317eaf5ff46a34305b202e73404f55f7389ef834b8dbf4da09b9b9b37f76dd2"}, + {file = "coverage-5.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b83835506dfc185a319031cf853fa4bb1b3974b1f913f5bb1a0f3d98bdcded04"}, + {file = "coverage-5.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5f2294dbf7875b991c381e3d5af2bcc3494d836affa52b809c91697449d0eda6"}, + {file = "coverage-5.1-cp27-cp27m-win32.whl", hash = "sha256:de807ae933cfb7f0c7d9d981a053772452217df2bf38e7e6267c9cbf9545a796"}, + {file = "coverage-5.1-cp27-cp27m-win_amd64.whl", hash = "sha256:bf9cb9a9fd8891e7efd2d44deb24b86d647394b9705b744ff6f8261e6f29a730"}, + {file = "coverage-5.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:acf3763ed01af8410fc36afea23707d4ea58ba7e86a8ee915dfb9ceff9ef69d0"}, + {file = "coverage-5.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:dec5202bfe6f672d4511086e125db035a52b00f1648d6407cc8e526912c0353a"}, + {file = "coverage-5.1-cp35-cp35m-macosx_10_12_x86_64.whl", hash = "sha256:7a5bdad4edec57b5fb8dae7d3ee58622d626fd3a0be0dfceda162a7035885ecf"}, + {file = "coverage-5.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1601e480b9b99697a570cea7ef749e88123c04b92d84cedaa01e117436b4a0a9"}, + {file = "coverage-5.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:dbe8c6ae7534b5b024296464f387d57c13caa942f6d8e6e0346f27e509f0f768"}, + {file = "coverage-5.1-cp35-cp35m-win32.whl", hash = "sha256:a027ef0492ede1e03a8054e3c37b8def89a1e3c471482e9f046906ba4f2aafd2"}, + {file = "coverage-5.1-cp35-cp35m-win_amd64.whl", hash = "sha256:0e61d9803d5851849c24f78227939c701ced6704f337cad0a91e0972c51c1ee7"}, + {file = "coverage-5.1-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:2d27a3f742c98e5c6b461ee6ef7287400a1956c11421eb574d843d9ec1f772f0"}, + {file = "coverage-5.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:66460ab1599d3cf894bb6baee8c684788819b71a5dc1e8fa2ecc152e5d752019"}, + {file = "coverage-5.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5c542d1e62eece33c306d66fe0a5c4f7f7b3c08fecc46ead86d7916684b36d6c"}, + {file = "coverage-5.1-cp36-cp36m-win32.whl", hash = "sha256:2742c7515b9eb368718cd091bad1a1b44135cc72468c731302b3d641895b83d1"}, + {file = "coverage-5.1-cp36-cp36m-win_amd64.whl", hash = "sha256:dead2ddede4c7ba6cb3a721870f5141c97dc7d85a079edb4bd8d88c3ad5b20c7"}, + {file = "coverage-5.1-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:01333e1bd22c59713ba8a79f088b3955946e293114479bbfc2e37d522be03355"}, + {file = "coverage-5.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:e1ea316102ea1e1770724db01998d1603ed921c54a86a2efcb03428d5417e489"}, + {file = "coverage-5.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:adeb4c5b608574a3d647011af36f7586811a2c1197c861aedb548dd2453b41cd"}, + {file = "coverage-5.1-cp37-cp37m-win32.whl", hash = "sha256:782caea581a6e9ff75eccda79287daefd1d2631cc09d642b6ee2d6da21fc0a4e"}, + {file = "coverage-5.1-cp37-cp37m-win_amd64.whl", hash = "sha256:00f1d23f4336efc3b311ed0d807feb45098fc86dee1ca13b3d6768cdab187c8a"}, + {file = "coverage-5.1-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:402e1744733df483b93abbf209283898e9f0d67470707e3c7516d84f48524f55"}, + {file = "coverage-5.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:a3f3654d5734a3ece152636aad89f58afc9213c6520062db3978239db122f03c"}, + {file = "coverage-5.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6402bd2fdedabbdb63a316308142597534ea8e1895f4e7d8bf7476c5e8751fef"}, + {file = "coverage-5.1-cp38-cp38-win32.whl", hash = "sha256:8fa0cbc7ecad630e5b0f4f35b0f6ad419246b02bc750de7ac66db92667996d24"}, + {file = "coverage-5.1-cp38-cp38-win_amd64.whl", hash = "sha256:79a3cfd6346ce6c13145731d39db47b7a7b859c0272f02cdb89a3bdcbae233a0"}, + {file = "coverage-5.1-cp39-cp39-win32.whl", hash = "sha256:a82b92b04a23d3c8a581fc049228bafde988abacba397d57ce95fe95e0338ab4"}, + {file = "coverage-5.1-cp39-cp39-win_amd64.whl", hash = "sha256:bb28a7245de68bf29f6fb199545d072d1036a1917dca17a1e75bbb919e14ee8e"}, + {file = "coverage-5.1.tar.gz", hash = "sha256:f90bfc4ad18450c80b024036eaf91e4a246ae287701aaa88eaebebf150868052"}, ] cryptography = [ {file = "cryptography-2.8-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8"}, @@ -1778,25 +1874,25 @@ cryptography = [ {file = "cryptography-2.8-cp38-cp38-win32.whl", hash = "sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e"}, {file = "cryptography-2.8-cp38-cp38-win_amd64.whl", hash = "sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13"}, {file = "cryptography-2.8.tar.gz", hash = "sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651"}, - {file = "cryptography-2.9-cp27-cp27m-macosx_10_9_intel.whl", hash = "sha256:ef9a55013676907df6c9d7dd943eb1770d014f68beaa7e73250fb43c759f4585"}, - {file = "cryptography-2.9-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:2a2ad24d43398d89f92209289f15265107928f22a8d10385f70def7a698d6a02"}, - {file = "cryptography-2.9-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:95e1296e0157361fe2f5f0ed307fd31f94b0ca13372e3673fa95095a627636a1"}, - {file = "cryptography-2.9-cp27-cp27m-win32.whl", hash = "sha256:192ca04a36852a994ef21df13cca4d822adbbdc9d5009c0f96f1d2929e375d4f"}, - {file = "cryptography-2.9-cp27-cp27m-win_amd64.whl", hash = "sha256:ed1d0760c7e46436ec90834d6f10477ff09475c692ed1695329d324b2c5cd547"}, - {file = "cryptography-2.9-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:19ae795137682a9778892fb4390c07811828b173741bce91e30f899424b3934d"}, - {file = "cryptography-2.9-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d1bf5a1a0d60c7f9a78e448adcb99aa101f3f9588b16708044638881be15d6bc"}, - {file = "cryptography-2.9-cp35-abi3-macosx_10_9_intel.whl", hash = "sha256:1b9b535d6b55936a79dbe4990b64bb16048f48747c76c29713fea8c50eca2acf"}, - {file = "cryptography-2.9-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:7a279f33a081d436e90e91d1a7c338553c04e464de1c9302311a5e7e4b746088"}, - {file = "cryptography-2.9-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:49870684da168b90110bbaf86140d4681032c5e6a2461adc7afdd93be5634216"}, - {file = "cryptography-2.9-cp35-cp35m-win32.whl", hash = "sha256:6b91cab3841b4c7cb70e4db1697c69f036c8bc0a253edc0baa6783154f1301e4"}, - {file = "cryptography-2.9-cp35-cp35m-win_amd64.whl", hash = "sha256:587f98ce27ac4547177a0c6fe0986b8736058daffe9160dcf5f1bd411b7fbaa1"}, - {file = "cryptography-2.9-cp36-cp36m-win32.whl", hash = "sha256:cc20316e3f5a6b582fc3b029d8dc03aabeb645acfcb7fc1d9848841a33265748"}, - {file = "cryptography-2.9-cp36-cp36m-win_amd64.whl", hash = "sha256:3be7a5722d5bfe69894d3f7bbed15547b17619f3a88a318aab2e37f457524164"}, - {file = "cryptography-2.9-cp37-cp37m-win32.whl", hash = "sha256:7598974f6879a338c785c513e7c5a4329fbc58b9f6b9a6305035fca5b1076552"}, - {file = "cryptography-2.9-cp37-cp37m-win_amd64.whl", hash = "sha256:5aca6f00b2f42546b9bdf11a69f248d1881212ce5b9e2618b04935b87f6f82a1"}, - {file = "cryptography-2.9-cp38-cp38-win32.whl", hash = "sha256:9fc9da390e98cb6975eadf251b6e5fa088820141061bf041cd5c72deba1dc526"}, - {file = "cryptography-2.9-cp38-cp38-win_amd64.whl", hash = "sha256:6b744039b55988519cc183149cceb573189b3e46e16ccf6f8c46798bb767c9dc"}, - {file = "cryptography-2.9.tar.gz", hash = "sha256:0cacd3ef5c604b8e5f59bf2582c076c98a37fe206b31430d0cd08138aff0986e"}, + {file = "cryptography-2.9.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:daf54a4b07d67ad437ff239c8a4080cfd1cc7213df57d33c97de7b4738048d5e"}, + {file = "cryptography-2.9.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:3b3eba865ea2754738616f87292b7f29448aec342a7c720956f8083d252bf28b"}, + {file = "cryptography-2.9.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:c447cf087cf2dbddc1add6987bbe2f767ed5317adb2d08af940db517dd704365"}, + {file = "cryptography-2.9.2-cp27-cp27m-win32.whl", hash = "sha256:f118a95c7480f5be0df8afeb9a11bd199aa20afab7a96bcf20409b411a3a85f0"}, + {file = "cryptography-2.9.2-cp27-cp27m-win_amd64.whl", hash = "sha256:c4fd17d92e9d55b84707f4fd09992081ba872d1a0c610c109c18e062e06a2e55"}, + {file = "cryptography-2.9.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d0d5aeaedd29be304848f1c5059074a740fa9f6f26b84c5b63e8b29e73dfc270"}, + {file = "cryptography-2.9.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e4014639d3d73fbc5ceff206049c5a9a849cefd106a49fa7aaaa25cc0ce35cf"}, + {file = "cryptography-2.9.2-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:96c080ae7118c10fcbe6229ab43eb8b090fccd31a09ef55f83f690d1ef619a1d"}, + {file = "cryptography-2.9.2-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:e993468c859d084d5579e2ebee101de8f5a27ce8e2159959b6673b418fd8c785"}, + {file = "cryptography-2.9.2-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:88c881dd5a147e08d1bdcf2315c04972381d026cdb803325c03fe2b4a8ed858b"}, + {file = "cryptography-2.9.2-cp35-cp35m-win32.whl", hash = "sha256:651448cd2e3a6bc2bb76c3663785133c40d5e1a8c1a9c5429e4354201c6024ae"}, + {file = "cryptography-2.9.2-cp35-cp35m-win_amd64.whl", hash = "sha256:726086c17f94747cedbee6efa77e99ae170caebeb1116353c6cf0ab67ea6829b"}, + {file = "cryptography-2.9.2-cp36-cp36m-win32.whl", hash = "sha256:091d31c42f444c6f519485ed528d8b451d1a0c7bf30e8ca583a0cac44b8a0df6"}, + {file = "cryptography-2.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:bb1f0281887d89617b4c68e8db9a2c42b9efebf2702a3c5bf70599421a8623e3"}, + {file = "cryptography-2.9.2-cp37-cp37m-win32.whl", hash = "sha256:18452582a3c85b96014b45686af264563e3e5d99d226589f057ace56196ec78b"}, + {file = "cryptography-2.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:22e91636a51170df0ae4dcbd250d318fd28c9f491c4e50b625a49964b24fe46e"}, + {file = "cryptography-2.9.2-cp38-cp38-win32.whl", hash = "sha256:844a76bc04472e5135b909da6aed84360f522ff5dfa47f93e3dd2a0b84a89fa0"}, + {file = "cryptography-2.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:1dfa985f62b137909496e7fc182dac687206d8d089dd03eaeb28ae16eec8e7d5"}, + {file = "cryptography-2.9.2.tar.gz", hash = "sha256:a0c30272fb4ddda5f5ffc1089d7405b7a71b0b0f51993cb4e5dbb4590b2fc229"}, ] distlib = [ {file = "distlib-0.3.0.zip", hash = "sha256:2e166e231a26b36d6dfe35a48c4464346620f8645ed0ace01ee31822b288de21"}, @@ -1840,8 +1936,8 @@ httpretty = [ {file = "httpretty-0.9.7.tar.gz", hash = "sha256:66216f26b9d2c52e81808f3e674a6fb65d4bf719721394a1a9be926177e55fbe"}, ] identify = [ - {file = "identify-1.4.14-py2.py3-none-any.whl", hash = "sha256:2bb8760d97d8df4408f4e805883dad26a2d076f04be92a10a3e43f09c6060742"}, - {file = "identify-1.4.14.tar.gz", hash = "sha256:faffea0fd8ec86bb146ac538ac350ed0c73908326426d387eded0bcc9d077522"}, + {file = "identify-1.4.19-py2.py3-none-any.whl", hash = "sha256:781fd3401f5d2b17b22a8b18b493a48d5d948e3330634e82742e23f9c20234ef"}, + {file = "identify-1.4.19.tar.gz", hash = "sha256:249ebc7e2066d6393d27c1b1be3b70433f824a120b1d8274d362f1eb419e3b52"}, ] idna = [ {file = "idna-2.8-py2.py3-none-any.whl", hash = "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"}, @@ -1856,8 +1952,8 @@ importlib-metadata = [ importlib-resources = [ {file = "importlib_resources-1.0.2-py2.py3-none-any.whl", hash = "sha256:6e2783b2538bd5a14678284a3962b0660c715e5a0f10243fd5e00a4b5974f50b"}, {file = "importlib_resources-1.0.2.tar.gz", hash = "sha256:d3279fd0f6f847cced9f7acc19bd3e5df54d34f93a2e7bb5f238f81545787078"}, - {file = "importlib_resources-1.4.0-py2.py3-none-any.whl", hash = "sha256:dd98ceeef3f5ad2ef4cc287b8586da4ebad15877f351e9688987ad663a0a29b8"}, - {file = "importlib_resources-1.4.0.tar.gz", hash = "sha256:4019b6a9082d8ada9def02bece4a76b131518866790d58fdda0b5f8c603b36c2"}, + {file = "importlib_resources-1.5.0-py2.py3-none-any.whl", hash = "sha256:85dc0b9b325ff78c8bef2e4ff42616094e16b98ebd5e3b50fe7e2f0bbcdcde49"}, + {file = "importlib_resources-1.5.0.tar.gz", hash = "sha256:6f87df66833e1942667108628ec48900e02a4ab4ad850e25fbf07cb17cf734ca"}, ] ipaddress = [ {file = "ipaddress-1.0.23-py2.py3-none-any.whl", hash = "sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc"}, @@ -1870,8 +1966,12 @@ jeepney = [ jinja2 = [ {file = "Jinja2-2.10.3-py2.py3-none-any.whl", hash = "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f"}, {file = "Jinja2-2.10.3.tar.gz", hash = "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"}, - {file = "Jinja2-2.11.1-py2.py3-none-any.whl", hash = "sha256:b0eaf100007721b5c16c1fc1eecb87409464edc10469ddc9a22a27a99123be49"}, - {file = "Jinja2-2.11.1.tar.gz", hash = "sha256:93187ffbc7808079673ef52771baa950426fd664d3aad1d0fa3e95644360e250"}, + {file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"}, + {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, +] +joblib = [ + {file = "joblib-0.14.1-py2.py3-none-any.whl", hash = "sha256:bdb4fd9b72915ffb49fde2229ce482dd7ae79d842ed8c2b4c932441495af1403"}, + {file = "joblib-0.14.1.tar.gz", hash = "sha256:0630eea4f5664c463f23fbf5dcfc54a2bc6168902719fa8e19daf033022786c8"}, ] jsonschema = [ {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, @@ -1892,16 +1992,16 @@ lockfile = [ {file = "lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799"}, ] lunr = [ - {file = "lunr-0.5.6-py2.py3-none-any.whl", hash = "sha256:1208622930c915a07e6f8e8640474357826bad48534c0f57969b6fca9bffc88e"}, - {file = "lunr-0.5.6.tar.gz", hash = "sha256:7be69d7186f65784a4f2adf81e5c58efd6a9921aa95966babcb1f2f2ada75c20"}, + {file = "lunr-0.5.8-py2.py3-none-any.whl", hash = "sha256:aab3f489c4d4fab4c1294a257a30fec397db56f0a50273218ccc3efdbf01d6ca"}, + {file = "lunr-0.5.8.tar.gz", hash = "sha256:c4fb063b98eff775dd638b3df380008ae85e6cb1d1a24d1cd81a10ef6391c26e"}, ] markdown = [ {file = "Markdown-3.0.1-py2.py3-none-any.whl", hash = "sha256:c00429bd503a47ec88d5e30a751e147dcb4c6889663cd3e2ba0afe858e009baa"}, {file = "Markdown-3.0.1.tar.gz", hash = "sha256:d02e0f9b04c500cde6637c11ad7c72671f359b87b9fe924b2383649d8841db7c"}, {file = "Markdown-3.1.1-py2.py3-none-any.whl", hash = "sha256:56a46ac655704b91e5b7e6326ce43d5ef72411376588afa1dd90e881b83c7e8c"}, {file = "Markdown-3.1.1.tar.gz", hash = "sha256:2e50876bcdd74517e7b71f3e7a76102050edec255b3983403f1a63e7c8a41e7a"}, - {file = "Markdown-3.2.1-py2.py3-none-any.whl", hash = "sha256:e4795399163109457d4c5af2183fbe6b60326c17cfdf25ce6e7474c6624f725d"}, - {file = "Markdown-3.2.1.tar.gz", hash = "sha256:90fee683eeabe1a92e149f7ba74e5ccdc81cd397bd6c516d93a8da0ef90b6902"}, + {file = "Markdown-3.2.2-py3-none-any.whl", hash = "sha256:c467cd6233885534bf0fe96e62e3cf46cfc1605112356c4f9981512b8174de59"}, + {file = "Markdown-3.2.2.tar.gz", hash = "sha256:1fafe3f1ecabfb514a5285fca634a53c1b32a81cb0feb154264d55bf2ff22c17"}, ] markdown-include = [ {file = "markdown-include-0.5.1.tar.gz", hash = "sha256:72a45461b589489a088753893bc95c5fa5909936186485f4ed55caa57d10250f"}, @@ -1934,18 +2034,13 @@ markupsafe = [ {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, ] mkdocs = [ {file = "mkdocs-1.0.4-py2.py3-none-any.whl", hash = "sha256:8cc8b38325456b9e942c981a209eaeb1e9f3f77b493ad755bfef889b9c8d356a"}, {file = "mkdocs-1.0.4.tar.gz", hash = "sha256:17d34329aad75d5de604b9ed4e31df3a4d235afefdc46ce7b1964fddb2e1e939"}, - {file = "mkdocs-1.1-py2.py3-none-any.whl", hash = "sha256:1e385a70aea8a9dedb731aea4fd5f3704b2074801c4f96f06b2920999babda8a"}, - {file = "mkdocs-1.1.tar.gz", hash = "sha256:9243291392f59e20b655e4e46210233453faf97787c2cf72176510e868143174"}, + {file = "mkdocs-1.1.2-py3-none-any.whl", hash = "sha256:096f52ff52c02c7e90332d2e53da862fde5c062086e1b5356a6e392d5d60f5e9"}, + {file = "mkdocs-1.1.2.tar.gz", hash = "sha256:f0b61e5402b99d7789efa032c7a74c90a20220a9c81749da06dbfbcbd52ffb39"}, ] mock = [ {file = "mock-3.0.5-py2.py3-none-any.whl", hash = "sha256:d157e52d4e5b938c550f39eb2fd15610db062441a9c2747d3dbfa9298211d0f8"}, @@ -1957,8 +2052,8 @@ more-itertools = [ {file = "more_itertools-5.0.0-py3-none-any.whl", hash = "sha256:fe7a7cae1ccb57d33952113ff4fa1bc5f879963600ed74918f1236e212ee50b9"}, {file = "more-itertools-7.2.0.tar.gz", hash = "sha256:409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832"}, {file = "more_itertools-7.2.0-py3-none-any.whl", hash = "sha256:92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4"}, - {file = "more-itertools-8.2.0.tar.gz", hash = "sha256:b1ddb932186d8a6ac451e1d95844b382f55e12686d51ca0c68b6f61f2ab7a507"}, - {file = "more_itertools-8.2.0-py3-none-any.whl", hash = "sha256:5dd8bcf33e5f9513ffa06d5ad33d78f31e1931ac9a18f33d37e77a180d393a7c"}, + {file = "more-itertools-8.3.0.tar.gz", hash = "sha256:558bb897a2232f5e4f8e2399089e35aecb746e1f9191b6584a151647e89267be"}, + {file = "more_itertools-8.3.0-py3-none-any.whl", hash = "sha256:7818f596b1e87be009031c7653d01acc46ed422e6656b394b0f765ce66ed4982"}, ] msgpack = [ {file = "msgpack-1.0.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:cec8bf10981ed70998d98431cd814db0ecf3384e6b113366e7f36af71a0fca08"}, @@ -1981,15 +2076,14 @@ msgpack = [ {file = "msgpack-1.0.0.tar.gz", hash = "sha256:9534d5cc480d4aff720233411a1f765be90885750b07df772380b34c10ecb5c0"}, ] nltk = [ - {file = "nltk-3.4.5.win32.exe", hash = "sha256:a08bdb4b8a1c13de16743068d9eb61c8c71c2e5d642e8e08205c528035843f82"}, - {file = "nltk-3.4.5.zip", hash = "sha256:bed45551259aa2101381bbdd5df37d44ca2669c5c3dad72439fa459b29137d94"}, + {file = "nltk-3.5.zip", hash = "sha256:845365449cd8c5f9731f7cb9f8bd6fd0767553b9d53af9eb1b3abf7700936b35"}, ] nodeenv = [ - {file = "nodeenv-1.3.5-py2.py3-none-any.whl", hash = "sha256:5b2438f2e42af54ca968dd1b374d14a1194848955187b0e5e4be1f73813a5212"}, + {file = "nodeenv-1.4.0-py2.py3-none-any.whl", hash = "sha256:4b0b77afa3ba9b54f4b6396e60b0c83f59eaeb2d63dc3cc7a70f7f4af96c82bc"}, ] packaging = [ - {file = "packaging-20.3-py2.py3-none-any.whl", hash = "sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752"}, - {file = "packaging-20.3.tar.gz", hash = "sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3"}, + {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, + {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, ] pastel = [ {file = "pastel-0.2.0-py2.py3-none-any.whl", hash = "sha256:18b559dc3ad4ba9b8bd5baebe6503f25f36d21460f021cf27a8d889cb5d17840"}, @@ -2069,20 +2163,23 @@ pyrsistent = [ {file = "pyrsistent-0.14.11.tar.gz", hash = "sha256:3ca82748918eb65e2d89f222b702277099aca77e34843c5eb9d52451173970e2"}, ] pytest = [ - {file = "pytest-4.6.9-py2.py3-none-any.whl", hash = "sha256:c77a5f30a90e0ce24db9eaa14ddfd38d4afb5ea159309bdd2dae55b931bc9324"}, - {file = "pytest-4.6.9.tar.gz", hash = "sha256:19e8f75eac01dd3f211edd465b39efbcbdc8fc5f7866d7dd49fedb30d8adf339"}, + {file = "pytest-4.6.11-py2.py3-none-any.whl", hash = "sha256:a00a7d79cbbdfa9d21e7d0298392a8dd4123316bfac545075e6f8f24c94d8c97"}, + {file = "pytest-4.6.11.tar.gz", hash = "sha256:50fa82392f2120cc3ec2ca0a75ee615be4c479e66669789771f1758332be4353"}, + {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"}, + {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"}, ] pytest-cov = [ {file = "pytest-cov-2.8.1.tar.gz", hash = "sha256:cc6742d8bac45070217169f5f72ceee1e0e55b0221f54bcf24845972d3a47f2b"}, {file = "pytest_cov-2.8.1-py2.py3-none-any.whl", hash = "sha256:cdbdef4f870408ebdbfeb44e63e07eb18bb4619fae852f6e760645fa36172626"}, + {file = "pytest-cov-2.9.0.tar.gz", hash = "sha256:b6a814b8ed6247bd81ff47f038511b57fe1ce7f4cc25b9106f1a4b106f1d9322"}, + {file = "pytest_cov-2.9.0-py2.py3-none-any.whl", hash = "sha256:c87dfd8465d865655a8213859f1b4749b43448b5fae465cb981e16d52a811424"}, ] pytest-mock = [ {file = "pytest-mock-1.13.0.tar.gz", hash = "sha256:e24a911ec96773022ebcc7030059b57cd3480b56d4f5d19b7c370ec635e6aed5"}, {file = "pytest_mock-1.13.0-py2.py3-none-any.whl", hash = "sha256:67e414b3caef7bff6fc6bd83b22b5bc39147e4493f483c2679bc9d4dc485a94d"}, ] pytest-sugar = [ - {file = "pytest-sugar-0.9.2.tar.gz", hash = "sha256:fcd87a74b2bce5386d244b49ad60549bfbc4602527797fac167da147983f58ab"}, - {file = "pytest_sugar-0.9.2-py2.py3-none-any.whl", hash = "sha256:26cf8289fe10880cbbc130bd77398c4e6a8b936d8393b116a5c16121d95ab283"}, + {file = "pytest-sugar-0.9.3.tar.gz", hash = "sha256:1630b5b7ea3624919b73fde37cffb87965c5087a4afab8a43074ff44e0d810c4"}, ] pywin32-ctypes = [ {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, @@ -2113,27 +2210,27 @@ pyyaml = [ {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, ] regex = [ - {file = "regex-2020.4.4-cp27-cp27m-win32.whl", hash = "sha256:90742c6ff121a9c5b261b9b215cb476eea97df98ea82037ec8ac95d1be7a034f"}, - {file = "regex-2020.4.4-cp27-cp27m-win_amd64.whl", hash = "sha256:24f4f4062eb16c5bbfff6a22312e8eab92c2c99c51a02e39b4eae54ce8255cd1"}, - {file = "regex-2020.4.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:08119f707f0ebf2da60d2f24c2f39ca616277bb67ef6c92b72cbf90cbe3a556b"}, - {file = "regex-2020.4.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c9423a150d3a4fc0f3f2aae897a59919acd293f4cb397429b120a5fcd96ea3db"}, - {file = "regex-2020.4.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:c087bff162158536387c53647411db09b6ee3f9603c334c90943e97b1052a156"}, - {file = "regex-2020.4.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:1cbe0fa0b7f673400eb29e9ef41d4f53638f65f9a2143854de6b1ce2899185c3"}, - {file = "regex-2020.4.4-cp36-cp36m-win32.whl", hash = "sha256:0ce9537396d8f556bcfc317c65b6a0705320701e5ce511f05fc04421ba05b8a8"}, - {file = "regex-2020.4.4-cp36-cp36m-win_amd64.whl", hash = "sha256:7e1037073b1b7053ee74c3c6c0ada80f3501ec29d5f46e42669378eae6d4405a"}, - {file = "regex-2020.4.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4385f12aa289d79419fede43f979e372f527892ac44a541b5446617e4406c468"}, - {file = "regex-2020.4.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a58dd45cb865be0ce1d5ecc4cfc85cd8c6867bea66733623e54bd95131f473b6"}, - {file = "regex-2020.4.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ccccdd84912875e34c5ad2d06e1989d890d43af6c2242c6fcfa51556997af6cd"}, - {file = "regex-2020.4.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:ea4adf02d23b437684cd388d557bf76e3afa72f7fed5bbc013482cc00c816948"}, - {file = "regex-2020.4.4-cp37-cp37m-win32.whl", hash = "sha256:2294f8b70e058a2553cd009df003a20802ef75b3c629506be20687df0908177e"}, - {file = "regex-2020.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:e91ba11da11cf770f389e47c3f5c30473e6d85e06d7fd9dcba0017d2867aab4a"}, - {file = "regex-2020.4.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5635cd1ed0a12b4c42cce18a8d2fb53ff13ff537f09de5fd791e97de27b6400e"}, - {file = "regex-2020.4.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:23069d9c07e115537f37270d1d5faea3e0bdded8279081c4d4d607a2ad393683"}, - {file = "regex-2020.4.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:c162a21e0da33eb3d31a3ac17a51db5e634fc347f650d271f0305d96601dc15b"}, - {file = "regex-2020.4.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:fb95debbd1a824b2c4376932f2216cc186912e389bdb0e27147778cf6acb3f89"}, - {file = "regex-2020.4.4-cp38-cp38-win32.whl", hash = "sha256:2a3bf8b48f8e37c3a40bb3f854bf0121c194e69a650b209628d951190b862de3"}, - {file = "regex-2020.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bfed051dbff32fd8945eccca70f5e22b55e4148d2a8a45141a3b053d6455ae3"}, - {file = "regex-2020.4.4.tar.gz", hash = "sha256:295badf61a51add2d428a46b8580309c520d8b26e769868b922750cf3ce67142"}, + {file = "regex-2020.5.14-cp27-cp27m-win32.whl", hash = "sha256:e565569fc28e3ba3e475ec344d87ed3cd8ba2d575335359749298a0899fe122e"}, + {file = "regex-2020.5.14-cp27-cp27m-win_amd64.whl", hash = "sha256:d466967ac8e45244b9dfe302bbe5e3337f8dc4dec8d7d10f5e950d83b140d33a"}, + {file = "regex-2020.5.14-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:27ff7325b297fb6e5ebb70d10437592433601c423f5acf86e5bc1ee2919b9561"}, + {file = "regex-2020.5.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ea55b80eb0d1c3f1d8d784264a6764f931e172480a2f1868f2536444c5f01e01"}, + {file = "regex-2020.5.14-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:c9bce6e006fbe771a02bda468ec40ffccbf954803b470a0345ad39c603402577"}, + {file = "regex-2020.5.14-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:d881c2e657c51d89f02ae4c21d9adbef76b8325fe4d5cf0e9ad62f850f3a98fd"}, + {file = "regex-2020.5.14-cp36-cp36m-win32.whl", hash = "sha256:99568f00f7bf820c620f01721485cad230f3fb28f57d8fbf4a7967ec2e446994"}, + {file = "regex-2020.5.14-cp36-cp36m-win_amd64.whl", hash = "sha256:70c14743320a68c5dac7fc5a0f685be63bc2024b062fe2aaccc4acc3d01b14a1"}, + {file = "regex-2020.5.14-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:a7c37f048ec3920783abab99f8f4036561a174f1314302ccfa4e9ad31cb00eb4"}, + {file = "regex-2020.5.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:89d76ce33d3266173f5be80bd4efcbd5196cafc34100fdab814f9b228dee0fa4"}, + {file = "regex-2020.5.14-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:51f17abbe973c7673a61863516bdc9c0ef467407a940f39501e786a07406699c"}, + {file = "regex-2020.5.14-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:ce5cc53aa9fbbf6712e92c7cf268274eaff30f6bd12a0754e8133d85a8fb0f5f"}, + {file = "regex-2020.5.14-cp37-cp37m-win32.whl", hash = "sha256:8044d1c085d49673aadb3d7dc20ef5cb5b030c7a4fa253a593dda2eab3059929"}, + {file = "regex-2020.5.14-cp37-cp37m-win_amd64.whl", hash = "sha256:c2062c7d470751b648f1cacc3f54460aebfc261285f14bc6da49c6943bd48bdd"}, + {file = "regex-2020.5.14-cp38-cp38-manylinux1_i686.whl", hash = "sha256:329ba35d711e3428db6b45a53b1b13a0a8ba07cbbcf10bbed291a7da45f106c3"}, + {file = "regex-2020.5.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:579ea215c81d18da550b62ff97ee187b99f1b135fd894a13451e00986a080cad"}, + {file = "regex-2020.5.14-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:3a9394197664e35566242686d84dfd264c07b20f93514e2e09d3c2b3ffdf78fe"}, + {file = "regex-2020.5.14-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ce367d21f33e23a84fb83a641b3834dd7dd8e9318ad8ff677fbfae5915a239f7"}, + {file = "regex-2020.5.14-cp38-cp38-win32.whl", hash = "sha256:1386e75c9d1574f6aa2e4eb5355374c8e55f9aac97e224a8a5a6abded0f9c927"}, + {file = "regex-2020.5.14-cp38-cp38-win_amd64.whl", hash = "sha256:7e61be8a2900897803c293247ef87366d5df86bf701083b6c43119c7c6c99108"}, + {file = "regex-2020.5.14.tar.gz", hash = "sha256:ce450ffbfec93821ab1fea94779a8440e10cf63819be6e176eb1973a6017aff5"}, ] requests = [ {file = "requests-2.21.0-py2.py3-none-any.whl", hash = "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b"}, @@ -2172,8 +2269,8 @@ singledispatch = [ {file = "singledispatch-3.4.0.3.tar.gz", hash = "sha256:5b06af87df13818d14f08a028e42f566640aef80805c3b50c5056b086e3c2b9c"}, ] six = [ - {file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"}, - {file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"}, + {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, + {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, ] subprocess32 = [ {file = "subprocess32-3.5.4-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:88e37c1aac5388df41cc8a8456bb49ebffd321a3ad4d70358e3518176de3a56b"}, @@ -2183,9 +2280,8 @@ termcolor = [ {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"}, ] toml = [ - {file = "toml-0.10.0-py2.7.egg", hash = "sha256:f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"}, - {file = "toml-0.10.0-py2.py3-none-any.whl", hash = "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"}, - {file = "toml-0.10.0.tar.gz", hash = "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c"}, + {file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"}, + {file = "toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"}, ] tomlkit = [ {file = "tomlkit-0.5.11-py2.py3-none-any.whl", hash = "sha256:4e1bd6c9197d984528f9ff0cc9db667c317d8881288db50db20eeeb0f6b0380b"}, @@ -2212,8 +2308,12 @@ tornado = [ tox = [ {file = "tox-3.12.1-py2.py3-none-any.whl", hash = "sha256:f5c8e446b51edd2ea97df31d4ded8c8b72e7d6c619519da6bb6084b9dd5770f9"}, {file = "tox-3.12.1.tar.gz", hash = "sha256:f87fd33892a2df0950e5e034def9468988b8d008c7e9416be665fcc0dd45b14f"}, - {file = "tox-3.14.6-py2.py3-none-any.whl", hash = "sha256:b2c4b91c975ea5c11463d9ca00bebf82654439c5df0f614807b9bdec62cc9471"}, - {file = "tox-3.14.6.tar.gz", hash = "sha256:a4a6689045d93c208d77230853b28058b7513f5123647b67bf012f82fa168303"}, + {file = "tox-3.15.1-py2.py3-none-any.whl", hash = "sha256:322dfdf007d7d53323f767badcb068a5cfa7c44d8aabb698d131b28cf44e62c4"}, + {file = "tox-3.15.1.tar.gz", hash = "sha256:8c9ad9b48659d291c5bc78bcabaa4d680d627687154b812fa52baedaa94f9f83"}, +] +tqdm = [ + {file = "tqdm-4.46.1-py2.py3-none-any.whl", hash = "sha256:07c06493f1403c1380b630ae3dcbe5ae62abcf369a93bbc052502279f189ab8c"}, + {file = "tqdm-4.46.1.tar.gz", hash = "sha256:cd140979c2bebd2311dfb14781d8f19bd5a9debb92dcab9f6ef899c987fcf71f"}, ] typed-ast = [ {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, @@ -2251,18 +2351,18 @@ typing-extensions = [ urllib3 = [ {file = "urllib3-1.24.3-py2.py3-none-any.whl", hash = "sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb"}, {file = "urllib3-1.24.3.tar.gz", hash = "sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4"}, - {file = "urllib3-1.25.8-py2.py3-none-any.whl", hash = "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc"}, - {file = "urllib3-1.25.8.tar.gz", hash = "sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc"}, + {file = "urllib3-1.25.9-py2.py3-none-any.whl", hash = "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115"}, + {file = "urllib3-1.25.9.tar.gz", hash = "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527"}, ] virtualenv = [ {file = "virtualenv-16.7.10-py2.py3-none-any.whl", hash = "sha256:105893c8dc66b7817691c7371439ec18e3b6c5e323a304b5ed96cdd2e75cc1ec"}, {file = "virtualenv-16.7.10.tar.gz", hash = "sha256:e88fdcb08b0ecb11da97868f463dd06275923f50d87f4b9c8b2fc0994eec40f4"}, - {file = "virtualenv-20.0.17-py2.py3-none-any.whl", hash = "sha256:00cfe8605fb97f5a59d52baab78e6070e72c12ca64f51151695407cc0eb8a431"}, - {file = "virtualenv-20.0.17.tar.gz", hash = "sha256:c8364ec469084046c779c9a11ae6340094e8a0bf1d844330fc55c1cefe67c172"}, + {file = "virtualenv-20.0.21-py2.py3-none-any.whl", hash = "sha256:a730548b27366c5e6cbdf6f97406d861cccece2e22275e8e1a757aeff5e00c70"}, + {file = "virtualenv-20.0.21.tar.gz", hash = "sha256:a116629d4e7f4d03433b8afa27f43deba09d48bc48f5ecefa4f015a178efb6cf"}, ] wcwidth = [ - {file = "wcwidth-0.1.9-py2.py3-none-any.whl", hash = "sha256:cafe2186b3c009a04067022ce1dcd79cb38d8d65ee4f4791b8888d6599d1bbe1"}, - {file = "wcwidth-0.1.9.tar.gz", hash = "sha256:ee73862862a156bf77ff92b09034fc4825dd3af9cf81bc5b360668d425f3c5f1"}, + {file = "wcwidth-0.2.3-py2.py3-none-any.whl", hash = "sha256:980fbf4f3c196c0f329cdcd1e84c554d6a211f18e252e525a0cf4223154a41d6"}, + {file = "wcwidth-0.2.3.tar.gz", hash = "sha256:edbc2b718b4db6cdf393eefe3a420183947d6aa312505ce6754516f458ff8830"}, ] webencodings = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, diff --git a/pyproject.toml b/pyproject.toml index 519fb373ca6..5156b969500 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,7 +58,10 @@ subprocess32 = { version = "^3.5", python = "~2.7 || ~3.4" } importlib-metadata = {version = "~1.1.3", python = "<3.8"} [tool.poetry.dev-dependencies] -pytest = "^4.1" +pytest = [ + {version = "^4.1", python = "<3.5"}, + {version = "^5.4.3", python = ">=3.5"} +] pytest-cov = "^2.5" mkdocs = { version = "^1.0", python = "~2.7.9 || ^3.4" } pymdown-extensions = "^6.0" From 288c4215fff4871b5cb4461be169418497416888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 5 Jun 2020 15:37:49 +0200 Subject: [PATCH 55/80] Bump version to 1.0.6 --- CHANGELOG.md | 24 +++++++++++++++++++++++- poetry/__version__.py | 2 +- pyproject.toml | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d196bd38d52..f19aeaf1500 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Change Log +## [1.0.6] - 2020-06-05 + +### Changed + +- The `self update` command has been updated in order to handle future releases of Poetry ([#2429](https://github.com/python-poetry/poetry/pull/2429)). + +### Fixed + +- Fixed an error were a new line was not written when displaying the virtual environment's path with `env info` ([#2196](https://github.com/python-poetry/poetry/pull/2196)). +- Fixed a misleading error message when the `packages` property was empty ([#2265](https://github.com/python-poetry/poetry/pull/2265)). +- Fixed shell detection by using environment variables ([#2147](https://github.com/python-poetry/poetry/pull/2147)). +- Fixed the removal of VCS dependencies ([#2239](https://github.com/python-poetry/poetry/pull/2239)). +- Fixed generated wheel ABI tags for Python 3.8 ([#2121](https://github.com/python-poetry/poetry/pull/2121)). +- Fixed a regression when building stub-only packages ([#2000](https://github.com/python-poetry/poetry/pull/2000)). +- Fixed errors when parsing PEP-440 constraints with whitespace ([#2347](https://github.com/python-poetry/poetry/pull/2347)). +- Fixed PEP 508 representation of VCS dependencies ([#2349](https://github.com/python-poetry/poetry/pull/2349)). +- Fixed errors when source distributions were read-only ([#1140](https://github.com/python-poetry/poetry/pull/1140)). +- Fixed dependency resolution errors and inconsistencies with directory, file and VCS dependencies ([#2398](https://github.com/python-poetry/poetry/pull/2398)). +- Fixed custom repositories information not being properly locked ([#2484](https://github.com/python-poetry/poetry/pull/2484)). + + ## [1.0.5] - 2020-02-29 ### Fixed @@ -824,7 +845,8 @@ Initial release -[Unreleased]: https://github.com/python-poetry/poetry/compare/1.0.5...master +[Unreleased]: https://github.com/python-poetry/poetry/compare/1.0.6...master +[1.0.6]: https://github.com/python-poetry/poetry/releases/tag/1.0.6 [1.0.5]: https://github.com/python-poetry/poetry/releases/tag/1.0.5 [1.0.4]: https://github.com/python-poetry/poetry/releases/tag/1.0.4 [1.0.3]: https://github.com/python-poetry/poetry/releases/tag/1.0.3 diff --git a/poetry/__version__.py b/poetry/__version__.py index 68cdeee4b21..382021f30ff 100644 --- a/poetry/__version__.py +++ b/poetry/__version__.py @@ -1 +1 @@ -__version__ = "1.0.5" +__version__ = "1.0.6" diff --git a/pyproject.toml b/pyproject.toml index 5156b969500..c2242083e0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "poetry" -version = "1.0.5" +version = "1.0.6" description = "Python dependency management and packaging made easy." authors = [ "Sébastien Eustace " From 09593800cf8b99f56c6c00c9e61474ac41f2de02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 5 Jun 2020 16:25:28 +0200 Subject: [PATCH 56/80] Fix a TypeError when trying to execute `setup.py` files (#2499) --- poetry/puzzle/provider.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/poetry/puzzle/provider.py b/poetry/puzzle/provider.py index 3157b2a52da..40537260815 100644 --- a/poetry/puzzle/provider.py +++ b/poetry/puzzle/provider.py @@ -866,7 +866,8 @@ def progress(self): self._in_progress = False - def _execute_setup(self): + @classmethod + def _execute_setup(cls): with temporary_directory() as tmp_dir: EnvManager.build_venv(tmp_dir) venv = VirtualEnv(Path(tmp_dir), Path(tmp_dir)) From cb866bffa76c056eb84c5b80527fb7f9bee6c1f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 5 Jun 2020 16:27:56 +0200 Subject: [PATCH 57/80] Bump version to 1.0.7 --- CHANGELOG.md | 10 +++++++++- poetry/__version__.py | 2 +- pyproject.toml | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f19aeaf1500..9a1641840ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## [1.0.7] - 2020-06-05 + +### Fixed + +- Fixed an error when trying to execute some packages `setup.py` file ([#2349](https://github.com/python-poetry/poetry/pull/2349)). + + ## [1.0.6] - 2020-06-05 ### Changed @@ -845,7 +852,8 @@ Initial release -[Unreleased]: https://github.com/python-poetry/poetry/compare/1.0.6...master +[Unreleased]: https://github.com/python-poetry/poetry/compare/1.0.7...master +[1.0.7]: https://github.com/python-poetry/poetry/releases/tag/1.0.7 [1.0.6]: https://github.com/python-poetry/poetry/releases/tag/1.0.6 [1.0.5]: https://github.com/python-poetry/poetry/releases/tag/1.0.5 [1.0.4]: https://github.com/python-poetry/poetry/releases/tag/1.0.4 diff --git a/poetry/__version__.py b/poetry/__version__.py index 382021f30ff..9e604c040e9 100644 --- a/poetry/__version__.py +++ b/poetry/__version__.py @@ -1 +1 @@ -__version__ = "1.0.6" +__version__ = "1.0.7" diff --git a/pyproject.toml b/pyproject.toml index c2242083e0e..8b6293d5140 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "poetry" -version = "1.0.6" +version = "1.0.7" description = "Python dependency management and packaging made easy." authors = [ "Sébastien Eustace " From a3b648ba141d88486b035eae383faa0adefbecac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 5 Jun 2020 19:35:10 +0200 Subject: [PATCH 58/80] Fix root package and directory dependency editable installation (#2505) --- poetry/installation/pip_installer.py | 3 +-- poetry/masonry/builders/editable.py | 2 +- tests/masonry/builders/test_editable.py | 4 +++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/poetry/installation/pip_installer.py b/poetry/installation/pip_installer.py index 331a69b580e..349f222c73c 100644 --- a/poetry/installation/pip_installer.py +++ b/poetry/installation/pip_installer.py @@ -181,7 +181,6 @@ def create_temporary_requirement(self, package): def install_directory(self, package): from poetry.factory import Factory - from poetry.utils.env import NullEnv from poetry.utils.toml_file import TomlFile if package.root_dir: @@ -215,7 +214,7 @@ def install_directory(self, package): from poetry.masonry.builders.editable import EditableBuilder builder = EditableBuilder( - Factory().create_poetry(pyproject.parent), NullEnv(), NullIO() + Factory().create_poetry(pyproject.parent), self._env, NullIO() ) builder.build() diff --git a/poetry/masonry/builders/editable.py b/poetry/masonry/builders/editable.py index 1757bd4ff3d..15cfe53676a 100644 --- a/poetry/masonry/builders/editable.py +++ b/poetry/masonry/builders/editable.py @@ -38,7 +38,7 @@ def _setup_build(self): str(self._poetry.file), str(self._poetry.file.with_suffix(".tmp")) ) try: - self._env.run_pip("install", "-e", str(self._path)) + self._env.run_pip("install", "--no-deps", "-e", str(self._path)) finally: shutil.move( str(self._poetry.file.with_suffix(".tmp")), diff --git a/tests/masonry/builders/test_editable.py b/tests/masonry/builders/test_editable.py index d1121243ca4..a067db46ea2 100644 --- a/tests/masonry/builders/test_editable.py +++ b/tests/masonry/builders/test_editable.py @@ -38,7 +38,9 @@ def test_build_should_temporarily_remove_the_pyproject_file(tmp_dir, mocker): builder = EditableBuilder(Factory().create_poetry(module_path), env, NullIO()) builder.build() - expected = [[sys.executable, "-m", "pip", "install", "-e", str(module_path)]] + expected = [ + [sys.executable, "-m", "pip", "install", "--no-deps", "-e", str(module_path)] + ] assert expected == env.executed assert 2 == move.call_count From 6f9d6b0e1b7b1d3a7d7b2ca3478ad2cb0a7188e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 5 Jun 2020 19:38:09 +0200 Subject: [PATCH 59/80] Bump version to 1.0.8 --- CHANGELOG.md | 11 ++++++++++- poetry/__version__.py | 2 +- pyproject.toml | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a1641840ba..b9aa53428da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## [1.0.8] - 2020-06-05 + +### Fixed + +- Fixed a possible error when installing the root package ([#2505](https://github.com/python-poetry/poetry/pull/2505)). +- Fixed an error where directory and VCS dependencies were not installed ([#2505](https://github.com/python-poetry/poetry/pull/2505)). + + ## [1.0.7] - 2020-06-05 ### Fixed @@ -852,7 +860,8 @@ Initial release -[Unreleased]: https://github.com/python-poetry/poetry/compare/1.0.7...master +[Unreleased]: https://github.com/python-poetry/poetry/compare/1.0.8...master +[1.0.8]: https://github.com/python-poetry/poetry/releases/tag/1.0.8 [1.0.7]: https://github.com/python-poetry/poetry/releases/tag/1.0.7 [1.0.6]: https://github.com/python-poetry/poetry/releases/tag/1.0.6 [1.0.5]: https://github.com/python-poetry/poetry/releases/tag/1.0.5 diff --git a/poetry/__version__.py b/poetry/__version__.py index 9e604c040e9..e13bd590c85 100644 --- a/poetry/__version__.py +++ b/poetry/__version__.py @@ -1 +1 @@ -__version__ = "1.0.7" +__version__ = "1.0.8" diff --git a/pyproject.toml b/pyproject.toml index 8b6293d5140..0cdaef9908a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "poetry" -version = "1.0.7" +version = "1.0.8" description = "Python dependency management and packaging made easy." authors = [ "Sébastien Eustace " From 156cd66685503c8ea4dafe5d0bb4d54aab5e9937 Mon Sep 17 00:00:00 2001 From: William Hayes Date: Sat, 6 Jun 2020 09:08:10 -0400 Subject: [PATCH 60/80] Added git ssh example to docs Added a cli add git ssh dependency example to documentation for easy reference. --- docs/docs/cli.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/docs/cli.md b/docs/docs/cli.md index 2b98b5f0371..b07a567d4ad 100644 --- a/docs/docs/cli.md +++ b/docs/docs/cli.md @@ -200,6 +200,12 @@ You can also add `git` dependencies: poetry add git+https://github.com/sdispater/pendulum.git ``` +or use ssh instead of https: + +```bash +poetry add git+ssh://git@github.com/sdispater/pendulum.git +``` + If you need to checkout a specific branch, tag or revision, you can specify it when using `add`: From 6f94c6f5e5c22a526d37dade1c5828bd564b0433 Mon Sep 17 00:00:00 2001 From: Haines Chan Date: Tue, 9 Jun 2020 14:18:44 +0800 Subject: [PATCH 61/80] Fix wrong indentation in mixology --- poetry/mixology/incompatibility.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/poetry/mixology/incompatibility.py b/poetry/mixology/incompatibility.py index 2af54b6c877..e731b743cb4 100644 --- a/poetry/mixology/incompatibility.py +++ b/poetry/mixology/incompatibility.py @@ -61,18 +61,18 @@ def __init__( else: by_ref[ref] = term - new_terms = [] - for by_ref in by_name.values(): - positive_terms = [ - term for term in by_ref.values() if term.is_positive() - ] - if positive_terms: - new_terms += positive_terms - continue - - new_terms += list(by_ref.values()) - - terms = new_terms + new_terms = [] + for by_ref in by_name.values(): + positive_terms = [ + term for term in by_ref.values() if term.is_positive() + ] + if positive_terms: + new_terms += positive_terms + continue + + new_terms += list(by_ref.values()) + + terms = new_terms self._terms = terms self._cause = cause From 2df5704e9bfc9c218c3e469749bc0182aeb8269e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Tue, 9 Jun 2020 13:56:49 +0200 Subject: [PATCH 62/80] Fix legacy repositories packages being continuously updated --- poetry/puzzle/solver.py | 2 +- tests/puzzle/test_solver.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/poetry/puzzle/solver.py b/poetry/puzzle/solver.py index aff19ca6813..e9ea1e80658 100644 --- a/poetry/puzzle/solver.py +++ b/poetry/puzzle/solver.py @@ -92,7 +92,7 @@ def solve(self, use_latest=None): # type: (...) -> List[Operation] elif package.version != pkg.version: # Checking version operations.append(Update(pkg, package)) - elif package.source_type != pkg.source_type: + elif pkg.source_type and package.source_type != pkg.source_type: operations.append(Update(pkg, package)) else: operations.append(Install(package).skip("Already installed")) diff --git a/tests/puzzle/test_solver.py b/tests/puzzle/test_solver.py index 1c75b59862f..6ee6fea911f 100644 --- a/tests/puzzle/test_solver.py +++ b/tests/puzzle/test_solver.py @@ -2039,3 +2039,22 @@ def test_solver_cannot_choose_another_version_for_url_dependencies( # via the git dependency with pytest.raises(SolverProblemError): solver.solve() + + +def test_solver_should_not_update_same_version_packages_if_installed_has_no_source_type( + solver, repo, package, installed +): + package.add_dependency("foo", "1.0.0") + + foo = get_package("foo", "1.0.0") + foo.source_type = "legacy" + foo.source_reference = "custom" + foo.source_url = "https://foo.bar" + repo.add_package(foo) + installed.add_package(get_package("foo", "1.0.0")) + + ops = solver.solve() + + check_solver_result( + ops, [{"job": "install", "package": foo, "skipped": True}], + ) From dcc2e40196d596a0dd8e2fbce52f03ceba904234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Tue, 9 Jun 2020 20:56:02 +0200 Subject: [PATCH 63/80] Fix handling of dependency markers with python precision >= 3 (#2526) --- poetry/packages/dependency.py | 21 +++++++++++++++++++-- poetry/version/markers.py | 6 +++++- tests/packages/test_dependency.py | 22 ++++++++++++++++++++++ tests/packages/test_main.py | 18 ++++++++++++++++++ 4 files changed, 64 insertions(+), 3 deletions(-) diff --git a/poetry/packages/dependency.py b/poetry/packages/dependency.py index 83ad36a129c..5b688a3b2bb 100644 --- a/poetry/packages/dependency.py +++ b/poetry/packages/dependency.py @@ -271,16 +271,30 @@ def _create_nested_marker(self, name, constraint): marker = glue.join(parts) elif isinstance(constraint, Version): + if constraint.precision >= 3 and name == "python_version": + name = "python_full_version" + marker = '{} == "{}"'.format(name, constraint.text) else: if constraint.min is not None: + min_name = name + if constraint.min.precision >= 3 and name == "python_version": + min_name = "python_full_version" + + if constraint.max is None: + name = min_name + op = ">=" if not constraint.include_min: op = ">" version = constraint.min.text if constraint.max is not None: - text = '{} {} "{}"'.format(name, op, version) + max_name = name + if constraint.max.precision >= 3 and name == "python_version": + max_name = "python_full_version" + + text = '{} {} "{}"'.format(min_name, op, version) op = "<=" if not constraint.include_max: @@ -288,10 +302,13 @@ def _create_nested_marker(self, name, constraint): version = constraint.max - text += ' and {} {} "{}"'.format(name, op, version) + text += ' and {} {} "{}"'.format(max_name, op, version) return text elif constraint.max is not None: + if constraint.max.precision >= 3 and name == "python_version": + name = "python_full_version" + op = "<=" if not constraint.include_max: op = "<" diff --git a/poetry/version/markers.py b/poetry/version/markers.py index bc4219a33d6..052c4662064 100644 --- a/poetry/version/markers.py +++ b/poetry/version/markers.py @@ -270,7 +270,11 @@ def __eq__(self, other): class SingleMarker(BaseMarker): _CONSTRAINT_RE = re.compile(r"(?i)^(~=|!=|>=?|<=?|==?|in|not in)?\s*(.+)$") - _VERSION_LIKE_MARKER_NAME = {"python_version", "platform_release"} + _VERSION_LIKE_MARKER_NAME = { + "python_version", + "python_full_version", + "platform_release", + } def __init__(self, name, constraint): from poetry.packages.constraints import ( diff --git a/tests/packages/test_dependency.py b/tests/packages/test_dependency.py index 91654f4b874..2a08b2c6ff0 100644 --- a/tests/packages/test_dependency.py +++ b/tests/packages/test_dependency.py @@ -1,3 +1,5 @@ +import pytest + from poetry.packages import Dependency from poetry.packages import Package @@ -108,3 +110,23 @@ def test_to_pep_508_with_single_version_excluded(): dependency = Dependency("foo", "!=1.2.3") assert "foo (!=1.2.3)" == dependency.to_pep_508() + + +@pytest.mark.parametrize( + "python_versions, marker", + [ + (">=3.5,<3.5.4", 'python_version >= "3.5" and python_full_version < "3.5.4"'), + (">=3.5.4,<3.6", 'python_full_version >= "3.5.4" and python_version < "3.6"'), + ("<3.5.4", 'python_full_version < "3.5.4"'), + (">=3.5.4", 'python_full_version >= "3.5.4"'), + ("== 3.5.4", 'python_full_version == "3.5.4"'), + ], +) +def test_to_pep_508_with_patch_python_version(python_versions, marker): + dependency = Dependency("Django", "^1.23") + dependency.python_versions = python_versions + + expected = "Django (>=1.23,<2.0); {}".format(marker) + + assert expected == dependency.to_pep_508() + assert marker == str(dependency.marker) diff --git a/tests/packages/test_main.py b/tests/packages/test_main.py index 5559057e4e9..508e080b8aa 100644 --- a/tests/packages/test_main.py +++ b/tests/packages/test_main.py @@ -218,3 +218,21 @@ def test_dependency_from_pep_508_with_wheel_url(): assert "example-wheel" == dep.name assert str(dep.constraint) == "14.0.2" + + +def test_dependency_from_pep_508_with_python_full_version(): + name = ( + "requests (==2.18.0); " + '(python_version >= "2.7" and python_version < "2.8") ' + 'or (python_full_version >= "3.4" and python_full_version < "3.5.4")' + ) + dep = dependency_from_pep_508(name) + + assert dep.name == "requests" + assert str(dep.constraint) == "2.18.0" + assert dep.extras == [] + assert dep.python_versions == ">=2.7 <2.8 || >=3.4 <3.5.4" + assert str(dep.marker) == ( + 'python_version >= "2.7" and python_version < "2.8" ' + 'or python_full_version >= "3.4" and python_full_version < "3.5.4"' + ) From 1d64e1c75cfd03d8f98533645a7815f0dbcaf421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Tue, 9 Jun 2020 21:02:33 +0200 Subject: [PATCH 64/80] Bump version to 1.0.9 --- CHANGELOG.md | 11 ++++++++++- poetry/__version__.py | 2 +- pyproject.toml | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9aa53428da..65553cf201e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## [1.0.9] - 2010-06-09 + +### Fixed + +- Fixed an issue where packages from custom indices where continuously updated ([#2525](https://github.com/python-poetry/poetry/pull/2525)). +- Fixed errors in the way Python environment markers were parsed and generated ([#2526](https://github.com/python-poetry/poetry/pull/2526)). + + ## [1.0.8] - 2020-06-05 ### Fixed @@ -860,7 +868,8 @@ Initial release -[Unreleased]: https://github.com/python-poetry/poetry/compare/1.0.8...master +[Unreleased]: https://github.com/python-poetry/poetry/compare/1.0.9...master +[1.0.9]: https://github.com/python-poetry/poetry/releases/tag/1.0.9 [1.0.8]: https://github.com/python-poetry/poetry/releases/tag/1.0.8 [1.0.7]: https://github.com/python-poetry/poetry/releases/tag/1.0.7 [1.0.6]: https://github.com/python-poetry/poetry/releases/tag/1.0.6 diff --git a/poetry/__version__.py b/poetry/__version__.py index e13bd590c85..39e0411d5cd 100644 --- a/poetry/__version__.py +++ b/poetry/__version__.py @@ -1 +1 @@ -__version__ = "1.0.8" +__version__ = "1.0.9" diff --git a/pyproject.toml b/pyproject.toml index 0cdaef9908a..7a384698f2d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "poetry" -version = "1.0.8" +version = "1.0.9" description = "Python dependency management and packaging made easy." authors = [ "Sébastien Eustace " From f81282213f88df2fdbc4d1c2eadbada47e0b4322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Wed, 10 Jun 2020 09:59:07 +0200 Subject: [PATCH 65/80] get-poetry.py fallback to standard executables (#1878) (#2426) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * get-poetry.py fallback to standard executables * documentation update * fix typo due to cleanup * favor python3 over python2 when creating launcher * launcher favors 3.5 and up, else the first valid one it finds. * favor any py3 over py2, not just 3.5+ Co-authored-by: Jonathan Piché Co-authored-by: Jonathan Piché Co-authored-by: Jonathan Piché --- README.md | 7 +++++++ get-poetry.py | 45 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 44145cba57c..4d1a0a68f6a 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,13 @@ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poet Alternatively, you can download the `get-poetry.py` file and execute it separately. +The setup script must be able to find one of following executables in your shell's path environment: + +- `python` (which can be a py3 or py2 interpreter) +- `python3` +- `py.exe -3` (Windows) +- `py.exe -2` (Windows) + If you want to install prerelease versions, you can do so by passing `--preview` to `get-poetry.py`: ```bash diff --git a/get-poetry.py b/get-poetry.py index b8085ca3c7c..c691b2e363d 100644 --- a/get-poetry.py +++ b/get-poetry.py @@ -197,8 +197,7 @@ def expanduser(path): POETRY_LIB_BACKUP = os.path.join(POETRY_HOME, "lib-backup") -BIN = """#!/usr/bin/env python -# -*- coding: utf-8 -*- +BIN = """# -*- coding: utf-8 -*- import glob import sys import os @@ -217,7 +216,7 @@ def expanduser(path): main() """ -BAT = u('@echo off\r\npython "{poetry_bin}" %*\r\n') +BAT = u('@echo off\r\n{python_executable} "{poetry_bin}" %*\r\n') PRE_MESSAGE = """# Welcome to {poetry}! @@ -589,23 +588,61 @@ def _make_lib(self, version): finally: gz.close() + def _which_python(self): + """Decides which python executable we'll embed in the launcher script.""" + allowed_executables = ["python", "python3"] + if WINDOWS: + allowed_executables += ["py.exe -3", "py.exe -2"] + + # \d in regex ensures we can convert to int later + version_matcher = re.compile(r"^Python (?P\d+)\.(?P\d+)\..+$") + fallback = None + for executable in allowed_executables: + try: + raw_version = subprocess.check_output( + executable + " --version", stderr=subprocess.STDOUT, shell=True + ).decode("utf-8") + except subprocess.CalledProcessError: + continue + + match = version_matcher.match(raw_version.strip()) + if match and tuple(map(int, match.groups())) >= (3, 0): + # favor the first py3 executable we can find. + return executable + if fallback is None: + # keep this one as the fallback; it was the first valid executable we found. + fallback = executable + + if fallback is None: + raise RuntimeError( + "No python executable found in shell environment. Tried: " + + str(allowed_executables) + ) + + return fallback + def make_bin(self): if not os.path.exists(POETRY_BIN): os.mkdir(POETRY_BIN, 0o755) + python_executable = self._which_python() + if WINDOWS: with open(os.path.join(POETRY_BIN, "poetry.bat"), "w") as f: f.write( u( BAT.format( + python_executable=python_executable, poetry_bin=os.path.join(POETRY_BIN, "poetry").replace( os.environ["USERPROFILE"], "%USERPROFILE%" - ) + ), ) ) ) with open(os.path.join(POETRY_BIN, "poetry"), "w", encoding="utf-8") as f: + if not WINDOWS: + f.write(u("#!/usr/bin/env {}\n".format(python_executable))) f.write(u(BIN)) if not WINDOWS: From 8e5d5aabe14d11c4e27492e01efd99c3c9ddc29a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20B=C3=BCtikofer?= Date: Wed, 10 Jun 2020 10:42:40 +0200 Subject: [PATCH 66/80] Broken Link: Index -> Managing Environments Just a very small change to fix the link from the main page to the managing environments page. --- docs/docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/index.md b/docs/docs/index.md index 9fe5b372c61..02f25b0f123 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -28,7 +28,7 @@ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poet !!! note You only need to install Poetry once. It will automatically pick up the current - Python version and use it to [create virtualenvs](/docs/managing-environments.md) accordingly. + Python version and use it to [create virtualenvs](/docs/managing-environments) accordingly. The installer installs the `poetry` tool to Poetry's `bin` directory. On Unix it is located at `$HOME/.poetry/bin` and on Windows at `%USERPROFILE%\.poetry\bin`. From 7403a4db14f318e36fffb3a2146bfcc6affe294c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Thu, 11 Jun 2020 09:50:41 +0200 Subject: [PATCH 67/80] Revert "get-poetry.py fallback to standard executables (#1878) (#2426)" This reverts commit f81282213f88df2fdbc4d1c2eadbada47e0b4322. --- README.md | 7 ------- get-poetry.py | 45 ++++----------------------------------------- 2 files changed, 4 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 4d1a0a68f6a..44145cba57c 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,6 @@ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poet Alternatively, you can download the `get-poetry.py` file and execute it separately. -The setup script must be able to find one of following executables in your shell's path environment: - -- `python` (which can be a py3 or py2 interpreter) -- `python3` -- `py.exe -3` (Windows) -- `py.exe -2` (Windows) - If you want to install prerelease versions, you can do so by passing `--preview` to `get-poetry.py`: ```bash diff --git a/get-poetry.py b/get-poetry.py index c691b2e363d..b8085ca3c7c 100644 --- a/get-poetry.py +++ b/get-poetry.py @@ -197,7 +197,8 @@ def expanduser(path): POETRY_LIB_BACKUP = os.path.join(POETRY_HOME, "lib-backup") -BIN = """# -*- coding: utf-8 -*- +BIN = """#!/usr/bin/env python +# -*- coding: utf-8 -*- import glob import sys import os @@ -216,7 +217,7 @@ def expanduser(path): main() """ -BAT = u('@echo off\r\n{python_executable} "{poetry_bin}" %*\r\n') +BAT = u('@echo off\r\npython "{poetry_bin}" %*\r\n') PRE_MESSAGE = """# Welcome to {poetry}! @@ -588,61 +589,23 @@ def _make_lib(self, version): finally: gz.close() - def _which_python(self): - """Decides which python executable we'll embed in the launcher script.""" - allowed_executables = ["python", "python3"] - if WINDOWS: - allowed_executables += ["py.exe -3", "py.exe -2"] - - # \d in regex ensures we can convert to int later - version_matcher = re.compile(r"^Python (?P\d+)\.(?P\d+)\..+$") - fallback = None - for executable in allowed_executables: - try: - raw_version = subprocess.check_output( - executable + " --version", stderr=subprocess.STDOUT, shell=True - ).decode("utf-8") - except subprocess.CalledProcessError: - continue - - match = version_matcher.match(raw_version.strip()) - if match and tuple(map(int, match.groups())) >= (3, 0): - # favor the first py3 executable we can find. - return executable - if fallback is None: - # keep this one as the fallback; it was the first valid executable we found. - fallback = executable - - if fallback is None: - raise RuntimeError( - "No python executable found in shell environment. Tried: " - + str(allowed_executables) - ) - - return fallback - def make_bin(self): if not os.path.exists(POETRY_BIN): os.mkdir(POETRY_BIN, 0o755) - python_executable = self._which_python() - if WINDOWS: with open(os.path.join(POETRY_BIN, "poetry.bat"), "w") as f: f.write( u( BAT.format( - python_executable=python_executable, poetry_bin=os.path.join(POETRY_BIN, "poetry").replace( os.environ["USERPROFILE"], "%USERPROFILE%" - ), + ) ) ) ) with open(os.path.join(POETRY_BIN, "poetry"), "w", encoding="utf-8") as f: - if not WINDOWS: - f.write(u("#!/usr/bin/env {}\n".format(python_executable))) f.write(u(BIN)) if not WINDOWS: From a08c4a91cc469f2c35ef827abfa80f1b53969e06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Thu, 11 Jun 2020 09:59:02 +0200 Subject: [PATCH 68/80] Do not use preview versions of Poetry in CI --- .github/workflows/main.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c7cea8e9120..3a343b6001d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -41,8 +41,7 @@ jobs: - name: Install poetry shell: bash run: | - curl -fsS -o get-poetry.py https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py - python get-poetry.py --preview -y + python get-poetry.py -y echo "::set-env name=PATH::$HOME/.poetry/bin:$PATH" - name: Configure poetry From 00c9e49c8ec71e8c9686e637b611d0def79f1414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Thu, 11 Jun 2020 16:06:19 +0200 Subject: [PATCH 69/80] Make get-poetry.py fallback to standard executables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jonathan Piché --- docs/docs/index.md | 9 +++++++++ get-poetry.py | 47 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/docs/docs/index.md b/docs/docs/index.md index 9fe5b372c61..c5d1e626fb8 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -77,6 +77,15 @@ POETRY_VERSION=0.12.0 python get-poetry.py Note that the installer does not support Poetry releases < 0.12.0. +!!!note + + The setup script must be able to find one of following executables in your shell's path environment: + + - `python` (which can be a py3 or py2 interpreter) + - `python3` + - `py.exe -3` (Windows) + - `py.exe -2` (Windows) + ### Alternative installation methods (not recommended) !!!note diff --git a/get-poetry.py b/get-poetry.py index b8085ca3c7c..fcac28c86f5 100644 --- a/get-poetry.py +++ b/get-poetry.py @@ -197,8 +197,7 @@ def expanduser(path): POETRY_LIB_BACKUP = os.path.join(POETRY_HOME, "lib-backup") -BIN = """#!/usr/bin/env python -# -*- coding: utf-8 -*- +BIN = """# -*- coding: utf-8 -*- import glob import sys import os @@ -217,7 +216,7 @@ def expanduser(path): main() """ -BAT = u('@echo off\r\npython "{poetry_bin}" %*\r\n') +BAT = u('@echo off\r\n{python_executable} "{poetry_bin}" %*\r\n') PRE_MESSAGE = """# Welcome to {poetry}! @@ -589,23 +588,63 @@ def _make_lib(self, version): finally: gz.close() + def _which_python(self): + """Decides which python executable we'll embed in the launcher script.""" + allowed_executables = ["python", "python3"] + if WINDOWS: + allowed_executables += ["py.exe -3", "py.exe -2"] + + # \d in regex ensures we can convert to int later + version_matcher = re.compile(r"^Python (?P\d+)\.(?P\d+)\..+$") + fallback = None + for executable in allowed_executables: + try: + raw_version = subprocess.check_output( + executable + " --version", stderr=subprocess.STDOUT, shell=True + ).decode("utf-8") + except subprocess.CalledProcessError: + continue + + match = version_matcher.match(raw_version.strip()) + if match: + return executable + + if fallback is None: + # keep this one as the fallback; it was the first valid executable we found. + fallback = executable + + if fallback is None: + raise RuntimeError( + "No python executable found in shell environment. Tried: " + + str(allowed_executables) + ) + + return fallback + def make_bin(self): if not os.path.exists(POETRY_BIN): os.mkdir(POETRY_BIN, 0o755) + python_executable = self._which_python() + if WINDOWS: with open(os.path.join(POETRY_BIN, "poetry.bat"), "w") as f: f.write( u( BAT.format( + python_executable=python_executable, poetry_bin=os.path.join(POETRY_BIN, "poetry").replace( os.environ["USERPROFILE"], "%USERPROFILE%" - ) + ), ) ) ) with open(os.path.join(POETRY_BIN, "poetry"), "w", encoding="utf-8") as f: + if WINDOWS: + python_executable = "python" + + f.write(u("#!/usr/bin/env {}\n".format(python_executable))) f.write(u(BIN)) if not WINDOWS: From 8d95143cae2c2f46c1f7479c3d9314cd0ac8960c Mon Sep 17 00:00:00 2001 From: mrh1997 Date: Sat, 13 Jun 2020 23:20:19 +0200 Subject: [PATCH 70/80] Fix documentation of "poetry env list" first sentence of chapter didn't make sense. --- docs/docs/managing-environments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/managing-environments.md b/docs/docs/managing-environments.md index 8a1475f7c45..8b626cd813a 100644 --- a/docs/docs/managing-environments.md +++ b/docs/docs/managing-environments.md @@ -92,7 +92,7 @@ poetry env info --path ## Listing the environments associated with the project -You can also list all the virtual environments associated with the current virtual environment +You can also list all the virtual environments associated with the current project with the `env list` command: ```bash From d7e73b36111e7d01616790f88ac0250c0c703f8b Mon Sep 17 00:00:00 2001 From: Sivan Becker Date: Mon, 15 Jun 2020 09:34:55 +0300 Subject: [PATCH 71/80] fix wrong manage env url on the commands docs page --- docs/docs/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/cli.md b/docs/docs/cli.md index b07a567d4ad..f6f13694c18 100644 --- a/docs/docs/cli.md +++ b/docs/docs/cli.md @@ -468,4 +468,4 @@ poetry export -f requirements.txt > requirements.txt The `env` command regroups sub commands to interact with the virtualenvs associated with a specific project. -See [Managing environments](/docs/managing-environments.md) for more information about these commands. +See [Managing environments](/docs/managing-environments/) for more information about these commands. From 667d87ddcef799e841fef0c7e9800843827e8cad Mon Sep 17 00:00:00 2001 From: dgnsrekt Date: Wed, 17 Jun 2020 11:01:19 -0500 Subject: [PATCH 72/80] Adds ways to specify a package to poetry add --help section. --- poetry/console/commands/add.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/poetry/console/commands/add.py b/poetry/console/commands/add.py index 275fc44f5f1..ce980dc8f7a 100644 --- a/poetry/console/commands/add.py +++ b/poetry/console/commands/add.py @@ -40,11 +40,18 @@ class AddCommand(EnvCommand, InitCommand): "Output the operations but do not execute anything (implicitly enables --verbose).", ), ] - - help = """The add command adds required packages to your pyproject.toml and installs them. - -If you do not specify a version constraint, poetry will choose a suitable one based on the available package versions. -""" + help = ( + "The add command adds required packages to your pyproject.toml and installs them.\n\n" + "If you do not specify a version constraint, poetry will choose a suitable one based on the available package versions.\n\n" + "You can specify a package in the following forms:\n" + " - A single name (requests)\n" + " - A name and a constraint (requests ^2.23.0)\n" + " - A git url (git+https://github.com/python-poetry/poetry.git)\n" + " - A git url with a revision (git+https://github.com/python-poetry/poetry.git#develop)\n" + " - A file path (../my-package/my-package.whl)\n" + " - A directory (../my-package/)\n" + " - A url (https://example.com/packages/my-package-0.1.0.tar.gz)\n" + ) loggers = ["poetry.repositories.pypi_repository"] From e76796b67429fd693d715719073d2e25b2a97288 Mon Sep 17 00:00:00 2001 From: Erik OShaughnessy Date: Fri, 19 Jun 2020 10:50:09 -0500 Subject: [PATCH 73/80] Update shell.py These small changes allow `poetry shell` to properly activate a python virtual environment when the user's shell is `tcsh`. --- poetry/utils/shell.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/poetry/utils/shell.py b/poetry/utils/shell.py index b18bda0dd20..2b2fe91f946 100644 --- a/poetry/utils/shell.py +++ b/poetry/utils/shell.py @@ -94,6 +94,8 @@ def _get_activate_script(self): suffix = ".fish" elif "csh" == self._name: suffix = ".csh" + elif "tcsh" == self._name: + suffix = ".csh" else: suffix = "" @@ -104,6 +106,8 @@ def _get_source_command(self): return "source" elif "csh" == self._name: return "source" + elif "tcsh" == self._name: + return "source" return "." From 1fb91320ccb0108af5c2e9358be0ed7497473d07 Mon Sep 17 00:00:00 2001 From: Christian Knittl-Frank Date: Tue, 16 Jun 2020 18:18:47 +0200 Subject: [PATCH 74/80] Fix link to SPDX Open Source License Registry Link with 'www' was being redirected wrong to 'https://spdx.org//licenses/' --- docs/docs/pyproject.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/pyproject.md b/docs/docs/pyproject.md index a3c75526d7a..c402f3498de 100644 --- a/docs/docs/pyproject.md +++ b/docs/docs/pyproject.md @@ -38,7 +38,7 @@ The recommended notation for the most common licenses is (alphabetical): * MIT Optional, but it is highly recommended to supply this. -More identifiers are listed at the [SPDX Open Source License Registry](https://www.spdx.org/licenses/). +More identifiers are listed at the [SPDX Open Source License Registry](https://spdx.org/licenses/). !!!note From d1786b892cd060fe2d7d7c63b5e57e0bb8eb5b5f Mon Sep 17 00:00:00 2001 From: dgnsrekt Date: Sat, 20 Jun 2020 09:51:19 -0500 Subject: [PATCH 75/80] Fixes add and init command --help documentation. --- poetry/console/commands/add.py | 2 +- poetry/console/commands/init.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/poetry/console/commands/add.py b/poetry/console/commands/add.py index ce980dc8f7a..378d7a2f871 100644 --- a/poetry/console/commands/add.py +++ b/poetry/console/commands/add.py @@ -45,7 +45,7 @@ class AddCommand(EnvCommand, InitCommand): "If you do not specify a version constraint, poetry will choose a suitable one based on the available package versions.\n\n" "You can specify a package in the following forms:\n" " - A single name (requests)\n" - " - A name and a constraint (requests ^2.23.0)\n" + " - A name and a constraint (requests@^2.23.0)\n" " - A git url (git+https://github.com/python-poetry/poetry.git)\n" " - A git url with a revision (git+https://github.com/python-poetry/poetry.git#develop)\n" " - A file path (../my-package/my-package.whl)\n" diff --git a/poetry/console/commands/init.py b/poetry/console/commands/init.py index b74d191fa5c..c85f441b8aa 100644 --- a/poetry/console/commands/init.py +++ b/poetry/console/commands/init.py @@ -146,7 +146,7 @@ def handle(self): help_message = ( "You can specify a package in the following forms:\n" " - A single name (requests)\n" - " - A name and a constraint (requests ^2.23.0)\n" + " - A name and a constraint (requests@^2.23.0)\n" " - A git url (git+https://github.com/python-poetry/poetry.git)\n" " - A git url with a revision (git+https://github.com/python-poetry/poetry.git#develop)\n" " - A file path (../my-package/my-package.whl)\n" From 65e042ca120bb516a9de285cf359d505bfaad70e Mon Sep 17 00:00:00 2001 From: Jamie McClymont Date: Wed, 27 Nov 2019 03:25:37 +1300 Subject: [PATCH 76/80] Provide hints when an invalid license id is input --- poetry/spdx/__init__.py | 31 ++++++++++++++++++++++++++++++- tests/spdx/test_main.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/poetry/spdx/__init__.py b/poetry/spdx/__init__.py index 80a2a67d736..41d1da5bd6a 100644 --- a/poetry/spdx/__init__.py +++ b/poetry/spdx/__init__.py @@ -17,7 +17,36 @@ def license_by_id(identifier): id = identifier.lower() if id not in _licenses: - raise ValueError("Invalid license id: {}".format(identifier)) + err = "Invalid license id: {}\nPoetry uses SPDX license identifiers: https://spdx.org/licenses/".format( + identifier + ) + + # Covers the licenses listed as common for python packages in https://snyk.io/blog/over-10-of-python-packages-on-pypi-are-distributed-without-any-license/ + # MIT/WTFPL/Unlicense are excluded as their ids are simply their name - if someone types "mit", they've already found the license they were looking for + + common_strings = ["agpl", "lgpl", "gpl", "bsd", "apache", "mpl", "cc0"] + for string in common_strings: + if string in id: + + err += "\n" + err += "Did you mean one of the following?" + + matches = sorted( + { + license.id + for license in _licenses.values() + if license.id.lower().startswith(string) + and not license.is_deprecated + } + ) + + for license in matches: + err += "\n * {}".format(license) + + # Don't match agpl for "gpl" + break + + raise ValueError(err) return _licenses[id] diff --git a/tests/spdx/test_main.py b/tests/spdx/test_main.py index 00e0910044d..ef941458c89 100644 --- a/tests/spdx/test_main.py +++ b/tests/spdx/test_main.py @@ -41,3 +41,38 @@ def test_license_by_id_with_full_name(): def test_license_by_id_invalid(): with pytest.raises(ValueError): license_by_id("invalid") + + +def test_license_by_id_invalid_gpl(): + with pytest.raises(ValueError) as exc_info: + license_by_id("gpl") + + assert "Did you mean" in str(exc_info.value) + assert " GPL-3.0-only" in str(exc_info.value) + assert " AGPL-3.0-only" not in str(exc_info.value) + + +def test_license_by_id_invalid_agpl(): + with pytest.raises(ValueError) as exc_info: + license_by_id("agpl") + + assert "Did you mean" in str(exc_info.value) + assert " GPL-3.0-only" not in str(exc_info.value) + assert " AGPL-3.0-only" in str(exc_info.value) + + +def test_license_by_id_invalid_agpl_versioned(): + with pytest.raises(ValueError) as exc_info: + license_by_id("gnu agpl v3+") + + assert "Did you mean" in str(exc_info.value) + assert " GPL-3.0-only" not in str(exc_info.value) + assert " AGPL-3.0-only" in str(exc_info.value) + + +def test_license_by_id_invalid_unpopular(): + with pytest.raises(ValueError) as exc_info: + license_by_id("not-a-well-known-license") + + assert "spdx.org" in str(exc_info.value) + assert "Did you mean" not in str(exc_info.value) From 6a0ac4a63affb38cba7e7f24768fc98f230c34d1 Mon Sep 17 00:00:00 2001 From: yamagen0915 Date: Fri, 26 Jun 2020 17:56:02 +0900 Subject: [PATCH 77/80] Raise a ValueError when author name has invalid --- poetry/packages/package.py | 6 ++---- tests/packages/test_package.py | 13 +++++++++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/poetry/packages/package.py b/poetry/packages/package.py index 4b39bb9eb5c..4a29318c25a 100644 --- a/poetry/packages/package.py +++ b/poetry/packages/package.py @@ -163,11 +163,10 @@ def _get_author(self): # type: () -> dict m = AUTHOR_REGEX.match(self._authors[0]) if m is None: - logger.warning( + raise ValueError( "Invalid author string. Must be in the format: " "John Smith " ) - return {"name": None, "email": None} name = m.group("name") email = m.group("email") @@ -181,11 +180,10 @@ def _get_maintainer(self): # type: () -> dict m = AUTHOR_REGEX.match(self._maintainers[0]) if m is None: - logger.warning( + raise ValueError( "Invalid maintainer string. Must be in the format: " "John Smith " ) - return {"name": None, "email": None} name = m.group("name") email = m.group("email") diff --git a/tests/packages/test_package.py b/tests/packages/test_package.py index c25e15cde48..5ac0b56efa5 100644 --- a/tests/packages/test_package.py +++ b/tests/packages/test_package.py @@ -17,9 +17,18 @@ def test_package_authors(): assert package.author_name == "John Doe" assert package.author_email is None + +def test_package_authors_invalid(): + package = Package("foo", "0.1.0") + package.authors.insert(0, "" + ) @pytest.mark.parametrize("category", ["main", "dev"]) From 5f27a25d4a357ce5e71cf9492fae7ca3d0b7a051 Mon Sep 17 00:00:00 2001 From: Dan Rose Date: Sun, 21 Jun 2020 19:45:15 -0500 Subject: [PATCH 78/80] Fix changelog year --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65553cf201e..a00edcf837a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log -## [1.0.9] - 2010-06-09 +## [1.0.9] - 2020-06-09 ### Fixed From b19873ae4f4391b89bd6fe89aed52963c44db078 Mon Sep 17 00:00:00 2001 From: Masahiro Sakai Date: Sun, 28 Jun 2020 22:03:24 +0900 Subject: [PATCH 79/80] pip installer: convert path requirement to string Ensure path requirement is converted to posix string. Relates-to: #2398 --- poetry/installation/pip_installer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/poetry/installation/pip_installer.py b/poetry/installation/pip_installer.py index 349f222c73c..3129e0b69f5 100644 --- a/poetry/installation/pip_installer.py +++ b/poetry/installation/pip_installer.py @@ -143,7 +143,7 @@ def requirement(self, package, formatted=False): if package.source_type in ["file", "directory"]: if package.root_dir: - req = os.path.join(package.root_dir, package.source_url) + req = (package.root_dir / package.source_url).as_posix() else: req = os.path.realpath(package.source_url) @@ -184,7 +184,7 @@ def install_directory(self, package): from poetry.utils.toml_file import TomlFile if package.root_dir: - req = os.path.join(package.root_dir, package.source_url) + req = (package.root_dir / package.source_url).as_posix() else: req = os.path.realpath(package.source_url) From a738d2a72b0a99cb65c30770f68050975e686991 Mon Sep 17 00:00:00 2001 From: Alex Triaca Date: Sun, 8 Mar 2020 12:06:32 +0000 Subject: [PATCH 80/80] Changed indirect access to more direct access methods to improve performance --- poetry/packages/dependency_package.py | 20 ++++++++++++++++++++ poetry/packages/package.py | 14 +++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/poetry/packages/dependency_package.py b/poetry/packages/dependency_package.py index f38892488d9..6285cf29ae4 100644 --- a/poetry/packages/dependency_package.py +++ b/poetry/packages/dependency_package.py @@ -3,6 +3,26 @@ def __init__(self, dependency, package): self._dependency = dependency self._package = package + @property + def name(self): + return self._package.name + + @property + def version(self): + return self._package.version + + @property + def constraint(self): + return self._package.constraint + + @property + def all_requires(self): + return self._package.all_requires + + @property + def marker(self): + return self._package.marker + @property def dependency(self): return self._dependency diff --git a/poetry/packages/package.py b/poetry/packages/package.py index 04854ec72af..03300e29d3d 100644 --- a/poetry/packages/package.py +++ b/poetry/packages/package.py @@ -40,7 +40,7 @@ def __init__(self, name, version, pretty_version=None): Creates a new in memory package. """ self._pretty_name = name - self._name = canonicalize_name(name) + self.name = canonicalize_name(name) if not isinstance(version, Version): self._version = Version.parse(version) @@ -88,10 +88,6 @@ def __init__(self, name, version, pretty_version=None): self.develop = True - @property - def name(self): - return self._name - @property def pretty_name(self): return self._pretty_name @@ -107,7 +103,7 @@ def pretty_version(self): @property def unique_name(self): if self.is_root(): - return self._name + return self.name return self.name + "-" + self._version.text @@ -402,7 +398,7 @@ def add_dependency( def to_dependency(self): from . import dependency_from_pep_508 - name = "{} (=={})".format(self._name, self._version) + name = "{} (=={})".format(self.name, self._version) if not self.marker.is_any(): name += " ; {}".format(str(self.marker)) @@ -440,13 +436,13 @@ def clone(self): # type: () -> Package return clone def __hash__(self): - return hash((self._name, self._version)) + return hash((self.name, self._version)) def __eq__(self, other): if not isinstance(other, Package): return NotImplemented - return self._name == other.name and self._version == other.version + return self.name == other.name and self._version == other.version def __str__(self): return self.unique_name