Skip to content
Open
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
10 changes: 8 additions & 2 deletions src/manage/installs.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def _make_alias_name_sortkey(n):
return re.sub(r"(\d+|\[|\])", _sk_sub, n)


def get_install_alias_names(aliases, friendly=True, windowed=True):
def get_install_alias_names(aliases, friendly=True, windowed=True, default_platform=None):
if not windowed:
aliases = [a for a in aliases if not a.get("windowed")]
if not friendly:
Expand All @@ -191,11 +191,17 @@ def get_install_alias_names(aliases, friendly=True, windowed=True):

result = []
for k, (n1, n2, n3) in seen.items():
plat_parts = plats.get(k)
plat = _make_opt_part(plat_parts)
if default_platform and plat_parts == {default_platform}:
# The bare alias was already shown for another install, but the
# suffix is still optional when it matches the default platform.
plat = f"[{default_platform}]"
result.append("".join([
n1,
_make_opt_part(has_w.get(k)),
n2,
_make_opt_part(plats.get(k)),
plat,
n3,
]))
return sorted(result, key=_make_alias_name_sortkey)
Expand Down
9 changes: 6 additions & 3 deletions src/manage/list_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
LOGGER = logging.LOGGER


def _format_alias(i, seen):
def _format_alias(cmd, i, seen):
from manage.installs import get_install_alias_names
aliases = [a for a in i.get("alias", ()) if a["name"].casefold() not in seen]
seen.update(a["name"].casefold() for a in aliases)

include_w = LOGGER.would_log_to_console(logging.VERBOSE)
names = get_install_alias_names(aliases, windowed=include_w)
default_platform = cmd.default_platform if cmd else None
names = get_install_alias_names(
aliases, windowed=include_w, default_platform=default_platform
)
return ", ".join(names)


Expand Down Expand Up @@ -46,7 +49,7 @@ def format_table(cmd, installs):
seen_alias = set()
installs = [{
**i,
"alias": _format_alias(i, seen_alias),
"alias": _format_alias(cmd, i, seen_alias),
"sort-version": str(i['sort-version']),
"default-star": "",
"tag-with-co": _format_tag_with_co(cmd, i),
Expand Down
44 changes: 44 additions & 0 deletions tests/test_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,50 @@ def test_format_table_aliases(assert_log):
)


def test_format_table_aliases_default_platform(assert_log):
# https://github.com/python/pymanager/issues/407
# Aliases from the online index, in feed order. Each install lists both
# the bare alias and its platform-specific variant; format_table shows
# only the first occurrence of each name, so the -64 install is left
# with lone "-64" names. Those must still render as optional ("[-64]"),
# mirroring how the Tag column marks the default platform.
import types

def online_aliases(plat):
return [
{"name": "python3.15.exe", "target": "python.exe"},
{"name": f"python3.15{plat}.exe", "target": "python.exe"},
{"name": "python3.exe", "target": "python.exe"},
{"name": f"python3{plat}.exe", "target": "python.exe"},
{"name": "pythonw3.15.exe", "target": "pythonw.exe", "windowed": 1},
{"name": f"pythonw3.15{plat}.exe", "target": "pythonw.exe", "windowed": 1},
{"name": "pythonw3.exe", "target": "pythonw.exe", "windowed": 1},
{"name": f"pythonw3{plat}.exe", "target": "pythonw.exe", "windowed": 1},
]

def online_install(tag, plat):
return {
"company": "PythonCore",
"tag": tag,
"display-name": "Python 3.15.0rc2",
"sort-version": "3.15.0rc2",
"alias": online_aliases(plat),
}

cmd = types.SimpleNamespace(default_platform="-64")
list_command.format_table(cmd, [
online_install("3.15-dev-32", "-32"),
online_install("3.15-dev-64", "-64"),
online_install("3.15-dev-arm64", "-arm64"),
])
assert_log(
(r"!B!Tag\s+Name\s+Managed By\s+Version\s+Alias\s*!W!", ()),
(r"3\.15-dev-32.*" + re.escape("python[w]3[-32].exe, python[w]3.15[-32].exe"), ()),
(r"3\.15-dev\[-64\].*" + re.escape("python[w]3[-64].exe, python[w]3.15[-64].exe"), ()),
(r"3\.15-dev-arm64.*" + re.escape("python[w]3-arm64.exe, python[w]3.15-arm64.exe"), ()),
)


def test_format_table_truncated(assert_log):
list_command.format_table(None, [
{
Expand Down