1+ from __future__ import annotations
2+
13from abc import ABC , abstractmethod
24from logging import getLogger
3- from pathlib import Path
4- from typing import Any , Callable , Optional , TextIO , Union
5+ from typing import TYPE_CHECKING , Any , TextIO
56
67from hbreader import FileInfo , hbread
78from jsonasobj2 import JsonObj , as_dict
1011from linkml_runtime import URI_TO_LOCAL
1112from linkml_runtime .utils .yamlutils import YAMLRoot
1213
14+ if TYPE_CHECKING :
15+ from collections .abc import Callable
16+ from pathlib import Path
17+
1318CACHE_SIZE = 1024
1419
1520
@@ -41,12 +46,12 @@ def _is_empty(o) -> bool:
4146
4247 def load_source (
4348 self ,
44- source : Union [ str , dict , TextIO ] ,
45- loader : Callable [[Union [ str , dict ] , FileInfo ], Optional [ Union [ dict , list ]] ],
46- target_class : Union [ type [YAMLRoot ], type [ BaseModel ] ],
47- accept_header : Optional [ str ] = "text/plain, application/yaml;q=0.9" ,
48- metadata : Optional [ FileInfo ] = None ,
49- ) -> Optional [ Union [ BaseModel , YAMLRoot , list [BaseModel ], list [YAMLRoot ]]] :
49+ source : str | dict | TextIO ,
50+ loader : Callable [[str | dict , FileInfo ], dict | list | None ],
51+ target_class : type [YAMLRoot | BaseModel ],
52+ accept_header : str | None = "text/plain, application/yaml;q=0.9" ,
53+ metadata : FileInfo | None = None ,
54+ ) -> BaseModel | YAMLRoot | list [BaseModel ] | list [YAMLRoot ] | None :
5055 """Base loader - convert a file, url, string, open file handle or dictionary into an instance
5156 of target_class
5257
@@ -63,7 +68,7 @@ def load_source(
6368 data_as_dict = loader (data , metadata )
6469 return self ._construct_target_class (data_as_dict , target_class = target_class )
6570
66- def load (self , * args , ** kwargs ) -> Union [ BaseModel , YAMLRoot ] :
71+ def load (self , * args , ** kwargs ) -> BaseModel | YAMLRoot :
6772 """
6873 Load source as an instance of target_class
6974
@@ -77,22 +82,22 @@ def load(self, *args, **kwargs) -> Union[BaseModel, YAMLRoot]:
7782 results = self .load_any (* args , ** kwargs )
7883 if isinstance (results , (BaseModel , YAMLRoot )):
7984 return results
80- else :
81- raise ValueError (f"Result is not an instance of BaseModel or YAMLRoot: { type ( results ) } " )
85+ msg = f"Result is not an instance of BaseModel or YAMLRoot: { type ( results ) } "
86+ raise ValueError (msg )
8287
83- def load_as_dict (self , * args , ** kwargs ) -> Union [ dict , list [dict ] ]:
88+ def load_as_dict (self , * args , ** kwargs ) -> dict | list [dict ]:
8489 raise NotImplementedError ()
8590
8691 @abstractmethod
8792 def load_any (
8893 self ,
89- source : Union [ str , dict , TextIO , Path ] ,
90- target_class : type [Union [ BaseModel , YAMLRoot ] ],
94+ source : str | dict | TextIO | Path ,
95+ target_class : type [BaseModel | YAMLRoot ],
9196 * ,
92- base_dir : Optional [ str ] = None ,
93- metadata : Optional [ FileInfo ] = None ,
97+ base_dir : str | None = None ,
98+ metadata : FileInfo | None = None ,
9499 ** _ ,
95- ) -> Union [ BaseModel , YAMLRoot , list [BaseModel ], list [YAMLRoot ] ]:
100+ ) -> BaseModel | YAMLRoot | list [BaseModel ] | list [YAMLRoot ]:
96101 """
97102 Load source as an instance of target_class, or list of instances of target_class
98103
@@ -106,8 +111,8 @@ def load_any(
106111 raise NotImplementedError ()
107112
108113 def loads_any (
109- self , source : str , target_class : type [Union [ BaseModel , YAMLRoot ]] , * , metadata : Optional [ FileInfo ] = None , ** _
110- ) -> Union [ BaseModel , YAMLRoot , list [BaseModel ], list [YAMLRoot ] ]:
114+ self , source : str , target_class : type [BaseModel | YAMLRoot ], * , metadata : FileInfo | None = None , ** _
115+ ) -> BaseModel | YAMLRoot | list [BaseModel ] | list [YAMLRoot ]:
111116 """
112117 Load source as a string as an instance of target_class, or list of instances of target_class
113118 @param source: source
@@ -119,8 +124,8 @@ def loads_any(
119124 return self .load_any (source , target_class , metadata = metadata )
120125
121126 def loads (
122- self , source : str , target_class : type [Union [ BaseModel , YAMLRoot ]] , * , metadata : Optional [ FileInfo ] = None , ** _
123- ) -> Union [ BaseModel , YAMLRoot ] :
127+ self , source : str , target_class : type [BaseModel | YAMLRoot ], * , metadata : FileInfo | None = None , ** _
128+ ) -> BaseModel | YAMLRoot :
124129 """
125130 Load source as a string
126131 :param source: source
@@ -132,53 +137,52 @@ def loads(
132137 return self .load (source , target_class , metadata = metadata )
133138
134139 def _construct_target_class (
135- self , data_as_dict : Union [ dict , list [dict ]] , target_class : Union [ type [YAMLRoot ], type [ BaseModel ] ]
136- ) -> Optional [ Union [ BaseModel , YAMLRoot , list [BaseModel ], list [YAMLRoot ]]] :
140+ self , data_as_dict : dict | list [dict ], target_class : type [YAMLRoot | BaseModel ]
141+ ) -> BaseModel | YAMLRoot | list [BaseModel ] | list [YAMLRoot ] | None :
137142 if data_as_dict :
138143 if isinstance (data_as_dict , list ):
139144 if issubclass (target_class , YAMLRoot ):
140145 return [target_class (** as_dict (x )) for x in data_as_dict ]
141- elif issubclass (target_class , BaseModel ):
146+ if issubclass (target_class , BaseModel ):
142147 return [target_class .model_validate (as_dict (x )) for x in data_as_dict ]
143- else :
144- raise ValueError (f"Cannot load list of { target_class } " )
145- elif isinstance (data_as_dict , dict ):
148+ msg = f"Cannot load list of { target_class } "
149+ raise ValueError (msg )
150+ if isinstance (data_as_dict , dict ):
146151 if issubclass (target_class , BaseModel ):
147152 return target_class .model_validate (data_as_dict )
148153 return target_class (** data_as_dict )
149154
150155 if isinstance (data_as_dict , JsonObj ):
151156 return [target_class (** as_dict (x )) for x in data_as_dict ]
152- else :
153- raise ValueError (f"Unexpected type { data_as_dict } " )
154- else :
155- return None
157+
158+ msg = f"Unexpected type { data_as_dict } "
159+ # should really be a TypeError
160+ raise ValueError (msg )
161+ return None
156162
157163 def _read_source (
158164 self ,
159- source : Union [ str , dict , TextIO ] ,
165+ source : str | dict | TextIO ,
160166 * ,
161- base_dir : Optional [ str ] = None ,
162- metadata : Optional [ FileInfo ] = None ,
163- accept_header : Optional [ str ] = "text/plain, application/yaml;q=0.9" ,
164- ) -> Union [ dict , str ] :
167+ base_dir : str | None = None ,
168+ metadata : FileInfo | None = None ,
169+ accept_header : str | None = "text/plain, application/yaml;q=0.9" ,
170+ ) -> dict | str :
165171 if metadata is None :
166172 metadata = FileInfo ()
167173 if base_dir and not metadata .base_path :
168174 metadata .base_path = base_dir
169175
170- if not isinstance (source , dict ):
171- # Try to get local version of schema, if one is known to exist
172- try :
173- if str (source ) in URI_TO_LOCAL :
174- source = str (URI_TO_LOCAL [str (source )])
175- except (TypeError , KeyError ) as e :
176- # Fine, use original `source` value
177- logger = getLogger ("linkml_runtime.loaders.Loader" )
178- logger .debug (f"Error converting stringlike source to local linkml file: { source } , got: { e } " )
179-
180- data = hbread (source , metadata , base_dir , accept_header )
181- else :
182- data = source
183-
184- return data
176+ if isinstance (source , dict ):
177+ return source
178+
179+ # Try to get local version of schema, if one is known to exist
180+ try :
181+ if str (source ) in URI_TO_LOCAL :
182+ source = str (URI_TO_LOCAL [str (source )])
183+ except (TypeError , KeyError ) as e :
184+ # Fine, use original `source` value
185+ logger = getLogger ("linkml_runtime.loaders.Loader" )
186+ logger .debug (f"Error converting stringlike source to local linkml file: { source } , got: { e } " )
187+
188+ return hbread (source , metadata , base_dir , accept_header )
0 commit comments