Coverage for pyyc/mod.py: 50%

44 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-10-11 23:51 +0200

1""" 

2Documentation for module `mod`. 

3""" 

4 

5__all__ = ['version'] # limits the content of "import *" 

6 

7version = "top-level module" 

8print("Initialization", version) # NO PRINT in a true module! 

9 

10#################################################### 

11 

12import os, sys # pylint: disable=wrong-import-position,multiple-imports 

13 

14def addition(*args): 

15 r""" 

16 Addition function (undefined type). 

17 

18 Arguments should support mutual addition: 

19 

20 .. math:: 

21 

22 \mathrm{out} = \sum_i \mathrm{arg}_i 

23 

24 :param args: parameters 

25 :return: python addition of args 

26 :raises TypeError: arguments cannot be summed together 

27 

28 >>> addition(1, 2, 3) 

29 6 

30 >>> addition("abc", "def") 

31 'abcdef' 

32 >>> addition([1], [2, 3], [4, 5, 6]) 

33 [1, 2, 3, 4, 5, 6] 

34 >>> addition(1, "abc") 

35 Traceback (most recent call last): 

36 ... 

37 TypeError: unsupported operand type(s) for +=: 'int' and 'str' 

38 """ 

39 

40 out = args[0] 

41 for arg in args[1:]: 

42 out += arg 

43 

44 return out 

45 

46 

47def addition_int(*args): 

48 """ 

49 Addition function for integers (includes cast to integer). 

50 

51 :param int args: arguments to be casted to integer 

52 :return: integer addition of args 

53 :rtype: int 

54 :raise ValueError: if arguments cannot be casted to integer. 

55 

56 >>> addition_int(1, 2, 3) 

57 6 

58 >>> addition_int('1', 2) 

59 3 

60 >>> addition_int("abc", "def") 

61 Traceback (most recent call last): 

62 ... 

63 ValueError: Arguments must cast to integer. 

64 """ 

65 

66 try: 

67 iargs = [ int(arg) for arg in args ] 

68 except ValueError as exc: 

69 raise ValueError("Arguments must cast to integer.") from exc 

70 

71 return sum(iargs) 

72 

73 

74if sys.version_info[:2] >= (3, 10): 

75 from importlib.resources import files # Python 3.10+ 

76else: 

77 from importlib_resources import files # External 

78 

79PYYC_PATH = files("pyyc.config") #: Path to pyyc configuration file. 

80 

81 

82def read_config(cfgname="default.cfg"): 

83 """ 

84 Get config from configuration file. 

85 

86 If the input filename does not specifically include a path, it will be 

87 looked for in the default :const:`PYYC_PATH` directory. 

88 

89 :param str cfgname: configuration file name 

90 :return: configuration object 

91 :rtype: configparser.ConfigParser 

92 

93 >>> cfg = read_config() # doctest: +ELLIPSIS 

94 Reading configuration from ... 

95 >>> cfg['DEFAULT']['version'] 

96 'cfg-1.0' 

97 """ 

98 

99 from configparser import ConfigParser # pylint: disable=import-outside-toplevel 

100 

101 if os.path.dirname(cfgname): # cfgname includes a path (e.g. `./path/to/file`) 

102 fname = cfgname 

103 else: # use PYYC_PATH as default 

104 fname = PYYC_PATH.joinpath(cfgname) 

105 print(f"Reading configuration from {fname!s}...") 

106 

107 cfg = ConfigParser() 

108 if not cfg.read(fname): # It silently failed 

109 raise IOError(f"Could not find or parse {fname!s}") 

110 

111 return cfg 

112 

113 

114def format_pkg_tree(node, max_depth=2, printout=False, depth=0): 

115 """ 

116 Format the package architecture. 

117 

118 :param module node: name of the top-level module 

119 :param int max_depth: maximum depth of recursion 

120 :param bool printout: print out the resulting string 

121 :param int depth: depth level (used for recursion) 

122 :return: structure as a list of strings (without newlines) 

123 :rtype: list 

124 

125 >>> import pyyc 

126 >>> format_pkg_tree(pyyc, max_depth=1) # doctest: +NORMALIZE_WHITESPACE 

127 ['pyyc', 

128 ' pyyc.config', 

129 ' pyyc.mod', 

130 ' pyyc.subpkgA', 

131 ' pyyc.subpkgB'] 

132 """ 

133 

134 if depth > max_depth: 

135 return [] 

136 

137 s = [] 

138 if hasattr(node, '__name__'): 

139 s.append(' ' * depth + node.__name__) 

140 for name in dir(node): 

141 if not name.startswith('_'): 

142 s.extend(format_pkg_tree(getattr(node, name), 

143 max_depth=max_depth, 

144 depth=depth + 1)) 

145 

146 if printout: 

147 print('\n'.join(s)) 

148 

149 return s 

150 

151 

152def greetings(): 

153 """ 

154 Stupid function, to illustrate tests on stdin/stdout. 

155 """ 

156 

157 name = input("What's you name? ") 

158 print(f"Hello, {name}!")