Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-findpython for 
openSUSE:Factory checked in at 2023-12-11 21:51:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-findpython (Old)
 and      /work/SRC/openSUSE:Factory/.python-findpython.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-findpython"

Mon Dec 11 21:51:13 2023 rev:8 rq:1132417 version:0.4.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-findpython/python-findpython.changes      
2023-06-16 16:56:05.918151457 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-findpython.new.25432/python-findpython.changes
   2023-12-11 21:51:21.969339808 +0100
@@ -1,0 +2,14 @@
+Mon Dec 11 07:18:35 UTC 2023 - Steve Kowalik <steven.kowa...@suse.com>
+
+- Update 0.4.1:
+  * feat: provider selector by @frostming in #20
+  * feat: add support for RyeProvider
+  * feat: Add way to filter providers by @bluss in #18
+  * feat: add register_provider function and change ALL_PROVIDERS to a map
+  * fix: don't import site-packages when running in-process scripts
+  * Make GET_VERSION_TIMEOUT settable via env vars
+  * Support allow_prereleases option
+- Add patch revert-back-to-pdm-pep517.patch:
+  * We need to use pdm-pep517, to avoid circular requirements.
+
+-------------------------------------------------------------------

Old:
----
  findpython-0.2.5.tar.gz

New:
----
  findpython-0.4.1.tar.gz
  revert-back-to-pdm-pep517.patch

BETA DEBUG BEGIN:
  New:  * Support allow_prereleases option
- Add patch revert-back-to-pdm-pep517.patch:
  * We need to use pdm-pep517, to avoid circular requirements.
BETA DEBUG END:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-findpython.spec ++++++
--- /var/tmp/diff_new_pack.iwTyNt/_old  2023-12-11 21:51:22.929375430 +0100
+++ /var/tmp/diff_new_pack.iwTyNt/_new  2023-12-11 21:51:22.933375580 +0100
@@ -18,12 +18,14 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-findpython
-Version:        0.2.5
+Version:        0.4.1
 Release:        0
 Summary:        Utility to find python versions on your system
 License:        MIT
 URL:            https://github.com/frostming/findpython
 Source:         
https://files.pythonhosted.org/packages/source/f/findpython/findpython-%{version}.tar.gz
+# PATCH-FIX-OPENSUSE pdm requires findpython, so we need to use pdm-pep517
+Patch0:         revert-back-to-pdm-pep517.patch
 BuildRequires:  %{python_module base >= 3.7}
 BuildRequires:  %{python_module packaging >= 20}
 BuildRequires:  %{python_module pdm-pep517}

++++++ findpython-0.2.5.tar.gz -> findpython-0.4.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/PKG-INFO 
new/findpython-0.4.1/PKG-INFO
--- old/findpython-0.2.5/PKG-INFO       1970-01-01 01:00:00.000000000 +0100
+++ new/findpython-0.4.1/PKG-INFO       1970-01-01 01:00:00.000000000 +0100
@@ -1,16 +1,18 @@
 Metadata-Version: 2.1
 Name: findpython
-Version: 0.2.5
+Version: 0.4.1
 Summary: A utility to find python versions on your system
+Author-Email: Frost Ming <miangh...@gmail.com>
 License: MIT
-Author-email: Frost Ming <miangh...@gmail.com>
-Requires-Python: >=3.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
 Project-URL: Homepage, https://github.com/frostming/findpython
+Requires-Python: >=3.7
+Requires-Dist: packaging>=20
 Description-Content-Type: text/markdown
 
 # FindPython
@@ -69,21 +71,24 @@
 In addition, FindPython provides a CLI interface to find python versions:
 
 ```
-usage: findpython [-h] [-V] [-a] [--resolve-symlink] [-v] [--no-same-file] 
[--no-same-python] [version_spec]
+usage: findpython [-h] [-V] [-a] [--resolve-symlink] [-v] [--no-same-file] 
[--no-same-python] [--providers PROVIDERS]
+                  [version_spec]
 
-Find python files in a directory
+A utility to find python versions on your system
 
 positional arguments:
-  version_spec       Python version spec or name
+  version_spec          Python version spec or name
 
 options:
-  -h, --help         show this help message and exit
-  -V, --version      show program's version number and exit
-  -a, --all          Show all matching python versions
-  --resolve-symlink  Resolve all symlinks
-  -v, --verbose      Verbose output
-  --no-same-file     Eliminate the duplicated results with the same file 
contents
-  --no-same-python   Eliminate the duplicated results with the same 
sys.executable
+  -h, --help            show this help message and exit
+  -V, --version         show program's version number and exit
+  -a, --all             Show all matching python versions
+  --resolve-symlink     Resolve all symlinks
+  -v, --verbose         Verbose output
+  --no-same-file        Eliminate the duplicated results with the same file 
contents
+  --no-same-python      Eliminate the duplicated results with the same 
sys.executable
+  --providers PROVIDERS
+                        Select provider(s) to use
 ```
 
 ## Integration
@@ -91,12 +96,12 @@
 FindPython finds Python from the following places:
 
 -   `PATH` environment variable
--   pyenv
--   asdf
+-   pyenv install root
+-   asdf python install root
+-   [rye](https://rye-up.com) toolchain install root
 -   `/Library/Frameworks/Python.framework/Versions` (MacOS)
--   winreg (Windows)
+-   Windows registry (Windows only)
 
 ## License
 
 FindPython is released under MIT License.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/README.md 
new/findpython-0.4.1/README.md
--- old/findpython-0.2.5/README.md      2023-05-10 10:27:49.053817000 +0200
+++ new/findpython-0.4.1/README.md      2023-12-07 05:39:09.105851000 +0100
@@ -54,21 +54,24 @@
 In addition, FindPython provides a CLI interface to find python versions:
 
 ```
-usage: findpython [-h] [-V] [-a] [--resolve-symlink] [-v] [--no-same-file] 
[--no-same-python] [version_spec]
+usage: findpython [-h] [-V] [-a] [--resolve-symlink] [-v] [--no-same-file] 
[--no-same-python] [--providers PROVIDERS]
+                  [version_spec]
 
-Find python files in a directory
+A utility to find python versions on your system
 
 positional arguments:
-  version_spec       Python version spec or name
+  version_spec          Python version spec or name
 
 options:
-  -h, --help         show this help message and exit
-  -V, --version      show program's version number and exit
-  -a, --all          Show all matching python versions
-  --resolve-symlink  Resolve all symlinks
-  -v, --verbose      Verbose output
-  --no-same-file     Eliminate the duplicated results with the same file 
contents
-  --no-same-python   Eliminate the duplicated results with the same 
sys.executable
+  -h, --help            show this help message and exit
+  -V, --version         show program's version number and exit
+  -a, --all             Show all matching python versions
+  --resolve-symlink     Resolve all symlinks
+  -v, --verbose         Verbose output
+  --no-same-file        Eliminate the duplicated results with the same file 
contents
+  --no-same-python      Eliminate the duplicated results with the same 
sys.executable
+  --providers PROVIDERS
+                        Select provider(s) to use
 ```
 
 ## Integration
@@ -76,10 +79,11 @@
 FindPython finds Python from the following places:
 
 -   `PATH` environment variable
--   pyenv
--   asdf
+-   pyenv install root
+-   asdf python install root
+-   [rye](https://rye-up.com) toolchain install root
 -   `/Library/Frameworks/Python.framework/Versions` (MacOS)
--   winreg (Windows)
+-   Windows registry (Windows only)
 
 ## License
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/pyproject.toml 
new/findpython-0.4.1/pyproject.toml
--- old/findpython-0.2.5/pyproject.toml 2023-05-10 10:27:49.053817000 +0200
+++ new/findpython-0.4.1/pyproject.toml 2023-12-07 05:39:20.101811400 +0100
@@ -16,8 +16,9 @@
     "Programming Language :: Python :: 3.8",
     "Programming Language :: Python :: 3.9",
     "Programming Language :: Python :: 3.10",
+    "Programming Language :: Python :: 3.11",
 ]
-version = "0.2.5"
+version = "0.4.1"
 
 [project.license]
 text = "MIT"
@@ -46,16 +47,40 @@
 include = "\\.pyi?$"
 exclude = "/(\n    \\.eggs\n  | \\.git\n  | \\.hg\n  | \\.mypy_cache\n  | 
\\.tox\n  | \\.venv\n  | build\n  | dist\n  | src/pythonfinder/_vendor\n)\n"
 
-[tool.isort]
-profile = "black"
-atomic = true
-filter_files = true
-known_first_party = [
+[tool.ruff]
+line-length = 90
+select = [
+    "B",
+    "C4",
+    "E",
+    "F",
+    "PGH",
+    "RUF",
+    "W",
+    "YTT",
+]
+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",
 ]
 
 [build-system]
 requires = [
-    "pdm-pep517",
+    "pdm-backend",
 ]
-build-backend = "pdm.pep517.api"
+build-backend = "pdm.backend"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/__init__.py 
new/findpython-0.4.1/src/findpython/__init__.py
--- old/findpython-0.2.5/src/findpython/__init__.py     2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/__init__.py     2023-12-07 
05:39:09.105851000 +0100
@@ -5,7 +5,11 @@
 """
 from __future__ import annotations
 
+from typing import TYPE_CHECKING, TypeVar
+
 from findpython.finder import Finder
+from findpython.providers import ALL_PROVIDERS
+from findpython.providers.base import BaseProvider
 from findpython.python import PythonVersion
 
 
@@ -41,4 +45,18 @@
     return Finder().find_all(*args, **kwargs)
 
 
-__all__ = ["Finder", "find", "find_all", "PythonVersion"]
+if TYPE_CHECKING:
+    P = TypeVar("P", bound=type[BaseProvider])
+
+
+def register_provider(provider: P) -> P:
+    """
+    Register a provider to use when finding python versions.
+
+    :param provider: A provider class
+    """
+    ALL_PROVIDERS[provider.name()] = provider
+    return provider
+
+
+__all__ = ["Finder", "find", "find_all", "PythonVersion", "register_provider"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/__main__.py 
new/findpython-0.4.1/src/findpython/__main__.py
--- old/findpython-0.2.5/src/findpython/__main__.py     2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/__main__.py     2023-12-07 
05:39:09.105851000 +0100
@@ -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__
@@ -21,11 +20,17 @@
     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.
     """
-    parser = ArgumentParser("findpython", description="Find python files in a 
directory")
+    parser = ArgumentParser(
+        "findpython", description="A utility to find python versions on your 
system"
+    )
     parser.add_argument(
         "-V", "--version", action="version", version=f"%(prog)s {__version__}"
     )
@@ -46,17 +51,27 @@
         action="store_true",
         help="Eliminate the duplicated results with the same sys.executable",
     )
+    parser.add_argument(
+        "--pre", "--prereleases", action="store_true", help="Allow prereleases"
+    )
+    parser.add_argument("--providers", 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.providers,
+    )
     if args.all:
         find_func = finder.find_all
     else:
-        find_func = finder.find
-    python_versions = find_func(args.version_spec)
+        find_func = finder.find  # type: ignore[assignment]
+
+    python_versions = find_func(args.version_spec, allow_prereleases=args.pre)
     if not python_versions:
         print("No matching python version found", file=sys.stderr)
         return 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/__version__.py 
new/findpython-0.4.1/src/findpython/__version__.py
--- old/findpython-0.2.5/src/findpython/__version__.py  2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/__version__.py  2023-12-07 
05:39:20.101811400 +0100
@@ -1 +1 @@
-__version__ = "0.0.0"
+__version__ = "0.4.1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/finder.py 
new/findpython-0.4.1/src/findpython/finder.py
--- old/findpython-0.2.5/src/findpython/finder.py       2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/finder.py       2023-12-07 
05:39:09.105851000 +0100
@@ -24,16 +24,22 @@
         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._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:
+        allowed_providers = ALL_PROVIDERS
+        if selected_providers is not None:
+            allowed_providers = {name: ALL_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__)
@@ -59,6 +65,7 @@
         dev: bool | None = None,
         name: str | None = None,
         architecture: str | None = None,
+        allow_prereleases: bool = False,
     ) -> list[PythonVersion]:
         """
         Return all Python versions matching the given version criteria.
@@ -70,8 +77,13 @@
         :param dev: Whether the python is a devrelease.
         :param name: The name of the python.
         :param architecture: The architecture of the python.
+        :param allow_prereleases: Whether to allow prereleases.
         :return: a list of PythonVersion objects
         """
+        if allow_prereleases and (pre is False or dev is False):
+            raise ValueError(
+                "If allow_prereleases is True, pre and dev must not be False."
+            )
         if isinstance(major, str):
             if any(v is not None for v in (minor, patch, pre, dev, name)):
                 raise ValueError(
@@ -85,6 +97,9 @@
                 patch = version_dict["patch"]
                 pre = version_dict["pre"]
                 dev = version_dict["dev"]
+                if allow_prereleases:
+                    pre = pre or None
+                    dev = dev or None
                 architecture = version_dict["architecture"]
             else:
                 name, major = major, None
@@ -112,6 +127,7 @@
         dev: bool | None = None,
         name: str | None = None,
         architecture: str | None = None,
+        allow_prereleases: bool = False,
     ) -> PythonVersion | None:
         """
         Return the Python version that is closest to the given version 
criteria.
@@ -123,10 +139,15 @@
         :param dev: Whether the python is a devrelease.
         :param name: The name of the python.
         :param architecture: The architecture of the python.
+        :param allow_prereleases: Whether to allow prereleases.
         :return: a Python object or None
         """
         return next(
-            iter(self.find_all(major, minor, patch, pre, dev, name, 
architecture)),
+            iter(
+                self.find_all(
+                    major, minor, patch, pre, dev, name, architecture, 
allow_prereleases
+                )
+            ),
             None,
         )
 
@@ -149,7 +170,7 @@
                 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),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/findpython-0.2.5/src/findpython/pep514tools/__init__.py 
new/findpython-0.4.1/src/findpython/pep514tools/__init__.py
--- old/findpython-0.2.5/src/findpython/pep514tools/__init__.py 2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/pep514tools/__init__.py 2023-12-07 
05:39:09.105851000 +0100
@@ -8,6 +8,6 @@
 __author__ = "Steve Dower <steve.do...@python.org>"
 __version__ = "0.1.0"
 
-from findpython.pep514tools.environment import findall, find, findone
+from findpython.pep514tools.environment import find, findall, findone
 
 __all__ = ["findall", "find", "findone"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/findpython-0.2.5/src/findpython/pep514tools/_registry.py 
new/findpython-0.4.1/src/findpython/pep514tools/_registry.py
--- old/findpython-0.2.5/src/findpython/pep514tools/_registry.py        
2023-05-10 10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/pep514tools/_registry.py        
2023-12-07 05:39:09.105851000 +0100
@@ -12,8 +12,8 @@
     "REGISTRY_SOURCE_CU",
 ]
 
-from itertools import count
 import re
+from itertools import count
 
 try:
     import winreg
@@ -86,10 +86,8 @@
         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):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/findpython-0.2.5/src/findpython/pep514tools/environment.py 
new/findpython-0.4.1/src/findpython/pep514tools/environment.py
--- old/findpython-0.2.5/src/findpython/pep514tools/environment.py      
2023-05-10 10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/pep514tools/environment.py      
2023-12-07 05:39:09.105851000 +0100
@@ -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 = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/findpython-0.2.5/src/findpython/providers/__init__.py 
new/findpython-0.4.1/src/findpython/providers/__init__.py
--- old/findpython-0.2.5/src/findpython/providers/__init__.py   2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/providers/__init__.py   2023-12-07 
05:39:09.109851000 +0100
@@ -1,25 +1,29 @@
 """
 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
 from findpython.providers.macos import MacOSProvider
 from findpython.providers.path import PathProvider
-from findpython.providers.pep514 import Pep514Provider
 from findpython.providers.pyenv import PyenvProvider
+from findpython.providers.rye import RyeProvider
+from findpython.providers.winreg import WinregProvider
 
-ALL_PROVIDERS: List[Type[BaseProvider]] = [
+_providers: list[type[BaseProvider]] = [
     # General:
     PathProvider,
     # Tool Specific:
     AsdfProvider,
     PyenvProvider,
+    RyeProvider,
     # Windows only:
-    Pep514Provider,
+    WinregProvider,
     # MacOS only:
     MacOSProvider,
 ]
 
-__all__ = [cls.__name__ for cls in ALL_PROVIDERS] + ["ALL_PROVIDERS", 
"BaseProvider"]
+ALL_PROVIDERS = {cls.name(): cls for cls in _providers}
+
+__all__ = [cls.__name__ for cls in _providers] + ["ALL_PROVIDERS", 
"BaseProvider"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/providers/asdf.py 
new/findpython-0.4.1/src/findpython/providers/asdf.py
--- old/findpython-0.2.5/src/findpython/providers/asdf.py       2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/providers/asdf.py       2023-12-07 
05:39:09.109851000 +0100
@@ -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
 
 
@@ -15,7 +15,7 @@
         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"))
         )
@@ -23,7 +23,7 @@
             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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/providers/base.py 
new/findpython-0.4.1/src/findpython/providers/base.py
--- old/findpython-0.2.5/src/findpython/providers/base.py       2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/providers/base.py       2023-12-07 
05:39:09.109851000 +0100
@@ -2,36 +2,46 @@
 
 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:
+        """Configuration name for this provider.
+
+        By default, the lowercase class name with 'provider' removed.
+        """
+        self_name = cls.__name__.lower()
+        if self_name.endswith("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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/providers/macos.py 
new/findpython-0.4.1/src/findpython/providers/macos.py
--- old/findpython-0.2.5/src/findpython/providers/macos.py      2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/providers/macos.py      2023-12-07 
05:39:09.109851000 +0100
@@ -1,9 +1,9 @@
 from __future__ import annotations
 
+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
 
 
@@ -15,12 +15,12 @@
     INSTALL_BASE = Path("/Library/Frameworks/Python.framework/Versions/")
 
     @classmethod
-    def create(cls: Type[T]) -> T | None:
+    def create(cls) -> t.Self | None:
         if not cls.INSTALL_BASE.exists():
             return None
         return cls()
 
-    def find_pythons(self) -> Iterable[PythonVersion]:
+    def find_pythons(self) -> t.Iterable[PythonVersion]:
         for version in self.INSTALL_BASE.iterdir():
             if version.is_dir():
                 yield from self.find_pythons_from_path(version / "bin", True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/providers/path.py 
new/findpython-0.4.1/src/findpython/providers/path.py
--- old/findpython-0.2.5/src/findpython/providers/path.py       2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/providers/path.py       2023-12-07 
05:39:09.109851000 +0100
@@ -1,11 +1,11 @@
 from __future__ import annotations
 
 import os
+import typing as t
 from dataclasses import dataclass
 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
 
 
@@ -16,10 +16,10 @@
     paths: list[Path]
 
     @classmethod
-    def create(cls: Type[T]) -> T | None:
+    def create(cls) -> t.Self | None:
         paths = [Path(path) for path in os.getenv("PATH", 
"").split(os.pathsep) if path]
         return cls(paths)
 
-    def find_pythons(self) -> Iterable[PythonVersion]:
+    def find_pythons(self) -> t.Iterable[PythonVersion]:
         for path in self.paths:
             yield from self.find_pythons_from_path(path)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/providers/pep514.py 
new/findpython-0.4.1/src/findpython/providers/pep514.py
--- old/findpython-0.2.5/src/findpython/providers/pep514.py     2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/providers/pep514.py     1970-01-01 
01:00:00.000000000 +0100
@@ -1,42 +0,0 @@
-from __future__ import annotations
-
-import platform
-from pathlib import Path
-from typing import Iterable, Type
-
-from findpython.providers.base import BaseProvider, T
-from findpython.python import PythonVersion
-from findpython.utils import WINDOWS
-
-SYS_ARCHITECTURE = platform.architecture()[0]
-
-
-class Pep514Provider(BaseProvider):
-    """A provider that finds Python from the winreg."""
-
-    @classmethod
-    def create(cls: Type[T]) -> T | None:
-        if not WINDOWS:
-            return None
-        return cls()
-
-    def find_pythons(self) -> Iterable[PythonVersion]:
-        from findpython.pep514tools import findall as pep514_findall
-
-        env_versions = pep514_findall()
-        for version in env_versions:
-            install_path = getattr(version.info, "install_path", None)
-            if install_path is None:
-                continue
-            try:
-                path = Path(install_path.executable_path)
-            except AttributeError:
-                continue
-            if path.exists():
-                py_ver = self.version_maker(
-                    path,
-                    None,
-                    getattr(version.info, "sys_architecture", 
SYS_ARCHITECTURE),
-                    path,
-                )
-                yield py_ver
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/providers/pyenv.py 
new/findpython-0.4.1/src/findpython/providers/pyenv.py
--- old/findpython-0.2.5/src/findpython/providers/pyenv.py      2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/providers/pyenv.py      2023-12-07 
05:39:09.109851000 +0100
@@ -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
 
 
@@ -15,7 +15,7 @@
         self.root = root
 
     @classmethod
-    def create(cls: Type[T]) -> T | None:
+    def create(cls) -> t.Self | None:
         pyenv_root = os.path.expanduser(
             os.path.expandvars(os.getenv("PYENV_ROOT", "~/.pyenv"))
         )
@@ -23,7 +23,7 @@
             return None
         return cls(Path(pyenv_root))
 
-    def find_pythons(self) -> Iterable[PythonVersion]:
+    def find_pythons(self) -> t.Iterable[PythonVersion]:
         versions_path = self.root.joinpath("versions")
         if versions_path.exists():
             for version in versions_path.iterdir():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/providers/rye.py 
new/findpython-0.4.1/src/findpython/providers/rye.py
--- old/findpython-0.2.5/src/findpython/providers/rye.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/findpython-0.4.1/src/findpython/providers/rye.py        2023-12-07 
05:39:09.109851000 +0100
@@ -0,0 +1,33 @@
+from __future__ import annotations
+
+import shutil
+import typing as t
+from pathlib import Path
+
+from findpython.providers.base import BaseProvider
+from findpython.python import PythonVersion
+from findpython.utils import WINDOWS, safe_iter_dir
+
+
+class RyeProvider(BaseProvider):
+    def __init__(self) -> None:
+        self.root = Path.home() / ".rye"
+        self.rye_bin = shutil.which("rye")
+
+    @classmethod
+    def create(cls) -> t.Self | None:
+        return cls()
+
+    def find_pythons(self) -> t.Iterable[PythonVersion]:
+        py_root = self.root / "py"
+        if not py_root.exists():
+            return
+        for child in safe_iter_dir(py_root):
+            if child.is_symlink():  # registered an existing python
+                continue
+            if WINDOWS:
+                python_bin = child / "install/python.exe"
+            else:
+                python_bin = child / "install/bin/python3"
+            if python_bin.exists():
+                yield self.version_maker(python_bin, _interpreter=python_bin)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/providers/winreg.py 
new/findpython-0.4.1/src/findpython/providers/winreg.py
--- old/findpython-0.2.5/src/findpython/providers/winreg.py     1970-01-01 
01:00:00.000000000 +0100
+++ new/findpython-0.4.1/src/findpython/providers/winreg.py     2023-12-07 
05:39:09.109851000 +0100
@@ -0,0 +1,42 @@
+from __future__ import annotations
+
+import platform
+import typing as t
+from pathlib import Path
+
+from findpython.providers.base import BaseProvider
+from findpython.python import PythonVersion
+from findpython.utils import WINDOWS
+
+SYS_ARCHITECTURE = platform.architecture()[0]
+
+
+class WinregProvider(BaseProvider):
+    """A provider that finds Python from the winreg."""
+
+    @classmethod
+    def create(cls) -> t.Self | None:
+        if not WINDOWS:
+            return None
+        return cls()
+
+    def find_pythons(self) -> t.Iterable[PythonVersion]:
+        from findpython.pep514tools import findall as pep514_findall
+
+        env_versions = pep514_findall()
+        for version in env_versions:
+            install_path = getattr(version.info, "install_path", None)
+            if install_path is None:
+                continue
+            try:
+                path = Path(install_path.executable_path)
+            except AttributeError:
+                continue
+            if path.exists():
+                py_ver = self.version_maker(
+                    path,
+                    None,
+                    getattr(version.info, "sys_architecture", 
SYS_ARCHITECTURE),
+                    path,
+                )
+                yield py_ver
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/python.py 
new/findpython-0.4.1/src/findpython/python.py
--- old/findpython-0.2.5/src/findpython/python.py       2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/python.py       2023-12-07 
05:39:09.109851000 +0100
@@ -2,6 +2,7 @@
 
 import dataclasses as dc
 import logging
+import os
 import subprocess
 from functools import lru_cache
 from pathlib import Path
@@ -11,7 +12,22 @@
 from findpython.utils import get_binary_hash
 
 logger = logging.getLogger("findpython")
-GET_VERSION_TIMEOUT = 5
+GET_VERSION_TIMEOUT = float(os.environ.get("FINDPYTHON_GET_VERSION_TIMEOUT", 
5))
+
+
+@lru_cache(maxsize=1024)
+def _run_script(executable: str, script: str, timeout: float | None = None) -> 
str:
+    """Run a script and return the output."""
+    command = [executable, "-EsSc", script]
+    logger.debug("Running script: %s", command)
+    return subprocess.run(
+        command,
+        stdout=subprocess.PIPE,
+        stderr=subprocess.DEVNULL,
+        timeout=timeout,
+        check=True,
+        text=True,
+    ).stdout
 
 
 @dc.dataclass
@@ -161,7 +177,9 @@
     def _get_version(self) -> Version:
         """Get the version of the python."""
         script = "import platform; print(platform.python_version())"
-        version = self._run_script(script, timeout=GET_VERSION_TIMEOUT).strip()
+        version = _run_script(
+            str(self.executable), script, timeout=GET_VERSION_TIMEOUT
+        ).strip()
         # Dev builds may produce version like `3.11.0+` and packaging.version
         # will reject it. Here we just remove the part after `+`
         # since it isn't critical for version comparison.
@@ -170,25 +188,11 @@
 
     def _get_architecture(self) -> str:
         script = "import platform; print(platform.architecture()[0])"
-        return self._run_script(script).strip()
+        return _run_script(str(self.executable), script).strip()
 
     def _get_interpreter(self) -> str:
         script = "import sys; print(sys.executable)"
-        return self._run_script(script).strip()
-
-    @lru_cache(maxsize=1024)
-    def _run_script(self, script: str, timeout: float | None = None) -> str:
-        """Run a script and return the output."""
-        command = [self.executable.as_posix(), "-c", script]
-        logger.debug("Running script: %s", command)
-        return subprocess.run(
-            command,
-            stdout=subprocess.PIPE,
-            stderr=subprocess.DEVNULL,
-            timeout=timeout,
-            check=True,
-            text=True,
-        ).stdout
+        return _run_script(str(self.executable), script).strip()
 
     def __lt__(self, other: PythonVersion) -> bool:
         """Sort by the version, then by length of the executable path."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/src/findpython/utils.py 
new/findpython-0.4.1/src/findpython/utils.py
--- old/findpython-0.2.5/src/findpython/utils.py        2023-05-10 
10:27:49.053817000 +0200
+++ new/findpython-0.4.1/src/findpython/utils.py        2023-12-07 
05:39:09.109851000 +0100
@@ -7,7 +7,10 @@
 import sys
 from functools import lru_cache
 from pathlib import Path
-from typing import Generator
+from typing import TYPE_CHECKING, cast
+
+if TYPE_CHECKING:
+    from typing import Generator, Sequence, TypedDict
 
 VERSION_RE = re.compile(
     r"(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>[0-9]+))?)?\.?"
@@ -30,7 +33,7 @@
     "micropython",
 )
 if WINDOWS:
-    KNOWN_EXTS = (".exe", "", ".py", ".bat")
+    KNOWN_EXTS: Sequence[str] = (".exe", "", ".py", ".bat")
 else:
     KNOWN_EXTS = ("", ".sh", ".bash", ".csh", ".zsh", ".fish", ".py")
 PY_MATCH_STR = (
@@ -117,7 +120,18 @@
     return hasher.hexdigest()
 
 
-def parse_major(version: str) -> dict[str, int | bool | None] | None:
+if TYPE_CHECKING:
+
+    class VersionDict(TypedDict):
+        pre: bool
+        dev: bool
+        major: int | None
+        minor: int | None
+        patch: int | None
+        architecture: str | None
+
+
+def parse_major(version: str) -> VersionDict | None:
     """Parse the version dict from the version string"""
     match = VERSION_RE.match(version)
     if not match:
@@ -130,7 +144,7 @@
             rv[int_values] = int(rv[int_values])
     if rv["architecture"]:
         rv["architecture"] = f"{rv['architecture']}bit"
-    return rv
+    return cast("VersionDict", rv)
 
 
 def get_suffix_preference(name: str) -> int:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/tests/conftest.py 
new/findpython-0.4.1/tests/conftest.py
--- old/findpython-0.2.5/tests/conftest.py      2023-05-10 10:27:49.053817000 
+0200
+++ new/findpython-0.4.1/tests/conftest.py      2023-12-07 05:39:09.109851000 
+0100
@@ -9,7 +9,7 @@
 
 class _MockRegistry:
     def __init__(self) -> None:
-        self.versions = {}
+        self.versions: dict[Path, PythonVersion] = {}
 
     def add_python(
         self,
@@ -51,7 +51,8 @@
     monkeypatch.setattr(
         "findpython.providers.base.BaseProvider.version_maker", 
mocked.version_maker
     )
-    ALL_PROVIDERS[:] = [PathProvider]
+    ALL_PROVIDERS.clear()
+    ALL_PROVIDERS["path"] = PathProvider
     monkeypatch.setenv("PATH", str(tmp_path))
     return mocked
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/tests/test_finder.py 
new/findpython-0.4.1/tests/test_finder.py
--- old/findpython-0.2.5/tests/test_finder.py   2023-05-10 10:27:49.053817000 
+0200
+++ new/findpython-0.4.1/tests/test_finder.py   2023-12-07 05:39:09.109851000 
+0100
@@ -4,8 +4,7 @@
 import pytest
 from packaging.version import Version
 
-from findpython import Finder
-from findpython.providers import ALL_PROVIDERS
+from findpython import Finder, register_provider
 from findpython.providers.pyenv import PyenvProvider
 
 
@@ -117,7 +116,7 @@
 
 
 def test_find_python_from_pyenv(mocked_python, tmp_path, monkeypatch):
-    ALL_PROVIDERS.append(PyenvProvider)
+    register_provider(PyenvProvider)
     python = mocked_python.add_python(
         tmp_path / ".pyenv/versions/3.8/bin/python", "3.8.0"
     )
@@ -128,7 +127,7 @@
 
 
 def test_find_python_skips_empty_pyenv(mocked_python, tmp_path, monkeypatch):
-    ALL_PROVIDERS.append(PyenvProvider)
+    register_provider(PyenvProvider)
     pyenv_path = Path(tmp_path / ".pyenv")
     pyenv_path.mkdir()
     monkeypatch.setenv("PYENV_ROOT", str(pyenv_path))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/tests/test_posix.py 
new/findpython-0.4.1/tests/test_posix.py
--- old/findpython-0.2.5/tests/test_posix.py    2023-05-10 10:27:49.053817000 
+0200
+++ new/findpython-0.4.1/tests/test_posix.py    2023-12-07 05:39:09.109851000 
+0100
@@ -4,9 +4,11 @@
 
 import pytest
 
+from findpython import register_provider
 from findpython.finder import Finder
-from findpython.providers import ALL_PROVIDERS
 from findpython.providers.asdf import AsdfProvider
+from findpython.providers.pyenv import PyenvProvider
+from findpython.providers.rye import RyeProvider
 
 if sys.platform == "win32":
     pytest.skip("Skip POSIX tests on Windows", allow_module_level=True)
@@ -23,7 +25,7 @@
 
 
 def test_find_python_from_asdf(mocked_python, tmp_path, monkeypatch):
-    ALL_PROVIDERS.append(AsdfProvider)
+    register_provider(AsdfProvider)
     python = mocked_python.add_python(
         tmp_path / ".asdf/installs/python/3.8/bin/python", "3.8.0"
     )
@@ -43,3 +45,45 @@
         assert python not in [version.executable for version in all_pythons]
     finally:
         python.chmod(0o744)
+
+
+def test_find_python_from_provider(mocked_python, tmp_path, monkeypatch):
+    register_provider(AsdfProvider)
+    register_provider(PyenvProvider)
+    python38 = mocked_python.add_python(
+        tmp_path / ".asdf/installs/python/3.8/bin/python", "3.8.0"
+    )
+    python381 = mocked_python.add_python(
+        tmp_path / ".pyenv/versions/3.8.1/bin/python", "3.8.1"
+    )
+    python382 = mocked_python.add_python(
+        tmp_path / ".asdf/installs/python/3.8.2/bin/python", "3.8.2"
+    )
+    monkeypatch.setenv("ASDF_DATA_DIR", str(tmp_path / ".asdf"))
+    monkeypatch.setenv("PYENV_ROOT", str(tmp_path / ".pyenv"))
+
+    pythons = Finder(selected_providers=["pyenv", "asdf"]).find_all(3, 8)
+    assert len(pythons) == 3
+    assert python38 in pythons
+    assert python381 in pythons
+    assert python382 in pythons
+
+    asdf_pythons = Finder(selected_providers=["asdf"]).find_all(3, 8)
+    assert len(asdf_pythons) == 2
+    assert python38 in asdf_pythons
+    assert python382 in asdf_pythons
+
+    pyenv_pythons = Finder(selected_providers=["pyenv"]).find_all(3, 8)
+    assert len(pyenv_pythons) == 1
+    assert python381 in pyenv_pythons
+
+
+def test_find_python_from_rye_provider(mocked_python, tmp_path, monkeypatch):
+    python310 = mocked_python.add_python(
+        tmp_path / ".rye/py/cpython@3.10.9/install/bin/python3", "3.10.9"
+    )
+    monkeypatch.setenv("HOME", str(tmp_path))
+
+    register_provider(RyeProvider)
+    pythons = Finder(selected_providers=["rye"]).find_all(3, 10)
+    assert python310 in pythons
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/findpython-0.2.5/tests/test_utils.py 
new/findpython-0.4.1/tests/test_utils.py
--- old/findpython-0.2.5/tests/test_utils.py    2023-05-10 10:27:49.053817000 
+0200
+++ new/findpython-0.4.1/tests/test_utils.py    2023-12-07 05:39:09.109851000 
+0100
@@ -1,6 +1,6 @@
-from findpython.utils import WINDOWS, looks_like_python
 import pytest
 
+from findpython.utils import WINDOWS, looks_like_python
 
 matrix = [
     ("python", True),

++++++ revert-back-to-pdm-pep517.patch ++++++
Index: findpython-0.4.1/pyproject.toml
===================================================================
--- findpython-0.4.1.orig/pyproject.toml
+++ findpython-0.4.1/pyproject.toml
@@ -81,6 +81,6 @@ known-first-party = [
 
 [build-system]
 requires = [
-    "pdm-backend",
+    "pdm-pep517",
 ]
-build-backend = "pdm.backend"
+build-backend = "pdm.pep517.api"

Reply via email to