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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

""" 

apipkg: control the exported namespace of a python package. 

 

see http://pypi.python.org/pypi/apipkg 

 

(c) holger krekel, 2009 - MIT license 

""" 

import os 

import sys 

from types import ModuleType 

 

__version__ = '1.3.dev' 

 

def _py_abspath(path): 

    """ 

    special version of abspath 

    that will leave paths from jython jars alone 

    """ 

21    if path.startswith('__pyclasspath__'): 

 

        return path 

    else: 

        return os.path.abspath(path) 

 

def initpkg(pkgname, exportdefs, attr=dict()): 

    """ initialize given package from the export definitions. """ 

    oldmod = sys.modules.get(pkgname) 

    d = {} 

    f = getattr(oldmod, '__file__', None) 

32    if f: 

        f = _py_abspath(f) 

    d['__file__'] = f 

35    if hasattr(oldmod, '__version__'): 

        d['__version__'] = oldmod.__version__ 

36    if hasattr(oldmod, '__loader__'): 

        d['__loader__'] = oldmod.__loader__ 

39    if hasattr(oldmod, '__path__'): 

        d['__path__'] = [_py_abspath(p) for p in oldmod.__path__] 

41    if '__doc__' not in exportdefs and getattr(oldmod, '__doc__', None): 

        d['__doc__'] = oldmod.__doc__ 

    d.update(attr) 

44    if hasattr(oldmod, "__dict__"): 

        oldmod.__dict__.update(d) 

    mod = ApiModule(pkgname, exportdefs, implprefix=pkgname, attr=d) 

    sys.modules[pkgname] = mod 

 

def importobj(modpath, attrname): 

    module = __import__(modpath, None, None, ['__doc__']) 

    if not attrname: 

        return module 

 

    retval = module 

    names = attrname.split(".") 

    for x in names: 

        retval = getattr(retval, x) 

    return retval 

 

class ApiModule(ModuleType): 

    def __docget(self): 

        try: 

            return self.__doc 

        except AttributeError: 

            if '__doc__' in self.__map__: 

                return self.__makeattr('__doc__') 

    def __docset(self, value): 

        self.__doc = value 

    __doc__ = property(__docget, __docset) 

 

    def __init__(self, name, importspec, implprefix=None, attr=None): 

        self.__name__ = name 

        self.__all__ = [x for x in importspec if x != '__onfirstaccess__'] 

        self.__map__ = {} 

        self.__implprefix__ = implprefix or name 

        if attr: 

            for name, val in attr.items(): 

                # print "setting", self.__name__, name, val 

                setattr(self, name, val) 

        for name, importspec in importspec.items(): 

            if isinstance(importspec, dict): 

                subname = '%s.%s' % (self.__name__, name) 

                apimod = ApiModule(subname, importspec, implprefix) 

                sys.modules[subname] = apimod 

                setattr(self, name, apimod) 

            else: 

                parts = importspec.split(':') 

                modpath = parts.pop(0) 

                attrname = parts and parts[0] or "" 

                if modpath[0] == '.': 

                    modpath = implprefix + modpath 

 

                if not attrname: 

                    subname = '%s.%s' % (self.__name__, name) 

                    apimod = AliasModule(subname, modpath) 

                    sys.modules[subname] = apimod 

                    if '.' not in name: 

                        setattr(self, name, apimod) 

                else: 

                    self.__map__[name] = (modpath, attrname) 

 

    def __repr__(self): 

        l = [] 

        if hasattr(self, '__version__'): 

            l.append("version=" + repr(self.__version__)) 

        if hasattr(self, '__file__'): 

            l.append('from ' + repr(self.__file__)) 

        if l: 

            return '<ApiModule %r %s>' % (self.__name__, " ".join(l)) 

        return '<ApiModule %r>' % (self.__name__,) 

 

    def __makeattr(self, name): 

        """lazily compute value for name or raise AttributeError if unknown.""" 

        # print "makeattr", self.__name__, name 

        target = None 

115        if '__onfirstaccess__' in self.__map__: 

            target = self.__map__.pop('__onfirstaccess__') 

            importobj(*target)() 

        try: 

            modpath, attrname = self.__map__[name] 

        except KeyError: 

122            if target is not None and name != '__onfirstaccess__': 

                # retry, onfirstaccess might have set attrs 

                return getattr(self, name) 

            raise AttributeError(name) 

        else: 

            result = importobj(modpath, attrname) 

            setattr(self, name, result) 

            try: 

                del self.__map__[name] 

            except KeyError: 

                pass  # in a recursive-import situation a double-del can happen 

            return result 

 

    __getattr__ = __makeattr 

 

    def __dict__(self): 

        # force all the content of the module to be loaded when __dict__ is read 

        dictdescr = ModuleType.__dict__['__dict__'] 

        dict = dictdescr.__get__(self) 

        if dict is not None: 

            hasattr(self, 'some') 

            for name in self.__all__: 

                try: 

                    self.__makeattr(name) 

                except AttributeError: 

                    pass 

        return dict 

    __dict__ = property(__dict__) 

 

 

def AliasModule(modname, modpath, attrname=None): 

    mod = [] 

 

    def getmod(): 

        if not mod: 

            x = importobj(modpath, None) 

            if attrname is not None: 

                x = getattr(x, attrname) 

            mod.append(x) 

        return mod[0] 

 

    class AliasModule(ModuleType): 

 

        def __repr__(self): 

            x = modpath 

            if attrname: 

                x += "." + attrname 

            return '<AliasModule %r for %r>' % (modname, x) 

 

        def __getattribute__(self, name): 

            try: 

                return getattr(getmod(), name) 

            except ImportError: 

                return None 

 

        def __setattr__(self, name, value): 

            setattr(getmod(), name, value) 

 

        def __delattr__(self, name): 

            delattr(getmod(), name) 

 

    return AliasModule(str(modname))