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

32 statements  

1from __future__ import annotations 

2 

3from typing import TYPE_CHECKING, Any 

4 

5from attrs import NOTHING, Attribute, Factory 

6 

7from .._compat import is_bare_final 

8from ..dispatch import StructureHook 

9from ..errors import StructureHandlerNotFoundError 

10from ..fns import raise_error 

11 

12if TYPE_CHECKING: 

13 from ..converters import BaseConverter 

14 

15 

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. 

20 

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. 

53 

54 def handler(v, _, _h=handler): 

55 return _h(v, type) 

56 

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