Lichen

docs/wiki/Imports

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