Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build-system]
requires = ["setuptools", "wheel"]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[tool.ruff]
Expand Down
8 changes: 6 additions & 2 deletions src/pickley/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ def __init__(self, given_package_spec: str, authoritative=False, settings=None):
self.auto_upgrade_spec = given_package_spec
runez.log.trace(f"Authoritative auto-upgrade spec '{self.auto_upgrade_spec}'")

else:
elif self._canonical_name:
# Non-authoritative specs are necessarily canonical names (since only authoritative specs can refer to git urls, etc.)
manifest = self.manifest
if manifest and manifest.settings and manifest.settings.auto_upgrade_spec:
Expand All @@ -398,6 +398,10 @@ def __init__(self, given_package_spec: str, authoritative=False, settings=None):
runez.log.trace(f"Assuming auto-upgrade spec '{self._canonical_name}'")
self.auto_upgrade_spec = self._canonical_name

else:
# Should not be reachable, unless we are given a non-authoritative spec that is not a canonical name
self.auto_upgrade_spec = given_package_spec

cache_file_name = self.auto_upgrade_spec
if PypiStd.std_package_name(cache_file_name) != cache_file_name:
# If package spec is not a canonical name, use md5 hash of it as filename
Expand Down Expand Up @@ -501,7 +505,7 @@ def target_installation_folder(self):
def upgrade_reason(self):
"""Reason this package spec needs an upgrade (if any)"""
if self.currently_installed_version != self.target_version:
return "new version available"
return f"new version available, current version is {self.currently_installed_version}"

manifest = self.manifest
if not manifest:
Expand Down
11 changes: 10 additions & 1 deletion src/pickley/package.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
import os
from pathlib import Path
from typing import List, TYPE_CHECKING
Expand All @@ -11,6 +12,8 @@
if TYPE_CHECKING:
from pickley.cli import Requirements

LOG = logging.getLogger(__name__)


class PythonVenv:
"""Python virtual environment as seen by pickley, typically in <base>/.pk/<package>-<version>/"""
Expand Down Expand Up @@ -138,13 +141,19 @@ def find_symbolic_invoker() -> str:
"""Symbolic major/minor symlink to invoker, when applicable"""
invoker = runez.SYS_INFO.invoker_python
folder = invoker.real_exe.parent.parent
LOG.info("Invoker python: %s", invoker)
v = Version.extracted_from_text(folder.name)
found = invoker.executable
if v and v.given_components_count == 3:
# For setups that provide a <folder>/pythonM.m -> <folder>/pythonM.m.p symlink, prefer the major/minor variant
candidates = [folder.parent / folder.name.replace(v.text, v.mm), folder.parent / f"python{v.mm}"]
candidates = []
for candidate in (folder.name.replace(v.text, v.mm), f"python{v.mm}"):
candidates.append(folder.parent / candidate)
candidates.append(folder.parent / candidate / "bin" / f"python{v.mm}")

for path in candidates:
if runez.is_executable(path):
LOG.info("Found symbolic invoker: %s", path)
found = path
break

Expand Down
Loading