Jason R. Coombs added the comment:

I recently ran into this error again. I was writing this class to provide 
backward-compatible context manager support for zipfile.ZipFile on Python 2.6 
and 3.1:

class ContextualZipFile(zipfile.ZipFile):
    """
    Supplement ZipFile class to support context manager for Python 2.6
    """

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        self.close()

    def __new__(cls, *args, **kwargs):
        """
        Construct a ZipFile or ContextualZipFile as appropriate
        """
        if hasattr(zipfile.ZipFile, '__exit__'):
            return zipfile.ZipFile(*args, **kwargs)
        return super(ContextualZipFile, cls).__new__(cls, *args, **kwargs)


At the point where super is called, the author is unaware of the details of the 
function signature for zipfile.ZipFile.__new__, so simply passes the same 
arguments as were received by the derived class. However, this behavior raises 
a DeprecationWarning on Python 2.6 and 3.1 (and would raise an error on Python 
3.2 if the code allowed it).

What's surprising is that the one cannot simply override a constructor or 
initializer without knowing in advance which of those methods are implemented 
(and with what signature) on the parent class.

It seems like the construction (calling of __new__) is special-cased for 
classes that don't implement __new__.

What is the proper implementation of ContextualZipFile.__new__? Should it use 
super but omit the args and kwargs? Should it call object.__new__ directly? 
Should it check for the existence of __new__ on the parent class (or compare it 
to object.__new__)?

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue1683368>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to