1 Micropython: A minimal implementation of Python for constrained devices
2
3 * "Full strength" Python:
4 * Introspection, interactivity, PEP/reference-compliance
5 * CPython, Jython, IronPython, PyPy, CLPython, etc.
6 * "Reduced strength" Python:
7 * Remove "luxury" semantics
8 * Shed Skin, RPython, etc.
9
10 Motivations
11
12 * Run Python programs in "small" devices
13 * Small programs plus few executed instructions
14 * Avoid expensive library code
15 (small footprint, lots of executed instructions)
16
17 Python's flexibility comes at a cost
18
19 * Modules, classes, instances are all objects
20 * Freedom to modify most objects at any time
21 * Difficult to predict eventual behaviour before execution
22 * Difficult to generate optimisations when compiling
23
24 Not all things are dynamic/equal in Python
25
26 * Locals, modules and classes are special in some way
27 * Locals don't tend to change unilaterally
28 * Parameter lists don't tend to change if fully specified
29 * Modules usually retain their identity
30 * Classes differ from objects (despite metaclasses)
31
32 Attribute access
33
34 * Must do a full lookup every time:
35 * Check instance dictionary
36 * Check class, superclasses
37 * Potentially lots of code
38 * Lots of executed instructions
39
40 Improving attribute access performance
41
42 * Achieve faster access using a different representation
43 * Must define attributes of objects in advance
44 * Restriction: modules, classes, instances are "closed"
45 * Evaluate the limitations: are they too disruptive?
46
47 Consequences of revised attribute access
48
49 * Cannot extend the range of attributes on objects of existing classes
50 * Further optimisations:
51 * Restriction: attempt to control modification of attributes
52 * Result: further optimisation of accesses
53
54 Invocations
55
56 * Target checking
57 * Number of arguments vs. number of parameters
58 * Keyword parameter resolution
59 * Defaults
60
61 Other costly operations
62
63 * Binary operators
64 * Comparisons
65
66 Examples of rarely used/unnecessary flexibility
67
68 * Can subclass dynamically:
69
70 for cls in A, B:
71 class C(cls):
72 pass
73
74 * Yet most people would relate to "class C"
75 * Not "the class currently known as C"
76
77 Examples of occasionally used flexibility
78
79 * Can evaluate classes and functions in dynamic contexts:
80
81 if platform == 'posix':
82 class C:
83 ...
84 else:
85 class C:
86 ...
87
88 * Seen quite often in the standard library with functions
89 * Dynamism used for configuration purposes
90
91 Distinguish between "good" and "bad" dynamism
92
93 * Dynamic class preparation
94 * Run-time choice of classes
95 * Assigning attributes to modules
96
97 Run-time configuration
98
99 * The source of a lot of "bad" dynamism
100 * Comparable to, but more robust than...
101 * Class loading tricks in Java
102 * Dynamic library loading magic in C/C++
103 * Has a place, but perhaps not in compiled, embedded programs
104
105 Micropython modules
106
107 * Modules contain attributes as with normal Python
108 * Inside the module:
109 * Attributes can be accessed and set as globals
110 * Classes and functions define module attributes
111 * Outside the module:
112 * Attributes can be accessed but not set
113 * This can be relaxed with attribute usage observations
114 * Definition from within means more predictable content
115
116 Micropython classes
117
118 * Classes contain attributes and expose superclass attributes
119 * Inside the class:
120 * Attributes can be accessed and set in the class scope
121 * Functions define methods
122 * Outside the class:
123 * Attributes can be accessed but not set
124 * This can be relaxed with attribute usage observations
125 * Definition from within means more predictable content
126
127 Micropython instances
128
129 * Instances contain attributes and expose class attributes
130 * Instance attributes must not shadow class attributes
131 * The set of attributes is detected by scanning the __init__ method
132
133 Rationale for restrictions
134
135 * Construct efficient run-time representations
136 * Predictable content means that access can be optimised
137 * No shadowing means that only a single lookup is necessary
138
139 References, attributes and values
140
141 * Almost everything can be considered as a kind of attribute:
142 * Module, class, instance
143 * Local variable is the exception
144 * Acquired attributes are "values":
145 * An object being manipulated
146 * Its context
147 * Most kinds of values have no real context:
148 * Module and class attributes, locals
149 * The exception:
150 * Instance attributes
151
152 Wild idea: isn't AttributeError just evidence of a bug in the program?
153
154 * Note down all attributes used by a particular name during its lifetime
155 * Upon recording name usage, record the location of usage
156 * Use the set of attributes to constrain the range of types that can be used
157 without an AttributeError being raised
158 * Convert all name usage to specific attribute usage (on the range of types
159 found) for all attribute accesses
160
161 Attributes on locals
162
163 * Control-flow can make attribute tracking awkward:
164
165 obj.x # obj must have x
166 if obj.p: # obj must have x, p
167 # (branch)
168 obj = ... # obj reset
169 obj.attr # obj must have attr
170 # (end of branch)
171 else: # (branch)
172 obj.name # obj must have x, p, name
173 # (end of branch)
174 # (merge branch ends)
175 # obj must have either attr or x, p, name
176
177 Attributes on locals with loops
178
179 * Loops complicate matters still further:
180
181 obj.x # obj must have x
182 while obj.p: # obj must have x, p
183 # (branch)
184 obj.y # obj must have x, p, y
185 obj = ... # obj reset
186 obj.z # obj must have z
187 # (re-test)
188 # obj must have z, p
189 # (end of branch)
190 # (null branch - no else)
191 # (merge branch ends)
192 # obj must have either z, p (from loop) or x, p (from null branch)
193
194 Attributes on attributes
195
196 * Classes and modules should preserve single interpretations of attributes
197 * Attributes on such attributes should accumulate on the targets
198 * Tracking attributes on such targets is only useful for unknown targets
199 * Instances cannot be relied upon to refer to a coherent set of targets