Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" 

2Commonly useful converters. 

3""" 

4 

5from __future__ import absolute_import, division, print_function 

6 

7from ._make import NOTHING, Factory, pipe 

8 

9 

10__all__ = [ 

11 "pipe", 

12 "optional", 

13 "default_if_none", 

14] 

15 

16 

17def optional(converter): 

18 """ 

19 A converter that allows an attribute to be optional. An optional attribute 

20 is one which can be set to ``None``. 

21 

22 :param callable converter: the converter that is used for non-``None`` 

23 values. 

24 

25 .. versionadded:: 17.1.0 

26 """ 

27 

28 def optional_converter(val): 

29 if val is None: 

30 return None 

31 return converter(val) 

32 

33 return optional_converter 

34 

35 

36def default_if_none(default=NOTHING, factory=None): 

37 """ 

38 A converter that allows to replace ``None`` values by *default* or the 

39 result of *factory*. 

40 

41 :param default: Value to be used if ``None`` is passed. Passing an instance 

42 of `attr.Factory` is supported, however the ``takes_self`` option 

43 is *not*. 

44 :param callable factory: A callable that takes not parameters whose result 

45 is used if ``None`` is passed. 

46 

47 :raises TypeError: If **neither** *default* or *factory* is passed. 

48 :raises TypeError: If **both** *default* and *factory* are passed. 

49 :raises ValueError: If an instance of `attr.Factory` is passed with 

50 ``takes_self=True``. 

51 

52 .. versionadded:: 18.2.0 

53 """ 

54 if default is NOTHING and factory is None: 

55 raise TypeError("Must pass either `default` or `factory`.") 

56 

57 if default is not NOTHING and factory is not None: 

58 raise TypeError( 

59 "Must pass either `default` or `factory` but not both." 

60 ) 

61 

62 if factory is not None: 

63 default = Factory(factory) 

64 

65 if isinstance(default, Factory): 

66 if default.takes_self: 

67 raise ValueError( 

68 "`takes_self` is not supported by default_if_none." 

69 ) 

70 

71 def default_if_none_converter(val): 

72 if val is not None: 

73 return val 

74 

75 return default.factory() 

76 

77 else: 

78 

79 def default_if_none_converter(val): 

80 if val is not None: 

81 return val 

82 

83 return default 

84 

85 return default_if_none_converter