blob: 4eb78a7aa4d5d0f307bc6882956b3fd146f95ea4 [file] [log] [blame]
Tim Peters6d6c1a32001-08-02 04:15:00 +00001Project: core implementation
2****************************
3
Guido van Rossumeb9f3842001-08-30 21:18:04 +00004Still to do
5-----------
Tim Peters6d6c1a32001-08-02 04:15:00 +00006
Guido van Rossum50fda3b2001-10-04 19:46:06 +00007Add __del__ handlers?
Guido van Rossum43b9a082001-09-28 18:19:21 +00008
9Allow assignment to __bases__ and __dict__?
10
11Support mixed multiple inheritance from classic and new-style classes?
12
Guido van Rossumeb9f3842001-08-30 21:18:04 +000013Check for conflicts between base classes. I fear that the rules used
14to decide whether multiple bases have conflicting instance variables
15aren't strict enough. I think that sometimes two different classes
16adding __dict__ may be incompatible after all.
17
18Check for order conflicts. Suppose there are two base classes X and
19Y. Suppose class B derives from X and Y, and class C from Y and X (in
20that order). Now suppose class D derives from B and C. In which
21order should the base classes X and Y be searched? This is an order
22conflict, and should be disallowed; currently the test for this is not
23implemented.
24
Guido van Rossumeb9f3842001-08-30 21:18:04 +000025Done (mostly)
26-------------
27
Guido van Rossum27b7f9f2001-10-12 17:43:43 +000028More performance work -- one particular test, test_descr.inherits(),
29is still about 50% slower with dynamic classes. :-( The approach of
30choice would be:
31
32 Add a list of weak refs to derived classes to each dynamic
33 class, and trap setattr+delattr on the base class so that they
34 update the tp_XXX slot in each derived class when the base class
35 __XXX__ gets set or deleted. More work, but more gain (zero waste
36 in slot_tp_XXX when __XXX__ is not overridden).
37*** That's done now, with great success. ***
38
Guido van Rossum50fda3b2001-10-04 19:46:06 +000039Make __dynamic__ the default. *** done (but more performance work
40needs to be done). ***
41
Guido van Rossumf49a9132001-10-03 03:00:56 +000042Treat all binary operators the same way as I just did for rich
43comparison: in a <op> b, if type(a) is not type(b) and isinstance(b,
44type(a)), try b.__rop__(a) before trying a.__op__(b). *** Done. ***
45
Guido van Rossumc39553a2001-09-25 06:20:52 +000046Fix comparisons. There's some nasty stuff here: when two types are
47not the same, and they're not instances, the fallback code doesn't
48account for the possibility that they might be subtypes of a common
49base type that defines a comparison. *** I believe this is now done,
50but it's a bit of a mess. ***
51
52Allow __class__ assignment. *** done ***
53
54Change __getattr__ to be more like classic __getattr__, and introduce
55a new name for new-style __getattr__. *** Done. The new-style method
56is called __getattribute__. ***
57
Guido van Rossumed8fa722001-09-20 05:27:24 +000058Make inspect and pydoc do the right thing for new-style classes. ***
59done ***
60
Guido van Rossumeb9f3842001-08-30 21:18:04 +000061Do binary operators properly. nb_add should try to call self.__add__
62and other.__radd__. I think I'll exclude base types that define any
63binary operator without setting the CHECKTYPES flag. *** This is
64done, AFAICT. Even supports __truediv__ and __floordiv__. ***
65
Tim Peters6d6c1a32001-08-02 04:15:00 +000066Fix subtype_dealloc(). This currently searches through the list of
67base types until it finds a type whose tp_dealloc is not
68subtype_dealloc. I think this is not safe. I think the alloc/dealloc
69policy needs to be rethought. *** There's an idea here that I haven't
70worked out yet: just as object creation now has separate API's tp_new,
71tp_alloc, and tp_init, destruction has tp_dealloc and tp_free. (Maybe
72tp_fini should be added to correspond to tp_init?) Something
73could/should be done with this. ***
74
75Clean up isinstance(), issubclass() and their C equivalents. There
76are a bunch of different APIs here and not all of them do the right
77thing yet. There should be fewer APIs and their implementation should
78be simpler. The old "abstract subclass" test should probably
79disappear (if we want to root out ExtensionClass). *** I think I've
80done 90% of this by creating PyType_IsSubtype() and using it
81appropriately. For now, the old "abstract subclass" test is still
82there, and there may be some places where PyObject_IsSubclass() is
83called where PyType_IsSubtype() would be more appropriate. ***
84
Tim Peters6d6c1a32001-08-02 04:15:00 +000085Clean up the GC interface. Currently, tp_basicsize includes the GC
86head size iff tp_flags includes the GC flag bit. This makes object
87size math a pain (e.g. to see if two object types have the same
88instance size, you can't just compare the tp_basicsize fields -- you
89have to conditionally subtract the GC head size). Neil has a patch
90that improves the API in this area, but it's backwards incompatible.
91(http://sf.net/tracker/?func=detail&aid=421893&group_id=5470&atid=305470)
92I think I know of a way to fix the incompatibility (by switching to a
93different flag bit). *** Tim proposed a better idea: macros to access
94tp_basicsize while hiding the nastiness. This is done now, so I think
Guido van Rossumeb9f3842001-08-30 21:18:04 +000095the rest of this task needn't be done. *** *** Neil checked in a
96much improved version of his idea, and it's all squared away. ***
Tim Peters6d6c1a32001-08-02 04:15:00 +000097
98Make the __dict__ of types declared with Python class statements
99writable -- only statically declared types must have an immutable
100dict, because they're shared between interpreter instances. Possibly
101trap writes to the __dict__ to update the corresponding tp_<slot> if
102an __<slot>__ name is affected. *** Done as part of the next task. ***
103
104It should be an option (maybe a different metaclass, maybe a flag) to
105*not* merge __dict__ with all the bases, but instead search the
106__dict__ (or __introduced__?) of all bases in __mro__ order. (This is
107needed anyway to unify classes completely.) *** Partly done.
108Inheritance of slots from bases is still icky: (1) MRO is not always
109respected when inheriting slots; (2) dynamic classes can't add slot
110implementations in Python after creation (e.g., setting C.__hash__
111doesn't set the tp_hash slot). ***
112
113Universal base class (object). How can we make the object class
114subclassable and define simple default methods for everything without
115having these inherited by built-in types that don't want these
116defaults? *** Done, really. ***
117
118Add error checking to the MRO calculation. *** Done. ***
119
120Make __new__ overridable through a Python class method (!). Make more
121of the sub-algorithms of type construction available as methods. ***
122After I implemented class methods, I found that in order to be able
123to make an upcall to Base.__new__() and have it create an instance of
124your class (rather than a Base instance), you can't use class methods
125-- you must use static methods. So I've implemented those too. I've
126hooked up __new__ in the right places, so the first part of this is
127now done. I've also exported the MRO calculation and made it
128overridable, as metamethod mro(). I believe that closes this topic
129for now. I expect that some warts will only be really debugged when
130we try to use this for some, eh, interesting types such as tuples. ***
131
Guido van Rossum04156202001-08-08 16:57:43 +0000132 There was a sequel to the __new__ story (see checkins). There
133 still is a problem: object.__new__ now no longer exists, because
134 it was inherited by certain extension types that could break. But
135 now when I write
136
137 class C(object):
138 def __new__(cls, *args):
139 "How do I call the default __new__ implementation???"
140
Guido van Rossum42a8c2b2001-08-09 20:25:58 +0000141 This was resolved nicely by putting object.__new__ back but not
142 inheriting __new__ from object when the subtype is a built-in or
143 extension type.
144
Tim Peters6d6c1a32001-08-02 04:15:00 +0000145More -- I'm sure new issues will crop up as we go.
146
147
148Project: loose ends and follow-through
149**************************************
150
Guido van Rossumeb9f3842001-08-30 21:18:04 +0000151Still to do
152-----------
Tim Peters6d6c1a32001-08-02 04:15:00 +0000153
154Exceptions should be types. This changes the rules, since now almost
155anything can be raised (as maybe it should). Or should we strive for
156enforcement of the convention that all exceptions should be derived
157from Exception? String exceptions will be another hassle, to be
158deprecated and eventually ruled out.
159
160Standardize a module containing names for all built-in types, and
161standardize on names. E.g. should the official name of the string
162type be 'str', 'string', or 'StringType'?
163
164Create a hierarchy of types, so that e.g. int and long are both
165subtypes of an abstract base type integer, which is itself a subtype
166of number, etc. A lot of thinking can go into this!
167
168*** NEW TASK??? ***
169Implement "signature" objects. These are alluded to in PEP 252 but
170not yet specified. Supposedly they provide an easily usable API to
171find out about function/method arguments. Building these for Python
172functions is simple. Building these for built-in functions will
173require a change to the PyMethodDef structure, so that a type can
174provide signature information for its C methods. (This would also
175help in supporting keyword arguments for C methods with less work than
176PyArg_ParseTupleAndKeywords() currently requires.) But should we do
177this? It's additional work and not required for any of the other
178parts.
179
Guido van Rossumeb9f3842001-08-30 21:18:04 +0000180Done (mostly)
181-------------
182
183Make more (most?) built-in types act as their own factory functions.
184*** Done for all reasonable built-in types. ***
185
186Make more (most?) built-in types subtypable -- with or without
187overridable allocation. *** This includes descriptors! It should be
188possible to write descriptors in Python, so metaclasses can do clever
189things with them. *** *** Done for most reasonable built-in types,
190except for descriptors ***
191
Tim Peters6d6c1a32001-08-02 04:15:00 +0000192
193Project: making classes use the new machinery
194*********************************************
195
196Tasks:
197
198Try to get rid of all code in classobject.c by deferring to the new
199mechanisms. How far can we get without breaking backwards
200compatibility? This is underspecified because I haven't thought much
201about it yet. Can we lose the use of PyInstance_Check() everywhere?
Guido van Rossumeb9f3842001-08-30 21:18:04 +0000202I would hope so! *** I'm dropping this goal for now -- classic
203classes will be 99% unchanged. ***
Tim Peters6d6c1a32001-08-02 04:15:00 +0000204
205
206Project: backwards compatibility
207********************************
208
209Tasks:
210
211Make sure all code checks the proper tp_flags bit before accessing
212type object fields.
213
214Identify areas of incompatibility with Python 2.1. Design solutions.
215Implement and test.
216
217Some specific areas: a fair amount of code probably depends on
218specific types having __members__ and/or __methods__ attributes.
219These are currently not present (conformant to PEP 252, which proposes
220to drop them) but we may have to add them back. This can be done in a
221generic way with not too much effort. Tim adds: Perhaps that dir(object)
222rarely returns anything but [] now is a consequence of this. I'm very
223used to doing, e.g., dir([]) or dir("") in an interactive shell to jog my
224memory; also one of the reasons test_generators failed.
225
226Another area: going all the way with classes and instances means that
227type(x) == types.InstanceType won't work any more to detect instances.
228Should there be a mode where this still works? Maybe this should be
229the default mode, with a warning, and an explicit way to get the new
230way to work? (Instead of a __future__ statement, I'm thinking of a
231module global __metaclass__ which would provide the default metaclass
232for baseless class statements.)
233
234
235Project: testing
236****************
237
238Tasks:
239
240Identify new functionality that needs testing. Conceive unit tests
241for all new functionality. Conceive stress tests for critical
242features. Run the tests. Fix bugs. Repeat until satisfied.
243
244Note: this may interact with the branch integration task.
245
246
Tim Petersf9803012001-08-02 22:06:35 +0000247Project: integration with main branch *** This is done - tim ***
Tim Peters6d6c1a32001-08-02 04:15:00 +0000248*************************************
249
250Tasks:
251
252Merge changes in the HEAD branch into the descr-branch. Then merge
253the descr-branch back into the HEAD branch.
254
255The longer we wait, the more effort this will be -- the descr-branch
256forked off quite a long time ago, and there are changes everywhere in
257the HEAD branch (e.g. the dict object has been radically rewritten).
258
259On the other hand, if we do this too early, we'll have to do it again
260later.
261
262Note from Tim: We should never again wait until literally 100s of files
263are out of synch. I don't care how often I need to do this, provided only
264that it's a tractable task each time. Once per week sounds like a good
265idea. As is, even the trunk change to rangeobject.c created more than its
266proper share of merge headaches, because it confused all the other reasons
267include file merges were getting conflicts (the more changes there are, the
268worse diff does; indeed, I came up with the ndiff algorithm in the 80s
269precisely because the source-control diff program Cray used at the time
270produced minimal but *senseless* diffs, thus creating artificial conflicts;
271paying unbounded attention to context does a much better job of putting
272changes where they make semantic sense too; but we're stuck with Unix diff
273here, and it isn't robust in this sense; if we don't keep its job simple,
274it will make my job hell).
275
276Done:
277To undo or rename before final merge: Modules/spam.c has worked its
278way into the branch Unix and Windows builds (pythoncore.dsp and
279PC/config.c); also imported by test_descr.py. How about renaming to
Tim Petersf9803012001-08-02 22:06:35 +0000280xxsubtype.c (whatever) now? *** this is done - tim ***
Tim Peters6d6c1a32001-08-02 04:15:00 +0000281
282
283Project: performance tuning
284***************************
285
286Tasks:
287
288Pick or create a general performance benchmark for Python. Benchmark
289the new system vs. the old system. Profile the new system. Improve
290hotspots. Repeat until satisfied.
291
292Note: this may interact with the branch integration task.
293
294
295Project: documentation
296**********************
297
298Tasks:
299
300Update PEP 252 (descriptors). Describe more of the prototype
301implementation
302
303Update PEP 253 (subtyping). Complicated architectural wrangling with
304metaclasses. There is an interaction between implementation and
305description.
306
307Write PEP 254 (unification of classes). This should discuss what
308changes for ordinary classes, and how we can make it more b/w
309compatible.
310
311Other documentation. There needs to be user documentation,
312eventually.
313
314
315Project: community interaction
316******************************
317
318Tasks:
319
320Once the PEPs are written, solicit community feedback, and formulate
321responses to the feedback. Give the community enough time to think
322over this complicated proposal. Provide the community with a
323prototype implementation to test. Try to do this *before* casting
324everything in stone!