Coverage for python/lsst/daf/persistence/utils.py: 8%

56 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2022-11-11 02:39 -0800

1#!/usr/bin/env python 

2 

3# 

4# LSST Data Management System 

5# Copyright 2016 LSST Corporation. 

6# 

7# This product includes software developed by the 

8# LSST Project (http://www.lsst.org/). 

9# 

10# This program is free software: you can redistribute it and/or modify 

11# it under the terms of the GNU General Public License as published by 

12# the Free Software Foundation, either version 3 of the License, or 

13# (at your option) any later version. 

14# 

15# This program is distributed in the hope that it will be useful, 

16# but WITHOUT ANY WARRANTY; without even the implied warranty of 

17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

18# GNU General Public License for more details. 

19# 

20# You should have received a copy of the LSST License Statement and 

21# the GNU General Public License along with this program. If not, 

22# see <http://www.lsstcorp.org/LegalNotices/>. 

23# 

24from collections.abc import Sequence, Set, Mapping 

25 

26 

27# -*- python -*- 

28 

29def listify(x): 

30 """Takes any object and puts that whole object in a list: 

31 - strings will be made into a single element in the list 

32 - tuples will be converted to list 

33 - lists will remain as lists 

34 - None will be made into an empty list 

35 """ 

36 if x is None: 

37 x = [] 

38 elif isinstance(x, str): 

39 x = [x] 

40 elif isinstance(x, dict): 

41 x = [x] 

42 elif hasattr(x, '__iter__'): 

43 x = list(x) 

44 else: 

45 x = [x] 

46 return x 

47 

48 

49def iterify(x): 

50 """Takes any object. Returns it if it is iterable. If it 

51 is not iterable it puts the object in a list and returns 

52 the list. None will return an empty list. If a new list 

53 is always required use listify(). Strings will be placed 

54 in a list with a single element. 

55 """ 

56 if x is None: 

57 x = [] 

58 elif isinstance(x, str): 

59 x = [x] 

60 elif hasattr(x, '__iter__'): 

61 pass 

62 else: 

63 x = [x] 

64 return x 

65 

66 

67def sequencify(x): 

68 """Takes an object, if it is a sequence return it, 

69 else put it in a tuple. Strings are not sequences. 

70 If x is a dict, returns a sorted tuple of keys.""" 

71 if isinstance(x, (Sequence, Set)) and not isinstance(x, str): 

72 pass 

73 elif isinstance(x, Mapping): 

74 x = tuple(sorted(x.keys())) 

75 else: 

76 x = (x, ) 

77 return x 

78 

79 

80def setify(x): 

81 """Take an object x and return it in a set. 

82 

83 If x is a container, will create a set from the contents of the container. 

84 If x is an object, will create a set with a single item in it. 

85 If x is a string, will treat the string as a single object (i.e. not as a list of chars)""" 

86 if x is None: 

87 x = set() 

88 

89 # Here we have to explicity for strings because the set initializer will use each character in a string as 

90 # a separate element. We cannot use the braces initialization because x might be a list, and we do not 

91 # want the list to be an item; we want each item in the list to be represented by an item in the set. 

92 # Then, we have to fall back to braces init because if the item is NOT a list then the set initializer 

93 # won't take it. 

94 if isinstance(x, str): 

95 x = set([x]) 

96 else: 

97 try: 

98 x = set(x) 

99 except TypeError: 

100 x = set([x]) 

101 return x 

102 

103 

104def doImport(pythonType): 

105 """Import a python object given an importable string""" 

106 try: 

107 if not isinstance(pythonType, str): 

108 raise TypeError("Unhandled type of pythonType, val:%s" % pythonType) 

109 # import this pythonType dynamically 

110 pythonTypeTokenList = pythonType.split('.') 

111 importClassString = pythonTypeTokenList.pop() 

112 importClassString = importClassString.strip() 

113 importPackage = ".".join(pythonTypeTokenList) 

114 importType = __import__(importPackage, globals(), locals(), [importClassString], 0) 

115 pythonType = getattr(importType, importClassString) 

116 return pythonType 

117 except ImportError: 

118 pass 

119 # maybe python type is a member function, in the form: path.to.object.Class.funcname 

120 pythonTypeTokenList = pythonType.split('.') 

121 importClassString = '.'.join(pythonTypeTokenList[0:-1]) 

122 importedClass = doImport(importClassString) 

123 pythonType = getattr(importedClass, pythonTypeTokenList[-1]) 

124 return pythonType