[Twisted-Python] Phasing out old-style classes

Glyph Lefkowitz glyph at twistedmatrix.com
Sun Oct 25 01:38:12 EDT 2009

On Oct 24, 2009, at 10:50 AM, exarkun at twistedmatrix.com wrote:

> I think that we should consider requests to make specific classes new-
> style (and grant them when doing so won't cause compatibility  
> problems),
> make all new classes new-style, but otherwise leave this alone until  
> 3.x
> is widely adopted.

While your argument makes sense to me, there's a fundamental problem  
with the way Python introduced new-style classes that creates an  
ongoing maintenance tension.  I think we should start addressing the  
problem incrementally now (especially since it sounded like Kelly was  
volunteering for some work!) rather than put it off for one big chunk  
when we do a 3k migration.

Let's say you're writing a new Twisted application today.  You want to  
be prepared for the day when everything is new-style, but you also  
want to use existing Twisted functionality.  You're using some long- 
standing library class, that looks like this:

# in Twisted
class Library: pass

What do you do?  Well, the obvious upgrade path here is to make a  
class which (A) inherits from "Library" to get Twisted functionality  
and (B) inherits from "object" to get new-style-ness.  So you go ahead  
and write:

# in your application
class Application(object, Library): pass

... and that's great.  It works, your class is new-style, and it gets  
all the library functionality that you want.  Except now, you've made  
the old-style-ness of 'Library' a very important part of its  
interface.  If, one day, we flip any kind of new-style switch, instead  
of neatly defining a new-style twisted-using class, your code will do  
this instead:

Traceback (most recent call last):
   File "your-application.py", line 1, in <module>
     class Application(object, Library): pass
TypeError: Error when calling the metaclass bases
     Cannot create a consistent method resolution
order (MRO) for bases object, Library

I would really like a more abstract declaration that applications can  
use in the meanwhile, to get new-style semantics but still allow  
inheritable classes to evolve.

I suspect that we could do this with some kind of metaclass, but that  
seems ugly.  More reasonable, I imagine, would be something like:

class Application(newStyle(Library)): pass

and we could implement 'newStyle' to do something sane in the face of  
either an old-style or a new-style "Library" class.

Of course, there are still issues with behavior differences on  
decorators and so on, and so the same compatibility issues might still  
come up, but in my experience those issues are significantly less  
serious and easier to fix than "my entire program blows up and will  
not start unless I make all my classes old-style".

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://twistedmatrix.com/pipermail/twisted-python/attachments/20091025/9b272f18/attachment-0001.htm 

More information about the Twisted-Python mailing list