@@ -78,6 +78,7 @@ The following code demonstrates roughly equivalent semantics for the
78
78
default behavior::
79
79
80
80
class Meta(type):
81
+ @classmethod
81
82
def __prepare__(cls, *args, **kwargs):
82
83
return OrderedDict()
83
84
@@ -96,7 +97,7 @@ Why a tuple?
96
97
97
98
Use of a tuple reflects the fact that we are exposing the order in
98
99
which attributes on the class were *defined*. Since the definition
99
- is already complete by the time ``definition_order__ `` is set, the
100
+ is already complete by the time ``__definition_order__ `` is set, the
100
101
content and order of the value won't be changing. Thus we use a type
101
102
that communicates that state of immutability.
102
103
@@ -156,6 +157,11 @@ so that consumers of ``__definition_order__`` may have a consistent
156
157
expectation for the value. That helps maximize the feature's
157
158
usefulness.
158
159
160
+ We could also also allow an arbitrary iterable for a manually set
161
+ ``__definition_order__`` and convert it into a tuple. However, not
162
+ all iterables infer a definition order (e.g. ``set``). So we opt in
163
+ favor of requiring a tuple.
164
+
159
165
Why is __definition_order__ even necessary?
160
166
-------------------------------------------
161
167
@@ -172,7 +178,8 @@ Compatibility
172
178
173
179
This PEP does not break backward compatibility, except in the case that
174
180
someone relies *strictly* on ``dict`` as the class definition namespace.
175
- This shouldn't be a problem.
181
+ This shouldn't be a problem since ``issubclass(OrderedDict, dict)`` is
182
+ true.
176
183
177
184
178
185
Changes
@@ -203,7 +210,7 @@ The implementation is found in the tracker. [impl_]
203
210
Alternatives
204
211
============
205
212
206
- <class> .__dict__ as OrderedDict
213
+ cls .__dict__ as OrderedDict
207
214
-------------------------------
208
215
209
216
Instead of storing the definition order in ``__definition_order__``,
@@ -223,6 +230,34 @@ PEP 422 introduced a new "namespace" keyword arg to class definitions
223
230
that effectively replaces the need to ``__prepare__()``. [pep422_]
224
231
However, the proposal was withdrawn in favor of the simpler PEP 487.
225
232
233
+ A stdlib Metaclass that Implements __prepare__() with OrderedDict
234
+ -----------------------------------------------------------------
235
+
236
+ This has all the same problems as writing your own metaclass. The
237
+ only advantage is that you don't have to actually write this
238
+ metaclass. So it doesn't offer any benefit in the context of this
239
+ PEP.
240
+
241
+ Set __definition_order__ at Compile-time
242
+ ----------------------------------------
243
+
244
+ Each class's ``__qualname__`` is determined at compile-time.
245
+ This same concept could be applied to ``__definition_order__``.
246
+ The result of composing ``__definition_order__`` at compile-time
247
+ would be nearly the same as doing so at run-time.
248
+
249
+ Comparative implementation difficulty aside, the key difference
250
+ would be that at compile-time it would not be practical to
251
+ preserve definition order for attributes that are set dynamically
252
+ in the class body (e.g. ``locals()[name] = value``). However,
253
+ they should still be reflected in the definition order. One
254
+ posible resolution would be to require class authors to manually
255
+ set ``__definition_order__`` if they define any class attributes
256
+ dynamically.
257
+
258
+ Ultimately, the use of ``OrderedDict`` at run-time or compile-time
259
+ discovery is almost entirely an implementation detail.
260
+
226
261
227
262
References
228
263
==========
0 commit comments