diff -r 6d5d2bda6acb Lib/operator.py --- a/Lib/operator.py Wed Jun 03 11:11:22 2015 -0600 +++ b/Lib/operator.py Mon Jun 22 18:15:45 2015 -0400 @@ -408,6 +408,20 @@ return a +class subscript(object): + def __new__(cls): + raise TypeError("cannot create '{}' instances".format(cls.__name__)) + + def __getitem__(self, key): + return key + + def __reduce__(self): + return 'subscript' + + +subscript = object.__new__(subscript) + + try: from _operator import * except ImportError: diff -r 6d5d2bda6acb Lib/test/test_operator.py --- a/Lib/test/test_operator.py Wed Jun 03 11:11:22 2015 -0600 +++ b/Lib/test/test_operator.py Mon Jun 22 18:15:45 2015 -0400 @@ -596,5 +596,40 @@ module2 = c_operator +class SubscriptTestCase(object): + def test_literal_syntax(self): + pairs = ( + (slice(1, 1, 1), self.module.subscript[1:1:1]), + (slice(1, 1, None), self.module.subscript[1:1]), + (slice(1, 1, None), self.module.subscript[1:1:]), + (slice(1, None, 1), self.module.subscript[1::1]), + (slice(1, None, None), self.module.subscript[1:]), + (slice(1, None, None), self.module.subscript[1::]), + (slice(None, 1, 1), self.module.subscript[:1:1]), + (slice(None, 1, None), self.module.subscript[:1]), + (slice(None, 1, None), self.module.subscript[:1:]), + (slice(None, None, None), self.module.subscript[:]), + (slice(None, None, None), self.module.subscript[::]), + ) + for call, literal in pairs: + self.assertEqual(call, literal) + + def test_singleton(self): + with self.assertRaises(TypeError): + type(self.module.subscript)() + + +class PySubscriptTestCase(SubscriptTestCase, PyOperatorTestCase): + pass + + +class CSubscriptTestCase(SubscriptTestCase, COperatorTestCase): + def test_pickle(self): + s = self.module.subscript + for protocol in (0, 1, 2): + t = pickle.loads(pickle.dumps(s, protocol)) + self.assertIs(t, s) + + if __name__ == "__main__": unittest.main() diff -r 6d5d2bda6acb Modules/_operator.c --- a/Modules/_operator.c Wed Jun 03 11:11:22 2015 -0600 +++ b/Modules/_operator.c Mon Jun 22 18:15:45 2015 -0400 @@ -1185,6 +1185,74 @@ 0, /* tp_free */ }; +/* subscript object **********************************************************/ + +static PyObject * +subscript_reduce(PyObject *op) +{ + return PyUnicode_FromString("subscript"); +} + +static PyObject * +subscript_getitem(PyObject *self, PyObject *key) +{ + Py_INCREF(key); + return key; +} + +static PyMappingMethods subscript_as_mapping = { + NULL, + (binaryfunc)subscript_getitem, + NULL, +}; + +static PyMethodDef subscript_methods[] = { + {"__getitem__", (PyCFunction)subscript_getitem, METH_O, NULL}, + {"__reduce__", (PyCFunction)subscript_reduce, METH_NOARGS, NULL}, + {NULL, NULL} +}; + +PyTypeObject subscript_type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "subscript", /* tp_name */ + 0, /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /*never called*/ /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + &subscript_as_mapping, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* 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 */ + subscript_methods, /* 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 */ + 0, /* tp_new */ +}; + /* Initialization function for the module (*must* be called PyInit__operator) */ @@ -1205,12 +1273,19 @@ PyInit__operator(void) { PyObject *m; + PyObject *subscript; /* Create the module and add the functions */ m = PyModule_Create(&operatormodule); if (m == NULL) return NULL; + if (PyType_Ready(&subscript_type) < 0) + return NULL; + if (!(subscript = PyObject_New(PyObject, &subscript_type))) + return NULL; + PyModule_AddObject(m, "subscript", subscript); + if (PyType_Ready(&itemgetter_type) < 0) return NULL; Py_INCREF(&itemgetter_type);