1010
1111
1212@overload
13- def install (packages : str ) -> "Module" :
13+ def install (
14+ packages : str ,
15+ ignore_installed : bool ,
16+ fallback : Optional [str ],
17+ ) -> "Module" :
1418 ...
1519
1620
1721@overload
18- def install (packages : Union [List [str ], Tuple [str ]]) -> List ["Module" ]:
22+ def install (
23+ packages : Union [List [str ], Tuple [str ]],
24+ ignore_installed : bool ,
25+ fallback : Optional [str ],
26+ ) -> List ["Module" ]:
1927 ...
2028
2129
2230def install (
23- packages : Union [str , List [str ], Tuple [str ]], ignore_installed : bool = False
31+ packages : Union [str , List [str ], Tuple [str ]],
32+ ignore_installed : bool = False ,
33+ fallback : Optional [str ] = None ,
2434) -> Union ["Module" , List ["Module" ]]:
2535 return_one = False
2636 if isinstance (packages , str ):
@@ -38,7 +48,11 @@ def install(
3848 f"{ client .current } failed to discover { list (not_discovered )} ."
3949 )
4050
41- return Module (pkg_names .pop ()) if return_one else [Module (pkg ) for pkg in pkg_names ]
51+ return (
52+ Module (pkg_names .pop (), fallback = fallback )
53+ if return_one
54+ else [Module (pkg , fallback = fallback ) for pkg in pkg_names ]
55+ )
4256
4357
4458class Module :
@@ -63,7 +77,7 @@ class Module:
6377 The URL this module will be imported from.
6478 """
6579
66- __slots__ = "url" , "exports" , "fallback "
80+ __slots__ = "url" , "fallback" , " exports" , "_export_names "
6781
6882 def __init__ (
6983 self ,
@@ -73,25 +87,26 @@ def __init__(
7387 check_exports : bool = True ,
7488 ) -> None :
7589 self .fallback = fallback
76- self .exports : Optional [List [str ]] = None
90+ self ._export_names : Optional [List [str ]] = None
7791 if source_file is not None :
7892 self .url = (
7993 client .current .web_module_url (url_or_name )
8094 if client .current .web_module_exists (url_or_name )
8195 else client .current .add_web_module (url_or_name , source_file )
8296 )
8397 if check_exports :
84- self .exports = client .current .web_module_exports (url_or_name )
98+ self ._export_names = client .current .web_module_exports (url_or_name )
8599 elif client .current .web_module_exists (url_or_name ):
86100 self .url = client .current .web_module_url (url_or_name )
87101 if check_exports :
88- self .exports = client .current .web_module_exports (url_or_name )
102+ self ._export_names = client .current .web_module_exports (url_or_name )
89103 elif _is_url (url_or_name ):
90104 self .url = url_or_name
91105 else :
92106 raise ValueError (f"{ url_or_name !r} is not installed or is not a URL" )
107+ self .exports = {name : self .declare (name ) for name in (self ._export_names or [])}
93108
94- def define (
109+ def declare (
95110 self ,
96111 name : str ,
97112 has_children : bool = True ,
@@ -109,16 +124,19 @@ def define(
109124 this :class:`Module` instance.
110125 """
111126 if (
112- self .exports is not None
127+ self ._export_names is not None
113128 # if 'default' is exported there's not much we can infer
114- and "default" not in self .exports
129+ and "default" not in self ._export_names
115130 ):
116- if name not in self .exports :
131+ if name not in self ._export_names :
117132 raise ValueError (
118- f"{ self } does not export { name !r} , available options are { self .exports } "
133+ f"{ self } does not export { name !r} , available options are { self ._export_names } "
119134 )
120135 return Import (self .url , name , has_children , fallback = fallback or self .fallback )
121136
137+ def __getattr__ (self , name : str ) -> "Import" :
138+ return self .exports .get (name ) or self .declare (name )
139+
122140 def __repr__ (self ) -> str :
123141 return f"{ type (self ).__name__ } ({ self .url } )"
124142
0 commit comments