[issue1683368] object.__init__ shouldn't allow args/kwds

2015-05-13 Thread Terry J. Reedy

Changes by Terry J. Reedy tjre...@udel.edu:


--
stage:  - resolved
type:  - behavior

___
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



[issue1683368] object.__init__ shouldn't allow args/kwds

2014-06-03 Thread Raymond Hettinger

Raymond Hettinger added the comment:

Jason, I made some recommendations on this subject in my blog post a few years 
ago:  http://rhettinger.wordpress.com/2011/05/26/super-considered-super/

'''
A more flexible approach is to have every method in the ancestor tree 
cooperatively designed to accept keyword arguments and a keyword-arguments 
dictionary, to remove any arguments that it needs, and to forward the remaining 
arguments using **kwds, eventually leaving the dictionary empty for the final 
call in the chain.

Each level strips-off the keyword arguments that it needs so that the final 
empty dict can be sent to a method that expects no arguments at all (for 
example, object.__init__ expects zero arguments):

class Shape:
def __init__(self, shapename, **kwds):
self.shapename = shapename
super().__init__(**kwds)

class ColoredShape(Shape):
def __init__(self, color, **kwds):
self.color = color
super().__init__(**kwds)

cs = ColoredShape(color='red', shapename='circle')

'''

--

___
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



[issue1683368] object.__init__ shouldn't allow args/kwds

2014-05-28 Thread Guido van Rossum

Changes by Guido van Rossum gu...@python.org:


--
Removed message: http://bugs.python.org/msg219253

___
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



[issue1683368] object.__init__ shouldn't allow args/kwds

2014-05-28 Thread Terry J. Reedy

Changes by Terry J. Reedy tjre...@udel.edu:


--
Removed message: http://bugs.python.org/msg219255

___
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



[issue1683368] object.__init__ shouldn't allow args/kwds

2014-05-28 Thread Guido van Rossum

Guido van Rossum added the comment:

If you don't know enough about the base class you shouldn't be subclassing it. 
In this particular case you should be overriding __init__, not __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



[issue1683368] object.__init__ shouldn't allow args/kwds

2014-05-28 Thread Terry J. Reedy

Terry J. Reedy added the comment:

From what I see, you do not need to change either __new__ or __init__, just 
add __enter__ and __exit__ , and you only need to do that in 2.6. Since 
Zipfile is written in Python, you could monkey-patch instead of subclassing, 
if that is easier in your particular case.

--

___
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



[issue1683368] object.__init__ shouldn't allow args/kwds

2014-05-28 Thread Eric Snow

Eric Snow added the comment:

 If you don't know enough about the base class you shouldn't be subclassing it.

That's important when overriding any API in subclass and absolutely
always essential when it comes to __new__ and __init__!  That's
something that isn't very obvious at first. :(

 In this particular case you should be overriding __init__, not __new__.

Jason's code is doing something like OSError.__new__ does now, which
returns an instance of a subclass depending on the errno.  However,
while the language supports it, I see that as a viable hack only when
backward-compatibilty is a big concern.  Otherwise I find factory
classmethods to be a much better solution for discoverability and
clarity of implementation.

--
nosy: +eric.snow

___
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



[issue1683368] object.__init__ shouldn't allow args/kwds

2014-05-28 Thread Guido van Rossum

Guido van Rossum added the comment:

Sorry, I didn't realize why __new__ was being used. But what Jason's code is 
doing isn't any cleaner than monkey-patching.

--

___
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



[issue1683368] object.__init__ shouldn't allow args/kwds

2014-05-28 Thread Jason R. Coombs

Jason R. Coombs added the comment:

Maybe I should have focused on a more trivial example to demonstrate the place 
where my expectation was violated. The use of a real-world example is 
distracting from my intended point. Consider instead this abstract example:

class SomeClass(SomeParentClass):
def __new__(cls, *args, **kwargs):
return super(SomeClass, cls).__new__(cls, *args, **kwargs)

def __init__(self, *args, **kwargs):
super(SomeClass, self).__init__(*args, **kwargs)

Ignoring for a moment the incongruity of the invocation of __new__ with 'cls' 
due to __new__ being a staticmethod, the naive programmer expects the above 
SomeClass to work exactly like SomeParentClass because both overrides are 
implemented as a trivial pass-through.

And indeed that technique will work just fine if the parent class implements 
both __init__ and __new__, but if the parent class (or one of its parents) does 
not implement either of those methods, the technique will fail, because the 
fall through to 'object' class.

I believe this incongruity stems from the fact that __new__ and __init__ are 
special-cased not to be called if they aren't implemented on the class.

Therefore, to write SomeClass without knowledge of the SomeParentClass 
implementation, one could write this instead:

class SomeClass(SomeParentClass):
def __new__(cls, *args, **kwargs):
super_new = super(SomeClass, cls).__new__
if super_new is object.__new__:
return super_new(cls)
return super_new(cls, *args, **kwargs)

def __init__(self, *args, **kwargs):
super_init = super(SomeClass, self).__init__
if super_init.__objclass__ is object:
return
super_init(*args, **kwargs)

Now that implementation is somewhat ugly and perhaps a bit brittle 
(particularly around use of __objclass__). Ignoring that for now, it does have 
the property that regardless of the class from which it derives, it will work, 
including:

SomeParentClass = datetime.datetime # implements only __new__
SomeParentClass = zipfile.ZipFile # implements only __init__
class SomeParentClass: pass # implements neither __init__ nor __new__

While I would prefer a language construct that didn't require this dance for 
special casing (or similarly require the programmer to hard-code the dance to a 
specific implementation of a specific parent class as Guido recommends), at the 
very least I would suggest that the documentation better reflect this somewhat 
surprising behavior.

Currently, the documentation states 
[https://docs.python.org/2/reference/datamodel.html#object.__new__] effectively 
Typical implementations of __new__ invoke the superclass’ __new__() method 
with appropriate arguments. It's left as an exercise to the reader to 
ascertain what 'appropriate arguments' are, and doesn't communicate that the 
introduction or omission of __new__ or __init__ to a class hierarchy affects 
the process by which a class is constructed/initialized.

Greg Smith's blog demonstrates some even more dangerous cases. I don't 
understand why his concerns weren't addressed, because they seem legitimate, 
and I agree with his conclusion that the older behavior is more desirable, 
despite the concerns raised by the OP.

--

___
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



[issue1683368] object.__init__ shouldn't allow args/kwds

2014-05-28 Thread Jason R. Coombs

Jason R. Coombs added the comment:

Based on the example above, I've created a blog post to publish my 
recommendation for overriding these special methods in a way that's safe 
regardless of the parent implementation, given the status quo:

http://blog.jaraco.com/2014/05/how-to-safely-override-init-or-new-in.html

--

___
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



[issue1683368] object.__init__ shouldn't allow args/kwds

2014-05-28 Thread Guido van Rossum

Guido van Rossum added the comment:

Hrm. I've always thought that the key point of cooperative MI was the term 
*cooperative*. Consider a regular (non-constructor) method. You must have a 
common base class that defines this method, and *that* method shouldn't be 
calling the super-method (because there isn't one). All cooperative classes 
extending this method must derive from that base class.

It's the same for __init__ and __new__, except that you may treat each 
(keyword) argument as a separate method. But you must still have a point in the 
tree to eat that argument, and that point must not pass it up the super call 
chain.

If in a particular framework you want unrecognized keyword arguments to the 
constructor to be ignored, you should define a common base class from which all 
your cooperative subclasses inherit. But given the prevalence of *single* 
inheritance, 'object' shouldn't be that common base class.

--

___
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



[issue1683368] object.__init__ shouldn't allow args/kwds

2014-05-27 Thread Jason R. Coombs

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



[issue1683368] object.__init__ shouldn't allow args/kwds

2014-05-27 Thread Jason R. Coombs

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



[issue1683368] object.__init__ shouldn't allow args/kwds

2013-01-14 Thread Jason R. Coombs

Jason R. Coombs added the comment:

For reference, I encountered an issue due to this change and didn't quite 
understand what was going on. I distilled the problem down and posted a 
question on stack overflow:

http://stackoverflow.com/questions/14300153/why-does-this-datetime-subclass-fail-on-python-3/14324503#14324503

The answer led me here, so now I understand. I wanted to share this use-case 
for posterity.

I didn't find anything in the what's new documents for Python 3.3 or 3.0. Was 
this fundamental signature change to all objects documented anywhere? Any 
objection if I draft a change to the docs?

--
nosy: +jason.coombs

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue1683368
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1683368] object.__init__ shouldn't allow args/kwds

2013-01-14 Thread Terry J. Reedy

Terry J. Reedy added the comment:

First, What's New  explains the new features in Python. This issue is a 
bugfix. AFAIK, object() has always been documented as having no parameters. The 
fact that passing extra args should raise a TypeError is no secret.

Second, this *is* documented. The third sentence of
http://docs.python.org/3/whatsnew/3.3.html
is  For full details, see the changelog. We really mean that ;-). The 
changelog is derived from Misc/NEWS in the repository. It says Issue #1683368: 
object.__new__ and object.__init__ raise a TypeError if they are passed 
arguments and their complementary method is not overridden. That is prefixed 
by Issue #1683368:, which links to this issue. This entry is easily found by 
searching for 'object.__init__' (or a sufficient prefix thereof).

For 3.2, the What's New sentence was For full details, see the Misc/NEWS file 
and the link went to the raw repository file.
http://hg.python.org/cpython/file/3.2/Misc/NEWS
My impression is that this issue played a role in including the prettified 
version, instead of just the repository link, in the on-line version of the 
docs. What's New for 2.7 does not even have the link.

In any case, *any* bugfix breaks code that depends on the bug. Hence the 
decision to make the full changelog more available and more readable.

I realize that the change to the header for What's New is hard to miss. But 
what are we to do? Add a new What's New in What's New doc for one release? Put 
the change in flashing red type?

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue1683368
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1683368] object.__init__ shouldn't allow args/kwds

2013-01-14 Thread Jason R. Coombs

Jason R. Coombs added the comment:

Aah. Indeed, that's where I should have looked. Thanks for the pointer.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue1683368
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1683368] object.__init__ shouldn't allow args/kwds

2012-03-16 Thread Roundup Robot

Roundup Robot devn...@psf.upfronthosting.co.za added the comment:

New changeset 25b71858cb14 by Benjamin Peterson in branch 'default':
make extra arguments to object.__init__/__new__ to errors in most cases 
(finishes #1683368)
http://hg.python.org/cpython/rev/25b71858cb14

--
nosy: +python-dev

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue1683368
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1683368] object.__init__ shouldn't allow args/kwds

2012-03-16 Thread Guido van Rossum

Guido van Rossum gu...@python.org added the comment:

Please don't add python-...@python.org to the nosy list.

--
nosy:  -python-dev

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue1683368
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1683368] object.__init__ shouldn't allow args/kwds

2012-03-16 Thread Benjamin Peterson

Benjamin Peterson benja...@python.org added the comment:

python-dev is just the name of the robot which notes records changesets.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue1683368
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1683368] object.__init__ shouldn't allow args/kwds

2010-04-01 Thread dauerbaustelle

dauerbaustelle jo...@lophus.org added the comment:

What exactly is the correct solution with Python 2.6 to avoid this warning? My 
use case is something like

class myunicode(unicode):
  def __init__(self, *args, **kwargs):
unicode.__init__(self, *args, **kwargs)
self.someattribute = calculate_attribute_once()

Shall I overwrite __new__ rather than __init__? Or what :-)

--
nosy: +dauerbaustelle

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue1683368
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1683368] object.__init__ shouldn't allow args/kwds

2010-04-01 Thread Terry J. Reedy

Terry J. Reedy tjre...@udel.edu added the comment:

@dauerbaustelle
I believe your question is a separate issue and that it should have been asked 
on Python list. However, yes, subclasses of immutables must override __new__. 
For more, do ask on the list, not here.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue1683368
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1683368] object.__init__ shouldn't allow args/kwds

2010-02-01 Thread Gregory P. Smith

Gregory P. Smith g...@krypto.org added the comment:

FYI - A discussion on why this change may have been a bad idea and breaks 
peoples existing code:

 http://freshfoo.com/blog/object__init__takes_no_parameters

--
nosy: +gregory.p.smith

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue1683368
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1683368] object.__init__ shouldn't allow args/kwds

2009-04-20 Thread Kirit Sælensminde

Changes by Kirit Sælensminde ki...@felspar.com:


--
nosy: +KayEss

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue1683368
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1683368] object.__init__ shouldn't allow args/kwds

2008-10-13 Thread Jesús Cea Avión

Changes by Jesús Cea Avión [EMAIL PROTECTED]:


--
nosy: +jcea

___
Python tracker [EMAIL PROTECTED]
http://bugs.python.org/issue1683368
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1683368] object.__init__ shouldn't allow args/kwds

2008-04-14 Thread Guido van Rossum

Changes by Guido van Rossum [EMAIL PROTECTED]:


--
status: open - closed

_
Tracker [EMAIL PROTECTED]
http://bugs.python.org/issue1683368
_
___
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1683368] object.__init__ shouldn't allow args/kwds

2008-04-12 Thread Benjamin Peterson

Benjamin Peterson [EMAIL PROTECTED] added the comment:

Can this be closed?

--
nosy: +benjamin.peterson

_
Tracker [EMAIL PROTECTED]
http://bugs.python.org/issue1683368
_
___
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1683368] object.__init__ shouldn't allow args/kwds

2007-08-29 Thread Guido van Rossum

Changes by Guido van Rossum:


--
versions: +Python 3.0

_
Tracker [EMAIL PROTECTED]
http://bugs.python.org/issue1683368
_
___
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com