Skip to content

Commit

Permalink
Editable project location (#148)
Browse files Browse the repository at this point in the history
* Added support for editable_project_location key

* black formatting
  • Loading branch information
weetster authored Jul 19, 2022
1 parent 59663a4 commit 3ef90ae
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 6 deletions.
28 changes: 23 additions & 5 deletions pip_api/_installed_distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,31 @@


class Distribution:
def __init__(self, name: str, version: str, location: Optional[str] = None):
def __init__(
self,
name: str,
version: str,
location: Optional[str] = None,
editable_project_location: Optional[str] = None,
):
self.name = name
self.version = parse(version)
self.location = location
self.editable = bool(self.location)
self.editable_project_location = editable_project_location

if pip_api.PIP_VERSION >= parse("21.3"):
self.editable = bool(self.editable_project_location)
else:
self.editable = bool(self.location)

def __repr__(self):
return "<Distribution(name='{}', version='{}'{})>".format(
return "<Distribution(name='{}', version='{}'{}{})>".format(
self.name,
self.version,
", location='{}'".format(self.location) if self.location else "",
", editable_project_location='{}'".format(self.editable_project_location)
if self.editable_project_location
else "",
)


Expand Down Expand Up @@ -71,10 +85,14 @@ def _new_installed_distributions(local: bool, paths: List[os.PathLike]):
# The returned JSON is an array of objects, each of which looks like this:
# { "name": "some-package", "version": "0.0.1", "location": "/path/", ... }
# The location key was introduced with pip 10.0.0b1, so we don't assume its
# presence.
# presence. The editable_project_location key was introduced with pip 21.3,
# so we also don't assume its presence.
for raw_dist in json.loads(result):
dist = Distribution(
raw_dist["name"], raw_dist["version"], raw_dist.get("location")
raw_dist["name"],
raw_dist["version"],
raw_dist.get("location"),
raw_dist.get("editable_project_location"),
)
ret[dist.name] = dist

Expand Down
11 changes: 11 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ def some_distribution(data):
version=Version("0.0.1"),
location=None,
filename=data.join("dummyproject-0.0.1-py3-none-any.whl"),
editable=False,
)


@pytest.fixture
def some_editable_distribution(data):
return pretend.stub(
name="dummyproject",
version=Version("0.0.1"),
location=None,
filename=data.join("dummyproject"),
editable=True,
)

Expand Down
7 changes: 7 additions & 0 deletions tests/data/dummyproject/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from distutils.core import setup

setup(
name="dummyproject",
version="1.0",
py_modules=["dummyproject"],
)
20 changes: 19 additions & 1 deletion tests/test_installed_distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@ def test_installed_distributions(pip, some_distribution):
assert distribution.version == some_distribution.version

# Various versions of `pip` have different behavior here:
# * `pip` 21.3 and newer include the `editable_project_location` key in the JSON output
# * `pip` 10.0.0b1 and newer include the `location` key in the JSON output
# * `pip` 9.0.0 through 10.0.0b0 support JSON, but don't include `location`
# * `pip` versions before 9.0.0 don't support JSON and don't include
# any location information in the textual output that we parse
if pip_api.PIP_VERSION >= parse("10.0.0b0"):
if pip_api.PIP_VERSION >= parse("21.3"):
assert os.path.exists(distribution.location)
assert not distribution.editable
elif pip_api.PIP_VERSION >= parse("10.0.0b0"):
# We don't know exactly where the distribution has been installed,
# but we know it exists and therefore is editable.
assert os.path.exists(distribution.location)
Expand All @@ -41,6 +45,20 @@ def test_installed_distributions(pip, some_distribution):
assert not distribution.editable


def test_installed_distributions_editable(pip, some_editable_distribution):
# `pip` 21.3 and newer include the `editable_project_location` key in the JSON output
if pip_api.PIP_VERSION >= parse("21.3"):
pip.run("install", "--editable", some_editable_distribution.filename)

distributions = pip_api.installed_distributions()
assert some_editable_distribution.name in distributions
distribution = distributions[some_editable_distribution.name]

assert distribution.editable_project_location is not None
assert os.path.exists(distribution.editable_project_location)
assert distribution.editable


def test_installed_distributions_legacy_version(pip, data):
distributions = pip_api.installed_distributions()

Expand Down

0 comments on commit 3ef90ae

Please sign in to comment.