]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Replace BadInternalCall with TypeError. Add a test case. Fix whitespace.
authorRaymond Hettinger <python@rcn.com>
Wed, 4 Dec 2002 07:32:25 +0000 (07:32 +0000)
committerRaymond Hettinger <python@rcn.com>
Wed, 4 Dec 2002 07:32:25 +0000 (07:32 +0000)
Just van Rossum showed a weird, but clever way for pure python code to
trigger the BadInternalCall.  The C code had assumed that calling a class
constructor would return an instance of that class; however, classes that
abuse __new__ can invalidate that assumption.

Lib/test/test_types.py
Objects/dictobject.c

index 9cfc6806adb4e3bb91b502a5c294576f54d0dd4d..1e982d14f94e5d2945cb498c4f865b22d1ac88f5 100644 (file)
@@ -558,6 +558,13 @@ if type(dictlike.fromkeys('a')) is not dictlike:
     raise TestFailed, 'dictsubclass.fromkeys created wrong type'
 if type(dictlike().fromkeys('a')) is not dictlike:
     raise TestFailed, 'dictsubclass.fromkeys created wrong type'
+from UserDict import UserDict
+class mydict(dict):
+    def __new__(cls, *args, **kwargs):
+        return UserDict(*args, **kwargs)
+try: mydict.fromkeys('a b c'.split())
+except TypeError: pass
+else: raise TestFailed, 'dict.fromkeys() failed to detect non-dict class.'
 # dict.copy()
 d = {1:1, 2:2, 3:3}
 if d.copy() != {1:1, 2:2, 3:3}: raise TestFailed, 'dict copy'
index eca86770a657fa61bb4bd9793932619bd5380b70..d3603f00458b8763978ecf8db05c09e1051ac9b2 100644 (file)
@@ -973,15 +973,16 @@ dict_fromkeys(PyObject *mp, PyObject *args)
        PyObject *cls;
        int status;
 
-        if (!PyArg_ParseTuple(args, "OO|O:fromkeys", &cls, &seq, &value))
+       if (!PyArg_ParseTuple(args, "OO|O:fromkeys", &cls, &seq, &value))
                return NULL;
 
        d = PyObject_CallObject(cls, NULL);
        if (d == NULL)
                return NULL;
        if (!PyDict_Check(d)) {
-               PyErr_BadInternalCall();
                Py_DECREF(d);
+               PyErr_SetString(PyExc_TypeError,
+                       "class constructor must return a subclass of dict");
                return NULL;
        }