Commit cd28d5c2 by Sébastien Eustace

Merge branch 'master' into develop

parents 9c944b15 a1b97707
......@@ -31,6 +31,7 @@ MANIFEST.in
/docs/site/*
pyproject.lock
/tests/fixtures/simple_project/setup.py
/tests/fixtures/project_with_extras/setup.py
.mypy_cache
.venv
# Change Log
## [0.11.4] - 2018-07-30
### Fixed
- Fixed wrong wheel being selected when resolving dependencies.
- Fixed an error when publishing.
- Fixed an error when building wheels with the `packages` property set.
- Fixed single value display in `config` command.
## [0.11.3] - 2018-07-26
### Changed
......@@ -446,7 +456,8 @@ Initial release
[Unreleased]: https://github.com/sdispater/poetry/compare/0.11.3...master
[Unreleased]: https://github.com/sdispater/poetry/compare/0.11.4...master
[0.11.4]: https://github.com/sdispater/poetry/releases/tag/0.11.4
[0.11.3]: https://github.com/sdispater/poetry/releases/tag/0.11.3
[0.11.2]: https://github.com/sdispater/poetry/releases/tag/0.11.2
[0.11.1]: https://github.com/sdispater/poetry/releases/tag/0.11.1
......
......@@ -51,3 +51,15 @@ commands =
poetry install -v
poetry run pytest tests/
```
## I don't want Poetry to manage my virtualenvs. Can I disable it?
While Poetry automatically creates virtualenvs to always work isolated
from the global Python installation, there are valid reasons why it's not necessary
and is an overhead, like when working with containers.
In this case, you can disable this feature by setting the `virtualenvs.create` setting to `false`:
```bash
poetry config settings.virtualenvs.create false
```
__version__ = "0.11.3"
__version__ = "0.11.4"
......@@ -118,6 +118,17 @@ To remove a repository (repo is a short alias for repositories):
value = repo
self.line(str(value))
else:
values = self.unique_config_values
if setting_key not in values:
raise ValueError("There is no {} setting.".format(setting_key))
values = self._get_setting(
self._config.content, setting_key, default=values[setting_key][-1]
)
for value in values:
self.line(value[1])
return 0
......@@ -240,17 +251,22 @@ To remove a repository (repo is a short alias for repositories):
self._list_setting(repositories, k="repositories.")
def _list_setting(self, contents, setting=None, k=None, default=None):
values = self._get_setting(contents, setting, k, default)
for value in values:
self.line(
"<comment>{}</comment> = <info>{}</info>".format(value[0], value[1])
)
def _get_setting(self, contents, setting=None, k=None, default=None):
orig_k = k
if setting and setting.split(".")[0] not in contents:
value = json.dumps(default)
self.line(
"<comment>{}</comment> = <info>{}</info>".format(
(k or "") + setting, value
)
)
return [((k or "") + setting, value)]
else:
values = []
for key, value in contents.items():
if k is None and key not in ["config", "repositories", "settings"]:
continue
......@@ -266,7 +282,9 @@ To remove a repository (repo is a short alias for repositories):
if setting and len(setting) > 1:
setting = ".".join(setting.split(".")[1:])
self._list_setting(value, k=k, setting=setting, default=default)
values += self._get_setting(
value, k=k, setting=setting, default=default
)
k = orig_k
continue
......@@ -281,11 +299,9 @@ To remove a repository (repo is a short alias for repositories):
value = json.dumps(value)
self.line(
"<comment>{}</comment> = <info>{}</info>".format(
(k or "") + key, value
)
)
values.append(((k or "") + key, value))
return values
def _get_formatted_value(self, value):
if isinstance(value, list):
......
......@@ -52,7 +52,7 @@ class Publisher:
"Unable to get repository information"
)
config = config_file.read(raw=True)
config = config_file.read()
if (
"repositories" not in config
......
......@@ -19,7 +19,7 @@ class Include(object):
def __init__(self, base, include): # type: (Path, str) -> None
self._base = base
self._include = include
self._include = str(include)
self._elements = sorted(list(self._base.glob(str(self._include))))
......
......@@ -77,6 +77,7 @@ class DirectoryDependency(Dependency):
self._package = Package(package.pretty_name, package.version)
self._package.requires += package.requires
self._package.dev_requires += package.dev_requires
self._package.extras = package.extras
self._package.python_versions = package.python_versions
self._package.platform = package.platform
else:
......
......@@ -314,12 +314,13 @@ class Provider:
]
def complete_package(self, package): # type: (str, Version) -> Package
if package.is_root() or package.source_type in {"git", "file", "directory"}:
if package.is_root() or package.source_type in {"git", "file"}:
return package
package = self._pool.package(
package.name, package.version.text, extras=package.requires_extras
)
if package.source_type != "directory":
package = self._pool.package(
package.name, package.version.text, extras=package.requires_extras
)
dependencies = [
r
......
import logging
import os
import re
import tarfile
import zipfile
......@@ -288,15 +289,42 @@ class PyPiRepository(Repository):
continue
# If bdist_wheel, check if it's universal
python_version = url["python_version"]
if python_version not in ["py2.py3", "py3", "py2"]:
filename = url["filename"]
if not re.search("-py2\.py3-none-any.whl", filename):
continue
parts = urlparse.urlparse(url["url"])
filename = os.path.basename(parts.path)
urls[dist_type] = url["url"]
if "-none-any" not in filename:
continue
if "sdist" in url and "bdist_wheel" not in urls:
# If can't found a universal wheel
# but we found an sdist, inspect the sdist first
info = self._get_info_from_urls(urls)
if info["requires_dist"]:
data["requires_dist"] = info["requires_dist"]
if not data["requires_python"]:
data["requires_python"] = info["requires_python"]
return data
else:
del urls["sdist"]
if not urls:
# If we don't have urls, we try to take the first one
# we find and go from there
if not json_data["urls"]:
return data
for url in json_data["urls"]:
# Only get sdist and universal wheels if they exist
dist_type = url["packagetype"]
if dist_type != "bdist_wheel":
continue
urls[url["packagetype"]] = url["url"]
break
if not urls or "bdist_wheel" not in urls:
# If we don't have urls, we try to take the first one
......
......@@ -6,7 +6,9 @@ MODIFIERS = (
"([+-]?([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?"
)
_COMPLETE_VERSION = "v?(\d+)(?:\.(\d+))?(?:\.(\d+))?{}(?:\+[^\s]+)?".format(MODIFIERS)
_COMPLETE_VERSION = "v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?{}(?:\+[^\s]+)?".format(
MODIFIERS
)
COMPLETE_VERSION = re.compile("(?i)" + _COMPLETE_VERSION)
......
......@@ -20,6 +20,7 @@ class Version(VersionRange):
major, # type: int
minor=None, # type: Union[int, None]
patch=None, # type: Union[int, None]
rest=None, # type: Union[int, None]
pre=None, # type: Union[str, None]
build=None, # type: Union[str, None]
text=None, # type: Union[str, None]
......@@ -44,10 +45,17 @@ class Version(VersionRange):
if self._precision is not None:
self._precision += 1
if rest is None:
rest = 0
else:
if self._precision is not None:
self._precision += 1
if precision is not None:
self._precision = precision
self._patch = int(patch)
self._rest = int(rest)
if text is None:
parts = [str(major)]
......@@ -57,6 +65,9 @@ class Version(VersionRange):
if self._precision >= 3 or patch != 0:
parts.append(str(patch))
if self._precision >= 4 or rest != 0:
parts.append(str(rest))
text = ".".join(parts)
if pre:
text += "-{}".format(pre)
......@@ -94,6 +105,10 @@ class Version(VersionRange):
return self._patch
@property
def rest(self): # type: () -> int
return self._rest
@property
def prerelease(self): # type: () -> List[str]
return self._prerelease
......@@ -185,14 +200,15 @@ class Version(VersionRange):
major = int(match.group(1))
minor = int(match.group(2)) if match.group(2) else None
patch = int(match.group(3)) if match.group(3) else None
rest = int(match.group(4)) if match.group(4) else None
pre = match.group(4)
build = match.group(5)
pre = match.group(5)
build = match.group(6)
if build:
build = build.lstrip("+")
return Version(major, minor, patch, pre, build, text)
return Version(major, minor, patch, rest, pre, build, text)
def is_any(self):
return False
......@@ -289,9 +305,6 @@ class Version(VersionRange):
if not build:
return
if build == "0":
return
if build.startswith("post"):
build = build.lstrip("post")
......@@ -339,6 +352,9 @@ class Version(VersionRange):
if self.patch != other.patch:
return self._cmp_parts(self.patch, other.patch)
if self.rest != other.rest:
return self._cmp_parts(self.rest, other.rest)
# Pre-releases always come before no pre-release string.
if not self.is_prerelease() and other.is_prerelease():
return 1
......@@ -380,7 +396,7 @@ class Version(VersionRange):
if a_part == b_part:
continue
# Missing parts come before present ones.
# Missing parts come after present ones.
if a_part is None:
return -1
......@@ -408,6 +424,7 @@ class Version(VersionRange):
self._major == other.major
and self._minor == other.minor
and self._patch == other.patch
and self._rest == other.rest
and self._prerelease == other.prerelease
and self._build == other.build
)
......
[tool.poetry]
name = "poetry"
version = "0.11.3"
version = "0.11.4"
description = "Python dependency management and packaging made easy."
authors = [
"Sébastien Eustace <sebastien@eustace.io>"
......
......@@ -64,3 +64,18 @@ repositories = {}
"""
assert tester.get_display(True) == expected
def test_display_single_setting(app, config):
command = app.find("config")
command._config = Config(config.file)
tester = CommandTester(command)
tester.execute(
[("command", command.get_name()), ("key", "settings.virtualenvs.create")]
)
expected = """true
"""
assert tester.get_display(True) == expected
[tool.poetry]
name = "project-with-extras"
version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
[tool.poetry.dependencies]
python = "*"
pendulum = { version = ">=1.4.4", optional = true }
cachy = { version = ">=0.2.0", optional = true }
[tool.poetry.extras]
extras_a = [ "pendulum" ]
extras_b = [ "cachy" ]
[tool.poetry.dev-dependencies]
[[package]]
description = ""
category = "main"
name = "pendulum"
optional = false
platform = "*"
python-versions = "*"
version = "1.4.4"
[[package]]
category = "main"
description = ""
name = "project-with-extras"
optional = false
platform = "*"
python-versions = "*"
version = "1.2.3"
[package.dependencies]
pendulum = ">=1.4.4"
[package.source]
reference = ""
type = "directory"
url = "tests/fixtures/project_with_extras"
[metadata]
content-hash = "123456789"
platform = "*"
python-versions = "*"
[metadata.hashes]
project-with-extras = []
pendulum = []
......@@ -609,7 +609,26 @@ def test_run_installs_with_local_file(installer, locker, repo, package):
assert len(installer.installer.installs) == 2
def test_run_installs_with_local_directory(installer, locker, repo, package):
def test_run_installs_with_local_poetry_directory_and_extras(
installer, locker, repo, package, tmpdir
):
file_path = Path("tests/fixtures/project_with_extras/")
package.add_dependency("demo", {"path": str(file_path), "extras": ["extras_a"]})
repo.add_package(get_package("pendulum", "1.4.4"))
installer.run()
expected = fixture("with-directory-dependency-poetry")
assert locker.written_data == expected
assert len(installer.installer.installs) == 2
def test_run_installs_with_local_setuptools_directory(
installer, locker, repo, package, tmpdir
):
file_path = Path("tests/fixtures/project_with_setup/")
package.add_dependency("demo", {"path": str(file_path)})
......@@ -618,7 +637,7 @@ def test_run_installs_with_local_directory(installer, locker, repo, package):
installer.run()
expected = fixture("with-directory-dependency")
expected = fixture("with-directory-dependency-setuptools")
assert locker.written_data == expected
......
......@@ -47,10 +47,9 @@ def test_wheel_c_extension():
assert sdist.exists()
tar = tarfile.open(str(sdist), "r")
assert "extended-0.1/build.py" in tar.getnames()
assert "extended-0.1/extended/extended.c" in tar.getnames()
with tarfile.open(str(sdist), "r") as tar:
assert "extended-0.1/build.py" in tar.getnames()
assert "extended-0.1/extended/extended.c" in tar.getnames()
whl = list((module_path / "dist").glob("extended-0.1-cp*-cp*-*.whl"))[0]
......@@ -167,9 +166,8 @@ def test_module_src():
assert sdist.exists()
tar = tarfile.open(str(sdist), "r")
assert "module-src-0.1/src/module_src.py" in tar.getnames()
with tarfile.open(str(sdist), "r") as tar:
assert "module-src-0.1/src/module_src.py" in tar.getnames()
whl = module_path / "dist" / "module_src-0.1-py2.py3-none-any.whl"
......@@ -192,9 +190,8 @@ def test_package_src():
assert sdist.exists()
tar = tarfile.open(str(sdist), "r")
assert "package-src-0.1/src/package_src/module.py" in tar.getnames()
with tarfile.open(str(sdist), "r") as tar:
assert "package-src-0.1/src/package_src/module.py" in tar.getnames()
whl = module_path / "dist" / "package_src-0.1-py2.py3-none-any.whl"
......
......@@ -239,9 +239,8 @@ def test_package():
assert sdist.exists()
tar = tarfile.open(str(sdist), "r")
assert "my-package-1.2.3/LICENSE" in tar.getnames()
with tarfile.open(str(sdist), "r") as tar:
assert "my-package-1.2.3/LICENSE" in tar.getnames()
def test_module():
......@@ -254,9 +253,8 @@ def test_module():
assert sdist.exists()
tar = tarfile.open(str(sdist), "r")
assert "module1-0.1/module1.py" in tar.getnames()
with tarfile.open(str(sdist), "r") as tar:
assert "module1-0.1/module1.py" in tar.getnames()
def test_prelease():
......@@ -280,10 +278,9 @@ def test_with_c_extensions():
assert sdist.exists()
tar = tarfile.open(str(sdist), "r")
assert "extended-0.1/build.py" in tar.getnames()
assert "extended-0.1/extended/extended.c" in tar.getnames()
with tarfile.open(str(sdist), "r") as tar:
assert "extended-0.1/build.py" in tar.getnames()
assert "extended-0.1/extended/extended.c" in tar.getnames()
def test_with_src_module_file():
......@@ -307,9 +304,8 @@ def test_with_src_module_file():
assert sdist.exists()
tar = tarfile.open(str(sdist), "r")
assert "module-src-0.1/src/module_src.py" in tar.getnames()
with tarfile.open(str(sdist), "r") as tar:
assert "module-src-0.1/src/module_src.py" in tar.getnames()
def test_with_src_module_dir():
......@@ -333,10 +329,9 @@ def test_with_src_module_dir():
assert sdist.exists()
tar = tarfile.open(str(sdist), "r")
assert "package-src-0.1/src/package_src/__init__.py" in tar.getnames()
assert "package-src-0.1/src/package_src/module.py" in tar.getnames()
with tarfile.open(str(sdist), "r") as tar:
assert "package-src-0.1/src/package_src/__init__.py" in tar.getnames()
assert "package-src-0.1/src/package_src/module.py" in tar.getnames()
def test_package_with_include(mocker):
......@@ -380,21 +375,20 @@ def test_package_with_include(mocker):
assert sdist.exists()
tar = tarfile.open(str(sdist), "r")
names = tar.getnames()
assert "with-include-1.2.3/LICENSE" in names
assert "with-include-1.2.3/README.rst" in names
assert "with-include-1.2.3/extra_dir/__init__.py" in names
assert "with-include-1.2.3/extra_dir/vcs_excluded.txt" in names
assert "with-include-1.2.3/extra_dir/sub_pkg/__init__.py" in names
assert "with-include-1.2.3/extra_dir/sub_pkg/vcs_excluded.txt" not in names
assert "with-include-1.2.3/my_module.py" in names
assert "with-include-1.2.3/notes.txt" in names
assert "with-include-1.2.3/package_with_include/__init__.py" in names
assert "with-include-1.2.3/pyproject.toml" in names
assert "with-include-1.2.3/setup.py" in names
assert "with-include-1.2.3/PKG-INFO" in names
with tarfile.open(str(sdist), "r") as tar:
names = tar.getnames()
assert "with-include-1.2.3/LICENSE" in names
assert "with-include-1.2.3/README.rst" in names
assert "with-include-1.2.3/extra_dir/__init__.py" in names
assert "with-include-1.2.3/extra_dir/vcs_excluded.txt" in names
assert "with-include-1.2.3/extra_dir/sub_pkg/__init__.py" in names
assert "with-include-1.2.3/extra_dir/sub_pkg/vcs_excluded.txt" not in names
assert "with-include-1.2.3/my_module.py" in names
assert "with-include-1.2.3/notes.txt" in names
assert "with-include-1.2.3/package_with_include/__init__.py" in names
assert "with-include-1.2.3/pyproject.toml" in names
assert "with-include-1.2.3/setup.py" in names
assert "with-include-1.2.3/PKG-INFO" in names
def test_proper_python_requires_if_single_version_specified():
......
......@@ -35,9 +35,8 @@ def test_wheel_module():
assert whl.exists()
z = zipfile.ZipFile(str(whl))
assert "module1.py" in z.namelist()
with zipfile.ZipFile(str(whl)) as z:
assert "module1.py" in z.namelist()
def test_wheel_package():
......@@ -48,9 +47,8 @@ def test_wheel_package():
assert whl.exists()
z = zipfile.ZipFile(str(whl))
assert "my_package/sub_pkg1/__init__.py" in z.namelist()
with zipfile.ZipFile(str(whl)) as z:
assert "my_package/sub_pkg1/__init__.py" in z.namelist()
def test_wheel_prerelease():
......@@ -70,10 +68,9 @@ def test_wheel_package_src():
assert whl.exists()
z = zipfile.ZipFile(str(whl))
assert "package_src/__init__.py" in z.namelist()
assert "package_src/module.py" in z.namelist()
with zipfile.ZipFile(str(whl)) as z:
assert "package_src/__init__.py" in z.namelist()
assert "package_src/module.py" in z.namelist()
def test_wheel_module_src():
......@@ -84,6 +81,44 @@ def test_wheel_module_src():
assert whl.exists()
z = zipfile.ZipFile(str(whl))
with zipfile.ZipFile(str(whl)) as z:
assert "module_src.py" in z.namelist()
def test_package_with_include(mocker):
# Patch git module to return specific excluded files
p = mocker.patch("poetry.vcs.git.Git.get_ignored_files")
p.return_value = [
str(
Path(__file__).parent
/ "fixtures"
/ "with-include"
/ "extra_dir"
/ "vcs_excluded.txt"
),
str(
Path(__file__).parent
/ "fixtures"
/ "with-include"
/ "extra_dir"
/ "sub_pkg"
/ "vcs_excluded.txt"
),
]
module_path = fixtures_dir / "with-include"
WheelBuilder.make(Poetry.create(str(module_path)), NullVenv(), NullIO())
whl = module_path / "dist" / "with_include-1.2.3-py3-none-any.whl"
assert whl.exists()
assert "module_src.py" in z.namelist()
with zipfile.ZipFile(str(whl)) as z:
names = z.namelist()
assert "with_include-1.2.3.dist-info/LICENSE" in names
assert "extra_dir/__init__.py" in names
assert "extra_dir/vcs_excluded.txt" in names
assert "extra_dir/sub_pkg/__init__.py" in names
assert "extra_dir/sub_pkg/vcs_excluded.txt" not in names
assert "my_module.py" in names
assert "notes.txt" in names
assert "package_with_include/__init__.py" in names
{
"info": {
"author": "Timothy Crosley",
"author_email": "timothy.crosley@gmail.com",
"bugtrack_url": null,
"classifiers": [
"Development Status :: 6 - Mature",
"Environment :: Console",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Natural Language :: English",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Libraries",
"Topic :: Utilities"
],
"description": "",
"description_content_type": null,
"docs_url": null,
"download_url": "",
"downloads": {
"last_day": -1,
"last_month": -1,
"last_week": -1
},
"home_page": "https://github.com/timothycrosley/isort",
"keywords": "Refactor",
"license": "MIT",
"maintainer": "",
"maintainer_email": "",
"name": "isort",
"package_url": "https://pypi.org/project/isort/",
"platform": "",
"project_url": "https://pypi.org/project/isort/",
"project_urls": {
"Homepage": "https://github.com/timothycrosley/isort"
},
"release_url": "https://pypi.org/project/isort/4.3.4/",
"requires_dist": null,
"requires_python": "",
"summary": "A Python utility / library to sort Python imports.",
"version": "4.3.4"
},
"last_serial": 3575149,
"releases": {
"4.3.4": [
{
"comment_text": "",
"digests": {
"md5": "f0ad7704b6dc947073398ba290c3517f",
"sha256": "ec9ef8f4a9bc6f71eec99e1806bfa2de401650d996c59330782b89a5555c1497"
},
"downloads": -1,
"filename": "isort-4.3.4-py2-none-any.whl",
"has_sig": false,
"md5_digest": "f0ad7704b6dc947073398ba290c3517f",
"packagetype": "bdist_wheel",
"python_version": "2.7",
"requires_python": null,
"size": 45393,
"upload_time": "2018-02-12T15:06:38",
"url": "https://files.pythonhosted.org/packages/41/d8/a945da414f2adc1d9e2f7d6e7445b27f2be42766879062a2e63616ad4199/isort-4.3.4-py2-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "fbaac4cd669ac21ea9e21ab1ea3180db",
"sha256": "1153601da39a25b14ddc54955dbbacbb6b2d19135386699e2ad58517953b34af"
},
"downloads": -1,
"filename": "isort-4.3.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "fbaac4cd669ac21ea9e21ab1ea3180db",
"packagetype": "bdist_wheel",
"python_version": "3.6",
"requires_python": null,
"size": 45352,
"upload_time": "2018-02-12T15:06:20",
"url": "https://files.pythonhosted.org/packages/1f/2c/22eee714d7199ae0464beda6ad5fedec8fee6a2f7ffd1e8f1840928fe318/isort-4.3.4-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "fb554e9c8f9aa76e333a03d470a5cf52",
"sha256": "b9c40e9750f3d77e6e4d441d8b0266cf555e7cdabdcff33c4fd06366ca761ef8"
},
"downloads": -1,
"filename": "isort-4.3.4.tar.gz",
"has_sig": false,
"md5_digest": "fb554e9c8f9aa76e333a03d470a5cf52",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 56070,
"upload_time": "2018-02-12T15:06:16",
"url": "https://files.pythonhosted.org/packages/b1/de/a628d16fdba0d38cafb3d7e34d4830f2c9cb3881384ce5c08c44762e1846/isort-4.3.4.tar.gz"
}
]
},
"urls": [
{
"comment_text": "",
"digests": {
"md5": "f0ad7704b6dc947073398ba290c3517f",
"sha256": "ec9ef8f4a9bc6f71eec99e1806bfa2de401650d996c59330782b89a5555c1497"
},
"downloads": -1,
"filename": "isort-4.3.4-py2-none-any.whl",
"has_sig": false,
"md5_digest": "f0ad7704b6dc947073398ba290c3517f",
"packagetype": "bdist_wheel",
"python_version": "2.7",
"requires_python": null,
"size": 45393,
"upload_time": "2018-02-12T15:06:38",
"url": "https://files.pythonhosted.org/packages/41/d8/a945da414f2adc1d9e2f7d6e7445b27f2be42766879062a2e63616ad4199/isort-4.3.4-py2-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "fbaac4cd669ac21ea9e21ab1ea3180db",
"sha256": "1153601da39a25b14ddc54955dbbacbb6b2d19135386699e2ad58517953b34af"
},
"downloads": -1,
"filename": "isort-4.3.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "fbaac4cd669ac21ea9e21ab1ea3180db",
"packagetype": "bdist_wheel",
"python_version": "3.6",
"requires_python": null,
"size": 45352,
"upload_time": "2018-02-12T15:06:20",
"url": "https://files.pythonhosted.org/packages/1f/2c/22eee714d7199ae0464beda6ad5fedec8fee6a2f7ffd1e8f1840928fe318/isort-4.3.4-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "fb554e9c8f9aa76e333a03d470a5cf52",
"sha256": "b9c40e9750f3d77e6e4d441d8b0266cf555e7cdabdcff33c4fd06366ca761ef8"
},
"downloads": -1,
"filename": "isort-4.3.4.tar.gz",
"has_sig": false,
"md5_digest": "fb554e9c8f9aa76e333a03d470a5cf52",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 56070,
"upload_time": "2018-02-12T15:06:16",
"url": "https://files.pythonhosted.org/packages/b1/de/a628d16fdba0d38cafb3d7e34d4830f2c9cb3881384ce5c08c44762e1846/isort-4.3.4.tar.gz"
}
]
}
{
"info": {
"author": "Jupyter Development Team",
"author_email": "jupyter@googlegroups.org",
"bugtrack_url": null,
"classifiers": [
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"Intended Audience :: System Administrators",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4"
],
"description": "Install the Jupyter system, including the notebook, qtconsole, and the IPython kernel.",
"description_content_type": null,
"docs_url": null,
"download_url": "UNKNOWN",
"downloads": {
"last_day": -1,
"last_month": -1,
"last_week": -1
},
"home_page": "http://jupyter.org",
"keywords": null,
"license": "BSD",
"maintainer": null,
"maintainer_email": null,
"name": "jupyter",
"package_url": "https://pypi.org/project/jupyter/",
"platform": "UNKNOWN",
"project_url": "https://pypi.org/project/jupyter/",
"project_urls": {
"Download": "UNKNOWN",
"Homepage": "http://jupyter.org"
},
"release_url": "https://pypi.org/project/jupyter/1.0.0/",
"requires_dist": null,
"requires_python": null,
"summary": "Jupyter metapackage. Install all the Jupyter components in one go.",
"version": "1.0.0"
},
"last_serial": 1673841,
"releases": {
"0.0.0": [],
"1.0.0": [
{
"comment_text": "",
"digests": {
"md5": "f81d039e084c2c0c4da9e4a86446b863",
"sha256": "5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78"
},
"downloads": -1,
"filename": "jupyter-1.0.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "f81d039e084c2c0c4da9e4a86446b863",
"packagetype": "bdist_wheel",
"python_version": "3.4",
"requires_python": null,
"size": 2736,
"upload_time": "2015-08-12T00:42:58",
"url": "https://files.pythonhosted.org/packages/83/df/0f5dd132200728a86190397e1ea87cd76244e42d39ec5e88efd25b2abd7e/jupyter-1.0.0-py2.py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "c6030444c7eb6c05a4d7b1768c72aed7",
"sha256": "d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f"
},
"downloads": -1,
"filename": "jupyter-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "c6030444c7eb6c05a4d7b1768c72aed7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 12916,
"upload_time": "2015-08-12T00:43:08",
"url": "https://files.pythonhosted.org/packages/c9/a9/371d0b8fe37dd231cf4b2cff0a9f0f25e98f3a73c3771742444be27f2944/jupyter-1.0.0.tar.gz"
},
{
"comment_text": "",
"digests": {
"md5": "25142b08e2ad7142b6f920bc8cc8dfeb",
"sha256": "3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7"
},
"downloads": -1,
"filename": "jupyter-1.0.0.zip",
"has_sig": false,
"md5_digest": "25142b08e2ad7142b6f920bc8cc8dfeb",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 16690,
"upload_time": "2015-08-12T00:43:12",
"url": "https://files.pythonhosted.org/packages/fc/21/a372b73e3a498b41b92ed915ada7de2ad5e16631546329c03e484c3bf4e9/jupyter-1.0.0.zip"
}
]
},
"urls": [
{
"comment_text": "",
"digests": {
"md5": "f81d039e084c2c0c4da9e4a86446b863",
"sha256": "5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78"
},
"downloads": -1,
"filename": "jupyter-1.0.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "f81d039e084c2c0c4da9e4a86446b863",
"packagetype": "bdist_wheel",
"python_version": "3.4",
"requires_python": null,
"size": 2736,
"upload_time": "2015-08-12T00:42:58",
"url": "https://files.pythonhosted.org/packages/83/df/0f5dd132200728a86190397e1ea87cd76244e42d39ec5e88efd25b2abd7e/jupyter-1.0.0-py2.py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "c6030444c7eb6c05a4d7b1768c72aed7",
"sha256": "d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f"
},
"downloads": -1,
"filename": "jupyter-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "c6030444c7eb6c05a4d7b1768c72aed7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 12916,
"upload_time": "2015-08-12T00:43:08",
"url": "https://files.pythonhosted.org/packages/c9/a9/371d0b8fe37dd231cf4b2cff0a9f0f25e98f3a73c3771742444be27f2944/jupyter-1.0.0.tar.gz"
},
{
"comment_text": "",
"digests": {
"md5": "25142b08e2ad7142b6f920bc8cc8dfeb",
"sha256": "3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7"
},
"downloads": -1,
"filename": "jupyter-1.0.0.zip",
"has_sig": false,
"md5_digest": "25142b08e2ad7142b6f920bc8cc8dfeb",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 16690,
"upload_time": "2015-08-12T00:43:12",
"url": "https://files.pythonhosted.org/packages/fc/21/a372b73e3a498b41b92ed915ada7de2ad5e16631546329c03e484c3bf4e9/jupyter-1.0.0.zip"
}
]
}
import json
import shutil
from poetry.repositories.pypi_repository import PyPiRepository
from poetry.utils._compat import Path
......@@ -6,11 +7,12 @@ from poetry.utils._compat import Path
class MockRepository(PyPiRepository):
FIXTURES = Path(__file__).parent / "fixtures" / "pypi.org" / "json"
JSON_FIXTURES = Path(__file__).parent / "fixtures" / "pypi.org" / "json"
DIST_FIXTURES = Path(__file__).parent / "fixtures" / "pypi.org" / "dists"
def __init__(self):
def __init__(self, fallback=False):
super(MockRepository, self).__init__(
url="http://foo.bar", disable_cache=True, fallback=False
url="http://foo.bar", disable_cache=True, fallback=fallback
)
def _get(self, url):
......@@ -22,15 +24,22 @@ class MockRepository(PyPiRepository):
version = None
if not version:
fixture = self.FIXTURES / (name + ".json")
fixture = self.JSON_FIXTURES / (name + ".json")
else:
fixture = self.FIXTURES / name / (version + ".json")
fixture = self.JSON_FIXTURES / name / (version + ".json")
if not fixture.exists():
fixture = self.FIXTURES / (name + ".json")
fixture = self.JSON_FIXTURES / (name + ".json")
with fixture.open() as f:
return json.loads(f.read())
def _download(self, url, dest):
filename = url.split("/")[-1]
fixture = self.DIST_FIXTURES / filename
shutil.copyfile(str(fixture), dest)
def test_find_packages():
repo = MockRepository()
......@@ -60,3 +69,35 @@ def test_package():
assert win_inet.name == "win-inet-pton"
assert win_inet.python_versions == "~2.7 || ~2.6"
assert win_inet.platform == "win32"
def test_fallback_on_downloading_packages():
repo = MockRepository(fallback=True)
package = repo.package("jupyter", "1.0.0")
assert package.name == "jupyter"
assert len(package.requires) == 6
dependency_names = sorted([dep.name for dep in package.requires])
assert dependency_names == [
"ipykernel",
"ipywidgets",
"jupyter-console",
"nbconvert",
"notebook",
"qtconsole",
]
def test_fallback_inspects_sdist_first_if_no_matching_wheels_can_be_found():
repo = MockRepository(fallback=True)
package = repo.package("isort", "4.3.4")
assert package.name == "isort"
assert len(package.requires) == 1
dep = package.requires[0]
assert dep.name == "futures"
assert dep.python_versions == "~2.7"
......@@ -22,7 +22,7 @@ from poetry.semver import VersionUnion
("=1.2.3", Version(1, 2, 3)),
("1.2.3", Version(1, 2, 3)),
("=1.0", Version(1, 0, 0)),
("1.2.3b5", Version(1, 2, 3, "b5")),
("1.2.3b5", Version(1, 2, 3, pre="b5")),
(">= 1.2.3", VersionRange(min=Version(1, 2, 3), include_min=True)),
(">dev", VersionRange(min=Version(0, 0, pre="dev"))), # Issue 206
],
......@@ -59,8 +59,11 @@ def test_parse_constraint_wildcard(input, constraint):
("~1.0.0", VersionRange(Version(1, 0, 0), Version(1, 1, 0), True)),
("~1.2", VersionRange(Version(1, 2, 0), Version(1, 3, 0), True)),
("~1.2.3", VersionRange(Version(1, 2, 3), Version(1, 3, 0), True)),
("~1.2-beta", VersionRange(Version(1, 2, 0, "beta"), Version(1, 3, 0), True)),
("~1.2-b2", VersionRange(Version(1, 2, 0, "b2"), Version(1, 3, 0), True)),
(
"~1.2-beta",
VersionRange(Version(1, 2, 0, pre="beta"), Version(1, 3, 0), True),
),
("~1.2-b2", VersionRange(Version(1, 2, 0, pre="b2"), Version(1, 3, 0), True)),
("~0.3", VersionRange(Version(0, 3, 0), Version(0, 4, 0), True)),
("~3.5", VersionRange(Version(3, 5, 0), Version(3, 6, 0), True)),
("~=3.5", VersionRange(Version(3, 5, 0), Version(4, 0, 0), True)), # PEP 440
......@@ -80,7 +83,7 @@ def test_parse_constraint_tilde(input, constraint):
("^1.2", VersionRange(Version(1, 2, 0), Version(2, 0, 0), True)),
(
"^1.2.3-beta.2",
VersionRange(Version(1, 2, 3, "beta.2"), Version(2, 0, 0), True),
VersionRange(Version(1, 2, 3, pre="beta.2"), Version(2, 0, 0), True),
),
("^1.2.3", VersionRange(Version(1, 2, 3), Version(2, 0, 0), True)),
("^0.2.3", VersionRange(Version(0, 2, 3), Version(0, 3, 0), True)),
......@@ -173,3 +176,21 @@ def test_parse_constraints_negative_wildcard(input, constraint):
)
def test_constraints_keep_version_precision(input, expected):
assert str(parse_constraint(input)) == expected
@pytest.mark.parametrize(
"unsorted, sorted_",
[
(["1.0.3", "1.0.2", "1.0.1"], ["1.0.1", "1.0.2", "1.0.3"]),
(["1.0.0.2", "1.0.0.0rc2"], ["1.0.0.0rc2", "1.0.0.2"]),
(["1.0.0.0", "1.0.0.0rc2"], ["1.0.0.0rc2", "1.0.0.0"]),
(["1.0.0.0.0", "1.0.0.0rc2"], ["1.0.0.0rc2", "1.0.0.0.0"]),
(["1.0.0rc2", "1.0.0rc1"], ["1.0.0rc1", "1.0.0rc2"]),
(["1.0.0rc2", "1.0.0b1"], ["1.0.0b1", "1.0.0rc2"]),
],
)
def test_versions_are_sortable(unsorted, sorted_):
unsorted = [parse_constraint(u) for u in unsorted]
sorted_ = [parse_constraint(s) for s in sorted_]
assert sorted(unsorted) == sorted_
......@@ -11,18 +11,18 @@ from poetry.semver import VersionRange
("1.0.0", Version(1, 0, 0)),
("1", Version(1, 0, 0)),
("1.0", Version(1, 0, 0)),
("1b1", Version(1, 0, 0, "beta1")),
("1.0b1", Version(1, 0, 0, "beta1")),
("1.0.0b1", Version(1, 0, 0, "beta1")),
("1.0.0-b1", Version(1, 0, 0, "beta1")),
("1.0.0-beta.1", Version(1, 0, 0, "beta1")),
("1.0.0+1", Version(1, 0, 0, None, "1")),
("1.0.0-1", Version(1, 0, 0, None, "1")),
("1b1", Version(1, 0, 0, pre="beta1")),
("1.0b1", Version(1, 0, 0, pre="beta1")),
("1.0.0b1", Version(1, 0, 0, pre="beta1")),
("1.0.0-b1", Version(1, 0, 0, pre="beta1")),
("1.0.0-beta.1", Version(1, 0, 0, pre="beta1")),
("1.0.0+1", Version(1, 0, 0, build="1")),
("1.0.0-1", Version(1, 0, 0, build="1")),
("1.0.0.0", Version(1, 0, 0)),
("1.0.0-post", Version(1, 0, 0)),
("1.0.0-post1", Version(1, 0, 0, None, "1")),
("0.6c", Version(0, 6, 0, "rc0")),
("0.6pre", Version(0, 6, 0, "rc0")),
("1.0.0-post1", Version(1, 0, 0, build="1")),
("0.6c", Version(0, 6, 0, pre="rc0")),
("0.6pre", Version(0, 6, 0, pre="rc0")),
],
)
def test_parse_valid(input, version):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment