1 """
2 Class Factory
3
4 NERC DataGrid project
5 """
6 __author__ = "Philip Kershaw"
7 __date__ = "15/02/10"
8 __copyright__ = "(C) 2010 Science and Technology Facilities Council"
9 __license__ = "BSD - see LICENSE file in top-level directory"
10 __contact__ = "Philip.Kershaw@stfc.ac.uk"
11 __revision__ = '$Id: factory.py 7696 2010-11-03 08:57:41Z pjkersha $'
12 import traceback
13 import logging, os, sys
14 log = logging.getLogger(__name__)
15
16
18 '''Import from a string module name and object name. Object can be
19 any entity contained in a module
20
21 @param moduleName: Name of module containing the class
22 @type moduleName: str
23 @param objectName: Name of the class to import. If none is given, the
24 class name will be assumed to be the last component of modulePath
25 @type objectName: str
26 @rtype: class object
27 @return: imported class'''
28 if objectName is None:
29 if ':' in moduleName:
30
31
32 _moduleName, objectName = moduleName.rsplit(':', 1)
33 if '.' in objectName:
34 objectName = objectName.split('.')
35 else:
36 _moduleName, objectName = moduleName.rsplit('.', 1)
37 else:
38 _moduleName = moduleName
39
40 if isinstance(objectName, basestring):
41 objectName = [objectName]
42
43 module = __import__(_moduleName, globals(), locals(), [])
44 components = _moduleName.split('.')
45 try:
46 for component in components[1:]:
47 module = getattr(module, component)
48 except AttributeError:
49 raise AttributeError("Error importing %r: %s" %
50 (objectName[0], traceback.format_exc()))
51
52 importedObject = module
53 for i in objectName:
54 importedObject = getattr(importedObject, i)
55
56
57 if objectType and not issubclass(importedObject, objectType):
58 raise TypeError("Specified class %r must be derived from %r; got %r" %
59 (objectName, objectType, importedObject))
60
61 log.info('Imported %r from module %r', objectName[0], _moduleName)
62 return importedObject
63
64
65 -def callModuleObject(moduleName, objectName=None, moduleFilePath=None,
66 objectType=None, objectArgs=None, objectProperties=None):
67 '''
68 Create and return an instance of the specified class or invoke callable
69 @param moduleName: Name of module containing the class
70 @type moduleName: str
71 @param objectName: Name of the class to instantiate. May be None in
72 which case, the class name is parsed from the moduleName last element
73 @type objectName: str
74 @param moduleFilePath: Path to the module - if unset, assume module on
75 system path already
76 @type moduleFilePath: str
77 @param objectProperties: dict of properties to use when instantiating the
78 class
79 @type objectProperties: dict
80 @param objectType: expected type for the object to instantiate - to
81 enforce use of specific interfaces
82 @type objectType: object
83 @return: object - instance of the class specified
84 '''
85
86
87
88 if not objectProperties:
89 objectProperties = {}
90
91 if not objectArgs:
92 objectArgs = ()
93
94
95 sysPathBak = None
96 try:
97 try:
98
99
100 if moduleFilePath:
101 if not os.path.exists(moduleFilePath):
102 raise IOError("Module file path '%s' doesn't exist" %
103 moduleFilePath)
104
105
106 sysPathBak = sys.path
107
108 sys.path.append(moduleFilePath)
109
110
111
112 importedObject = importModuleObject(moduleName,
113 objectName=objectName,
114 objectType=objectType)
115 finally:
116
117
118
119 if sysPathBak:
120 sys.path = sysPathBak
121
122 except Exception, e:
123 log.debug('%r module import raised %r type exception: %s',
124 moduleName, e.__class__, traceback.format_exc())
125 raise
126
127
128 if objectArgs:
129 object = importedObject(*objectArgs, **objectProperties)
130 else:
131 object = importedObject(**objectProperties)
132
133 return object
134