summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_builtin.py7
-rw-r--r--Misc/NEWS3
-rw-r--r--Objects/object.c69
-rw-r--r--Objects/sliceobject.c29
4 files changed, 108 insertions, 0 deletions
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index aa9b4e2ed8..4e33c23409 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -1343,6 +1343,13 @@ class BuiltinTest(unittest.TestCase):
self.assertRaises(ValueError, x.translate, b"1", 1)
self.assertRaises(TypeError, x.translate, b"1"*256, 1)
+ def test_construct_singletons(self):
+ for const in None, Ellipsis, NotImplemented:
+ tp = type(const)
+ self.assertIs(tp(), const)
+ self.assertRaises(TypeError, tp, 1, 2)
+ self.assertRaises(TypeError, tp, a=1, b=2)
+
class TestSorted(unittest.TestCase):
def test_basic(self):
diff --git a/Misc/NEWS b/Misc/NEWS
index b0a747c918..34fdd55df9 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1?
Core and Builtins
-----------------
+- Make type(None), type(Ellipsis), and type(NotImplemented) callable. They
+ return the respective singleton instances.
+
- Forbid summing bytes in sum().
- Verify the types of AST strings and identifiers provided by the user before
diff --git a/Objects/object.c b/Objects/object.c
index 27d7089dcf..cf10f3cb1b 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -1277,6 +1277,16 @@ none_dealloc(PyObject* ignore)
Py_FatalError("deallocating None");
}
+static PyObject *
+none_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+ if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_Size(kwargs))) {
+ PyErr_SetString(PyExc_TypeError, "NoneType takes no arguments");
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
static int
none_bool(PyObject *v)
{
@@ -1335,6 +1345,30 @@ static PyTypeObject PyNone_Type = {
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
+ 0, /*tp_call */
+ 0, /*tp_str */
+ 0, /*tp_getattro */
+ 0, /*tp_setattro */
+ 0, /*tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /*tp_flags */
+ 0, /*tp_doc */
+ 0, /*tp_traverse */
+ 0, /*tp_clear */
+ 0, /*tp_richcompare */
+ 0, /*tp_weaklistoffset */
+ 0, /*tp_iter */
+ 0, /*tp_iternext */
+ 0, /*tp_methods */
+ 0, /*tp_members */
+ 0, /*tp_getset */
+ 0, /*tp_base */
+ 0, /*tp_dict */
+ 0, /*tp_descr_get */
+ 0, /*tp_descr_set */
+ 0, /*tp_dictoffset */
+ 0, /*tp_init */
+ 0, /*tp_alloc */
+ none_new, /*tp_new */
};
PyObject _Py_NoneStruct = {
@@ -1351,6 +1385,17 @@ NotImplemented_repr(PyObject *op)
return PyUnicode_FromString("NotImplemented");
}
+static PyObject *
+notimplemented_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+ if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_Size(kwargs))) {
+ PyErr_SetString(PyExc_TypeError, "NotImplementedType takes no arguments");
+ return NULL;
+ }
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
static PyTypeObject PyNotImplemented_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"NotImplementedType",
@@ -1366,6 +1411,30 @@ static PyTypeObject PyNotImplemented_Type = {
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
+ 0, /*tp_call */
+ 0, /*tp_str */
+ 0, /*tp_getattro */
+ 0, /*tp_setattro */
+ 0, /*tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /*tp_flags */
+ 0, /*tp_doc */
+ 0, /*tp_traverse */
+ 0, /*tp_clear */
+ 0, /*tp_richcompare */
+ 0, /*tp_weaklistoffset */
+ 0, /*tp_iter */
+ 0, /*tp_iternext */
+ 0, /*tp_methods */
+ 0, /*tp_members */
+ 0, /*tp_getset */
+ 0, /*tp_base */
+ 0, /*tp_dict */
+ 0, /*tp_descr_get */
+ 0, /*tp_descr_set */
+ 0, /*tp_dictoffset */
+ 0, /*tp_init */
+ 0, /*tp_alloc */
+ notimplemented_new, /*tp_new */
};
PyObject _Py_NotImplementedStruct = {
diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c
index 51c53a8a11..53cc951a73 100644
--- a/Objects/sliceobject.c
+++ b/Objects/sliceobject.c
@@ -17,6 +17,17 @@ this type and there is exactly one in existence.
#include "structmember.h"
static PyObject *
+ellipsis_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+ if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_Size(kwargs))) {
+ PyErr_SetString(PyExc_TypeError, "EllipsisType takes no arguments");
+ return NULL;
+ }
+ Py_INCREF(Py_Ellipsis);
+ return Py_Ellipsis;
+}
+
+static PyObject *
ellipsis_repr(PyObject *op)
{
return PyUnicode_FromString("Ellipsis");
@@ -43,6 +54,24 @@ PyTypeObject PyEllipsis_Type = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ ellipsis_new, /* tp_new */
};
PyObject _Py_EllipsisObject = {