1
- # from jaraco.path 3.7
1
+ # from jaraco.path 3.7.2
2
+
3
+ from __future__ import annotations
2
4
3
5
import functools
4
6
import pathlib
5
- from typing import Dict , Protocol , Union
6
- from typing import runtime_checkable
7
+ from collections .abc import Mapping
8
+ from typing import TYPE_CHECKING , Protocol , Union , runtime_checkable
9
+
10
+ if TYPE_CHECKING :
11
+ from typing_extensions import Self
7
12
8
13
9
14
class Symlink (str ):
@@ -12,29 +17,25 @@ class Symlink(str):
12
17
"""
13
18
14
19
15
- FilesSpec = Dict [str , Union [str , bytes , Symlink , 'FilesSpec' ]] # type: ignore
20
+ FilesSpec = Mapping [str , Union [str , bytes , Symlink , 'FilesSpec' ]]
16
21
17
22
18
23
@runtime_checkable
19
24
class TreeMaker (Protocol ):
20
- def __truediv__ (self , * args , ** kwargs ): ... # pragma: no cover
21
-
22
- def mkdir (self , ** kwargs ): ... # pragma: no cover
23
-
24
- def write_text (self , content , ** kwargs ): ... # pragma: no cover
25
-
26
- def write_bytes (self , content ): ... # pragma: no cover
27
-
28
- def symlink_to (self , target ): ... # pragma: no cover
25
+ def __truediv__ (self , other , / ) -> Self : ...
26
+ def mkdir (self , * , exist_ok ) -> object : ...
27
+ def write_text (self , content , / , * , encoding ) -> object : ...
28
+ def write_bytes (self , content , / ) -> object : ...
29
+ def symlink_to (self , target , / ) -> object : ...
29
30
30
31
31
- def _ensure_tree_maker (obj : Union [ str , TreeMaker ] ) -> TreeMaker :
32
- return obj if isinstance (obj , TreeMaker ) else pathlib .Path (obj ) # type: ignore
32
+ def _ensure_tree_maker (obj : str | TreeMaker ) -> TreeMaker :
33
+ return obj if isinstance (obj , TreeMaker ) else pathlib .Path (obj )
33
34
34
35
35
36
def build (
36
37
spec : FilesSpec ,
37
- prefix : Union [ str , TreeMaker ] = pathlib .Path (), # type: ignore
38
+ prefix : str | TreeMaker = pathlib .Path (),
38
39
):
39
40
"""
40
41
Build a set of files/directories, as described by the spec.
@@ -66,23 +67,24 @@ def build(
66
67
67
68
68
69
@functools .singledispatch
69
- def create (content : Union [ str , bytes , FilesSpec ] , path ) :
70
+ def create (content : str | bytes | FilesSpec , path : TreeMaker ) -> None :
70
71
path .mkdir (exist_ok = True )
71
- build (content , prefix = path ) # type: ignore
72
+ # Mypy only looks at the signature of the main singledispatch method. So it must contain the complete Union
73
+ build (content , prefix = path ) # type: ignore[arg-type] # python/mypy#11727
72
74
73
75
74
76
@create .register
75
- def _ (content : bytes , path ) :
77
+ def _ (content : bytes , path : TreeMaker ) -> None :
76
78
path .write_bytes (content )
77
79
78
80
79
81
@create .register
80
- def _ (content : str , path ) :
82
+ def _ (content : str , path : TreeMaker ) -> None :
81
83
path .write_text (content , encoding = 'utf-8' )
82
84
83
85
84
86
@create .register
85
- def _ (content : Symlink , path ) :
87
+ def _ (content : Symlink , path : TreeMaker ) -> None :
86
88
path .symlink_to (content )
87
89
88
90
0 commit comments