Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/cattrs/gen/_shared.py: 28%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from __future__ import annotations
3from typing import TYPE_CHECKING, Any
5from attrs import NOTHING, Attribute, Factory
7from .._compat import is_bare_final
8from ..dispatch import StructureHook
9from ..errors import StructureHandlerNotFoundError
10from ..fns import raise_error
12if TYPE_CHECKING:
13 from ..converters import BaseConverter
16def find_structure_handler(
17 a: Attribute, type: Any, c: BaseConverter, prefer_attrs_converters: bool = False
18) -> StructureHook | None:
19 """Find the appropriate structure handler to use.
21 Return `None` if no handler should be used.
22 """
23 try:
24 if a.converter is not None and prefer_attrs_converters:
25 # If the user as requested to use attrib converters, use nothing
26 # so it falls back to that.
27 handler = None
28 elif (
29 a.converter is not None and not prefer_attrs_converters and type is not None
30 ):
31 try:
32 handler = c.get_structure_hook(type, cache_result=False)
33 except StructureHandlerNotFoundError:
34 handler = None
35 else:
36 # The legacy way, should still work.
37 if handler == raise_error:
38 handler = None
39 elif type is not None:
40 if (
41 is_bare_final(type)
42 and a.default is not NOTHING
43 and not isinstance(a.default, Factory)
44 ):
45 # This is a special case where we can use the
46 # type of the default to dispatch on.
47 type = a.default.__class__
48 handler = c.get_structure_hook(type, cache_result=False)
49 if handler == c._structure_call:
50 # Finals can't really be used with _structure_call, so
51 # we wrap it so the rest of the toolchain doesn't get
52 # confused.
54 def handler(v, _, _h=handler):
55 return _h(v, type)
57 else:
58 handler = c.get_structure_hook(type, cache_result=False)
59 else:
60 handler = c.structure
61 return handler
62 except RecursionError:
63 # This means we're dealing with a reference cycle, so use late binding.
64 return c.structure