Issue 17179: Misleading error from type() when passing unknown keyword argument (original) (raw)

Created on 2013-02-11 08:26 by cjw296, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (10)
msg181884 - (view) Author: Chris Withers (cjw296) * (Python committer) Date: 2013-02-11 08:26
>>> from types import new_class >>> from datetime import datetime >>> new_class('tdatetime', (datetime, ), kwds={'foo':'bar'}) Traceback (most recent call last): File "", line 1, in File "/src/Python-3.Lib/types.py", line 52, in new_class return meta(name, bases, ns, **kwds) TypeError: type() takes 1 or 3 arguments I'm guessing ns and kwds should be combined before being passed through to meta? (meta is 'type' in this case)
msg182064 - (view) Author: Chris Withers (cjw296) * (Python committer) Date: 2013-02-13 23:16
Eric, surely this is a bugfix candidate for 3.3.1?
msg182065 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2013-02-13 23:17
> I'm guessing ns and kwds should be combined before being passed through to meta? Possibly; can you try that? > surely this is a bugfix candidate for 3.3.1? If we get a patch with a test in time, otherwise 3.3.2.
msg182118 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2013-02-14 19:26
I don't think this is a bug: >>> from datetime import datetime >>> class tdatetime(datetime, foo='bar'): ... pass ... Traceback (most recent call last): File "", line 1, in TypeError: type() takes 1 or 3 arguments >>>
msg182142 - (view) Author: Ramchandra Apte (Ramchandra Apte) * Date: 2013-02-15 13:23
@Daniel Urban Me too.
msg182175 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2013-02-15 21:09
As far as I know, currently, the only valid 'keyword' argument for a class statement is 'metaclass' and that is so advanced that it is not mentioned in *8.7. Class definitions* but only in the linked section *3.3.3. Customizing class creation*. The types.newclass doc also only mentions 'metaclass' as a possible keyword. (Maybe it should currently say that that is the only possibility, but perhaps the window was being left open for possible additions in the future.) So I agree that passing anything else is a bug and should raise. If so, this issue should be closed.
msg182211 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2013-02-16 05:05
The types.new_class docs are quite clear that the supplied keyword arguments are equivalent to those provided in the type header (if you want to pre-populate the namespace, that's what exec_body is for). The problem here is that the dual signature of type (retrieving the type of an existing object, or creating a new one), and the fact that type.__prepare__ ignores all arguments, means the error message is thoroughly misleading when you pass an unknown keyword argument: >>> type.__prepare__(foo=1) {} >>> type("Example", (), {}, foo=1) Traceback (most recent call last): File "", line 1, in TypeError: type() takes 1 or 3 arguments >>> class Example(foo=1): pass ... Traceback (most recent call last): File "", line 1, in TypeError: type() takes 1 or 3 arguments >>> import types >>> types.new_class("Example", (), dict(foo=1)) Traceback (most recent call last): File "", line 1, in File "/home/ncoghlan/devel/py3k/Lib/types.py", line 52, in new_class return meta(name, bases, ns, **kwds) TypeError: type() takes 1 or 3 arguments The reason type.__prepare__ ignores its arguments is to make it easy for people to use type to anchor a custom metaclass hierarchy and call super().__prepare__(name, bases, **kwds) without needing to worry much about filtering the keyword arguments. (The class machinery intercepts the metaclass hint and never passes it to __prepare__ or the metaclass constructor). That means the real change needed here is to update type's error message for bad arguments to properly report unknown keyword errors when using the PEP 3115 metaclass API.
msg182304 - (view) Author: Chris Withers (cjw296) * (Python committer) Date: 2013-02-18 08:14
Some background: I hit this problem when adding Python 3 compatibility to one of my libraries, where I had the following code: from types import ClassType ... class_ = ClassType(n, (sometype, ), dict(class_attr1='foo', class_attr2='bar') It wasn't at all clear how to port this to Python 3, given that ClassType was gone. types.new_class looks fair game, but the help is not exactly helpful: new_class(name, bases=(), kwds=None, exec_body=None) Create a class object dynamically using the appropriate metaclass. No indication there as to what type should be passed for kwds or exec_body. I guessed and, by the sound of it, guessed wrong. I'd certainly agree that the error message is very misleading. cheers, Chris
msg182310 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2013-02-18 09:53
For the simple case where you don't need to provide a metaclass hint, the simplest conversion is actually directly to the 3-argument form of type(). As far as the docstring goes, I don't want to make it as long as the full docs, but it could probably stand to be longer than it is.
msg406936 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2021-11-24 16:23
This seems to have been fixed by now. I get this on 3.11: >>> from types import new_class >>> from datetime import datetime >>> new_class('tdatetime', (datetime, ), kwds={'foo':'bar'}) Traceback (most recent call last): File "", line 1, in File "/Users/iritkatriel/src/cpython-1/Lib/types.py", line 77, in new_class return meta(name, resolved_bases, ns, **kwds) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: tdatetime.__init_subclass__() takes no keyword arguments
History
Date User Action Args
2022-04-11 14:57:41 admin set github: 61381
2021-12-06 00:07:05 iritkatriel set status: pending -> closedstage: needs patch -> resolved
2021-11-24 16:23:06 iritkatriel set status: open -> pendingnosy: + iritkatrielmessages: + resolution: out of date
2013-02-18 09:53:40 ncoghlan set messages: +
2013-02-18 08:14:21 cjw296 set messages: +
2013-02-16 05:05:12 ncoghlan set title: Incorrect use of type function in types.new_class -> Misleading error from type() when passing unknown keyword argumentnosy: + docs@pythonmessages: + assignee: docs@pythoncomponents: + Documentation
2013-02-15 21:09:42 terry.reedy set nosy: + terry.reedymessages: +
2013-02-15 13:23:58 Ramchandra Apte set type: behavior
2013-02-15 13:23:48 Ramchandra Apte set nosy: + Ramchandra Aptemessages: +
2013-02-14 19:26:33 daniel.urban set nosy: + daniel.urbanmessages: +
2013-02-14 15🔞29 pitrou set nosy: + ncoghlan
2013-02-13 23:17:42 eric.araujo set messages: +
2013-02-13 23:16:42 cjw296 set messages: +
2013-02-13 23:15:38 eric.araujo set title: TypeError: type() takes 1 or 3 arguments -> Incorrect use of type function in types.new_classnosy: + eric.araujoversions: + Python 3.4keywords: + easystage: needs patch
2013-02-11 08:26:41 cjw296 create