Skip to content

Commit 401297c

Browse files
committed
modernize type hints and remove deprecated python support
1 parent bb60a2c commit 401297c

10 files changed

Lines changed: 60 additions & 78 deletions

File tree

plux/build/discovery.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __init__(self, modules: t.Iterable[ModuleType], resolver: PluginSpecResolver
3232
self.modules = modules
3333
self.resolver = resolver or PluginSpecResolver()
3434

35-
def find_plugins(self) -> t.List[PluginSpec]:
35+
def find_plugins(self) -> list[PluginSpec]:
3636
plugins = list()
3737

3838
for module in self.modules:

plux/build/setuptools.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class plugins(InfoCommon, setuptools.Command):
6464

6565
description = "Discover plux plugins and store them in .egg_info"
6666

67-
user_options: t.ClassVar[t.List[t.Tuple[str, str, str]]] = [
67+
user_options: t.ClassVar[list[tuple[str, str, str]]] = [
6868
(
6969
"exclude=",
7070
"e",
@@ -368,7 +368,7 @@ def entry_points_from_egg_info(egg_info_dir: str) -> EntryPointDict:
368368
return entry_points_from_metadata_path(egg_info_dir)
369369

370370

371-
def _should_read_existing_egg_info() -> t.Tuple[bool, t.Optional[str]]:
371+
def _should_read_existing_egg_info() -> tuple[bool, str | None]:
372372
# we want to read the .egg-info dir only if it exists, and if we are creating the egg_info or
373373
# installing it with pip install -e (which calls 'setup.py develop')
374374

@@ -419,7 +419,7 @@ def _is_local_build_context():
419419
return False
420420

421421

422-
def find_egg_info_dir() -> t.Optional[str]:
422+
def find_egg_info_dir() -> str | None:
423423
"""
424424
Heuristic to find the .egg-info dir of the current build context.
425425
"""
@@ -546,8 +546,8 @@ class DistributionPackageFinder(_PackageFinder):
546546
def __init__(
547547
self,
548548
distribution: setuptools.Distribution,
549-
exclude: t.Optional[t.Iterable[str]] = None,
550-
include: t.Optional[t.Iterable[str]] = None,
549+
exclude: t.Iterable[str] | None = None,
550+
include: t.Iterable[str] | None = None,
551551
):
552552
self.distribution = distribution
553553
self.exclude = _Filter(exclude or [])
@@ -596,7 +596,7 @@ class PluginFromPackageFinder(PluginFinder):
596596
def __init__(self, finder: _PackageFinder):
597597
self.finder = finder
598598

599-
def find_plugins(self) -> t.List[PluginSpec]:
599+
def find_plugins(self) -> list[PluginSpec]:
600600
collector = ModuleScanningPluginFinder(self.load_modules())
601601
return collector.find_plugins()
602602

plux/core/entrypoint.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class EntryPoint(t.NamedTuple):
1111
group: str
1212

1313

14-
EntryPointDict = t.Dict[str, t.List[str]]
14+
EntryPointDict = dict[str, list[str]]
1515

1616

1717
def discover_entry_points(finder: PluginFinder) -> EntryPointDict:
@@ -24,7 +24,7 @@ def discover_entry_points(finder: PluginFinder) -> EntryPointDict:
2424
return to_entry_point_dict([spec_to_entry_point(spec) for spec in finder.find_plugins()])
2525

2626

27-
def to_entry_point_dict(eps: t.List[EntryPoint]) -> EntryPointDict:
27+
def to_entry_point_dict(eps: list[EntryPoint]) -> EntryPointDict:
2828
"""
2929
Convert the list of EntryPoint objects to a dictionary that maps entry point groups to their respective list of
3030
``name=value`` entry points. Each pair is represented as a string.

plux/core/plugin.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Plugin(abc.ABC):
3535

3636
namespace: str
3737
name: str
38-
requirements: t.List[str]
38+
requirements: list[str]
3939

4040
def should_load(self) -> bool:
4141
return True
@@ -94,7 +94,7 @@ class PluginFinder(abc.ABC):
9494
(e.g., using StevedorePluginFinder that finds plugins from entrypoints)
9595
"""
9696

97-
def find_plugins(self) -> t.List[PluginSpec]:
97+
def find_plugins(self) -> list[PluginSpec]:
9898
raise NotImplementedError # pragma: no cover
9999

100100

@@ -148,8 +148,8 @@ def on_load_before(
148148
self,
149149
plugin_spec: PluginSpec,
150150
plugin: Plugin,
151-
load_args: t.Union[t.List, t.Tuple],
152-
load_kwargs: t.Dict,
151+
load_args: list | tuple,
152+
load_kwargs: dict,
153153
):
154154
pass
155155

@@ -163,7 +163,7 @@ def on_load_exception(self, plugin_spec: PluginSpec, plugin: Plugin, exception:
163163
class CompositePluginLifecycleListener(PluginLifecycleListener):
164164
"""A PluginLifecycleListener decorator that dispatches to multiple delegates."""
165165

166-
listeners: t.List[PluginLifecycleListener]
166+
listeners: list[PluginLifecycleListener]
167167

168168
def __init__(self, initial: t.Iterable[PluginLifecycleListener] = None):
169169
self.listeners = list(initial) if initial else []
@@ -210,7 +210,7 @@ class FunctionPlugin(Plugin):
210210
def __init__(
211211
self,
212212
fn: t.Callable,
213-
should_load: t.Union[bool, t.Callable[[], bool]] = None,
213+
should_load: bool | t.Callable[[], bool] = None,
214214
load: t.Callable = None,
215215
) -> None:
216216
super().__init__()
@@ -238,7 +238,7 @@ def should_load(self) -> bool:
238238
def plugin(
239239
namespace,
240240
name=None,
241-
should_load: t.Union[bool, t.Callable[[], bool]] = None,
241+
should_load: bool | t.Callable[[], bool] = None,
242242
load: t.Callable = None,
243243
):
244244
"""

plux/runtime/cache.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import struct
77
import sys
88
import threading
9-
import typing as t
109
from importlib import metadata
1110
from pathlib import Path
1211

@@ -67,7 +66,7 @@ class EntryPointsCache(EntryPointsResolver):
6766
_instance: "EntryPointsCache" = None
6867
_instance_lock: threading.RLock = threading.RLock()
6968

70-
_cache: t.Dict[t.Tuple[str, ...], t.Dict[str, t.List[metadata.EntryPoint]]]
69+
_cache: dict[tuple[str, ...], dict[str, list[metadata.EntryPoint]]]
7170
"""For each specific path (like sys.path), we store a dict of group -> [entry point]."""
7271

7372
def __init__(self):
@@ -76,7 +75,7 @@ def __init__(self):
7675
self._resolver = MetadataEntryPointsResolver()
7776
self._cache_dir = get_user_cache_dir() / "plux"
7877

79-
def get_entry_points(self) -> t.Dict[str, t.List[metadata.EntryPoint]]:
78+
def get_entry_points(self) -> dict[str, list[metadata.EntryPoint]]:
8079
"""
8180
Returns a dictionary of entry points for the current ``sys.path``.
8281
"""
@@ -98,7 +97,7 @@ def get_entry_points(self) -> t.Dict[str, t.List[metadata.EntryPoint]]:
9897

9998
return self._cache[key]
10099

101-
def _build_and_store_index(self, cache_dir: Path) -> t.Dict[str, t.List[metadata.EntryPoint]]:
100+
def _build_and_store_index(self, cache_dir: Path) -> dict[str, list[metadata.EntryPoint]]:
102101
# first, try and load the index from the file system
103102
path_key = self._calculate_hash_key(sys.path)
104103

@@ -117,7 +116,7 @@ def _build_and_store_index(self, cache_dir: Path) -> t.Dict[str, t.List[metadata
117116

118117
return index
119118

120-
def _calculate_hash_key(self, path: t.List[str]):
119+
def _calculate_hash_key(self, path: list[str]):
121120
"""
122121
Calculates a hash of all modified times of all ``entry_point.txt`` files in the path. Basic idea
123122
taken from ``stevedore._cache._hash_settings_for_path``. The main difference to it is that it also

plux/runtime/filter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class MatchingPluginFilter:
5454
A MatchingPluginFilter can be used to exclude specific plugins from loading.
5555
"""
5656

57-
exclusions: t.List[PluginSpecMatcher]
57+
exclusions: list[PluginSpecMatcher]
5858

5959
def __init__(self):
6060
self.exclusions = []

plux/runtime/manager.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
P = t.TypeVar("P", bound=Plugin)
2121

2222

23-
def _call_safe(func: t.Callable, args: t.Tuple, exception_message: str):
23+
def _call_safe(func: t.Callable, args: tuple, exception_message: str):
2424
"""
2525
Call the given function with the given arguments, and if it fails, log the given exception_message. If
2626
logging.DEBUG is set for the logger, then we also log the traceback. An exception is made for any
@@ -47,7 +47,7 @@ class PluginLifecycleNotifierMixin:
4747
Mixin that provides functions to dispatch calls to a PluginLifecycleListener in a safe way.
4848
"""
4949

50-
listeners: t.List[PluginLifecycleListener]
50+
listeners: list[PluginLifecycleListener]
5151

5252
def _fire_on_resolve_after(self, plugin_spec):
5353
for listener in self.listeners:
@@ -155,19 +155,19 @@ class PluginManager(PluginLifecycleNotifierMixin, t.Generic[P]):
155155

156156
namespace: str
157157

158-
load_args: t.Union[t.List, t.Tuple]
159-
load_kwargs: t.Dict[str, t.Any]
160-
listeners: t.List[PluginLifecycleListener]
161-
filters: t.List[PluginFilter]
158+
load_args: list | tuple
159+
load_kwargs: dict[str, t.Any]
160+
listeners: list[PluginLifecycleListener]
161+
filters: list[PluginFilter]
162162

163163
def __init__(
164164
self,
165165
namespace: str,
166-
load_args: t.Union[t.List, t.Tuple] = None,
167-
load_kwargs: t.Dict = None,
168-
listener: t.Union[PluginLifecycleListener, t.Iterable[PluginLifecycleListener]] = None,
166+
load_args: list | tuple = None,
167+
load_kwargs: dict = None,
168+
listener: PluginLifecycleListener | t.Iterable[PluginLifecycleListener] = None,
169169
finder: PluginFinder = None,
170-
filters: t.List[PluginFilter] = None,
170+
filters: list[PluginFilter] = None,
171171
):
172172
"""
173173
Create a new PluginManager.
@@ -236,7 +236,7 @@ def load(self, name: str) -> P:
236236

237237
return container.plugin
238238

239-
def load_all(self, propagate_exceptions=False) -> t.List[P]:
239+
def load_all(self, propagate_exceptions=False) -> list[P]:
240240
"""
241241
Attempts to load all plugins found in the namespace, and returns those that were loaded successfully. If
242242
propagate_exception is set to True, then the method will re-raise any errors as soon as it encouters them.
@@ -261,13 +261,13 @@ def load_all(self, propagate_exceptions=False) -> t.List[P]:
261261

262262
return plugins
263263

264-
def list_plugin_specs(self) -> t.List[PluginSpec]:
264+
def list_plugin_specs(self) -> list[PluginSpec]:
265265
return [container.plugin_spec for container in self._plugins.values()]
266266

267-
def list_names(self) -> t.List[str]:
267+
def list_names(self) -> list[str]:
268268
return [spec.name for spec in self.list_plugin_specs()]
269269

270-
def list_containers(self) -> t.List[PluginContainer[P]]:
270+
def list_containers(self) -> list[PluginContainer[P]]:
271271
return list(self._plugins.values())
272272

273273
def get_container(self, name: str) -> PluginContainer[P]:
@@ -280,7 +280,7 @@ def is_loaded(self, name: str) -> bool:
280280
return self._require_plugin(name).is_loaded
281281

282282
@property
283-
def _plugins(self) -> t.Dict[str, PluginContainer[P]]:
283+
def _plugins(self) -> dict[str, PluginContainer[P]]:
284284
if self._plugin_index is None:
285285
with self._init_mutex:
286286
if self._plugin_index is None:
@@ -363,7 +363,7 @@ def _plugin_from_spec(self, plugin_spec: PluginSpec) -> P:
363363

364364
return factory()
365365

366-
def _init_plugin_index(self) -> t.Dict[str, PluginContainer]:
366+
def _init_plugin_index(self) -> dict[str, PluginContainer]:
367367
return {plugin.name: plugin for plugin in self._import_plugins() if plugin}
368368

369369
def _import_plugins(self) -> t.Iterable[PluginContainer]:

plux/runtime/metadata.py

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,23 @@
66
import inspect
77
import io
88
import os
9-
import sys
109
import typing as t
1110
from functools import lru_cache
1211
from importlib import metadata
1312

14-
if sys.version_info >= (3, 10):
15-
from importlib.metadata import packages_distributions as metadata_packages_distributions
16-
else:
17-
18-
def metadata_packages_distributions() -> t.Mapping[str, t.List[str]]:
19-
"""Copied from Pyton 3.10 stdlib."""
20-
pkg_to_dist = collections.defaultdict(list)
21-
for dist in metadata.distributions():
22-
for pkg in (dist.read_text("top_level.txt") or "").split():
23-
pkg_to_dist[pkg].append(dist.metadata["Name"])
24-
return dict(pkg_to_dist)
25-
26-
2713
from plux.core.entrypoint import EntryPointDict, to_entry_point_dict
2814
from plux.core.plugin import PluginSpec
2915

3016
Distribution = metadata.Distribution
3117

3218

19+
def metadata_packages_distributions():
20+
"""Wrapper around ``importlib.metadata.packages_distributions``, which returns a mapping of top-level packages."""
21+
return metadata.packages_distributions()
22+
23+
3324
@lru_cache()
34-
def packages_distributions() -> t.Mapping[str, t.List[str]]:
25+
def packages_distributions() -> t.Mapping[str, list[str]]:
3526
"""
3627
Cache wrapper around ``metadata.packages_distributions``, which returns a mapping of top-level packages to
3728
their distributions. This index is created by scanning all ``top_level.txt`` metadata files in the path.
@@ -53,7 +44,7 @@ def packages_distributions() -> t.Mapping[str, t.List[str]]:
5344
return distributions
5445

5546

56-
def resolve_distribution_information(plugin_spec: PluginSpec) -> t.Optional[Distribution]:
47+
def resolve_distribution_information(plugin_spec: PluginSpec) -> Distribution | None:
5748
"""
5849
Resolves for a PluginSpec the python distribution package it comes from. Currently, this raises an
5950
error for plugins that come from a namespace package (i.e., when a package is part of multiple
@@ -83,7 +74,7 @@ def entry_points_from_metadata_path(metadata_path: str) -> EntryPointDict:
8374

8475
def resolve_entry_points(
8576
distributions: t.Iterable[Distribution] = None,
86-
) -> t.List[metadata.EntryPoint]:
77+
) -> list[metadata.EntryPoint]:
8778
"""
8879
Resolves all entry points using a combination of ``importlib.metadata``, and also follows entry points
8980
links in ``entry_points_editable.txt`` created by plux while building editable wheels.
@@ -120,7 +111,7 @@ def resolve_entry_points(
120111

121112
def build_entry_point_index(
122113
entry_points: t.Iterable[metadata.EntryPoint],
123-
) -> t.Dict[str, t.List[metadata.EntryPoint]]:
114+
) -> dict[str, list[metadata.EntryPoint]]:
124115
"""
125116
Organizes the given list of entry points into a dictionary that maps entry point groups to their
126117
respective entry points, which resembles the data structure of an ``entry_points.txt``.
@@ -138,24 +129,17 @@ def build_entry_point_index(
138129
return dict(result)
139130

140131

141-
if sys.version_info >= (3, 10):
142-
143-
def parse_entry_points_text(text: str) -> t.List[metadata.EntryPoint]:
144-
"""
145-
Parses the content of an ``entry_points.txt`` into a list of entry point objects.
146-
147-
:param text: the string to parse
148-
:return: a list of metadata EntryPoint objects
149-
"""
150-
return metadata.EntryPoints._from_text(text)
151-
152-
else:
132+
def parse_entry_points_text(text: str) -> list[metadata.EntryPoint]:
133+
"""
134+
Parses the content of an ``entry_points.txt`` into a list of entry point objects.
153135
154-
def parse_entry_points_text(text: str) -> t.List[metadata.EntryPoint]:
155-
return metadata.EntryPoint._from_text(text)
136+
:param text: the string to parse
137+
:return: a list of metadata EntryPoint objects
138+
"""
139+
return metadata.EntryPoints._from_text(text)
156140

157141

158-
def serialize_entry_points_text(index: t.Dict[str, t.List[metadata.EntryPoint]]) -> str:
142+
def serialize_entry_points_text(index: dict[str, list[metadata.EntryPoint]]) -> str:
159143
"""
160144
Serializes an entry point index generated via ``build_entry_point_index`` into a string that can be
161145
written into an ``entry_point.txt``. Example::
@@ -185,7 +169,7 @@ class EntryPointsResolver:
185169
Interface for something that builds an entry point index.
186170
"""
187171

188-
def get_entry_points(self) -> t.Dict[str, t.List[metadata.EntryPoint]]:
172+
def get_entry_points(self) -> dict[str, list[metadata.EntryPoint]]:
189173
raise NotImplementedError
190174

191175

@@ -194,5 +178,5 @@ class MetadataEntryPointsResolver(EntryPointsResolver):
194178
Implementation that uses regular ``importlib.metadata`` methods to resolve entry points.
195179
"""
196180

197-
def get_entry_points(self) -> t.Dict[str, t.List[metadata.EntryPoint]]:
181+
def get_entry_points(self) -> dict[str, list[metadata.EntryPoint]]:
198182
return build_entry_point_index(resolve_entry_points(metadata.distributions()))

plux/runtime/resolve.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def __init__(
3131
self.spec_resolver = spec_resolver or PluginSpecResolver()
3232
self.entry_points_resolver = entry_points_resolver or EntryPointsCache.instance()
3333

34-
def find_plugins(self) -> t.List[PluginSpec]:
34+
def find_plugins(self) -> list[PluginSpec]:
3535
specs = []
3636
finds = self.entry_points_resolver.get_entry_points().get(self.namespace, [])
3737
for ep in finds:

0 commit comments

Comments
 (0)