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