1- # from jaraco.path 3.7 
1+ # from jaraco.path 3.7.2 
2+ 
3+ from  __future__ import  annotations 
24
35import  functools 
46import  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 
712
813
914class  Symlink (str ):
@@ -12,29 +17,25 @@ class Symlink(str):
1217    """ 
1318
1419
15- FilesSpec  =  Dict [str , Union [str , bytes , Symlink , 'FilesSpec' ]]   # type: ignore 
20+ FilesSpec  =  Mapping [str , Union [str , bytes , Symlink , 'FilesSpec' ]]
1621
1722
1823@runtime_checkable  
1924class  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 : ...
2930
3031
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 )
3334
3435
3536def  build (
3637    spec : FilesSpec ,
37-     prefix : Union [ str ,  TreeMaker ]  =  pathlib .Path (),   # type: ignore 
38+     prefix : str   |   TreeMaker  =  pathlib .Path (),
3839):
3940    """ 
4041    Build a set of files/directories, as described by the spec. 
@@ -66,23 +67,24 @@ def build(
6667
6768
6869@functools .singledispatch  
69- def  create (content : Union [ str ,  bytes ,  FilesSpec ] , path ) :
70+ def  create (content : str   |   bytes   |   FilesSpec , path :  TreeMaker )  ->   None :
7071    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 
7274
7375
7476@create .register  
75- def  _ (content : bytes , path ) :
77+ def  _ (content : bytes , path :  TreeMaker )  ->   None :
7678    path .write_bytes (content )
7779
7880
7981@create .register  
80- def  _ (content : str , path ) :
82+ def  _ (content : str , path :  TreeMaker )  ->   None :
8183    path .write_text (content , encoding = 'utf-8' )
8284
8385
8486@create .register  
85- def  _ (content : Symlink , path ) :
87+ def  _ (content : Symlink , path :  TreeMaker )  ->   None :
8688    path .symlink_to (content )
8789
8890
0 commit comments