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

# This module is from mx/DateTime/LazyModule.py and is 

# distributed under the terms of the eGenix.com Public License Agreement 

# http://www.egenix.com/products/eGenix.com-Public-License-1.1.0.pdf 

 

""" Helper to enable simple lazy module import. 

 

    'Lazy' means the actual import is deferred until an attribute is 

    requested from the module's namespace. This has the advantage of 

    allowing all imports to be done at the top of a script (in a 

    prominent and visible place) without having a great impact 

    on startup time. 

 

    Copyright (c) 1999-2005, Marc-Andre Lemburg; mailto:mal@lemburg.com 

    See the documentation for further information on copyrights, 

    or contact the author. All Rights Reserved. 

""" 

from __future__ import print_function 

 

### Constants 

 

_debug = 0 

 

### 

 

class LazyModule: 

 

    """ Lazy module class. 

 

        Lazy modules are imported into the given namespaces whenever a 

        non-special attribute (there are some attributes like __doc__ 

        that class instances handle without calling __getattr__) is 

        requested. The module is then registered under the given name 

        in locals usually replacing the import wrapper instance. The 

        import itself is done using globals as global namespace. 

 

        Example of creating a lazy load module: 

 

        ISO = LazyModule('ISO',locals(),globals()) 

 

        Later, requesting an attribute from ISO will load the module 

        automatically into the locals() namespace, overriding the 

        LazyModule instance: 

 

        t = ISO.Week(1998,1,1) 

 

    """ 

    # Flag which inidicates whether the LazyModule is initialized or not 

    __lazymodule_init = 0 

 

    # Name of the module to load 

    __lazymodule_name = '' 

 

    # Flag which indicates whether the module was loaded or not 

    __lazymodule_loaded = 0 

 

    # Locals dictionary where to register the module 

    __lazymodule_locals = None 

 

    # Globals dictionary to use for the module import 

    __lazymodule_globals = None 

 

    def __init__(self, name, locals, globals=None): 

 

        """ Create a LazyModule instance wrapping module name. 

 

            The module will later on be registered in locals under the 

            given module name. 

 

            globals is optional and defaults to locals. 

 

        """ 

        self.__lazymodule_locals = locals 

        if globals is None: 

            globals = locals 

        self.__lazymodule_globals = globals 

        mainname = globals.get('__name__', '') 

        if mainname: 

            self.__name__ = mainname + '.' + name 

            self.__lazymodule_name = name 

        else: 

            self.__name__ = self.__lazymodule_name = name 

        self.__lazymodule_init = 1 

 

    def __lazymodule_import(self): 

 

        """ Import the module now. 

        """ 

        # Load and register module 

        name = self.__lazymodule_name 

        if self.__lazymodule_loaded: 

            return self.__lazymodule_locals[name] 

        if _debug: 

            print('LazyModule: Loading module %r' % name) 

        self.__lazymodule_locals[name] \ 

             = module \ 

             = __import__(name, 

                          self.__lazymodule_locals, 

                          self.__lazymodule_globals, 

                          '*') 

 

        # Fill namespace with all symbols from original module to 

        # provide faster access. 

        self.__dict__.update(module.__dict__) 

 

        # Set import flag 

        self.__dict__['__lazymodule_loaded'] = 1 

 

        if _debug: 

            print('LazyModule: Module %r loaded' % name) 

        return module 

 

    def __getattr__(self, name): 

 

        """ Import the module on demand and get the attribute. 

        """ 

        if self.__lazymodule_loaded: 

            raise AttributeError(name) 

        if _debug: 

            print('LazyModule: ' \ 

                  'Module load triggered by attribute %r read access' % name) 

        module = self.__lazymodule_import() 

        return getattr(module, name) 

 

    def __setattr__(self, name, value): 

 

        """ Import the module on demand and set the attribute. 

        """ 

        if not self.__lazymodule_init: 

            self.__dict__[name] = value 

            return 

        if self.__lazymodule_loaded: 

            self.__lazymodule_locals[self.__lazymodule_name] = value 

            self.__dict__[name] = value 

            return 

        if _debug: 

            print('LazyModule: ' \ 

                  'Module load triggered by attribute %r write access' % name) 

        module = self.__lazymodule_import() 

        setattr(module, name, value) 

 

    def __repr__(self): 

        return "<LazyModule '%s'>" % self.__name__