MCPcopy
hub / github.com/sqlalchemy/sqlalchemy / _cleanup_mapped_str_annotation

Function _cleanup_mapped_str_annotation

lib/sqlalchemy/orm/util.py:2247–2334  ·  view source on GitHub ↗
(
    annotation: str, originating_module: str
)

Source from the content-addressed store, hash-verified

2245
2246
2247def _cleanup_mapped_str_annotation(
2248 annotation: str, originating_module: str
2249) -> str:
2250 # fix up an annotation that comes in as the form:
2251 # 'Mapped[List[Address]]' so that it instead looks like:
2252 # 'Mapped[List["Address"]]' , which will allow us to get
2253 # "Address" as a string
2254
2255 # additionally, resolve symbols for these names since this is where
2256 # we'd have to do it
2257
2258 inner: Optional[Match[str]]
2259
2260 mm = re.match(r"^([^ \|]+?)\[(.+)\]$", annotation)
2261
2262 if not mm:
2263 return annotation
2264
2265 # ticket #8759. Resolve the Mapped name to a real symbol.
2266 # originally this just checked the name.
2267 try:
2268 obj = eval_name_only(mm.group(1), originating_module)
2269 except NameError as ne:
2270 raise _CleanupError(
2271 f'For annotation "{annotation}", could not resolve '
2272 f'container type "{mm.group(1)}". '
2273 "Please ensure this type is imported at the module level "
2274 "outside of TYPE_CHECKING blocks"
2275 ) from ne
2276
2277 if obj is typing.ClassVar:
2278 real_symbol = "ClassVar"
2279 else:
2280 try:
2281 if issubclass(obj, _MappedAnnotationBase):
2282 real_symbol = obj.__name__
2283 else:
2284 return annotation
2285 except TypeError:
2286 # avoid isinstance(obj, type) check, just catch TypeError
2287 return annotation
2288
2289 # note: if one of the codepaths above didn't define real_symbol and
2290 # then didn't return, real_symbol raises UnboundLocalError
2291 # which is actually a NameError, and the calling routines don't
2292 # notice this since they are catching NameError anyway. Just in case
2293 # this is being modified in the future, something to be aware of.
2294
2295 stack = []
2296 inner = mm
2297 while True:
2298 stack.append(real_symbol if mm is inner else inner.group(1))
2299 g2 = inner.group(2)
2300 inner = re.match(r"^([^ \|]+?)\[(.+)\]$", g2)
2301 if inner is None:
2302 stack.append(g2)
2303 break
2304

Callers 1

Calls 7

eval_name_onlyFunction · 0.85
_CleanupErrorClass · 0.85
stripMethod · 0.80
splitMethod · 0.80
matchMethod · 0.45
appendMethod · 0.45
joinMethod · 0.45

Tested by 1