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