Skip to content

Commit 8295c1d

Browse files
committed
info: enhance local path poetry project support
This change ensures that package inspection will handle rich core metadata available for poetry managed projects. This will allow, nested local path dependencies to use "develop" mode packages. Resolves: #3098
1 parent f2d53e5 commit 8295c1d

File tree

10 files changed

+147
-39
lines changed

10 files changed

+147
-39
lines changed

poetry/inspection/info.py

+9
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,15 @@ def to_package(
156156
package.python_versions = self.requires_python or "*"
157157
package.files = self.files
158158

159+
if root_dir or (self._source_type in {"directory"} and self._source_url):
160+
# this is a local poetry project, this means we can extract "richer" requirement information
161+
# eg: development requirements etc.
162+
poetry_package = self._get_poetry_package(path=root_dir or self._source_url)
163+
if poetry_package:
164+
package.extras = poetry_package.extras
165+
package.requires = poetry_package.requires
166+
return package
167+
159168
for req in self.requires_dist or []:
160169
try:
161170
# Attempt to parse the PEP-508 requirement string

tests/conftest.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,14 @@ def http():
141141

142142

143143
@pytest.fixture
144-
def fixture_dir():
144+
def fixture_base():
145+
return Path(__file__).parent / "fixtures"
146+
147+
148+
@pytest.fixture
149+
def fixture_dir(fixture_base):
145150
def _fixture_dir(name):
146-
return Path(__file__).parent / "fixtures" / name
151+
return fixture_base / name
147152

148153
return _fixture_dir
149154

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[tool.poetry]
2+
name = "bar"
3+
version = "1.2.3"
4+
description = "Some description."
5+
authors = ["Poetry Maintainer <[email protected]>"]
6+
license = "MIT"
7+
8+
# Requirements
9+
[tool.poetry.dependencies]
10+
python = "~2.7 || ^3.4"
11+
quix = { path = "../quix", develop = true }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[tool.poetry]
2+
name = "foo"
3+
version = "1.2.3"
4+
description = "Some description."
5+
authors = ["Poetry Maintainer <[email protected]>"]
6+
license = "MIT"
7+
8+
# Requirements
9+
[tool.poetry.dependencies]
10+
python = "~2.7 || ^3.4"
11+
bar = { path = "../bar", develop = true }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[tool.poetry]
2+
name = "project-with-nested-local"
3+
version = "1.2.3"
4+
description = "Some description."
5+
authors = ["Poetry Maintainer <[email protected]>"]
6+
license = "MIT"
7+
8+
# Requirements
9+
[tool.poetry.dependencies]
10+
python = "~2.7 || ^3.4"
11+
foo = { path = "./foo", develop = true }
12+
bar = { path = "./bar", develop = true }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[tool.poetry]
2+
name = "quix"
3+
version = "1.2.3"
4+
description = "Some description."
5+
authors = ["Poetry Maintainer <[email protected]>"]
6+
license = "MIT"
7+
8+
# Requirements
9+
[tool.poetry.dependencies]
10+
python = "~2.7 || ^3.4"

tests/installation/fixtures/with-directory-dependency-poetry.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ python-versions = "*"
1616
version = "1.2.3"
1717

1818
[package.dependencies]
19-
pendulum = {version = ">=1.4.4", optional = true, markers = "extra == \"extras_a\""}
19+
pendulum = {version = ">=1.4.4", optional = true}
2020

2121
[package.extras]
2222
extras_a = ["pendulum (>=1.4.4)"]

tests/installation/test_installer.py

+16-19
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@
2929
from tests.repositories.test_pypi_repository import MockRepository
3030

3131

32-
fixtures_dir = Path("tests/fixtures")
33-
34-
3532
class Installer(BaseInstaller):
3633
def _get_installer(self):
3734
return NoopInstaller()
@@ -779,8 +776,8 @@ def test_installer_with_pypi_repository(package, locker, installed, config):
779776
assert locker.written_data == expected
780777

781778

782-
def test_run_installs_with_local_file(installer, locker, repo, package):
783-
file_path = fixtures_dir / "distributions/demo-0.1.0-py2.py3-none-any.whl"
779+
def test_run_installs_with_local_file(installer, locker, repo, package, fixture_dir):
780+
file_path = fixture_dir("distributions/demo-0.1.0-py2.py3-none-any.whl")
784781
package.add_dependency(Factory.create_dependency("demo", {"file": str(file_path)}))
785782

786783
repo.add_package(get_package("pendulum", "1.4.4"))
@@ -793,9 +790,11 @@ def test_run_installs_with_local_file(installer, locker, repo, package):
793790
assert 2 == installer.executor.installations_count
794791

795792

796-
def test_run_installs_wheel_with_no_requires_dist(installer, locker, repo, package):
797-
file_path = (
798-
fixtures_dir / "wheel_with_no_requires_dist/demo-0.1.0-py2.py3-none-any.whl"
793+
def test_run_installs_wheel_with_no_requires_dist(
794+
installer, locker, repo, package, fixture_dir
795+
):
796+
file_path = fixture_dir(
797+
"wheel_with_no_requires_dist/demo-0.1.0-py2.py3-none-any.whl"
799798
)
800799
package.add_dependency(Factory.create_dependency("demo", {"file": str(file_path)}))
801800

@@ -809,31 +808,29 @@ def test_run_installs_wheel_with_no_requires_dist(installer, locker, repo, packa
809808

810809

811810
def test_run_installs_with_local_poetry_directory_and_extras(
812-
installer, locker, repo, package, tmpdir
811+
installer, locker, repo, package, tmpdir, fixture_dir
813812
):
814-
file_path = fixtures_dir / "project_with_extras"
813+
file_path = fixture_dir("project_with_extras")
815814
package.add_dependency(
816815
Factory.create_dependency(
817816
"project-with-extras", {"path": str(file_path), "extras": ["extras_a"]}
818817
)
819818
)
820-
print(package.requires[0].develop)
821819

822820
repo.add_package(get_package("pendulum", "1.4.4"))
823821

824822
installer.run()
825823

826824
expected = fixture("with-directory-dependency-poetry")
827-
828825
assert locker.written_data == expected
829826

830827
assert 2 == installer.executor.installations_count
831828

832829

833830
def test_run_installs_with_local_poetry_directory_transitive(
834-
installer, locker, repo, package, tmpdir
831+
installer, locker, repo, package, tmpdir, fixture_dir
835832
):
836-
root_dir = fixtures_dir.joinpath("directory")
833+
root_dir = fixture_dir("directory")
837834
package.root_dir = root_dir
838835
locker.set_lock_path(root_dir)
839836
directory = root_dir.joinpath("project_with_transitive_directory_dependencies")
@@ -858,12 +855,12 @@ def test_run_installs_with_local_poetry_directory_transitive(
858855

859856

860857
def test_run_installs_with_local_poetry_file_transitive(
861-
installer, locker, repo, package, tmpdir
858+
installer, locker, repo, package, tmpdir, fixture_dir
862859
):
863-
root_dir = fixtures_dir.joinpath("directory")
860+
root_dir = fixture_dir("directory")
864861
package.root_dir = root_dir
865862
locker.set_lock_path(root_dir)
866-
directory = fixtures_dir.joinpath("directory").joinpath(
863+
directory = fixture_dir("directory").joinpath(
867864
"project_with_transitive_file_dependencies"
868865
)
869866
package.add_dependency(
@@ -887,9 +884,9 @@ def test_run_installs_with_local_poetry_file_transitive(
887884

888885

889886
def test_run_installs_with_local_setuptools_directory(
890-
installer, locker, repo, package, tmpdir
887+
installer, locker, repo, package, tmpdir, fixture_dir
891888
):
892-
file_path = fixtures_dir / "project_with_setup/"
889+
file_path = fixture_dir("project_with_setup/")
893890
package.add_dependency(
894891
Factory.create_dependency("project-with-setup", {"path": str(file_path)})
895892
)

tests/installation/test_installer_old.py

+16-17
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727
from tests.repositories.test_pypi_repository import MockRepository
2828

2929

30-
fixtures_dir = Path("tests/fixtures")
31-
32-
3330
class Installer(BaseInstaller):
3431
def _get_installer(self):
3532
return NoopInstaller()
@@ -749,8 +746,8 @@ def test_installer_with_pypi_repository(package, locker, installed, config):
749746
assert locker.written_data == expected
750747

751748

752-
def test_run_installs_with_local_file(installer, locker, repo, package):
753-
file_path = fixtures_dir / "distributions/demo-0.1.0-py2.py3-none-any.whl"
749+
def test_run_installs_with_local_file(installer, locker, repo, package, fixture_dir):
750+
file_path = fixture_dir("distributions/demo-0.1.0-py2.py3-none-any.whl")
754751
package.add_dependency(Factory.create_dependency("demo", {"file": str(file_path)}))
755752

756753
repo.add_package(get_package("pendulum", "1.4.4"))
@@ -764,9 +761,11 @@ def test_run_installs_with_local_file(installer, locker, repo, package):
764761
assert len(installer.installer.installs) == 2
765762

766763

767-
def test_run_installs_wheel_with_no_requires_dist(installer, locker, repo, package):
768-
file_path = (
769-
fixtures_dir / "wheel_with_no_requires_dist/demo-0.1.0-py2.py3-none-any.whl"
764+
def test_run_installs_wheel_with_no_requires_dist(
765+
installer, locker, repo, package, fixture_dir
766+
):
767+
file_path = fixture_dir(
768+
"wheel_with_no_requires_dist/demo-0.1.0-py2.py3-none-any.whl"
770769
)
771770
package.add_dependency(Factory.create_dependency("demo", {"file": str(file_path)}))
772771

@@ -780,9 +779,9 @@ def test_run_installs_wheel_with_no_requires_dist(installer, locker, repo, packa
780779

781780

782781
def test_run_installs_with_local_poetry_directory_and_extras(
783-
installer, locker, repo, package, tmpdir
782+
installer, locker, repo, package, tmpdir, fixture_dir
784783
):
785-
file_path = fixtures_dir / "project_with_extras"
784+
file_path = fixture_dir("project_with_extras")
786785
package.add_dependency(
787786
Factory.create_dependency(
788787
"project-with-extras", {"path": str(file_path), "extras": ["extras_a"]}
@@ -801,9 +800,9 @@ def test_run_installs_with_local_poetry_directory_and_extras(
801800

802801

803802
def test_run_installs_with_local_poetry_directory_transitive(
804-
installer, locker, repo, package, tmpdir
803+
installer, locker, repo, package, tmpdir, fixture_dir
805804
):
806-
root_dir = fixtures_dir.joinpath("directory")
805+
root_dir = fixture_dir("directory")
807806
package.root_dir = root_dir
808807
locker.set_lock_path(root_dir)
809808
directory = root_dir.joinpath("project_with_transitive_directory_dependencies")
@@ -828,16 +827,16 @@ def test_run_installs_with_local_poetry_directory_transitive(
828827

829828

830829
def test_run_installs_with_local_poetry_file_transitive(
831-
installer, locker, repo, package, tmpdir
830+
installer, locker, repo, package, tmpdir, fixture_dir
832831
):
833-
root_dir = fixtures_dir.joinpath("directory")
832+
root_dir = fixture_dir("directory")
834833
package.root_dir = root_dir
835834
locker.set_lock_path(root_dir)
836835
directory = root_dir.joinpath("project_with_transitive_file_dependencies")
837836
package.add_dependency(
838837
Factory.create_dependency(
839838
"project-with-transitive-file-dependencies",
840-
{"path": str(directory.relative_to(fixtures_dir.joinpath("directory")))},
839+
{"path": str(directory.relative_to(fixture_dir("directory")))},
841840
root_dir=root_dir,
842841
)
843842
)
@@ -855,9 +854,9 @@ def test_run_installs_with_local_poetry_file_transitive(
855854

856855

857856
def test_run_installs_with_local_setuptools_directory(
858-
installer, locker, repo, package, tmpdir
857+
installer, locker, repo, package, tmpdir, fixture_dir
859858
):
860-
file_path = fixtures_dir / "project_with_setup/"
859+
file_path = fixture_dir("project_with_setup/")
861860
package.add_dependency(
862861
Factory.create_dependency("project-with-setup", {"path": str(file_path)})
863862
)

tests/puzzle/test_solver.py

+54
Original file line numberDiff line numberDiff line change
@@ -1672,6 +1672,60 @@ def test_solver_can_resolve_directory_dependencies(solver, repo, package):
16721672
assert op.package.source_url == path
16731673

16741674

1675+
def test_solver_can_resolve_directory_dependencies_nested_editable(
1676+
solver, repo, pool, installed, locked, io
1677+
):
1678+
base = Path(__file__).parent.parent / "fixtures" / "project_with_nested_local"
1679+
poetry = Factory().create_poetry(cwd=base)
1680+
package = poetry.package
1681+
1682+
solver = Solver(
1683+
package, pool, installed, locked, io, provider=Provider(package, pool, io)
1684+
)
1685+
1686+
ops = solver.solve()
1687+
1688+
check_solver_result(
1689+
ops,
1690+
[
1691+
{
1692+
"job": "install",
1693+
"package": Package(
1694+
"quix",
1695+
"1.2.3",
1696+
source_type="directory",
1697+
source_url=(base / "quix").as_posix(),
1698+
),
1699+
"skipped": False,
1700+
},
1701+
{
1702+
"job": "install",
1703+
"package": Package(
1704+
"bar",
1705+
"1.2.3",
1706+
source_type="directory",
1707+
source_url=(base / "bar").as_posix(),
1708+
),
1709+
"skipped": False,
1710+
},
1711+
{
1712+
"job": "install",
1713+
"package": Package(
1714+
"foo",
1715+
"1.2.3",
1716+
source_type="directory",
1717+
source_url=(base / "foo").as_posix(),
1718+
),
1719+
"skipped": False,
1720+
},
1721+
],
1722+
)
1723+
1724+
for op in ops:
1725+
assert op.package.source_type == "directory"
1726+
assert op.package.develop is True
1727+
1728+
16751729
def test_solver_can_resolve_directory_dependencies_with_extras(solver, repo, package):
16761730
pendulum = get_package("pendulum", "2.0.3")
16771731
cleo = get_package("cleo", "1.0.0")

0 commit comments

Comments
 (0)