1 = Imports = 2 3 An '''import''' is a declaration of one or more names that are provided by another source file or '''module''': 4 5 * `import` statements declare names that correspond to modules 6 * `from` statements declare names provided by modules 7 8 Imports occur either through explicit import operations initiated by the `from` and `import` statements, or through implicit import operations occurring to satisfy the requirements of another kind of operation. 9 10 <<TableOfContents(2,3)>> 11 12 == Packages and Submodules == 13 14 A '''package''' is a collection of modules whose names are all prefixed by the package name. For example: 15 16 {{{ 17 compiler 18 compiler.ast 19 compiler.transformer 20 }}} 21 22 Here, the `compiler` package is said to contain the `compiler.ast` and `compiler.transformer` modules. 23 24 === Defining Packages === 25 26 The package root or top-level module is defined in a file called `__init__.py` inside the directory bearing the package's name, and this file provides a namespace for the top-level module. However, a package does not expose its member modules ('''submodules''') as members of its top-level module. Instead, the hierarchical relationship between a package and its submodules exists purely in the naming of those modules, and where submodules are imported they must be done so using their full names. 27 28 Thus, relationships between packages and modules must be explicitly defined in module namespaces. For example, in the `compiler` module, the following would define relationships to the submodules: 29 30 {{{ 31 from compiler.ast import ast 32 from compiler.transformer import transformer 33 }}} 34 35 Without such import statements, no attempt will be made upon importing `compiler` to access the submodules and automatically populate the package. 36 37 === Accessing Submodules Directly === 38 39 Importing of submodules from packages will not cause the package itself to be imported. For example: 40 41 {{{ 42 import compiler.ast 43 }}} 44 45 This initialises the name `ast` which refers to the `compiler.ast` module, but the `compiler` package and its top-level module will not be imported. Thus, submodules can be considered independent of their packages, although they may seek to import their package top-level module should they need to access objects provided by that module. 46 47 == Implicit Imports == 48 49 The following kinds of operations cause implicit imports: 50 51 || '''Operations''' ||<-2> '''Import names provided by...''' || 52 || Augmented assignments ||<|5> `operator` || `operator.augmented` || 53 || Binary operators || `operator.binary` || 54 || Comparison operators || `operator.comparison` || 55 || Slice operators || `operator.sequence`<<BR>>~-Subscript operators are converted to item method invocations-~ || 56 || Unary operators || `operator.unary` || 57 || Access to built-in name || `__builtins__` || (various modules in the [[../Builtins|built-ins]] package hierarchy) || 58 59 Operator usage will cause a local name referring to an `operator` module function to be created, with the appropriate function being exposed by the `operator` module itself. However, the inspection process will seek to obtain a reference to the function in its actual definition location, ultimately referencing the function in one of the modules indicated above. 60 61 == Import Sequencing == 62 63 In order to populate modules, other modules may themselves be required to provide names to a given module, and in turn these other modules may rely on yet more modules, and so on. One logical consequence of this is that circular imports become possible, but the resulting mutual dependencies may not be easily untangled without careful attention to the state of each of the participating modules. Consider the following situation: 64 65 {{{{#!table 66 {{{#!graphviz 67 //format=svg 68 //transform=notugly 69 digraph mutual { 70 node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Mutually-dependent modules"]; 71 edge [tooltip="Mutually-dependent modules"]; 72 rankdir=LR; 73 74 subgraph { 75 rank=same; 76 moduleA [label="module A",shape=ellipse]; 77 fromB [label="from B import C",style=filled,fillcolor=gold]; 78 D [label="class D(C)"]; 79 } 80 81 subgraph { 82 rank=same; 83 moduleB [label="module B",shape=ellipse]; 84 fromA [label="from A import D",style=filled,fillcolor=gold]; 85 C [label="class C"]; 86 E [label="class E(D)"]; 87 } 88 89 moduleA -> fromB -> D [dir=none,style=dashed]; 90 moduleB -> fromA -> C -> E [dir=none,style=dashed]; 91 92 fromB -> fromA; 93 fromA -> fromB; 94 } 95 }}} 96 || 97 Module A: 98 99 {{{ 100 from B import C 101 102 class D(C): 103 ... 104 }}} 105 106 Module B: 107 108 {{{ 109 from A import D 110 111 class C: 112 ... 113 114 class E(D): 115 ... 116 }}} 117 }}}} 118 119 If modules were loaded upon being encountered in import statements, module A would not be completely processed when attempting to import from module B, and thus the import within module B of module A would only yield some information about module A. Consequently, the details of class D might not be available, and this would then have an impact on whether module B could even be completely processed itself. 120 121 The approach taken to generally deal with such situations is to defer resolution until all modules have been populated. Then, names are resolved with any names employing kinds of references specified as `<depends>` (instead of, for example, `<class>`) being resolved according to the recorded import dependencies. 122 123 Since the classes in one module may depend on those in other modules, it is not always possible to finalise the details of classes in a module context. And since modules may depend on each other, it is not always possible to finalise the details of classes until the details of all classes in a program are known. 124 125 === Module Initialisation === 126 127 Although static objects can be defined with interdependencies in a declarative fashion, the initialisation of objects in modules may require the availability of completely-initialised objects defined in other modules. Thus, an initialisation order needs to be established, with some modules being initialised before others, so that all modules do not encounter uninitialised names when they are expecting those names to provide valid objects. 128 129 The most obvious example of a module requiring the initialisation of others before it is itself evaluated is, of course, the `__main__` module. Given that it may import instances defined as attribute on other modules, it clearly requires those modules to have been initialised and those instances to have been created. It would be absurd to consider running the body of the `__main__` module before such other modules. Similarly, such dependencies exist between other modules, and consequently, an appropriate initialisation ordering must be defined for them. In its entirety, then, a program must define a workable ordering for all of its modules, signalling a concrete error if no such ordering can be established. 130 131 == Hidden Modules == 132 133 Imports that do not obtain the imported module name itself, such as those initiated by the `from` statement and by implicit operations, keep the imported module '''hidden'''. Unless other operations expose hidden modules, they will remain hidden and may consequently be omitted from the final generated program: there would be no way of referencing such modules and they would therefore be unable to contribute their contents to the rest of the program. 134 135 However, where an object provided by a module is referenced, a module cannot remain hidden, since the provided object may depend on other parts of the module in order to function correctly. And since a provided object might reference or return other objects in the module, the general module contents must also be exposed. 136 137 Import dependencies are defined for namespaces indicating modules that are required by each namespace. By following dependency relationships, it is possible to determine the eventual target of an import and to potentially skip over modules that merely import and expose names. For example: 138 139 {{{{#!table 140 {{{#!graphviz 141 //format=svg 142 //transform=notugly 143 digraph imports { 144 node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Import dependencies"]; 145 edge [tooltip="Import dependencies"]; 146 rankdir=LR; 147 148 importer [label="from A import C",style=filled,fillcolor=darkorange]; 149 150 subgraph { 151 rank=same; 152 moduleA [label="module A",shape=ellipse]; 153 fromB [label="from B import C",style=filled,fillcolor=gold]; 154 } 155 156 subgraph { 157 rank=same; 158 moduleB [label="module B",shape=ellipse]; 159 C [label="class C",style=filled,fillcolor=darkorange]; 160 } 161 162 moduleA -> fromB [dir=none,style=dashed]; 163 moduleB -> C [dir=none,style=dashed]; 164 165 importer -> fromB -> C; 166 } 167 }}} 168 || 169 {{{ 170 from A import C 171 }}} 172 173 Module A: 174 175 {{{ 176 from B import C 177 }}} 178 179 Module B: 180 181 {{{ 182 class C: 183 ... 184 }}} 185 }}}} 186 187 Here, B is never explicitly referenced, nor does it provide any referenced objects other than an imported name. Consequently, B is hidden and ultimately excluded from the final program. Such techniques are employed in the [[../Builtins|built-ins]] package hierarchy to reduce the amount of functionality employed by (and bundled in) a generated program.