Skip to content

Commit

Permalink
chore: switch to ruff, switch to pdm-backend
Browse files Browse the repository at this point in the history
Signed-off-by: Frost Ming <[email protected]>
  • Loading branch information
frostming committed Jul 5, 2023
1 parent 4b5a529 commit 2fafd5c
Show file tree
Hide file tree
Showing 19 changed files with 146 additions and 126 deletions.
24 changes: 12 additions & 12 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ exclude: >
\.venv|
build|
dist|
src/findpython/_vendor/.*\.py
src/findpython/_vendor/.*\.py|
src/findpython/pep514tools/_registry\.py
)$
repos:
- repo: https://github.com/ambv/black
rev: 22.3.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.0.276'
hooks:
- id: black
- id: ruff
args: [--fix, --exit-non-zero-on-fix, --show-fixes]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.5.0
- repo: https://github.com/ambv/black
rev: 23.3.0
hooks:
- id: flake8
additional_dependencies:
- flake8-bugbear
- id: black

- repo: https://github.com/pre-commit/mirrors-isort
rev: v5.10.1
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.4.1
hooks:
- id: isort
- id: mypy
32 changes: 25 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ package-dir = "src"
tests = ["pytest"]

[build-system]
requires = ["pdm-pep517"]
build-backend = "pdm.pep517.api"
requires = ["pdm-backend"]
build-backend = "pdm.backend"

[tool.black]
line-length = 90
Expand All @@ -58,9 +58,27 @@ exclude = '''
)
'''

[tool.isort]
profile = "black"
atomic = true
filter_files = true
known_first_party = ["findpython"]
[tool.ruff]
line-length = 90
select = [
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"E", # pycodestyle
"F", # pyflakes
"PGH", # pygrep-hooks
"RUF", # ruff
"W", # pycodestyle
"YTT", # flake8-2020
]
extend-ignore = ["B018", "B019"]
src = ["src"]
exclude = ["tests/fixtures"]
target-version = "py37"

[tool.ruff.mccabe]
max-complexity = 10

[tool.ruff.isort]
known-first-party = ["findpython"]


24 changes: 14 additions & 10 deletions src/findpython/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import logging
import sys
from argparse import ArgumentParser
from typing import List

from findpython import Finder
from findpython.__version__ import __version__
Expand All @@ -21,7 +20,11 @@ def setup_logger(level: int = logging.DEBUG) -> None:
logger.setLevel(level)


def cli(argv: List[str] | None = None) -> int:
def split_str(value: str) -> list[str]:
return value.split(",")


def cli(argv: list[str] | None = None) -> int:
"""
Command line interface for findpython.
"""
Expand All @@ -46,23 +49,24 @@ def cli(argv: List[str] | None = None) -> int:
action="store_true",
help="Eliminate the duplicated results with the same sys.executable",
)
parser.add_argument(
"--provider",
nargs="+",
help="Select provider(s) to use",
)
parser.add_argument("--provider", type=split_str, help="Select provider(s) to use")
parser.add_argument("version_spec", nargs="?", help="Python version spec or name")

args = parser.parse_args(argv)
if args.verbose:
setup_logger()
finder = Finder(resolve_symlinks=args.resolve_symlink, no_same_file=args.no_same_file)

finder = Finder(
resolve_symlinks=args.resolve_symlink,
no_same_file=args.no_same_file,
selected_providers=args.provider,
)
if args.all:
find_func = finder.find_all
else:
find_func = finder.find
find_func = finder.find # type: ignore[assignment]

python_versions = find_func(args.version_spec, from_provider=args.provider)
python_versions = find_func(args.version_spec)
if not python_versions:
print("No matching python version found", file=sys.stderr)
return 1
Expand Down
51 changes: 17 additions & 34 deletions src/findpython/finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,24 @@ def __init__(
resolve_symlinks: bool = False,
no_same_file: bool = False,
no_same_interpreter: bool = False,
selected_providers: list[str] | None = None,
) -> None:
self.resolve_symlinks = resolve_symlinks
self.no_same_file = no_same_file
self.no_same_interpreter = no_same_interpreter
self._allowed_provider_names = set()
self._providers = self.setup_providers(selected_providers)

self._providers = self.setup_providers()

def setup_providers(self) -> list[BaseProvider]:
def setup_providers(
self,
selected_providers: list[str] | None = None,
) -> list[BaseProvider]:
providers: list[BaseProvider] = []
for provider_class in ALL_PROVIDERS:
self._allowed_provider_names.add(provider_class.name())
allowed_providers = {p.name(): p for p in ALL_PROVIDERS}
if selected_providers is not None:
allowed_providers = {
name: allowed_providers[name] for name in selected_providers
}
for provider_class in allowed_providers.values():
provider = provider_class.create()
if provider is None:
logger.debug("Provider %s is not available", provider_class.__name__)
Expand All @@ -47,7 +53,6 @@ def add_provider(self, provider: BaseProvider, pos: int | None = None) -> None:
"""Add provider to the provider list.
If pos is given, it will be inserted at the given position.
"""
self._allowed_provider_names.add(provider.name())
if pos is not None:
self._providers.insert(pos, provider)
else:
Expand All @@ -62,7 +67,6 @@ def find_all(
dev: bool | None = None,
name: str | None = None,
architecture: str | None = None,
from_provider: list[str] | None = None,
) -> list[PythonVersion]:
"""
Return all Python versions matching the given version criteria.
Expand Down Expand Up @@ -105,7 +109,7 @@ def find_all(
architecture,
)
# Deduplicate with the python executable path
matched_python = set(self._find_all_python_versions(from_provider))
matched_python = set(self._find_all_python_versions())
return self._dedup(matched_python, version_matcher)

def find(
Expand All @@ -117,7 +121,6 @@ def find(
dev: bool | None = None,
name: str | None = None,
architecture: str | None = None,
from_provider: list[str] | None = None,
) -> PythonVersion | None:
"""
Return the Python version that is closest to the given version criteria.
Expand All @@ -133,35 +136,15 @@ def find(
:return: a Python object or None
"""
return next(
iter(self.find_all(major, minor, patch, pre, dev, name, architecture,
from_provider)),
iter(self.find_all(major, minor, patch, pre, dev, name, architecture)),
None,
)

def _find_all_python_versions(
self,
from_provider: list[str] | None = None
) -> Iterable[PythonVersion]:
def _find_all_python_versions(self) -> Iterable[PythonVersion]:
"""Find all python versions on the system."""
for provider in self._filtered_providers(from_provider):
for provider in self._providers:
yield from provider.find_pythons()

def _filtered_providers(
self,
from_provider: list[str] | None = None
) -> Iterable[BaseProvider]:
if from_provider is None:
yield from self._providers
return

provider_map = {provider.name(): provider for provider in self._providers}
for provider_name in from_provider:
try:
yield provider_map[provider_name]
except KeyError:
if provider_name not in self._allowed_provider_names:
raise ValueError(f"No such provider {provider_name}")

def _dedup(
self,
python_versions: Iterable[PythonVersion],
Expand All @@ -176,7 +159,7 @@ def dedup_key(python_version: PythonVersion) -> str:
return python_version.real_path.as_posix()
return python_version.executable.as_posix()

def sort_key(python_version: PythonVersion) -> tuple[int, int]:
def sort_key(python_version: PythonVersion) -> tuple[int, int, int]:
return (
python_version.executable.is_symlink(),
get_suffix_preference(python_version.name),
Expand Down
2 changes: 1 addition & 1 deletion src/findpython/pep514tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
__author__ = "Steve Dower <[email protected]>"
__version__ = "0.1.0"

from findpython.pep514tools.environment import findall, find, findone
from findpython.pep514tools.environment import find, findall, findone

__all__ = ["findall", "find", "findone"]
6 changes: 2 additions & 4 deletions src/findpython/pep514tools/_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"REGISTRY_SOURCE_CU",
]

from itertools import count
import re
from itertools import count

try:
import winreg
Expand Down Expand Up @@ -86,10 +86,8 @@ def __getattr__(self, attr):
key = self._attr_to_key(attr)
try:
return self._d[key]
except KeyError:
pass
except Exception:
raise AttributeError(attr)
pass
raise AttributeError(attr)

def __setattr__(self, attr, value):
Expand Down
7 changes: 4 additions & 3 deletions src/findpython/pep514tools/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@

__all__ = ["Environment", "findall", "find", "findone"]

import sys

from findpython.pep514tools._registry import (
open_source,
REGISTRY_SOURCE_CU,
REGISTRY_SOURCE_LM,
REGISTRY_SOURCE_LM_WOW6432,
REGISTRY_SOURCE_CU,
open_source,
)
import sys

# These tags are treated specially when the Company is 'PythonCore'
_PYTHONCORE_COMPATIBILITY_TAGS = {
Expand Down
4 changes: 2 additions & 2 deletions src/findpython/providers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
This package contains all the providers for the pythonfinder module.
"""
from typing import List, Type
from __future__ import annotations

from findpython.providers.asdf import AsdfProvider
from findpython.providers.base import BaseProvider
Expand All @@ -10,7 +10,7 @@
from findpython.providers.pep514 import Pep514Provider
from findpython.providers.pyenv import PyenvProvider

ALL_PROVIDERS: List[Type[BaseProvider]] = [
ALL_PROVIDERS: list[type[BaseProvider]] = [
# General:
PathProvider,
# Tool Specific:
Expand Down
8 changes: 4 additions & 4 deletions src/findpython/providers/asdf.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from __future__ import annotations

import os
import typing as t
from pathlib import Path
from typing import Iterable, Type

from findpython.providers.base import BaseProvider, T
from findpython.providers.base import BaseProvider
from findpython.python import PythonVersion


Expand All @@ -15,15 +15,15 @@ def __init__(self, root: Path) -> None:
self.root = root

@classmethod
def create(cls: Type[T]) -> T | None:
def create(cls) -> t.Self | None:
asdf_root = os.path.expanduser(
os.path.expandvars(os.getenv("ASDF_DATA_DIR", "~/.asdf"))
)
if not os.path.exists(asdf_root):
return None
return cls(Path(asdf_root))

def find_pythons(self) -> Iterable[PythonVersion]:
def find_pythons(self) -> t.Iterable[PythonVersion]:
python_dir = self.root / "installs/python"
if not python_dir.exists():
return
Expand Down
13 changes: 6 additions & 7 deletions src/findpython/providers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@

import abc
import logging
import typing as t
from pathlib import Path
from typing import Callable, Iterable, Type, TypeVar

from findpython.python import PythonVersion
from findpython.utils import path_is_python, safe_iter_dir

T = TypeVar("T", bound="BaseProvider")
logger = logging.getLogger("findpython")


class BaseProvider(metaclass=abc.ABCMeta):
"""The base class for python providers"""

version_maker: Callable[..., PythonVersion] = PythonVersion
version_maker: t.Callable[..., PythonVersion] = PythonVersion

@classmethod
def name(cls) -> str:
Expand All @@ -25,24 +24,24 @@ def name(cls) -> str:
"""
self_name = cls.__name__.lower()
if self_name.endswith("provider"):
self_name = self_name[:-len("provider")]
self_name = self_name[: -len("provider")]
return self_name

@classmethod
@abc.abstractmethod
def create(cls: Type[T]) -> T | None:
def create(cls) -> t.Self | None:
"""Return an instance of the provider or None if it is not available"""
pass

@abc.abstractmethod
def find_pythons(self) -> Iterable[PythonVersion]:
def find_pythons(self) -> t.Iterable[PythonVersion]:
"""Return the python versions found by the provider"""
pass

@classmethod
def find_pythons_from_path(
cls, path: Path, as_interpreter: bool = False
) -> Iterable[PythonVersion]:
) -> t.Iterable[PythonVersion]:
"""A general helper method to return pythons under a given path.
:param path: The path to search for pythons
Expand Down
Loading

0 comments on commit 2fafd5c

Please sign in to comment.