Skip to content

Commit

Permalink
feat: support find by implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Frost Ming <[email protected]>
  • Loading branch information
frostming committed Mar 26, 2024
1 parent 7cc1e55 commit 5e7624a
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 2 deletions.
16 changes: 15 additions & 1 deletion src/findpython/finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def find_all(
name: str | None = None,
architecture: str | None = None,
allow_prereleases: bool = False,
implementation: str | None = None,
) -> list[PythonVersion]:
"""
Return all Python versions matching the given version criteria.
Expand All @@ -78,6 +79,7 @@ def find_all(
:param name: The name of the python.
:param architecture: The architecture of the python.
:param allow_prereleases: Whether to allow prereleases.
:param implementation: The implementation of the python. E.g. "cpython", "pypy".
:return: a list of PythonVersion objects
"""
if allow_prereleases and (pre is False or dev is False):
Expand All @@ -101,6 +103,7 @@ def find_all(
pre = pre or None
dev = dev or None
architecture = version_dict["architecture"]
implementation = version_dict["implementation"]
else:
name, major = major, None

Expand All @@ -113,6 +116,7 @@ def find_all(
dev,
name,
architecture,
implementation,
)
# Deduplicate with the python executable path
matched_python = set(self._find_all_python_versions())
Expand All @@ -128,6 +132,7 @@ def find(
name: str | None = None,
architecture: str | None = None,
allow_prereleases: bool = False,
implementation: str | None = None,
) -> PythonVersion | None:
"""
Return the Python version that is closest to the given version criteria.
Expand All @@ -140,12 +145,21 @@ def find(
:param name: The name of the python.
:param architecture: The architecture of the python.
:param allow_prereleases: Whether to allow prereleases.
:param implementation: The implementation of the python. E.g. "cpython", "pypy".
:return: a Python object or None
"""
return next(
iter(
self.find_all(
major, minor, patch, pre, dev, name, architecture, allow_prereleases
major,
minor,
patch,
pre,
dev,
name,
architecture,
allow_prereleases,
implementation,
)
),
None,
Expand Down
8 changes: 8 additions & 0 deletions src/findpython/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ def matches(
dev: bool | None = None,
name: str | None = None,
architecture: str | None = None,
implementation: str | None = None,
) -> bool:
"""
Return True if the python matches the provided criteria.
Expand All @@ -149,6 +150,8 @@ def matches(
:type name: str
:param architecture: The architecture of the python.
:type architecture: str
:param implementation: The implementation of the python.
:type implementation: str
:return: Whether the python matches the provided criteria.
:rtype: bool
"""
Expand All @@ -166,6 +169,11 @@ def matches(
return False
if architecture is not None and self.architecture != architecture:
return False
if (
implementation is not None
and self.implementation.lower() != implementation.lower()
):
return False
return True

def __hash__(self) -> int:
Expand Down
3 changes: 2 additions & 1 deletion src/findpython/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from typing import Generator, Sequence, TypedDict

VERSION_RE = re.compile(
r"(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>[0-9]+))?)?\.?"
r"(?:(?P<implementation>\w+)@)?(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>[0-9]+))?)?\.?"
r"(?:(?P<prerel>[abc]|rc|dev)(?:(?P<prerelversion>\d+(?:\.\d+)*))?)"
r"?(?P<postdev>(\.post(?P<post>\d+))?(\.dev(?P<dev>\d+))?)?"
r"(?:-(?P<architecture>32|64))?"
Expand Down Expand Up @@ -129,6 +129,7 @@ class VersionDict(TypedDict):
minor: int | None
patch: int | None
architecture: str | None
implementation: str | None


def parse_major(version: str) -> VersionDict | None:
Expand Down

0 comments on commit 5e7624a

Please sign in to comment.