Commit 4fa0dcee by Sébastien Eustace

Merge branch 'master' into develop

parents 1cc05e18 6065675d
......@@ -20,16 +20,17 @@ script: pytest -q tests/
jobs:
include:
- python: '2.7'
- python: '3.5'
- python: '3.6'
- python: '3.7'
dist: xenial
sudo: true
- stage: linting
python: '3.6'
install:
- pip install pre-commit
- pre-commit install-hooks
script:
- pre-commit run --all-files
- python: "2.7"
- python: "3.4"
- python: "3.5"
- python: "3.6"
- python: "3.7"
dist: xenial
- stage: linting
python: "3.6"
install:
- pip install pre-commit
- pre-commit install-hooks
script:
- pre-commit run --all-files
......@@ -102,7 +102,7 @@ $ poetry run pytest tests/
Poetry uses the [black](https://github.com/ambv/black) coding style and you must ensure that your
code follows it. If not, the CI will fail and your Pull Request will not be merged.
To make sure that you don't accidently commit code that does not follow the coding style, you can
To make sure that you don't accidentally commit code that does not follow the coding style, you can
install a pre-commit hook that will check that everything is in order:
```bash
......@@ -117,4 +117,3 @@ will not be merged.
* Fill in [the required template](https://github.com/sdispater/poetry/blob/master/.github/PULL_REQUEST_TEMPLATE.md)
* Be sure that you pull request contains tests that cover the changed or added code.
* If you changes warrant a documentation change, the pull request must also update the documentation.
......@@ -177,7 +177,7 @@ that I don't like.
#### Dependency resolution
The dependency resolution is erratic and will fail even is there is a solution. Let's take an example:
The dependency resolution is erratic and will fail even if there is a solution. Let's take an example:
```bash
pipenv install oslo.utils==1.4.0
......
# Basic usage
For the basic usage introduction we will be installing `pendulum`, a datetime library.
If you have not yet installed Poetry, refer to the [Introduction](/) chapter.
If you have not yet installed Poetry, refer to the [Introduction](/docs/) chapter.
## Project setup
......@@ -21,7 +21,7 @@ poetry-demo
│ └── __init__.py
└── tests
├── __init__.py
└── test_poetry_demo
└── test_poetry_demo.py
```
The `pyproject.toml` file is what is the most important here. This will orchestrate
......@@ -69,7 +69,7 @@ It will automatically find a suitable version constraint.
In our example, we are requesting the `pendulum` package with the version constraint `^1.4`.
This means any version greater or equal to 1.4.0 and less than 2.0.0 (`>=1.4.0 <2.0.0`).
Please read [versions](/versions/) for more in-depth information on versions, how versions relate to each other, and on version constraints.
Please read [versions](/docs/versions/) for more in-depth information on versions, how versions relate to each other, and on version constraints.
!!!note
......
......@@ -281,7 +281,7 @@ poetry config [options] [setting-key] [setting-value1] ... [setting-valueN]
````
`setting-key` is a configuration option name and `setting-value1` is a configuration value.
See [Configuration](/configuration/) for all available settings.
See [Configuration](/docs/configuration/) for all available settings.
### Options
......@@ -313,10 +313,21 @@ poetry run my-script
Note that this command has no option.
## shell
The `shell` command spawns a shell,
according to the `$SHELL` environment variable,
within the virtual environment.
If one doesn't exist yet, it will be created.
```bash
poetry shell
```
## check
The `check` command validate the structure of the `pyproject.toml` file
and returns a detailed report is there are any errors.
and returns a detailed report if there are any errors.
```bash
poetry check
......
# Configuration
Poetry can be configured via the `config` command ([see more about its usage here](/cli/#config))
Poetry can be configured via the `config` command ([see more about its usage here](/docs/cli/#config))
or directly in the `config.toml` file that will be automatically be created when you first run that command.
This file can typically be found in one of the following directories:
......@@ -10,18 +10,20 @@ This file can typically be found in one of the following directories:
For Unix, we follow the XDG spec and support `$XDG_CONFIG_HOME`.
That means, by default `~/.config/pypoetry`
## Available settings
### `settings.virtualenvs.create`: boolean
Create a new virtualenv if one doesn't already exist.
Defaults to `true`.
### `settings.virtualenvs.in-project`: boolean
Create the virtualenv inside the project's root directory.
Defaults to `false`.
### `settings.virtualenvs.path`: string
Directory where virtualenvs will be created.
Defaults to one of the following directories:
......@@ -29,5 +31,6 @@ Defaults to one of the following directories:
- Windows: `C:\Users\<username>\AppData\Local\pypoetry\Cache/virtualenvs`
- Unix: `~/.cache/pypoetry/virtualenvs`
### `repository.<name>`: string
Set a new alternative repository. See [Repositories](/repositories/) for more information.
### `repositories.<name>`: string
Set a new alternative repository. See [Repositories](/docs/repositories/) for more information.
......@@ -14,7 +14,7 @@ While Poetry does not enforce any convention regarding package versioning,
it **strongly** recommends to follow [semantic versioning](https://semver.org).
This has many advantages for the end users and allows them to set appropriate
[version constraints](/versions/).
[version constraints](/docs/versions/).
## Lock file
......@@ -54,7 +54,7 @@ poetry publish
```
This will package and publish the library to PyPI, at the condition that you are a registered user
and you have [configured your credentials](/repositories/#adding-credentials) properly.
and you have [configured your credentials](/docs/repositories/#adding-credentials) properly.
!!!note
......@@ -73,7 +73,7 @@ Sometimes, you may want to keep your library private but also being accessible t
In this case, you will need to use a private repository.
In order to publish to a private repository, you will need to add it to your
global list of repositories. See [Adding a repository](/repositories/#adding-a-repository)
global list of repositories. See [Adding a repository](/docs/repositories/#adding-a-repository)
for more information.
Once this is done, you can actually publish to it like so:
......
......@@ -68,6 +68,25 @@ An URL to the documentation of the project. **Optional**
A list of keywords (max: 5) that the package is related to. **Optional**
## classifiers
A list of PyPI [trove classifiers](https://pypi.org/classifiers/) that describe the project. **Optional**
```toml
[tool.poetry]
# ...
classifiers = [
"Topic :: Software Development :: Build Tools",
"Topic :: Software Development :: Libraries :: Python Modules"
]
```
!!!note
Note that Python classifiers are still automatically added for you and are determined by your `python` requirement.
The `license` property will also set the License classifier automatically.
## packages
A list of packages and modules to include in the final distribution.
......@@ -207,7 +226,7 @@ poetry install -E mysql -E pgsql
## `plugins`
Poetry supports arbitrary plugins wich work similarly to
Poetry supports arbitrary plugins which work similarly to
[setuptools entry points](http://setuptools.readthedocs.io/en/latest/setuptools.html).
To match the example in the setuptools documentation, you would use the following:
......
{%- if nav_item.url %}
<a class="{% if nav_item.active%}current{%endif%}" href="{{ nav_item.url }}">{{ nav_item.title }}</a>
<a class="{% if nav_item.active%}current{%endif%}" href="{{ base_url }}/{{ nav_item.url }}">{{ nav_item.title }}</a>
{%- else %}
<span class="caption-text">{{ nav_item.title }}</span>
<span class="caption-text">{{ nav_item.title }}</span>
{%- endif %}
{%- if nav_item == page or nav_item.children %}
<ul class="subnav">
{%- if nav_item == page %}
{% include 'toc.html' %}
{%- endif %}
{%- if nav_item.children %}
{%- set navlevel = navlevel + 1%}
{%- for nav_item in nav_item.children %}
<li class="{% if navlevel > 2 %}toctree-l{{ navlevel }}{% endif %}{% if nav_item.active%} current{%endif%}">
{% include 'nav.html' %}
</li>
{%- endfor %}
{%- set navlevel = navlevel - 1%}
{%- endif %}
</ul>
<ul class="subnav">
{%- if nav_item == page %}
{% include 'toc.html' %}
{%- endif %}
{%- if nav_item.children %}
{%- set navlevel = navlevel + 1%}
{%- for nav_item in nav_item.children %}
<li class="{% if navlevel > 2 %}toctree-l{{ navlevel }}{% endif %}{% if nav_item.active%} current{%endif%}">
{% include 'nav.html' %}
</li>
{%- endfor %}
{%- set navlevel = navlevel - 1%}
{%- endif %}
</ul>
{%- endif %}
{% for toc_item in page.toc %}
<!--<li class="toctree-l{{ navlevel + 1 }}"><a href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>-->
{% if toc_item.children %}
<ul>
{% for toc_item in toc_item.children %}
<li><a class="toctree-l{{ navlevel + 2 }}" href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
<!--<li class="toctree-l{{ navlevel + 1 }}"><a href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>-->
{% if toc_item.children %}
<ul>
{% for toc_item in toc_item.children %}
<li><a class="toctree-l{{ navlevel + 2 }}" href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
......@@ -275,13 +275,13 @@ class Installer:
CURRENT_PYTHON_VERSION = sys.version_info[:2]
METADATA_URL = "https://pypi.org/pypi/poetry/json"
VERSION_REGEX = re.compile(
"v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?"
r"v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?"
"("
"[._-]?"
"(?:(stable|beta|b|RC|alpha|a|patch|pl|p)((?:[.-]?\d+)*)?)?"
r"(?:(stable|beta|b|RC|alpha|a|patch|pl|p)((?:[.-]?\d+)*)?)?"
"([.-]?dev)?"
")?"
"(?:\+[^\s]+)?"
r"(?:\+[^\s]+)?"
)
BASE_URL = "https://github.com/sdispater/poetry/releases/download/"
......
......@@ -148,12 +148,12 @@ class Application(BaseApplication):
formatter = o.get_formatter()
lines = []
for line in re.split("\r?\n", str(e)):
for line in re.split(r"\r?\n", str(e)):
for splitline in [
line[x : x + (width - 4)] for x in range(0, len(line), width - 4)
]:
line_length = (
len(re.sub("\[[^m]*m", "", formatter.format(splitline))) + 4
len(re.sub(r"\[[^m]*m", "", formatter.format(splitline))) + 4
)
lines.append((splitline, line_length))
......
......@@ -102,7 +102,7 @@ To remove a repository (repo is a short alias for repositories):
# show the value if no value is provided
if not self.argument("value") and not self.option("unset"):
m = re.match("^repos?(?:itories)?(?:\.(.+))?", self.argument("key"))
m = re.match(r"^repos?(?:itories)?(?:\.(.+))?", self.argument("key"))
if m:
if not m.group(1):
value = {}
......@@ -144,7 +144,7 @@ To remove a repository (repo is a short alias for repositories):
)
# handle repositories
m = re.match("^repos?(?:itories)?(?:\.(.+))?", self.argument("key"))
m = re.match(r"^repos?(?:itories)?(?:\.(.+))?", self.argument("key"))
if m:
if not m.group(1):
raise ValueError("You cannot remove the [repositories] section")
......@@ -173,7 +173,7 @@ To remove a repository (repo is a short alias for repositories):
)
# handle auth
m = re.match("^(http-basic)\.(.+)", self.argument("key"))
m = re.match(r"^(http-basic)\.(.+)", self.argument("key"))
if m:
if self.option("unset"):
if not self._auth_config.setting(
......@@ -278,7 +278,7 @@ To remove a repository (repo is a short alias for repositories):
if k is None:
k = ""
k += re.sub("^config\.", "", key + ".")
k += re.sub(r"^config\.", "", key + ".")
if setting and len(setting) > 1:
setting = ".".join(setting.split(".")[1:])
......
......@@ -40,10 +40,10 @@ class PipInstaller(BaseInstaller):
if parsed.scheme == "http":
self._io.write_error(
" <warning>Installing from unsecure host: {}</warning>".format(
parsed.netloc
parsed.hostname
)
)
args += ["--trusted-host", parsed.netloc]
args += ["--trusted-host", parsed.hostname]
auth = get_http_basic_auth(package.source_reference)
if auth:
......
......@@ -15,7 +15,7 @@ from ..utils.module import Module
from ..utils.package_include import PackageInclude
AUTHOR_REGEX = re.compile("(?u)^(?P<name>[- .,\w\d'’\"()]+) <(?P<email>.+?)>$")
AUTHOR_REGEX = re.compile(r"(?u)^(?P<name>[- .,\w\d'’\"()]+) <(?P<email>.+?)>$")
class Builder(object):
......
......@@ -302,7 +302,7 @@ class SdistBuilder(Builder):
):
main = []
extras = defaultdict(list)
req_regex = re.compile("^(.+) \((.+)\)$")
req_regex = re.compile(r"^(.+) \((.+)\)$")
for dependency in dependencies:
if dependency.is_optional():
......
......@@ -184,8 +184,8 @@ class WheelBuilder(Builder):
@property
def wheel_filename(self): # type: () -> str
return "{}-{}-{}.whl".format(
re.sub("[^\w\d.]+", "_", self._package.pretty_name, flags=re.UNICODE),
re.sub("[^\w\d.]+", "_", self._meta.version, flags=re.UNICODE),
re.sub(r"[^\w\d.]+", "_", self._package.pretty_name, flags=re.UNICODE),
re.sub(r"[^\w\d.]+", "_", self._meta.version, flags=re.UNICODE),
self.tag,
)
......@@ -195,8 +195,8 @@ class WheelBuilder(Builder):
)
def dist_info_name(self, distribution, version): # type: (...) -> str
escaped_name = re.sub("[^\w\d.]+", "_", distribution, flags=re.UNICODE)
escaped_version = re.sub("[^\w\d.]+", "_", version, flags=re.UNICODE)
escaped_name = re.sub(r"[^\w\d.]+", "_", distribution, flags=re.UNICODE)
escaped_version = re.sub(r"[^\w\d.]+", "_", version, flags=re.UNICODE)
return "{}-{}.dist-info".format(escaped_name, escaped_version)
......@@ -301,7 +301,7 @@ class WheelBuilder(Builder):
fp.write("Version: {}\n".format(self._meta.version))
fp.write("Summary: {}\n".format(self._meta.summary))
fp.write("Home-page: {}\n".format(self._meta.home_page or "UNKNOWN"))
fp.write("License: {}\n".format(self._meta.license or "UNKOWN"))
fp.write("License: {}\n".format(self._meta.license or "UNKNOWN"))
# Optional fields
if self._meta.keywords:
......
......@@ -60,9 +60,9 @@ class Uploader:
dist.glob(
"{}-{}-*.whl".format(
re.sub(
"[^\w\d.]+", "_", self._package.pretty_name, flags=re.UNICODE
r"[^\w\d.]+", "_", self._package.pretty_name, flags=re.UNICODE
),
re.sub("[^\w\d.]+", "_", version, flags=re.UNICODE),
re.sub(r"[^\w\d.]+", "_", version, flags=re.UNICODE),
)
)
)
......
......@@ -64,7 +64,7 @@ def dependency_from_pep_508(name):
link = Link(path_to_url(os.path.normpath(os.path.abspath(link.path))))
# wheel file
if link.is_wheel:
m = re.match("^(?P<namever>(?P<name>.+?)-(?P<ver>\d.*?))", link.filename)
m = re.match(r"^(?P<namever>(?P<name>.+?)-(?P<ver>\d.*?))", link.filename)
if not m:
raise ValueError("Invalid wheel name: {}".format(link.filename))
......
......@@ -6,7 +6,7 @@ from .constraint import Constraint
class WilcardConstraint(Constraint):
def __init__(self, constraint): # type: (str) -> None
m = re.match(
"^(!= ?|==)?v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.[xX*])+$", constraint
r"^(!= ?|==)?v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.[xX*])+$", constraint
)
if not m:
raise ValueError("Invalid value for wildcard constraint")
......
......@@ -164,7 +164,7 @@ class Locker:
def _get_content_hash(self): # type: () -> str
"""
Returns the sha256 hash of the sorted content of the composer file.
Returns the sha256 hash of the sorted content of the pyproject file.
"""
content = self._local_config
......
......@@ -22,7 +22,7 @@ from .vcs_dependency import VCSDependency
from .utils.utils import convert_markers
from .utils.utils import create_nested_marker
AUTHOR_REGEX = re.compile("(?u)^(?P<name>[- .,\w\d'’\"()]+)(?: <(?P<email>.+?)>)?$")
AUTHOR_REGEX = re.compile(r"(?u)^(?P<name>[- .,\w\d'’\"()]+)(?: <(?P<email>.+?)>)?$")
class Package(object):
......
......@@ -559,8 +559,8 @@ class Provider:
if message.startswith("fact:"):
if "depends on" in message:
m = re.match("fact: (.+?) depends on (.+?) \((.+?)\)", message)
m2 = re.match("(.+?) \((.+?)\)", m.group(1))
m = re.match(r"fact: (.+?) depends on (.+?) \((.+?)\)", message)
m2 = re.match(r"(.+?) \((.+?)\)", m.group(1))
if m2:
name = m2.group(1)
version = " (<comment>{}</comment>)".format(m2.group(2))
......@@ -582,19 +582,19 @@ class Provider:
)
else:
message = re.sub(
"(?<=: )(.+?) \((.+?)\)",
r"(?<=: )(.+?) \((.+?)\)",
"<info>\\1</info> (<comment>\\2</comment>)",
message,
)
message = "<fg=blue>fact</>: {}".format(message.split("fact: ")[1])
elif message.startswith("selecting "):
message = re.sub(
"selecting (.+?) \((.+?)\)",
r"selecting (.+?) \((.+?)\)",
"<fg=blue>selecting</> <info>\\1</info> (<comment>\\2</comment>)",
message,
)
elif message.startswith("derived:"):
m = re.match("derived: (.+?) \((.+?)\)$", message)
m = re.match(r"derived: (.+?) \((.+?)\)$", message)
if m:
message = "<fg=blue>derived</>: <info>{}</info> (<comment>{}</comment>)".format(
m.group(1), m.group(2)
......@@ -604,9 +604,9 @@ class Provider:
message.split("derived: ")[1]
)
elif message.startswith("conflict:"):
m = re.match("conflict: (.+?) depends on (.+?) \((.+?)\)", message)
m = re.match(r"conflict: (.+?) depends on (.+?) \((.+?)\)", message)
if m:
m2 = re.match("(.+?) \((.+?)\)", m.group(1))
m2 = re.match(r"(.+?) \((.+?)\)", m.group(1))
if m2:
name = m2.group(1)
version = " (<comment>{}</comment>)".format(m2.group(2))
......
......@@ -46,7 +46,7 @@ from .pypi_repository import PyPiRepository
class Page:
VERSION_REGEX = re.compile("(?i)([a-z0-9_\-.]+?)-(?=\d)([a-z0-9_.!+-]+)")
VERSION_REGEX = re.compile(r"(?i)([a-z0-9_\-.]+?)-(?=\d)([a-z0-9_.!+-]+)")
SUPPORTED_FORMATS = [
".tar.gz",
".whl",
......@@ -309,6 +309,12 @@ class LegacyRepository(PyPiRepository):
}
links = list(page.links_for_version(Version.parse(version)))
if not links:
raise ValueError(
'No valid distribution links found for package: "{}" version: "{}"'.format(
name, version
)
)
urls = {}
hashes = []
default_link = links[0]
......
......@@ -306,7 +306,7 @@ class PyPiRepository(Repository):
# If bdist_wheel, check if it's universal
filename = url["filename"]
if not re.search("-py2\.py3-none-any.whl", filename):
if not re.search(r"-py2\.py3-none-any.whl", filename):
continue
urls[dist_type] = url["url"]
......
......@@ -16,7 +16,7 @@ def parse_constraint(constraints): # type: (str) -> VersionConstraint
if constraints == "*":
return VersionRange()
or_constraints = re.split("\s*\|\|?\s*", constraints.strip())
or_constraints = re.split(r"\s*\|\|?\s*", constraints.strip())
or_groups = []
for constraints in or_constraints:
and_constraints = re.split(
......@@ -46,7 +46,7 @@ def parse_constraint(constraints): # type: (str) -> VersionConstraint
def parse_single_constraint(constraint): # type: (str) -> VersionConstraint
m = re.match("(?i)^v?[xX*](\.[xX*])*$", constraint)
m = re.match(r"(?i)^v?[xX*](\.[xX*])*$", constraint)
if m:
return VersionRange()
......
......@@ -2,20 +2,20 @@ import re
MODIFIERS = (
"[._-]?"
"((?!post)(?:beta|b|c|pre|RC|alpha|a|patch|pl|p|dev)(?:(?:[.-]?\d+)*)?)?"
"([+-]?([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?"
r"((?!post)(?:beta|b|c|pre|RC|alpha|a|patch|pl|p|dev)(?:(?:[.-]?\d+)*)?)?"
r"([+-]?([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?"
)
_COMPLETE_VERSION = "v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?{}(?:\+[^\s]+)?".format(
_COMPLETE_VERSION = r"v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?{}(?:\+[^\s]+)?".format(
MODIFIERS
)
COMPLETE_VERSION = re.compile("(?i)" + _COMPLETE_VERSION)
CARET_CONSTRAINT = re.compile("(?i)^\^({})$".format(_COMPLETE_VERSION))
CARET_CONSTRAINT = re.compile(r"(?i)^\^({})$".format(_COMPLETE_VERSION))
TILDE_CONSTRAINT = re.compile("(?i)^~(?!=)({})$".format(_COMPLETE_VERSION))
TILDE_PEP440_CONSTRAINT = re.compile("(?i)^~=({})$".format(_COMPLETE_VERSION))
X_CONSTRAINT = re.compile("^(!=|==)?\s*v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.[xX*])+$")
X_CONSTRAINT = re.compile(r"^(!=|==)?\s*v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.[xX*])+$")
BASIC_CONSTRAINT = re.compile(
"(?i)^(<>|!=|>=?|<=?|==?)?\s*({}|dev)".format(_COMPLETE_VERSION)
r"(?i)^(<>|!=|>=?|<=?|==?)?\s*({}|dev)".format(_COMPLETE_VERSION)
)
......@@ -280,7 +280,7 @@ class Version(VersionRange):
if not pre:
return
m = re.match("(?i)^(a|alpha|b|beta|c|pre|rc|dev)[-.]?(\d+)?$", pre)
m = re.match(r"(?i)^(a|alpha|b|beta|c|pre|rc|dev)[-.]?(\d+)?$", pre)
if not m:
return
......
......@@ -64,7 +64,7 @@ def user_cache_dir(appname):
def user_data_dir(appname, roaming=False):
"""
r"""
Return full path to the user-specific data dir for this application.
"appname" is the name of application.
......@@ -84,8 +84,8 @@ def user_data_dir(appname, roaming=False):
...Application Data\<AppName>
Win XP (roaming): C:\Documents and Settings\<username>\Local ...
...Settings\Application Data\<AppName>
Win 7 (not roaming): C:\\Users\<username>\AppData\Local\<AppName>
Win 7 (roaming): C:\\Users\<username>\AppData\Roaming\<AppName>
Win 7 (not roaming): C:\Users\<username>\AppData\Local\<AppName>
Win 7 (roaming): C:\Users\<username>\AppData\Roaming\<AppName>
For Unix, we follow the XDG spec and support $XDG_DATA_HOME.
That means, by default "~/.local/share/<AppName>".
......@@ -137,7 +137,7 @@ def user_config_dir(appname, roaming=True):
# for the discussion regarding site_config_dirs locations
# see <https://github.com/pypa/pip/issues/1733>
def site_config_dirs(appname):
"""Return a list of potential user-shared config dirs for this application.
r"""Return a list of potential user-shared config dirs for this application.
"appname" is the name of application.
......
......@@ -12,7 +12,7 @@ _Version = namedtuple("_Version", ["epoch", "release", "dev", "pre", "post", "lo
VERSION_PATTERN = re.compile(
"""
r"""
^
v?
(?:
......
......@@ -75,7 +75,7 @@ def test_wheel_c_extension():
Wheel-Version: 1.0
Generator: poetry {}
Root-Is-Purelib: false
Tag: cp[23]\d-cp[23]\dmu?-.+
Tag: cp[23]\\d-cp[23]\\dmu?-.+
$""".format(
__version__
),
......
......@@ -7,6 +7,7 @@ from poetry.masonry.builders import WheelBuilder
from poetry.poetry import Poetry
from poetry.utils._compat import Path
from poetry.utils.env import NullEnv
from poetry.packages import ProjectPackage
fixtures_dir = Path(__file__).parent / "fixtures"
......@@ -123,3 +124,23 @@ def test_package_with_include(mocker):
assert "my_module.py" in names
assert "notes.txt" in names
assert "package_with_include/__init__.py" in names
def test_write_metadata_file_license_homepage_default(mocker):
# Preparation
mocked_poetry = mocker.Mock()
mocked_poetry.file.parent = Path(".")
mocked_poetry.package = ProjectPackage("pkg_name", "1.0.0")
mocked_file = mocker.Mock()
mocked_venv = mocker.Mock()
mocked_io = mocker.Mock()
# patch Module init inside Builder class
mocker.patch("poetry.masonry.builders.builder.Module")
w = WheelBuilder(mocked_poetry, mocked_venv, mocked_io)
# Action
w._write_metadata_file(mocked_file)
# Assertion
mocked_file.write.assert_any_call("Home-page: UNKNOWN\n")
mocked_file.write.assert_any_call("License: UNKNOWN\n")
<!DOCTYPE html>
<html>
<head>
<title>Links for poetry</title>
</head>
<body>
<h1>Links for poetry</h1>
<a href="poetry-0.1.0-py3-none-any.whl#sha256=1d85132efab8ead3c6f69202843da40a03823992091c29f8d65a31af68940163" data-requires-python="&gt;=3.6.0">poetry-0.1.0-py3-none-any.whl</a><br/>
</body>
</html>
<!--SERIAL 3907384-->
\ No newline at end of file
import pytest
from poetry.repositories.legacy_repository import LegacyRepository
from poetry.repositories.legacy_repository import Page
from poetry.utils._compat import Path
......@@ -48,3 +50,10 @@ def test_sdist_format_support():
bz2_links = list(filter(lambda link: link.ext == ".tar.bz2", page.links))
assert len(bz2_links) == 1
assert bz2_links[0].filename == "poetry-0.1.1.tar.bz2"
def test_missing_version(mocker):
repo = MockRepository()
with pytest.raises(ValueError):
repo._get_release_info("missing_version", "1.1.0")
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