Skip to content

Commit 435a26c

Browse files
committed
refactor(types): Hide .types imports behind TypeGuard
This avoids the need for typing-extensions as an official dependency and fixes #412.
1 parent 18a73e4 commit 435a26c

File tree

5 files changed

+29
-21
lines changed

5 files changed

+29
-21
lines changed

src/vcspull/config.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@
1616

1717
from . import exc
1818
from ._internal.config_reader import ConfigReader
19-
from .types import ConfigDict, RawConfigDict
2019
from .util import get_config_dir, update_dict
2120

2221
log = logging.getLogger(__name__)
2322

2423
if t.TYPE_CHECKING:
2524
from typing_extensions import TypeGuard
2625

26+
from .types import ConfigDict, RawConfigDict
27+
2728

2829
def expand_dir(
2930
_dir: pathlib.Path, cwd: pathlib.Path = pathlib.Path.cwd()
@@ -50,8 +51,8 @@ def expand_dir(
5051

5152

5253
def extract_repos(
53-
config: RawConfigDict, cwd: pathlib.Path = pathlib.Path.cwd()
54-
) -> list[ConfigDict]:
54+
config: "RawConfigDict", cwd: pathlib.Path = pathlib.Path.cwd()
55+
) -> list["ConfigDict"]:
5556
"""Return expanded configuration.
5657
5758
end-user configuration permit inline configuration shortcuts, expand to
@@ -68,7 +69,7 @@ def extract_repos(
6869
-------
6970
list : List of normalized repository information
7071
"""
71-
configs: list[ConfigDict] = []
72+
configs: list["ConfigDict"] = []
7273
for directory, repos in config.items():
7374
assert isinstance(repos, dict)
7475
for repo, repo_data in repos.items():
@@ -220,7 +221,7 @@ def find_config_files(
220221

221222
def load_configs(
222223
files: list[pathlib.Path], cwd: pathlib.Path = pathlib.Path.cwd()
223-
) -> t.List[ConfigDict]:
224+
) -> t.List["ConfigDict"]:
224225
"""Return repos from a list of files.
225226
226227
Parameters
@@ -239,7 +240,7 @@ def load_configs(
239240
----
240241
Validate scheme, check for duplicate destinations, VCS urls
241242
"""
242-
repos: list[ConfigDict] = []
243+
repos: list["ConfigDict"] = []
243244
for file in files:
244245
if isinstance(file, str):
245246
file = pathlib.Path(file)
@@ -262,11 +263,11 @@ def load_configs(
262263
return repos
263264

264265

265-
ConfigDictTuple = tuple[ConfigDict, ConfigDict]
266+
ConfigDictTuple = tuple["ConfigDict", "ConfigDict"]
266267

267268

268269
def detect_duplicate_repos(
269-
config1: list[ConfigDict], config2: list[ConfigDict]
270+
config1: list["ConfigDict"], config2: list["ConfigDict"]
270271
) -> list[ConfigDictTuple]:
271272
"""Return duplicate repos dict if repo_dir same and vcs different.
272273
@@ -329,11 +330,11 @@ def in_dir(
329330

330331

331332
def filter_repos(
332-
config: t.List[ConfigDict],
333+
config: t.List["ConfigDict"],
333334
dir: t.Union[pathlib.Path, t.Literal["*"], str, None] = None,
334335
vcs_url: t.Union[str, None] = None,
335336
name: t.Union[str, None] = None,
336-
) -> list[ConfigDict]:
337+
) -> list["ConfigDict"]:
337338
"""Return a :py:obj:`list` list of repos from (expanded) config file.
338339
339340
dir, vcs_url and name all support fnmatch.
@@ -354,7 +355,7 @@ def filter_repos(
354355
list :
355356
Repos
356357
"""
357-
repo_list: list[ConfigDict] = []
358+
repo_list: list["ConfigDict"] = []
358359

359360
if dir:
360361
repo_list.extend(

src/vcspull/validator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import pathlib
22
import typing as t
33

4-
from vcspull.types import RawConfigDict
5-
64
if t.TYPE_CHECKING:
75
from typing_extensions import TypeGuard
86

7+
from vcspull.types import RawConfigDict
8+
99

1010
def is_valid_config(config: t.Dict[str, t.Any]) -> "TypeGuard[RawConfigDict]":
1111
if not isinstance(config, dict):

tests/fixtures/example.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import pathlib
2+
import typing as t
23

34
from libvcs.sync.git import GitRemote
4-
from vcspull.types import ConfigDict
5+
6+
if t.TYPE_CHECKING:
7+
from vcspull.types import ConfigDict
58

69
config_dict = {
710
"/home/me/myproject/study/": {
@@ -33,7 +36,7 @@
3336
},
3437
}
3538

36-
config_dict_expanded: list[ConfigDict] = [
39+
config_dict_expanded: list["ConfigDict"] = [
3740
{
3841
"vcs": "git",
3942
"name": "linux",

tests/test_config.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
import pytest
55

66
from vcspull import config
7-
from vcspull.types import ConfigDict
7+
8+
if t.TYPE_CHECKING:
9+
from vcspull.types import ConfigDict
810

911

1012
class LoadYAMLFn(t.Protocol):
@@ -14,7 +16,7 @@ def __call__(
1416
dir: str = "randomdir",
1517
filename: str = "randomfilename.yaml",
1618
) -> t.Tuple[
17-
pathlib.Path, t.List[t.Union[t.Any, pathlib.Path]], t.List[ConfigDict]
19+
pathlib.Path, t.List[t.Union[t.Any, pathlib.Path]], t.List["ConfigDict"]
1820
]:
1921
...
2022

@@ -23,7 +25,7 @@ def __call__(
2325
def load_yaml(tmp_path: pathlib.Path) -> LoadYAMLFn:
2426
def fn(
2527
content: str, dir: str = "randomdir", filename: str = "randomfilename.yaml"
26-
) -> t.Tuple[pathlib.Path, t.List[pathlib.Path], t.List[ConfigDict]]:
28+
) -> t.Tuple[pathlib.Path, t.List[pathlib.Path], t.List["ConfigDict"]]:
2729
_dir = tmp_path / dir
2830
_dir.mkdir()
2931
_config = _dir / filename

tests/test_sync.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
from vcspull._internal.config_reader import ConfigReader
1111
from vcspull.cli.sync import update_repo
1212
from vcspull.config import extract_repos, filter_repos, load_configs
13-
from vcspull.types import ConfigDict
1413
from vcspull.validator import is_valid_config
1514

1615
from .helpers import write_config
1716

17+
if t.TYPE_CHECKING:
18+
from vcspull.types import ConfigDict
19+
1820

1921
def test_makes_recursive(
2022
tmp_path: pathlib.Path,
@@ -176,7 +178,7 @@ def test_updating_remote(
176178
repo_parent = tmp_path / "study" / "myrepo"
177179
repo_parent.mkdir(parents=True)
178180

179-
initial_config: ConfigDict = {
181+
initial_config: "ConfigDict" = {
180182
"vcs": "git",
181183
"name": "myclone",
182184
"dir": tmp_path / "study/myrepo/myclone",
@@ -198,7 +200,7 @@ def test_updating_remote(
198200

199201
expected_remote_url = f"git+file://{mirror_repo}"
200202

201-
expected_config: ConfigDict = initial_config.copy()
203+
expected_config: "ConfigDict" = initial_config.copy()
202204
assert isinstance(expected_config["remotes"], dict)
203205
expected_config["remotes"][mirror_name] = GitRemote(
204206
name=mirror_name,

0 commit comments

Comments
 (0)