Skip to content

Commit

Permalink
cherry-picked #3406 for v1.1
Browse files Browse the repository at this point in the history
Add PyPI registry correctly to pool depending on other sources (#3406)

In the event where we defined sources that were set as
secondary = True, we would end up with PyPI being after this source
when it should have acted as default in that case.

The main issue stems from the fact that it's not because you have
sources configured that PyPI should not be a default. Instead, PyPI
should be default if there are no sources with secondary = False and
not default if there are sources with secondary = True.
  • Loading branch information
tomzx authored and abn committed Jul 3, 2021
1 parent fff04c7 commit 7504b33
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 6 deletions.
13 changes: 7 additions & 6 deletions poetry/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,15 @@ def create_poetry(

poetry.pool.add_repository(repository, is_default, secondary=is_secondary)

# Always put PyPI last to prefer private repositories
# but only if we have no other default source
if not poetry.pool.has_default():
has_sources = bool(sources)
poetry.pool.add_repository(PyPiRepository(), not has_sources, has_sources)
else:
# Put PyPI last to prefer private repositories
# unless we have no default source AND no primary sources
# (default = false, secondary = false)
if poetry.pool.has_default():
if io.is_debug():
io.write_line("Deactivating the PyPI repository")
else:
default = not poetry.pool.has_primary_repositories()
poetry.pool.add_repository(PyPiRepository(), default, not default)

return poetry

Expand Down
5 changes: 5 additions & 0 deletions poetry/repositories/pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def __init__(
self._lookup = {} # type: Dict[str, int]
self._repositories = [] # type: List[Repository]
self._default = False
self._has_primary_repositories = False
self._secondary_start_idx = None

for repository in repositories:
Expand All @@ -38,6 +39,9 @@ def repositories(self): # type: () -> List[Repository]
def has_default(self): # type: () -> bool
return self._default

def has_primary_repositories(self): # type: () -> bool
return self._has_primary_repositories

def has_repository(self, name): # type: (str) -> bool
name = name.lower() if name is not None else None

Expand Down Expand Up @@ -81,6 +85,7 @@ def add_repository(
self._repositories.append(repository)
self._lookup[repository_name] = len(self._repositories) - 1
else:
self._has_primary_repositories = True
if self._secondary_start_idx is None:
self._repositories.append(repository)
self._lookup[repository_name] = len(self._repositories) - 1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[tool.poetry]
name = "my-package"
version = "1.2.3"
description = "Some description."
authors = [
"Your Name <[email protected]>"
]
license = "MIT"

# Requirements
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"

[tool.poetry.dev-dependencies]

[[tool.poetry.source]]
name = "foo"
url = "https://foo.bar/simple/"
secondary = true

[[tool.poetry.source]]
name = "bar"
url = "https://bar.baz/simple/"
secondary = true
23 changes: 23 additions & 0 deletions tests/fixtures/with_non_default_multiple_sources/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[tool.poetry]
name = "my-package"
version = "1.2.3"
description = "Some description."
authors = [
"Your Name <[email protected]>"
]
license = "MIT"

# Requirements
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"

[tool.poetry.dev-dependencies]

[[tool.poetry.source]]
name = "foo"
url = "https://foo.bar/simple/"
secondary = true

[[tool.poetry.source]]
name = "bar"
url = "https://bar.baz/simple/"
19 changes: 19 additions & 0 deletions tests/fixtures/with_non_default_secondary_source/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[tool.poetry]
name = "my-package"
version = "1.2.3"
description = "Some description."
authors = [
"Your Name <[email protected]>"
]
license = "MIT"

# Requirements
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"

[tool.poetry.dev-dependencies]

[[tool.poetry.source]]
name = "foo"
url = "https://foo.bar/simple/"
secondary = true
58 changes: 58 additions & 0 deletions tests/test_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,64 @@ def test_poetry_with_non_default_source():
assert isinstance(poetry.pool.repositories[1], PyPiRepository)


def test_poetry_with_non_default_secondary_source():
poetry = Factory().create_poetry(fixtures_dir / "with_non_default_secondary_source")

assert len(poetry.pool.repositories) == 2

assert poetry.pool.has_default()

repository = poetry.pool.repositories[0]
assert repository.name == "PyPI"
assert isinstance(repository, PyPiRepository)

repository = poetry.pool.repositories[1]
assert repository.name == "foo"
assert isinstance(repository, LegacyRepository)


def test_poetry_with_non_default_multiple_secondary_sources():
poetry = Factory().create_poetry(
fixtures_dir / "with_non_default_multiple_secondary_sources"
)

assert len(poetry.pool.repositories) == 3

assert poetry.pool.has_default()

repository = poetry.pool.repositories[0]
assert repository.name == "PyPI"
assert isinstance(repository, PyPiRepository)

repository = poetry.pool.repositories[1]
assert repository.name == "foo"
assert isinstance(repository, LegacyRepository)

repository = poetry.pool.repositories[2]
assert repository.name == "bar"
assert isinstance(repository, LegacyRepository)


def test_poetry_with_non_default_multiple_sources():
poetry = Factory().create_poetry(fixtures_dir / "with_non_default_multiple_sources")

assert len(poetry.pool.repositories) == 3

assert not poetry.pool.has_default()

repository = poetry.pool.repositories[0]
assert repository.name == "bar"
assert isinstance(repository, LegacyRepository)

repository = poetry.pool.repositories[1]
assert repository.name == "foo"
assert isinstance(repository, LegacyRepository)

repository = poetry.pool.repositories[2]
assert repository.name == "PyPI"
assert isinstance(repository, PyPiRepository)


def test_poetry_with_no_default_source():
poetry = Factory().create_poetry(fixtures_dir / "sample_project")

Expand Down

0 comments on commit 7504b33

Please sign in to comment.