Skip to content

Commit

Permalink
add setter for version on ProjectPackage (#447)
Browse files Browse the repository at this point in the history
This enables support for dynamically setting the package version
(e.g., from a plugin)

Co-authored-by: Randy Döring <30527984+radoering@users.noreply.github.com>
  • Loading branch information
bcavagnolo and radoering committed Aug 26, 2022
1 parent bb35db3 commit e19dd6e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 7 deletions.
20 changes: 13 additions & 7 deletions src/poetry/core/packages/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ def __init__(
"""
Creates a new in memory package.
"""
from poetry.core.semver.version import Version
from poetry.core.version.markers import AnyMarker

super().__init__(
Expand All @@ -79,12 +78,7 @@ def __init__(
features=features,
)

if not isinstance(version, Version):
self._version = Version.parse(version)
self._pretty_version = pretty_version or version
else:
self._version = version
self._pretty_version = pretty_version or self._version.text
self._set_version(version, pretty_version)

self.description = ""

Expand Down Expand Up @@ -216,6 +210,18 @@ def all_requires(
for dependency in group.dependencies
]

def _set_version(
self, version: str | Version, pretty_version: str | None = None
) -> None:
from poetry.core.semver.version import Version

if not isinstance(version, Version):
self._version = Version.parse(version)
self._pretty_version = pretty_version or version
else:
self._version = version
self._pretty_version = pretty_version or self._version.text

def _get_author(self) -> dict[str, str | None]:
if not self._authors:
return {"name": None, "email": None}
Expand Down
15 changes: 15 additions & 0 deletions src/poetry/core/packages/project_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ def python_versions(self, value: str) -> None:
create_nested_marker("python_version", self._python_constraint)
)

@property
def version(self) -> Version:
# override version to make it settable
return super().version

@version.setter
def version(self, value: str | Version) -> None:
self._set_version(value)

@property
def urls(self) -> dict[str, str]:
urls = super().urls
Expand All @@ -71,5 +80,11 @@ def urls(self) -> dict[str, str]:

return urls

def __hash__(self) -> int:
# The parent Package class's __hash__ incorporates the version because
# a Package's version is immutable. But a ProjectPackage's version is
# mutable. So call Package's parent hash function.
return super(Package, self).__hash__()

def build_should_generate_setup(self) -> bool:
return self.build_config.get("generate-setup-file", True)
34 changes: 34 additions & 0 deletions tests/packages/test_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
from poetry.core.packages.directory_dependency import DirectoryDependency
from poetry.core.packages.file_dependency import FileDependency
from poetry.core.packages.package import Package
from poetry.core.packages.project_package import ProjectPackage
from poetry.core.packages.url_dependency import URLDependency
from poetry.core.packages.vcs_dependency import VCSDependency
from poetry.core.semver.version import Version


@pytest.fixture()
Expand Down Expand Up @@ -540,3 +542,35 @@ def test_python_versions_are_normalized() -> None:
== 'python_version > "3.6" and python_version <= "3.10"'
)
assert str(package.python_constraint) == ">=3.7,<3.11"


def test_cannot_update_package_version() -> None:
package = Package("foo", "1.2.3")
with pytest.raises(AttributeError):
package.version = "1.2.4" # type: ignore[misc,assignment]


def test_project_package_version_update_string() -> None:
package = ProjectPackage("foo", "1.2.3")
package.version = "1.2.4" # type: ignore[assignment]
assert package.version.text == "1.2.4"


def test_project_package_version_update_version() -> None:
package = ProjectPackage("foo", "1.2.3")
package.version = Version.parse("1.2.4")
assert package.version.text == "1.2.4"


def test_project_package_hash_not_changed_when_version_is_changed() -> None:
package = ProjectPackage("foo", "1.2.3")
package_hash = hash(package)
package_clone = package.clone()
assert package == package_clone
assert hash(package) == hash(package_clone)

package.version = Version.parse("1.2.4")

assert hash(package) == package_hash, "Hash must not change!"
assert hash(package_clone) == package_hash
assert package != package_clone

0 comments on commit e19dd6e

Please sign in to comment.