Skip to content

Commit ac7c948

Browse files
kiukchungfacebook-github-bot
authored andcommitted
(torchx/entrypoints) Use importlib.metadata instead of the backported importlib_metadata (#1087)
Summary: Pull Request resolved: #1087 torchx dropped support for python<=3.7 2 years ago (see: #728). But we kept using the backported `importlib_metadata` module to load configurations from `entry_points`. Reviewed By: highker Differential Revision: D77619564
1 parent 9cddd7f commit ac7c948

File tree

3 files changed

+54
-18
lines changed

3 files changed

+54
-18
lines changed

requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
docstring-parser>=0.8.1
2-
importlib-metadata
32
pyyaml
43
docker
54
filelock

torchx/util/entrypoints.py

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@
55
# LICENSE file in the root directory of this source tree.
66

77
# pyre-strict
8+
# pyre-ignore-all-errors[3, 2, 16]
89

10+
from importlib import metadata
11+
from importlib.metadata import EntryPoint
912
from typing import Any, Dict, Optional
1013

11-
import importlib_metadata as metadata
12-
from importlib_metadata import EntryPoint
1314

14-
15-
# pyre-ignore-all-errors[3, 2]
1615
def load(group: str, name: str, default=None):
1716
"""
1817
Loads the entry point specified by
@@ -30,13 +29,34 @@ def load(group: str, name: str, default=None):
3029
raises an error.
3130
"""
3231

33-
entrypoints = metadata.entry_points().select(group=group)
32+
# [note_on_entrypoints]
33+
# return type of importlib.metadata.entry_points() is different between python-3.9 and python-3.10
34+
# https://docs.python.org/3.9/library/importlib.metadata.html#importlib.metadata.entry_points
35+
# https://docs.python.org/3.10/library/importlib.metadata.html#importlib.metadata.entry_points
36+
if hasattr(metadata.entry_points(), "select"):
37+
# python>=3.10
38+
entrypoints = metadata.entry_points().select(group=group)
3439

35-
if name not in entrypoints.names and default is not None:
36-
return default
40+
if name not in entrypoints.names and default is not None:
41+
return default
42+
43+
ep = entrypoints[name]
44+
return ep.load()
3745

38-
ep = entrypoints[name]
39-
return ep.load()
46+
else:
47+
# python<3.10 (e.g. 3.9)
48+
# metadata.entry_points() returns dict[str, tuple[EntryPoint]] (not EntryPoints) in python-3.9
49+
entrypoints = metadata.entry_points().get(group, ())
50+
51+
for ep in entrypoints:
52+
if ep.name == name:
53+
return ep.load()
54+
55+
# [group].name not found
56+
if default is not None:
57+
return default
58+
else:
59+
raise KeyError(f"entrypoint {group}.{name} not found")
4060

4161

4262
def _defer_load_ep(ep: EntryPoint) -> object:
@@ -49,7 +69,6 @@ def run(*args: object, **kwargs: object) -> object:
4969
return run
5070

5171

52-
# pyre-ignore-all-errors[3, 2]
5372
def load_group(
5473
group: str, default: Optional[Dict[str, Any]] = None, skip_defaults: bool = False
5574
):
@@ -87,7 +106,13 @@ def load_group(
87106
88107
"""
89108

90-
entrypoints = metadata.entry_points().select(group=group)
109+
# see [note_on_entrypoints] above
110+
if hasattr(metadata.entry_points(), "select"):
111+
# python>=3.10
112+
entrypoints = metadata.entry_points().select(group=group)
113+
else:
114+
# python<3.10 (e.g. 3.9)
115+
entrypoints = metadata.entry_points().get(group, ())
91116

92117
if len(entrypoints) == 0:
93118
if skip_defaults:

torchx/util/test/entrypoints_test.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@
88

99
import unittest
1010
from configparser import ConfigParser
11+
12+
from importlib.metadata import EntryPoint
1113
from types import ModuleType
12-
from typing import List
13-
from unittest.mock import MagicMock, patch
1414

15-
from importlib_metadata import EntryPoint, EntryPoints
15+
from unittest.mock import MagicMock, patch
1616

1717
from torchx.util.entrypoints import load, load_group
1818

1919

20-
def EntryPoint_from_config(config: ConfigParser) -> List[EntryPoint]:
20+
def EntryPoint_from_config(config: ConfigParser) -> list[EntryPoint]:
2121
# from stdlib, Copyright (c) Python Authors
2222
return [
2323
EntryPoint(name, value, group)
@@ -26,7 +26,7 @@ def EntryPoint_from_config(config: ConfigParser) -> List[EntryPoint]:
2626
]
2727

2828

29-
def EntryPoint_from_text(text: str) -> List[EntryPoint]:
29+
def EntryPoint_from_text(text: str) -> list[EntryPoint]:
3030
# from stdlib, Copyright (c) Python Authors
3131
config = ConfigParser(delimiters="=")
3232
config.read_string(text)
@@ -66,14 +66,26 @@ def barbaz() -> str:
6666
[ep.grp.missing.mod.test]
6767
baz = torchx.util.test.entrypoints_test.missing_module
6868
"""
69-
_ENTRY_POINTS: EntryPoints = EntryPoints(
69+
70+
_EPS: list[EntryPoint] = (
7071
EntryPoint_from_text(_EP_TXT)
7172
+ EntryPoint_from_text(_EP_GRP_TXT)
7273
+ EntryPoint_from_text(_EP_GRP_IGN_ATTR_TXT)
7374
+ EntryPoint_from_text(_EP_GRP_MOD_TXT)
7475
+ EntryPoint_from_text(_EP_GRP_IGN_MOD_TXT)
7576
)
7677

78+
try:
79+
from importlib.metadata import EntryPoints
80+
except ImportError:
81+
# python<=3.9
82+
_ENTRY_POINTS: dict[str, list[EntryPoint]] = {}
83+
for ep in _EPS:
84+
_ENTRY_POINTS.setdefault(ep.group, []).append(ep)
85+
else:
86+
# python>=3.10
87+
_ENTRY_POINTS: EntryPoints = EntryPoints(_EPS)
88+
7789
_METADATA_EPS: str = "torchx.util.entrypoints.metadata.entry_points"
7890

7991

0 commit comments

Comments
 (0)