From e09cf818c459214ed2b133088e2fd595675e8de4 Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Sun, 2 Dec 2018 17:40:34 -0800 Subject: [PATCH 01/39] Make Posixmodule use PyType_FromSpec --- Modules/posixmodule.c | 133 ++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 90 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 7571385ae51da3..d3e03fa574b712 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -11997,7 +11997,7 @@ os_set_blocking_impl(PyObject *module, int fd, int blocking) /*[clinic input] -class os.DirEntry "DirEntry *" "&DirEntryType" +class os.DirEntry "DirEntry *" "DirEntryType" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/ @@ -12327,39 +12327,24 @@ static PyMethodDef DirEntry_methods[] = { {NULL} }; -static PyTypeObject DirEntryType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODNAME ".DirEntry", /* tp_name */ - sizeof(DirEntry), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)DirEntry_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - (reprfunc)DirEntry_repr, /* tp_repr */ - 0, /* tp_as_number */ - 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 */ - DirEntry_methods, /* tp_methods */ - DirEntry_members, /* tp_members */ +static PyType_Slot DirEntryType_slots[] = { + {Py_tp_dealloc, DirEntry_dealloc}, + {Py_tp_repr, DirEntry_repr}, + {Py_tp_methods, DirEntry_methods}, + {Py_tp_members, DirEntry_members}, + {0, 0}, }; +static PyType_Spec DirEntryType_spec = { + MODNAME ".DirEntry", + sizeof(DirEntry), + 0, + Py_TPFLAGS_DEFAULT, + DirEntryType_slots +}; + +static PyTypeObject* DirEntryType; + #ifdef MS_WINDOWS static wchar_t * @@ -12403,7 +12388,7 @@ DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW) ULONG reparse_tag; wchar_t *joined_path; - entry = PyObject_New(DirEntry, &DirEntryType); + entry = PyObject_New(DirEntry, DirEntryType); if (!entry) return NULL; entry->name = NULL; @@ -12490,7 +12475,7 @@ DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len, DirEntry *entry; char *joined_path; - entry = PyObject_New(DirEntry, &DirEntryType); + entry = PyObject_New(DirEntry, DirEntryType); if (!entry) return NULL; entry->name = NULL; @@ -12765,59 +12750,25 @@ static PyMethodDef ScandirIterator_methods[] = { {NULL} }; -static PyTypeObject ScandirIteratorType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODNAME ".ScandirIterator", /* tp_name */ - sizeof(ScandirIterator), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)ScandirIterator_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 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 - | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)ScandirIterator_iternext, /* tp_iternext */ - ScandirIterator_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 */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - (destructor)ScandirIterator_finalize, /* tp_finalize */ +static PyType_Slot ScandirIteratorType_slots[] = { + {Py_tp_dealloc, ScandirIterator_dealloc}, + {Py_tp_finalize, ScandirIterator_finalize}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, ScandirIterator_iternext}, + {Py_tp_methods, ScandirIterator_methods}, + {0, 0}, }; +static PyType_Spec ScandirIteratorType_spec = { + MODNAME ".ScandirIterator", + sizeof(ScandirIterator), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, + ScandirIteratorType_slots +}; + +static PyTypeObject* ScandirIteratorType; + /*[clinic input] os.scandir @@ -12846,7 +12797,7 @@ os_scandir_impl(PyObject *module, path_t *path) #endif #endif - iterator = PyObject_New(ScandirIterator, &ScandirIteratorType); + iterator = PyObject_New(ScandirIterator, ScandirIteratorType); if (!iterator) return NULL; @@ -13949,9 +13900,11 @@ INITFUNC(void) } /* initialize scandir types */ - if (PyType_Ready(&ScandirIteratorType) < 0) + ScandirIteratorType = (PyTypeObject *)PyType_FromSpec(&ScandirIteratorType_spec); + if (ScandirIteratorType == NULL) return NULL; - if (PyType_Ready(&DirEntryType) < 0) + DirEntryType = (PyTypeObject *)PyType_FromSpec(&DirEntryType_spec); + if (DirEntryType == NULL) return NULL; } #if defined(HAVE_WAITID) && !defined(__APPLE__) @@ -14055,8 +14008,8 @@ INITFUNC(void) } PyModule_AddObject(m, "_have_functions", list); - Py_INCREF((PyObject *) &DirEntryType); - PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType); + Py_INCREF((PyObject *) DirEntryType); + PyModule_AddObject(m, "DirEntry", (PyObject *)DirEntryType); initialized = 1; From 40f0ff45f1baee07f416d496c7ddf31b2b706dce Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Sun, 2 Dec 2018 22:39:59 -0800 Subject: [PATCH 02/39] Added NEWS --- Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst diff --git a/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst b/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst new file mode 100644 index 00000000000000..760af024df1b87 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst @@ -0,0 +1 @@ +Move the remaining posixmodule types to be Heap-allocated. From 5be18a1550de63d2d8b5e1a51e35f7f0b2301eb1 Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Sun, 2 Dec 2018 22:42:22 -0800 Subject: [PATCH 03/39] Updated hash --- Modules/posixmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index d3e03fa574b712..d2019d9a3b2ffe 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -11999,7 +11999,7 @@ os_set_blocking_impl(PyObject *module, int fd, int blocking) /*[clinic input] class os.DirEntry "DirEntry *" "DirEntryType" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/ typedef struct { PyObject_HEAD From 9479848307c2ab7c97f94405f7978bb42d02f7d8 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Fri, 18 Jan 2019 16:44:31 -0800 Subject: [PATCH 04/39] Addressed PR Issues --- Include/objimpl.h | 3 + Lib/test/test_os.py | 30 ++++++++ .../2018-12-02-22-39-41.bpo-35381.HjI3j_.rst | 1 - Modules/clinic/posixmodule.c.h | 47 ++++++++++++- Modules/posixmodule.c | 69 +++++++++++++++++++ Objects/object.c | 8 ++- 6 files changed, 153 insertions(+), 5 deletions(-) delete mode 100644 Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst diff --git a/Include/objimpl.h b/Include/objimpl.h index f475ed001d02f8..2337d8a56c774e 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -138,6 +138,9 @@ _PyObject_INIT(PyObject *op, PyTypeObject *typeobj) { assert(op != NULL); Py_TYPE(op) = typeobj; + if (PyType_GetFlags(typeobj) & Py_TPFLAGS_HEAPTYPE) { + Py_INCREF(typeobj); + } _Py_NewReference(op); return op; } diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index aca445f9162004..6332a14c941f72 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3324,6 +3324,24 @@ def test_os_all(self): self.assertIn('walk', os.__all__) +class TestDirEntry(unittest.TestCase): + def setUp(self): + self.path = os.path.realpath(support.TESTFN) + self.addCleanup(support.rmtree, self.path) + os.mkdir(self.path) + + def test_uninstantiable(self): + self.assertRaises(TypeError, os.DirEntry) + + def test_unpickable(self): + filename = create_file(os.path.join(self.path, "file.txt"), b'python') + entry = [entry for entry in os.scandir(self.path)].pop() + self.assertIsInstance(entry, os.DirEntry) + self.assertEqual(entry.name, "file.txt") + import pickle + self.assertRaises(TypeError, pickle.dumps, entry, filename) + + class TestScandir(unittest.TestCase): check_no_resource_warning = support.check_no_resource_warning @@ -3358,6 +3376,18 @@ def assert_stat_equal(self, stat1, stat2, skip_fields): else: self.assertEqual(stat1, stat2) + def test_uninstantiable(self): + scandir_iter = os.scandir(self.path) + self.assertRaises(TypeError, type(scandir_iter)) + scandir_iter.close() + + def test_unpickable(self): + filename = self.create_file("file.txt") + scandir_iter = os.scandir(self.path) + import pickle + self.assertRaises(TypeError, pickle.dumps, scandir_iter, filename) + scandir_iter.close() + def check_entry(self, entry, name, is_dir, is_file, is_symlink): self.assertIsInstance(entry, os.DirEntry) self.assertEqual(entry.name, name) diff --git a/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst b/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst deleted file mode 100644 index 760af024df1b87..00000000000000 --- a/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst +++ /dev/null @@ -1 +0,0 @@ -Move the remaining posixmodule types to be Heap-allocated. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 80690703ee2c65..28f06b93f4b145 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -6116,6 +6116,51 @@ os_DirEntry_inode(DirEntry *self, PyObject *Py_UNUSED(ignored)) return os_DirEntry_inode_impl(self); } +PyDoc_STRVAR(os_DirEntry___reduce____doc__, +"__reduce__($self, /)\n" +"--\n" +"\n" +"returns null and raises an exception to avoid pickling"); + +#define OS_DIRENTRY___REDUCE___METHODDEF \ + {"__reduce__", (PyCFunction)os_DirEntry___reduce__, METH_NOARGS, os_DirEntry___reduce____doc__}, + +static PyObject * +os_DirEntry___reduce___impl(DirEntry *self); + +static PyObject * +os_DirEntry___reduce__(DirEntry *self, PyObject *Py_UNUSED(ignored)) +{ + return os_DirEntry___reduce___impl(self); +} + +PyDoc_STRVAR(os_DirEntry___reduce_ex____doc__, +"__reduce_ex__($self, protocol, /)\n" +"--\n" +"\n" +"Returns NULL and raises an exception to avoid pickling"); + +#define OS_DIRENTRY___REDUCE_EX___METHODDEF \ + {"__reduce_ex__", (PyCFunction)os_DirEntry___reduce_ex__, METH_O, os_DirEntry___reduce_ex____doc__}, + +static PyObject * +os_DirEntry___reduce_ex___impl(DirEntry *self, int protocol); + +static PyObject * +os_DirEntry___reduce_ex__(DirEntry *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int protocol; + + if (!PyArg_Parse(arg, "i:__reduce_ex__", &protocol)) { + goto exit; + } + return_value = os_DirEntry___reduce_ex___impl(self, protocol); + +exit: + return return_value; +} + PyDoc_STRVAR(os_DirEntry___fspath____doc__, "__fspath__($self, /)\n" "--\n" @@ -6757,4 +6802,4 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ -/*[clinic end generated code: output=d62c0bb988141e70 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e061751fda697cda input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index d2019d9a3b2ffe..ea7a00183fbd10 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12020,6 +12020,14 @@ typedef struct { #endif } DirEntry; +static PyObject * +DirEntry_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, + "cannot create '%.100s' instances", type->tp_name); + return NULL; +} + static void DirEntry_dealloc(DirEntry *entry) { @@ -12027,6 +12035,7 @@ DirEntry_dealloc(DirEntry *entry) Py_XDECREF(entry->path); Py_XDECREF(entry->stat); Py_XDECREF(entry->lstat); + Py_DECREF(Py_TYPE(entry)); Py_TYPE(entry)->tp_free((PyObject *)entry); } @@ -12287,6 +12296,37 @@ os_DirEntry_inode_impl(DirEntry *self) #endif } +/*[clinic input] +os.DirEntry.__reduce__ + +returns null and raises an exception to avoid pickling +[clinic start generated code]*/ + +static PyObject * +os_DirEntry___reduce___impl(DirEntry *self) +/*[clinic end generated code: output=45167543e30c210c input=c1689a589f9c38f2]*/ +{ + PyErr_Format(PyExc_TypeError, + "cannot pickle '%.100s' instances", Py_TYPE(self)->tp_name); + return NULL; +} + +/*[clinic input] +os.DirEntry.__reduce_ex__ + + protocol: int + / + +Returns NULL and raises an exception to avoid pickling +[clinic start generated code]*/ + +static PyObject * +os_DirEntry___reduce_ex___impl(DirEntry *self, int protocol) +/*[clinic end generated code: output=a81881dfe241a631 input=1afbee3b136a7ece]*/ +{ + return os_DirEntry___reduce___impl(self); +} + static PyObject * DirEntry_repr(DirEntry *self) { @@ -12318,6 +12358,8 @@ static PyMemberDef DirEntry_members[] = { #include "clinic/posixmodule.c.h" static PyMethodDef DirEntry_methods[] = { + OS_DIRENTRY___REDUCE___METHODDEF + OS_DIRENTRY___REDUCE_EX___METHODDEF OS_DIRENTRY_IS_DIR_METHODDEF OS_DIRENTRY_IS_FILE_METHODDEF OS_DIRENTRY_IS_SYMLINK_METHODDEF @@ -12328,6 +12370,7 @@ static PyMethodDef DirEntry_methods[] = { }; static PyType_Slot DirEntryType_slots[] = { + {Py_tp_new, DirEntry_new}, {Py_tp_dealloc, DirEntry_dealloc}, {Py_tp_repr, DirEntry_repr}, {Py_tp_methods, DirEntry_methods}, @@ -12734,16 +12777,41 @@ ScandirIterator_finalize(ScandirIterator *iterator) PyErr_Restore(error_type, error_value, error_traceback); } +static PyObject * +ScandirIterator_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, + "cannot create '%.100s' instances", type->tp_name); + return NULL; +} + +static PyObject * +ScandirIterator_reduce(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, + "cannot pickle '%.100s' instances", Py_TYPE(self)->tp_name); + return NULL; +} + +static PyObject * +ScandirIterator_reduce_ex(PyObject *self, PyObject *arg) +{ + return ScandirIterator_reduce(self, NULL, NULL); +} + static void ScandirIterator_dealloc(ScandirIterator *iterator) { if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0) return; + Py_DECREF(Py_TYPE(iterator)); Py_TYPE(iterator)->tp_free((PyObject *)iterator); } static PyMethodDef ScandirIterator_methods[] = { + {"__reduce__", (PyCFunction)ScandirIterator_reduce, METH_NOARGS}, + {"__reduce_ex__", (PyCFunction)ScandirIterator_reduce_ex, METH_O}, {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS}, {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS}, {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS}, @@ -12751,6 +12819,7 @@ static PyMethodDef ScandirIterator_methods[] = { }; static PyType_Slot ScandirIteratorType_slots[] = { + {Py_tp_new, ScandirIterator_new}, {Py_tp_dealloc, ScandirIterator_dealloc}, {Py_tp_finalize, ScandirIterator_finalize}, {Py_tp_iter, PyObject_SelfIter}, diff --git a/Objects/object.c b/Objects/object.c index c2d78aa47e65c5..39dfc1587cb437 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -230,6 +230,9 @@ PyObject_Init(PyObject *op, PyTypeObject *tp) return PyErr_NoMemory(); /* Any changes should be reflected in PyObject_INIT (objimpl.h) */ Py_TYPE(op) = tp; + if (PyType_GetFlags(tp) & Py_TPFLAGS_HEAPTYPE) { + Py_INCREF(tp); + } _Py_NewReference(op); return op; } @@ -240,9 +243,8 @@ PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size) if (op == NULL) return (PyVarObject *) PyErr_NoMemory(); /* Any changes should be reflected in PyObject_INIT_VAR */ - op->ob_size = size; - Py_TYPE(op) = tp; - _Py_NewReference((PyObject *)op); + Py_SIZE(op) = size; + PyObject_Init((PyObject *)op, tp); return op; } From c84689c5ef6949107f645153c3b11ee35f826135 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Fri, 18 Jan 2019 16:59:52 -0800 Subject: [PATCH 05/39] Ran argument clinic --- Modules/clinic/posixmodule.c.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index d6bf9ad8548fec..d6b76d6a7021ca 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -6722,7 +6722,13 @@ os_DirEntry___reduce_ex__(DirEntry *self, PyObject *arg) PyObject *return_value = NULL; int protocol; - if (!PyArg_Parse(arg, "i:__reduce_ex__", &protocol)) { + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + protocol = _PyLong_AsInt(arg); + if (protocol == -1 && PyErr_Occurred()) { goto exit; } return_value = os_DirEntry___reduce_ex___impl(self, protocol); @@ -7376,4 +7382,4 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ -/*[clinic end generated code: output=dabd0fa27bf87044 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8c980838ccf517c3 input=a9049054013a1b77]*/ From 796a8d7b601a9cdf0f22cf4ecb28199f57535b19 Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Fri, 18 Jan 2019 17:05:33 -0800 Subject: [PATCH 06/39] Added NEWS --- .../next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst diff --git a/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst b/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst new file mode 100644 index 00000000000000..b64644659e78fa --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst @@ -0,0 +1,4 @@ +Convert posixmodule.c statically allocated types ``DirEntryType`` and +``ScandirIteratorType`` to heap-allocated types. This also modified +`PyObject_New` and `PyObject_NewVar` to increase the type refcount for heap- +allocated types. From b7cae5b7ab330465b468d489cfbf0eeb52f05d5d Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Fri, 18 Jan 2019 17:47:08 -0800 Subject: [PATCH 07/39] Remove INCREF from GenericAlloc --- Objects/typeobject.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index ace45ba5794ba4..abe92a4fb6e760 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -981,9 +981,6 @@ PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) memset(obj, '\0', size); - if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) - Py_INCREF(type); - if (type->tp_itemsize == 0) (void)PyObject_INIT(obj, type); else From 5fa6e46543066f5fd37b933d589534d4bffe2423 Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Sun, 2 Dec 2018 17:40:34 -0800 Subject: [PATCH 08/39] Make Posixmodule use PyType_FromSpec --- Modules/posixmodule.c | 132 ++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 89 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 4f8c074a671670..0069f91b475cbb 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12324,7 +12324,7 @@ os_set_blocking_impl(PyObject *module, int fd, int blocking) /*[clinic input] -class os.DirEntry "DirEntry *" "&DirEntryType" +class os.DirEntry "DirEntry *" "DirEntryType" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/ @@ -12654,39 +12654,24 @@ static PyMethodDef DirEntry_methods[] = { {NULL} }; -static PyTypeObject DirEntryType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODNAME ".DirEntry", /* tp_name */ - sizeof(DirEntry), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)DirEntry_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)DirEntry_repr, /* tp_repr */ - 0, /* tp_as_number */ - 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 */ - DirEntry_methods, /* tp_methods */ - DirEntry_members, /* tp_members */ +static PyType_Slot DirEntryType_slots[] = { + {Py_tp_dealloc, DirEntry_dealloc}, + {Py_tp_repr, DirEntry_repr}, + {Py_tp_methods, DirEntry_methods}, + {Py_tp_members, DirEntry_members}, + {0, 0}, }; +static PyType_Spec DirEntryType_spec = { + MODNAME ".DirEntry", + sizeof(DirEntry), + 0, + Py_TPFLAGS_DEFAULT, + DirEntryType_slots +}; + +static PyTypeObject* DirEntryType; + #ifdef MS_WINDOWS static wchar_t * @@ -12730,7 +12715,7 @@ DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW) ULONG reparse_tag; wchar_t *joined_path; - entry = PyObject_New(DirEntry, &DirEntryType); + entry = PyObject_New(DirEntry, DirEntryType); if (!entry) return NULL; entry->name = NULL; @@ -12817,7 +12802,7 @@ DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len, DirEntry *entry; char *joined_path; - entry = PyObject_New(DirEntry, &DirEntryType); + entry = PyObject_New(DirEntry, DirEntryType); if (!entry) return NULL; entry->name = NULL; @@ -13092,58 +13077,25 @@ static PyMethodDef ScandirIterator_methods[] = { {NULL} }; -static PyTypeObject ScandirIteratorType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODNAME ".ScandirIterator", /* tp_name */ - sizeof(ScandirIterator), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)ScandirIterator_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 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 */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)ScandirIterator_iternext, /* tp_iternext */ - ScandirIterator_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 */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - (destructor)ScandirIterator_finalize, /* tp_finalize */ +static PyType_Slot ScandirIteratorType_slots[] = { + {Py_tp_dealloc, ScandirIterator_dealloc}, + {Py_tp_finalize, ScandirIterator_finalize}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, ScandirIterator_iternext}, + {Py_tp_methods, ScandirIterator_methods}, + {0, 0}, }; +static PyType_Spec ScandirIteratorType_spec = { + MODNAME ".ScandirIterator", + sizeof(ScandirIterator), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, + ScandirIteratorType_slots +}; + +static PyTypeObject* ScandirIteratorType; + /*[clinic input] os.scandir @@ -13177,7 +13129,7 @@ os_scandir_impl(PyObject *module, path_t *path) return NULL; } - iterator = PyObject_New(ScandirIterator, &ScandirIteratorType); + iterator = PyObject_New(ScandirIterator, ScandirIteratorType); if (!iterator) return NULL; @@ -14424,9 +14376,11 @@ INITFUNC(void) } /* initialize scandir types */ - if (PyType_Ready(&ScandirIteratorType) < 0) + ScandirIteratorType = (PyTypeObject *)PyType_FromSpec(&ScandirIteratorType_spec); + if (ScandirIteratorType == NULL) return NULL; - if (PyType_Ready(&DirEntryType) < 0) + DirEntryType = (PyTypeObject *)PyType_FromSpec(&DirEntryType_spec); + if (DirEntryType == NULL) return NULL; } #if defined(HAVE_WAITID) && !defined(__APPLE__) @@ -14530,8 +14484,8 @@ INITFUNC(void) } PyModule_AddObject(m, "_have_functions", list); - Py_INCREF((PyObject *) &DirEntryType); - PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType); + Py_INCREF((PyObject *) DirEntryType); + PyModule_AddObject(m, "DirEntry", (PyObject *)DirEntryType); initialized = 1; From df178b45c50ba9093909cccefb6ee329f2ef6fd7 Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Sun, 2 Dec 2018 22:39:59 -0800 Subject: [PATCH 09/39] Added NEWS --- Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst diff --git a/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst b/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst new file mode 100644 index 00000000000000..760af024df1b87 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst @@ -0,0 +1 @@ +Move the remaining posixmodule types to be Heap-allocated. From e59208fe89f6754d792240aca680573252cb3124 Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Sun, 2 Dec 2018 22:42:22 -0800 Subject: [PATCH 10/39] Updated hash --- Modules/posixmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 0069f91b475cbb..afc2db13215889 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12326,7 +12326,7 @@ os_set_blocking_impl(PyObject *module, int fd, int blocking) /*[clinic input] class os.DirEntry "DirEntry *" "DirEntryType" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/ typedef struct { PyObject_HEAD From def6467746cbbb17cf87657adb94e3de884fed79 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Fri, 18 Jan 2019 16:44:31 -0800 Subject: [PATCH 11/39] Addressed PR Issues --- Lib/test/test_os.py | 30 ++++++++ .../2018-12-02-22-39-41.bpo-35381.HjI3j_.rst | 1 - Modules/posixmodule.c | 69 +++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) delete mode 100644 Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index b2cd4cca5f21fe..8e65e47c30a78e 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3566,6 +3566,24 @@ def test_os_all(self): self.assertIn('walk', os.__all__) +class TestDirEntry(unittest.TestCase): + def setUp(self): + self.path = os.path.realpath(support.TESTFN) + self.addCleanup(support.rmtree, self.path) + os.mkdir(self.path) + + def test_uninstantiable(self): + self.assertRaises(TypeError, os.DirEntry) + + def test_unpickable(self): + filename = create_file(os.path.join(self.path, "file.txt"), b'python') + entry = [entry for entry in os.scandir(self.path)].pop() + self.assertIsInstance(entry, os.DirEntry) + self.assertEqual(entry.name, "file.txt") + import pickle + self.assertRaises(TypeError, pickle.dumps, entry, filename) + + class TestScandir(unittest.TestCase): check_no_resource_warning = support.check_no_resource_warning @@ -3600,6 +3618,18 @@ def assert_stat_equal(self, stat1, stat2, skip_fields): else: self.assertEqual(stat1, stat2) + def test_uninstantiable(self): + scandir_iter = os.scandir(self.path) + self.assertRaises(TypeError, type(scandir_iter)) + scandir_iter.close() + + def test_unpickable(self): + filename = self.create_file("file.txt") + scandir_iter = os.scandir(self.path) + import pickle + self.assertRaises(TypeError, pickle.dumps, scandir_iter, filename) + scandir_iter.close() + def check_entry(self, entry, name, is_dir, is_file, is_symlink): self.assertIsInstance(entry, os.DirEntry) self.assertEqual(entry.name, name) diff --git a/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst b/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst deleted file mode 100644 index 760af024df1b87..00000000000000 --- a/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst +++ /dev/null @@ -1 +0,0 @@ -Move the remaining posixmodule types to be Heap-allocated. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index afc2db13215889..73d06782974bde 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12347,6 +12347,14 @@ typedef struct { #endif } DirEntry; +static PyObject * +DirEntry_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, + "cannot create '%.100s' instances", type->tp_name); + return NULL; +} + static void DirEntry_dealloc(DirEntry *entry) { @@ -12354,6 +12362,7 @@ DirEntry_dealloc(DirEntry *entry) Py_XDECREF(entry->path); Py_XDECREF(entry->stat); Py_XDECREF(entry->lstat); + Py_DECREF(Py_TYPE(entry)); Py_TYPE(entry)->tp_free((PyObject *)entry); } @@ -12614,6 +12623,37 @@ os_DirEntry_inode_impl(DirEntry *self) #endif } +/*[clinic input] +os.DirEntry.__reduce__ + +returns null and raises an exception to avoid pickling +[clinic start generated code]*/ + +static PyObject * +os_DirEntry___reduce___impl(DirEntry *self) +/*[clinic end generated code: output=45167543e30c210c input=c1689a589f9c38f2]*/ +{ + PyErr_Format(PyExc_TypeError, + "cannot pickle '%.100s' instances", Py_TYPE(self)->tp_name); + return NULL; +} + +/*[clinic input] +os.DirEntry.__reduce_ex__ + + protocol: int + / + +Returns NULL and raises an exception to avoid pickling +[clinic start generated code]*/ + +static PyObject * +os_DirEntry___reduce_ex___impl(DirEntry *self, int protocol) +/*[clinic end generated code: output=a81881dfe241a631 input=1afbee3b136a7ece]*/ +{ + return os_DirEntry___reduce___impl(self); +} + static PyObject * DirEntry_repr(DirEntry *self) { @@ -12645,6 +12685,8 @@ static PyMemberDef DirEntry_members[] = { #include "clinic/posixmodule.c.h" static PyMethodDef DirEntry_methods[] = { + OS_DIRENTRY___REDUCE___METHODDEF + OS_DIRENTRY___REDUCE_EX___METHODDEF OS_DIRENTRY_IS_DIR_METHODDEF OS_DIRENTRY_IS_FILE_METHODDEF OS_DIRENTRY_IS_SYMLINK_METHODDEF @@ -12655,6 +12697,7 @@ static PyMethodDef DirEntry_methods[] = { }; static PyType_Slot DirEntryType_slots[] = { + {Py_tp_new, DirEntry_new}, {Py_tp_dealloc, DirEntry_dealloc}, {Py_tp_repr, DirEntry_repr}, {Py_tp_methods, DirEntry_methods}, @@ -13061,16 +13104,41 @@ ScandirIterator_finalize(ScandirIterator *iterator) PyErr_Restore(error_type, error_value, error_traceback); } +static PyObject * +ScandirIterator_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, + "cannot create '%.100s' instances", type->tp_name); + return NULL; +} + +static PyObject * +ScandirIterator_reduce(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, + "cannot pickle '%.100s' instances", Py_TYPE(self)->tp_name); + return NULL; +} + +static PyObject * +ScandirIterator_reduce_ex(PyObject *self, PyObject *arg) +{ + return ScandirIterator_reduce(self, NULL, NULL); +} + static void ScandirIterator_dealloc(ScandirIterator *iterator) { if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0) return; + Py_DECREF(Py_TYPE(iterator)); Py_TYPE(iterator)->tp_free((PyObject *)iterator); } static PyMethodDef ScandirIterator_methods[] = { + {"__reduce__", (PyCFunction)ScandirIterator_reduce, METH_NOARGS}, + {"__reduce_ex__", (PyCFunction)ScandirIterator_reduce_ex, METH_O}, {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS}, {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS}, {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS}, @@ -13078,6 +13146,7 @@ static PyMethodDef ScandirIterator_methods[] = { }; static PyType_Slot ScandirIteratorType_slots[] = { + {Py_tp_new, ScandirIterator_new}, {Py_tp_dealloc, ScandirIterator_dealloc}, {Py_tp_finalize, ScandirIterator_finalize}, {Py_tp_iter, PyObject_SelfIter}, From bb2ead84acd9955e33f5cf72099505f8bcb88ee3 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Fri, 18 Jan 2019 16:59:52 -0800 Subject: [PATCH 12/39] Ran argument clinic --- Modules/clinic/posixmodule.c.h | 51 ++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index aa1ab79bd96a53..6db8073108f2a0 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -7949,6 +7949,57 @@ os_DirEntry_inode(DirEntry *self, PyObject *Py_UNUSED(ignored)) return os_DirEntry_inode_impl(self); } +PyDoc_STRVAR(os_DirEntry___reduce____doc__, +"__reduce__($self, /)\n" +"--\n" +"\n" +"returns null and raises an exception to avoid pickling"); + +#define OS_DIRENTRY___REDUCE___METHODDEF \ + {"__reduce__", (PyCFunction)os_DirEntry___reduce__, METH_NOARGS, os_DirEntry___reduce____doc__}, + +static PyObject * +os_DirEntry___reduce___impl(DirEntry *self); + +static PyObject * +os_DirEntry___reduce__(DirEntry *self, PyObject *Py_UNUSED(ignored)) +{ + return os_DirEntry___reduce___impl(self); +} + +PyDoc_STRVAR(os_DirEntry___reduce_ex____doc__, +"__reduce_ex__($self, protocol, /)\n" +"--\n" +"\n" +"Returns NULL and raises an exception to avoid pickling"); + +#define OS_DIRENTRY___REDUCE_EX___METHODDEF \ + {"__reduce_ex__", (PyCFunction)os_DirEntry___reduce_ex__, METH_O, os_DirEntry___reduce_ex____doc__}, + +static PyObject * +os_DirEntry___reduce_ex___impl(DirEntry *self, int protocol); + +static PyObject * +os_DirEntry___reduce_ex__(DirEntry *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int protocol; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + protocol = _PyLong_AsInt(arg); + if (protocol == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = os_DirEntry___reduce_ex___impl(self, protocol); + +exit: + return return_value; +} + PyDoc_STRVAR(os_DirEntry___fspath____doc__, "__fspath__($self, /)\n" "--\n" From 427c77251409e93a6e315276dc17676b7c4c0162 Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Fri, 18 Jan 2019 17:05:33 -0800 Subject: [PATCH 13/39] Added NEWS --- .../next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst diff --git a/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst b/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst new file mode 100644 index 00000000000000..b64644659e78fa --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst @@ -0,0 +1,4 @@ +Convert posixmodule.c statically allocated types ``DirEntryType`` and +``ScandirIteratorType`` to heap-allocated types. This also modified +`PyObject_New` and `PyObject_NewVar` to increase the type refcount for heap- +allocated types. From 99d5c26baae5afb8e87f04445623b8df9546046c Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Tue, 10 Sep 2019 22:36:39 -0700 Subject: [PATCH 14/39] Cleaned up slot acces --- Modules/posixmodule.c | 71 ++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index ff7b60f28a09a8..db7882f8e88d19 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -537,7 +537,7 @@ _Py_Uid_Converter(PyObject *obj, void *p) if (index == NULL) { PyErr_Format(PyExc_TypeError, "uid should be integer, not %.200s", - Py_TYPE(obj)->tp_name); + _PyType_Name(Py_TYPE(obj))); return 0; } @@ -643,7 +643,7 @@ _Py_Gid_Converter(PyObject *obj, void *p) if (index == NULL) { PyErr_Format(PyExc_TypeError, "gid should be integer, not %.200s", - Py_TYPE(obj)->tp_name); + _PyType_Name(Py_TYPE(obj))); return 0; } @@ -810,7 +810,7 @@ dir_fd_converter(PyObject *o, void *p) else { PyErr_Format(PyExc_TypeError, "argument should be integer or None, not %.200s", - Py_TYPE(o)->tp_name); + _PyType_Name(Py_TYPE(o))); return 0; } } @@ -1005,8 +1005,8 @@ path_converter(PyObject *o, void *p) else { PyErr_Format(PyExc_TypeError, "expected %.200s.__fspath__() to return str or bytes, " - "not %.200s", Py_TYPE(o)->tp_name, - Py_TYPE(res)->tp_name); + "not %.200s", _PyType_Name(Py_TYPE(o)), + _PyType_Name(Py_TYPE(res))); Py_DECREF(res); goto error_exit; } @@ -1058,7 +1058,7 @@ path_converter(PyObject *o, void *p) path->allow_fd ? "string, bytes, os.PathLike or integer" : path->nullable ? "string, bytes, os.PathLike or None" : "string, bytes or os.PathLike", - Py_TYPE(o)->tp_name)) { + _PyType_Name(Py_TYPE(o)))) { goto error_exit; } bytes = PyBytes_FromObject(o); @@ -1089,7 +1089,7 @@ path_converter(PyObject *o, void *p) path->allow_fd ? "string, bytes, os.PathLike or integer" : path->nullable ? "string, bytes, os.PathLike or None" : "string, bytes or os.PathLike", - Py_TYPE(o)->tp_name); + _PyType_Name(Py_TYPE(o))); goto error_exit; } @@ -2059,12 +2059,16 @@ static PyTypeObject* SchedParamType; static newfunc structseq_new; static PyObject * -statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +statresult_new(PyTypeObject *type, PyObject *args) { + PyObject *sequence, *kwds; PyStructSequence *result; int i; - result = (PyStructSequence*)structseq_new(type, args, kwds); + /* Remove the cls object from the argument list */ + sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + kwds = PyDict_New(); + result = (PyStructSequence*)structseq_new(type, sequence, kwds); if (!result) return NULL; /* If we have been initialized from a tuple, @@ -4715,7 +4719,7 @@ split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns) if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) { PyErr_Format(PyExc_TypeError, "%.200s.__divmod__() must return a 2-tuple, not %.200s", - Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name); + _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod))); goto exit; } *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0)); @@ -5962,7 +5966,7 @@ check_null_or_callable(PyObject *obj, const char* obj_name) { if (obj && !PyCallable_Check(obj)) { PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s", - obj_name, Py_TYPE(obj)->tp_name); + obj_name, _PyType_Name(Py_TYPE(obj))); return -1; } return 0; @@ -12390,19 +12394,20 @@ static PyObject * DirEntry_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyErr_Format(PyExc_TypeError, - "cannot create '%.100s' instances", type->tp_name); + "cannot create '%.100s' instances", _PyType_Name(type)); return NULL; } static void DirEntry_dealloc(DirEntry *entry) { + PyTypeObject *tp = Py_TYPE(entry); Py_XDECREF(entry->name); Py_XDECREF(entry->path); Py_XDECREF(entry->stat); Py_XDECREF(entry->lstat); - Py_DECREF(Py_TYPE(entry)); Py_TYPE(entry)->tp_free((PyObject *)entry); + Py_DECREF(tp); } /* Forward reference */ @@ -12673,7 +12678,7 @@ os_DirEntry___reduce___impl(DirEntry *self) /*[clinic end generated code: output=45167543e30c210c input=c1689a589f9c38f2]*/ { PyErr_Format(PyExc_TypeError, - "cannot pickle '%.100s' instances", Py_TYPE(self)->tp_name); + "cannot pickle '%.100s' instances", _PyType_Name(Py_TYPE(self))); return NULL; } @@ -13147,7 +13152,7 @@ static PyObject * ScandirIterator_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyErr_Format(PyExc_TypeError, - "cannot create '%.100s' instances", type->tp_name); + "cannot create '%.100s' instances", _PyType_Name(type)); return NULL; } @@ -13155,7 +13160,7 @@ static PyObject * ScandirIterator_reduce(PyObject *self, PyObject *args, PyObject *kwargs) { PyErr_Format(PyExc_TypeError, - "cannot pickle '%.100s' instances", Py_TYPE(self)->tp_name); + "cannot pickle '%.100s' instances", _PyType_Name(Py_TYPE(self))); return NULL; } @@ -13168,11 +13173,12 @@ ScandirIterator_reduce_ex(PyObject *self, PyObject *arg) static void ScandirIterator_dealloc(ScandirIterator *iterator) { + PyTypeObject *tp = Py_TYPE(iterator); if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0) return; - Py_DECREF(Py_TYPE(iterator)); Py_TYPE(iterator)->tp_free((PyObject *)iterator); + Py_DECREF(tp); } static PyMethodDef ScandirIterator_methods[] = { @@ -13341,7 +13347,7 @@ PyOS_FSPath(PyObject *path) return PyErr_Format(PyExc_TypeError, "expected str, bytes or os.PathLike object, " "not %.200s", - Py_TYPE(path)->tp_name); + _PyType_Name(Py_TYPE(path))); } path_repr = _PyObject_CallNoArg(func); @@ -13353,8 +13359,8 @@ PyOS_FSPath(PyObject *path) if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) { PyErr_Format(PyExc_TypeError, "expected %.200s.__fspath__() to return str or bytes, " - "not %.200s", Py_TYPE(path)->tp_name, - Py_TYPE(path_repr)->tp_name); + "not %.200s", _PyType_Name(Py_TYPE(path)), + _PyType_Name(Py_TYPE(path_repr))); Py_DECREF(path_repr); return NULL; } @@ -13550,6 +13556,16 @@ os__remove_dll_directory_impl(PyObject *module, PyObject *cookie) #endif +#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) +static PyMethodDef SchedParamType_dunder_new = { + "__new__", (PyCFunction)os_sched_param, METH_VARARGS | METH_KEYWORDS +}; +#endif + +static PyMethodDef StatResultType_dunder_new = { + "__new__", (PyCFunction)statresult_new, METH_VARARGS +}; + static PyMethodDef posix_methods[] = { OS_STAT_METHODDEF @@ -14403,7 +14419,7 @@ static const char * const have_functions[] = { PyMODINIT_FUNC INITFUNC(void) { - PyObject *m, *v; + PyObject *m, *v, *dunder_new; PyObject *list; const char * const *trace; @@ -14449,8 +14465,12 @@ INITFUNC(void) if (StatResultType == NULL) { return NULL; } - structseq_new = StatResultType->tp_new; - StatResultType->tp_new = statresult_new; + + /* Add a custom __new__ to the structsequence */ + structseq_new = (newfunc)PyType_GetSlot((PyTypeObject *)StatResultType, Py_tp_new); + dunder_new = PyDescr_NewClassMethod((PyTypeObject *)StatResultType, &StatResultType_dunder_new); + PyObject_SetAttrString((PyObject *)StatResultType, "__new__", dunder_new); + Py_DECREF(dunder_new); statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc); @@ -14473,7 +14493,10 @@ INITFUNC(void) if (SchedParamType == NULL) { return NULL; } - SchedParamType->tp_new = os_sched_param; + /* Add a custom __new__ to the structsequence */ + dunder_new = PyDescr_NewClassMethod((PyTypeObject *)SchedParamType, &SchedParamType_dunder_new); + PyObject_SetAttrString((PyObject *)SchedParamType, "__new__", dunder_new); + Py_DECREF(dunder_new); #endif /* initialize TerminalSize_info */ From ca19f515f2bd009c8aa57ddd472778eaf153e66a Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Tue, 10 Sep 2019 22:38:04 -0700 Subject: [PATCH 15/39] Cleaned up more slot accesses --- Modules/posixmodule.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index db7882f8e88d19..7173b417021e2d 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12406,7 +12406,8 @@ DirEntry_dealloc(DirEntry *entry) Py_XDECREF(entry->path); Py_XDECREF(entry->stat); Py_XDECREF(entry->lstat); - Py_TYPE(entry)->tp_free((PyObject *)entry); + freefunc entry_free = PyType_GetSlot(Py_TYPE(entry), Py_tp_free); + entry_free((PyObject *)entry); Py_DECREF(tp); } @@ -13177,7 +13178,8 @@ ScandirIterator_dealloc(ScandirIterator *iterator) if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0) return; - Py_TYPE(iterator)->tp_free((PyObject *)iterator); + freefunc iterator_free = PyType_GetSlot(Py_TYPE(iterator), Py_tp_free); + iterator_free((PyObject *)iterator); Py_DECREF(tp); } From 8af0c4ea74905e2b13243f71c75ba9f1cebd948a Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Tue, 10 Sep 2019 22:47:54 -0700 Subject: [PATCH 16/39] Nits --- .../2019-01-18-17-05-26.bpo-35381.9CbeW3.rst | 4 +- Modules/clinic/posixmodule.c.h | 51 ------------------- Modules/posixmodule.c | 50 ------------------ 3 files changed, 1 insertion(+), 104 deletions(-) diff --git a/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst b/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst index b64644659e78fa..a7efce468c6d81 100644 --- a/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst +++ b/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst @@ -1,4 +1,2 @@ Convert posixmodule.c statically allocated types ``DirEntryType`` and -``ScandirIteratorType`` to heap-allocated types. This also modified -`PyObject_New` and `PyObject_NewVar` to increase the type refcount for heap- -allocated types. +``ScandirIteratorType`` to heap-allocated types. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 927a2743792c90..cb4ef5978dbf23 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -7936,57 +7936,6 @@ os_DirEntry_inode(DirEntry *self, PyObject *Py_UNUSED(ignored)) return os_DirEntry_inode_impl(self); } -PyDoc_STRVAR(os_DirEntry___reduce____doc__, -"__reduce__($self, /)\n" -"--\n" -"\n" -"returns null and raises an exception to avoid pickling"); - -#define OS_DIRENTRY___REDUCE___METHODDEF \ - {"__reduce__", (PyCFunction)os_DirEntry___reduce__, METH_NOARGS, os_DirEntry___reduce____doc__}, - -static PyObject * -os_DirEntry___reduce___impl(DirEntry *self); - -static PyObject * -os_DirEntry___reduce__(DirEntry *self, PyObject *Py_UNUSED(ignored)) -{ - return os_DirEntry___reduce___impl(self); -} - -PyDoc_STRVAR(os_DirEntry___reduce_ex____doc__, -"__reduce_ex__($self, protocol, /)\n" -"--\n" -"\n" -"Returns NULL and raises an exception to avoid pickling"); - -#define OS_DIRENTRY___REDUCE_EX___METHODDEF \ - {"__reduce_ex__", (PyCFunction)os_DirEntry___reduce_ex__, METH_O, os_DirEntry___reduce_ex____doc__}, - -static PyObject * -os_DirEntry___reduce_ex___impl(DirEntry *self, int protocol); - -static PyObject * -os_DirEntry___reduce_ex__(DirEntry *self, PyObject *arg) -{ - PyObject *return_value = NULL; - int protocol; - - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - protocol = _PyLong_AsInt(arg); - if (protocol == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = os_DirEntry___reduce_ex___impl(self, protocol); - -exit: - return return_value; -} - PyDoc_STRVAR(os_DirEntry___fspath____doc__, "__fspath__($self, /)\n" "--\n" diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 7173b417021e2d..428cfcd7a9fafd 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12668,37 +12668,6 @@ os_DirEntry_inode_impl(DirEntry *self) #endif } -/*[clinic input] -os.DirEntry.__reduce__ - -returns null and raises an exception to avoid pickling -[clinic start generated code]*/ - -static PyObject * -os_DirEntry___reduce___impl(DirEntry *self) -/*[clinic end generated code: output=45167543e30c210c input=c1689a589f9c38f2]*/ -{ - PyErr_Format(PyExc_TypeError, - "cannot pickle '%.100s' instances", _PyType_Name(Py_TYPE(self))); - return NULL; -} - -/*[clinic input] -os.DirEntry.__reduce_ex__ - - protocol: int - / - -Returns NULL and raises an exception to avoid pickling -[clinic start generated code]*/ - -static PyObject * -os_DirEntry___reduce_ex___impl(DirEntry *self, int protocol) -/*[clinic end generated code: output=a81881dfe241a631 input=1afbee3b136a7ece]*/ -{ - return os_DirEntry___reduce___impl(self); -} - static PyObject * DirEntry_repr(DirEntry *self) { @@ -12730,8 +12699,6 @@ static PyMemberDef DirEntry_members[] = { #include "clinic/posixmodule.c.h" static PyMethodDef DirEntry_methods[] = { - OS_DIRENTRY___REDUCE___METHODDEF - OS_DIRENTRY___REDUCE_EX___METHODDEF OS_DIRENTRY_IS_DIR_METHODDEF OS_DIRENTRY_IS_FILE_METHODDEF OS_DIRENTRY_IS_SYMLINK_METHODDEF @@ -13157,20 +13124,6 @@ ScandirIterator_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) return NULL; } -static PyObject * -ScandirIterator_reduce(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyErr_Format(PyExc_TypeError, - "cannot pickle '%.100s' instances", _PyType_Name(Py_TYPE(self))); - return NULL; -} - -static PyObject * -ScandirIterator_reduce_ex(PyObject *self, PyObject *arg) -{ - return ScandirIterator_reduce(self, NULL, NULL); -} - static void ScandirIterator_dealloc(ScandirIterator *iterator) { @@ -13184,8 +13137,6 @@ ScandirIterator_dealloc(ScandirIterator *iterator) } static PyMethodDef ScandirIterator_methods[] = { - {"__reduce__", (PyCFunction)ScandirIterator_reduce, METH_NOARGS}, - {"__reduce_ex__", (PyCFunction)ScandirIterator_reduce_ex, METH_O}, {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS}, {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS}, {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS}, @@ -14467,7 +14418,6 @@ INITFUNC(void) if (StatResultType == NULL) { return NULL; } - /* Add a custom __new__ to the structsequence */ structseq_new = (newfunc)PyType_GetSlot((PyTypeObject *)StatResultType, Py_tp_new); dunder_new = PyDescr_NewClassMethod((PyTypeObject *)StatResultType, &StatResultType_dunder_new); From cee2cd99dc053aeeb26d03912d637f73a1df9a9d Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Tue, 10 Sep 2019 23:14:07 -0700 Subject: [PATCH 17/39] Fixes --- Modules/clinic/posixmodule.c.h | 38 ---------------------------------- Modules/posixmodule.c | 37 +++++++++++++++++++-------------- 2 files changed, 21 insertions(+), 54 deletions(-) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index cb4ef5978dbf23..b428b37989a6ba 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -2831,44 +2831,6 @@ os_sched_getscheduler(PyObject *module, PyObject *arg) #endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETSCHEDULER) */ -#if defined(HAVE_SCHED_H) && (defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)) - -PyDoc_STRVAR(os_sched_param__doc__, -"sched_param(sched_priority)\n" -"--\n" -"\n" -"Current has only one field: sched_priority\");\n" -"\n" -" sched_priority\n" -" A scheduling parameter."); - -static PyObject * -os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority); - -static PyObject * -os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"sched_priority", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sched_param", 0}; - PyObject *argsbuf[1]; - PyObject * const *fastargs; - Py_ssize_t nargs = PyTuple_GET_SIZE(args); - PyObject *sched_priority; - - fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); - if (!fastargs) { - goto exit; - } - sched_priority = fastargs[0]; - return_value = os_sched_param_impl(type, sched_priority); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SCHED_H) && (defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)) */ - #if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETSCHEDULER) PyDoc_STRVAR(os_sched_setscheduler__doc__, diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 428cfcd7a9fafd..1d92bdf058c9c9 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6161,25 +6161,31 @@ os_sched_getscheduler_impl(PyObject *module, pid_t pid) #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) -/*[clinic input] -class os.sched_param "PyObject *" "SchedParamType" - -@classmethod -os.sched_param.__new__ - - sched_priority: object - A scheduling parameter. - -Current has only one field: sched_priority"); -[clinic start generated code]*/ +PyDoc_STRVAR(os_sched_param__doc__, +"sched_param(sched_priority)\n" +"--\n" +"\n" +"Current has only one field: sched_priority\");\n" +"\n" +" sched_priority\n" +" A scheduling parameter."); static PyObject * -os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) -/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/ +os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - PyObject *res; + static char* _keywords[] = {"sched_priority", NULL}; + static const char * _format = "O:sched_param"; + PyObject *sequence, *sched_priority, *res; - res = PyStructSequence_New(type); + /* Remove the cls object from the argument list */ + sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + int result = PyArg_ParseTupleAndKeywords(sequence, kwargs, _format, _keywords, + &sched_priority); + Py_DECREF(sequence); + if (!result) { + return NULL; + } + res = PyStructSequence_New((PyTypeObject *)type); if (!res) return NULL; Py_INCREF(sched_priority); @@ -6187,7 +6193,6 @@ os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) return res; } - PyDoc_VAR(os_sched_param__doc__); static PyStructSequence_Field sched_param_fields[] = { From a8d2f5661f1df219c34ae3f881f3699b0b07f106 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Tue, 10 Sep 2019 23:27:53 -0700 Subject: [PATCH 18/39] Run clinic --- Modules/clinic/posixmodule.c.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index b428b37989a6ba..3e57c4620fc662 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -616,7 +616,7 @@ os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * goto exit; } if (!PyLong_Check(args[1])) { - _PyArg_BadArgument("chflags", "argument 'flags'", "int", args[1]); + _PyArg_BadArgument("chflags", 2, "int", args[1]); goto exit; } flags = PyLong_AsUnsignedLongMask(args[1]); @@ -674,7 +674,7 @@ os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } if (!PyLong_Check(args[1])) { - _PyArg_BadArgument("lchflags", "argument 'flags'", "int", args[1]); + _PyArg_BadArgument("lchflags", 2, "int", args[1]); goto exit; } flags = PyLong_AsUnsignedLongMask(args[1]); @@ -4918,7 +4918,7 @@ os_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("write", "argument 2", "contiguous buffer", args[1]); + _PyArg_BadArgument("write", 2, "contiguous buffer", args[1]); goto exit; } _return_value = os_write_impl(module, fd, &data); @@ -5241,7 +5241,7 @@ os_pwrite(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("pwrite", "argument 2", "contiguous buffer", args[1]); + _PyArg_BadArgument("pwrite", 2, "contiguous buffer", args[1]); goto exit; } if (!Py_off_t_converter(args[2], &offset)) { @@ -5974,7 +5974,7 @@ os_putenv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("putenv", "argument 1", "str", args[0]); + _PyArg_BadArgument("putenv", 1, "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -5982,7 +5982,7 @@ os_putenv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } name = args[0]; if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("putenv", "argument 2", "str", args[1]); + _PyArg_BadArgument("putenv", 2, "str", args[1]); goto exit; } if (PyUnicode_READY(args[1]) == -1) { @@ -7178,7 +7178,7 @@ os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } if (!PyBuffer_IsContiguous(&value, 'C')) { - _PyArg_BadArgument("setxattr", "argument 'value'", "contiguous buffer", args[2]); + _PyArg_BadArgument("setxattr", 3, "contiguous buffer", args[2]); goto exit; } if (!noptargs) { @@ -8686,4 +8686,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ -/*[clinic end generated code: output=3c5cb675b0d09145 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=37e29e373b81782e input=a9049054013a1b77]*/ From 5e4d2ab2bc4429bb939a042b6472a263b288eb8d Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Tue, 10 Sep 2019 23:28:53 -0700 Subject: [PATCH 19/39] Run clinic --- Modules/clinic/posixmodule.c.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 3e57c4620fc662..d1144e07f8c11a 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -616,7 +616,7 @@ os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * goto exit; } if (!PyLong_Check(args[1])) { - _PyArg_BadArgument("chflags", 2, "int", args[1]); + _PyArg_BadArgument("chflags", "argument 'flags'", "int", args[1]); goto exit; } flags = PyLong_AsUnsignedLongMask(args[1]); @@ -674,7 +674,7 @@ os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } if (!PyLong_Check(args[1])) { - _PyArg_BadArgument("lchflags", 2, "int", args[1]); + _PyArg_BadArgument("lchflags", "argument 'flags'", "int", args[1]); goto exit; } flags = PyLong_AsUnsignedLongMask(args[1]); @@ -4918,7 +4918,7 @@ os_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("write", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("write", "argument 2", "contiguous buffer", args[1]); goto exit; } _return_value = os_write_impl(module, fd, &data); @@ -5241,7 +5241,7 @@ os_pwrite(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("pwrite", 2, "contiguous buffer", args[1]); + _PyArg_BadArgument("pwrite", "argument 2", "contiguous buffer", args[1]); goto exit; } if (!Py_off_t_converter(args[2], &offset)) { @@ -5974,7 +5974,7 @@ os_putenv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("putenv", 1, "str", args[0]); + _PyArg_BadArgument("putenv", "argument 1", "str", args[0]); goto exit; } if (PyUnicode_READY(args[0]) == -1) { @@ -5982,7 +5982,7 @@ os_putenv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } name = args[0]; if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("putenv", 2, "str", args[1]); + _PyArg_BadArgument("putenv", "argument 2", "str", args[1]); goto exit; } if (PyUnicode_READY(args[1]) == -1) { @@ -7178,7 +7178,7 @@ os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } if (!PyBuffer_IsContiguous(&value, 'C')) { - _PyArg_BadArgument("setxattr", 3, "contiguous buffer", args[2]); + _PyArg_BadArgument("setxattr", "argument 'value'", "contiguous buffer", args[2]); goto exit; } if (!noptargs) { @@ -8686,4 +8686,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ -/*[clinic end generated code: output=37e29e373b81782e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5edce0087b201e5f input=a9049054013a1b77]*/ From c42ec45b0967bdd67451987dc9f06826fdc8ec36 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 11 Sep 2019 14:19:09 +0100 Subject: [PATCH 20/39] Improve error handling --- Modules/posixmodule.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 1d92bdf058c9c9..f55326272c1096 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2067,10 +2067,20 @@ statresult_new(PyTypeObject *type, PyObject *args) /* Remove the cls object from the argument list */ sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + if (!sequence) { + return NULL; + } kwds = PyDict_New(); + if (!kwds) { + Py_DECREF(sequence); + return NULL; + } result = (PyStructSequence*)structseq_new(type, sequence, kwds); - if (!result) + if (!result) { + Py_DECREF(sequence); + Py_DECREF(kwds); return NULL; + } /* If we have been initialized from a tuple, st_?time might be set to None. Initialize it from the int slots. */ @@ -6179,6 +6189,9 @@ os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) /* Remove the cls object from the argument list */ sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + if (!sequence) { + return NULL; + } int result = PyArg_ParseTupleAndKeywords(sequence, kwargs, _format, _keywords, &sched_priority); Py_DECREF(sequence); @@ -6186,8 +6199,9 @@ os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) return NULL; } res = PyStructSequence_New((PyTypeObject *)type); - if (!res) + if (!res) { return NULL; + } Py_INCREF(sched_priority); PyStructSequence_SET_ITEM(res, 0, sched_priority); return res; From d27a5479d191adb1f4c92423b00e745cb714cd28 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Thu, 12 Sep 2019 10:40:34 -0700 Subject: [PATCH 21/39] Remove static from posixmodule.c --- Modules/posixmodule.c | 386 +++++++++++++++++++++++++++--------------- 1 file changed, 245 insertions(+), 141 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 1d92bdf058c9c9..d3522c53f17fdf 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -815,6 +815,35 @@ dir_fd_converter(PyObject *o, void *p) } } +typedef struct { + PyObject *billion; + PyObject *posix_putenv_garbage; + PyObject *DirEntryType; + PyObject *ScandirIteratorType; +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) + PyObject *SchedParamType; +#endif + PyObject *StatResultType; + PyObject *StatVFSResultType; + PyObject *TerminalSizeType; + PyObject *TimesResultType; + PyObject *UnameResultType; +#if defined(HAVE_WAITID) && !defined(__APPLE__) + PyObject *WaitidResultType; +#endif +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) + PyObject *struct_rusage; +#endif + PyObject *st_mode; + PyObject *fspath; + PyObject *dunderget; + newfunc structseq_new; +} _posixstate; + +static struct PyModuleDef posixmodule; + +#define _posixstate(o) ((_posixstate *)PyModule_GetState(o)) +#define _posixstate_global ((_posixstate *)PyModule_GetState(PyState_FindModule(&posixmodule))) /* * A PyArg_ParseTuple "converter" function @@ -927,6 +956,24 @@ typedef struct { {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL} #endif +// _PyType_LookupSpecial with PyObject* rather than _Py_Identifier +static PyObject* +fspath_lookup_special(PyObject *self) { + PyObject *func, *getter; + PyTypeObject *path_type = Py_TYPE(self); + func = _PyType_Lookup(path_type, _posixstate_global->fspath); + if (func != NULL) { + getter = _PyType_Lookup(Py_TYPE(func), _posixstate_global->dunderget); + if (getter == NULL) { + Py_INCREF(func); + } else { + func = PyObject_CallFunctionObjArgs( + getter, func, self, (PyObject *)path_type, NULL); + } + } + return func; +} + static void path_cleanup(path_t *path) { @@ -984,10 +1031,9 @@ path_converter(PyObject *o, void *p) if (!is_index && !is_buffer && !is_unicode && !is_bytes) { /* Inline PyOS_FSPath() for better error messages. */ - _Py_IDENTIFIER(__fspath__); PyObject *func, *res; - func = _PyObject_LookupSpecial(o, &PyId___fspath__); + func = fspath_lookup_special(o); if (NULL == func) { goto error_format; } @@ -2047,17 +2093,8 @@ static PyStructSequence_Desc waitid_result_desc = { waitid_result_fields, 5 }; -static PyTypeObject* WaitidResultType; #endif -static int initialized; -static PyTypeObject* StatResultType; -static PyTypeObject* StatVFSResultType; -#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) -static PyTypeObject* SchedParamType; -#endif -static newfunc structseq_new; - static PyObject * statresult_new(PyTypeObject *type, PyObject *args) { @@ -2068,7 +2105,9 @@ statresult_new(PyTypeObject *type, PyObject *args) /* Remove the cls object from the argument list */ sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); kwds = PyDict_New(); - result = (PyStructSequence*)structseq_new(type, sequence, kwds); + result = (PyStructSequence*)_posixstate_global->structseq_new(type, sequence, kwds); + Py_DECREF(sequence); + Py_DECREF(kwds); if (!result) return NULL; /* If we have been initialized from a tuple, @@ -2084,8 +2123,65 @@ statresult_new(PyTypeObject *type, PyObject *args) return (PyObject*)result; } +static int +_posix_clear(PyObject *module) +{ + Py_CLEAR(_posixstate(module)->billion); + Py_CLEAR(_posixstate(module)->posix_putenv_garbage); + Py_CLEAR(_posixstate(module)->DirEntryType); + Py_CLEAR(_posixstate(module)->ScandirIteratorType); +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) + Py_CLEAR(_posixstate(module)->SchedParamType); +#endif + Py_CLEAR(_posixstate(module)->StatResultType); + Py_CLEAR(_posixstate(module)->StatVFSResultType); + Py_CLEAR(_posixstate(module)->TerminalSizeType); + Py_CLEAR(_posixstate(module)->TimesResultType); + Py_CLEAR(_posixstate(module)->UnameResultType); +#if defined(HAVE_WAITID) && !defined(__APPLE__) + Py_CLEAR(_posixstate(module)->WaitidResultType); +#endif +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) + Py_CLEAR(_posixstate(module)->struct_rusage); +#endif + Py_CLEAR(_posixstate(module)->st_mode); + Py_CLEAR(_posixstate(module)->fspath); + Py_CLEAR(_posixstate(module)->dunderget); + return 0; +} + +static int +_posix_traverse(PyObject *module, visitproc visit, void *arg) +{ + Py_VISIT(_posixstate(module)->billion); + Py_VISIT(_posixstate(module)->posix_putenv_garbage); + Py_VISIT(_posixstate(module)->DirEntryType); + Py_VISIT(_posixstate(module)->ScandirIteratorType); +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) + Py_VISIT(_posixstate(module)->SchedParamType); +#endif + Py_VISIT(_posixstate(module)->StatResultType); + Py_VISIT(_posixstate(module)->StatVFSResultType); + Py_VISIT(_posixstate(module)->TerminalSizeType); + Py_VISIT(_posixstate(module)->TimesResultType); + Py_VISIT(_posixstate(module)->UnameResultType); +#if defined(HAVE_WAITID) && !defined(__APPLE__) + Py_VISIT(_posixstate(module)->WaitidResultType); +#endif +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) + Py_VISIT(_posixstate(module)->struct_rusage); +#endif + Py_VISIT(_posixstate(module)->st_mode); + Py_VISIT(_posixstate(module)->fspath); + Py_VISIT(_posixstate(module)->dunderget); + return 0; +} -static PyObject *billion = NULL; +static void +_posix_free(void *module) +{ + _posix_clear((PyObject *)module); +} static void fill_time(PyObject *v, int index, time_t sec, unsigned long nsec) @@ -2099,7 +2195,7 @@ fill_time(PyObject *v, int index, time_t sec, unsigned long nsec) if (!(s && ns_fractional)) goto exit; - s_in_ns = PyNumber_Multiply(s, billion); + s_in_ns = PyNumber_Multiply(s, _posixstate_global->billion); if (!s_in_ns) goto exit; @@ -2132,7 +2228,8 @@ static PyObject* _pystat_fromstructstat(STRUCT_STAT *st) { unsigned long ansec, mnsec, cnsec; - PyObject *v = PyStructSequence_New(StatResultType); + PyObject *StatResultType = _posixstate_global->StatResultType; + PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType); if (v == NULL) return NULL; @@ -4504,9 +4601,6 @@ static PyStructSequence_Desc uname_result_desc = { 5 }; -static PyTypeObject* UnameResultType; - - #ifdef HAVE_UNAME /*[clinic input] os.uname @@ -4532,7 +4626,8 @@ os_uname_impl(PyObject *module) if (res < 0) return posix_error(); - value = PyStructSequence_New(UnameResultType); + PyObject *UnameResultType = _posixstate(module)->UnameResultType; + value = PyStructSequence_New((PyTypeObject *)UnameResultType); if (value == NULL) return NULL; @@ -4713,7 +4808,7 @@ split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns) { int result = 0; PyObject *divmod; - divmod = PyNumber_Divmod(py_long, billion); + divmod = PyNumber_Divmod(py_long, _posixstate_global->billion); if (!divmod) goto exit; if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) { @@ -6212,7 +6307,8 @@ convert_sched_param(PyObject *param, struct sched_param *res) { long priority; - if (Py_TYPE(param) != SchedParamType) { + PyObject *SchedParamType = _posixstate_global->SchedParamType; + if (Py_TYPE(param) != (PyTypeObject *)SchedParamType) { PyErr_SetString(PyExc_TypeError, "must have a sched_param object"); return 0; } @@ -6283,7 +6379,8 @@ os_sched_getparam_impl(PyObject *module, pid_t pid) if (sched_getparam(pid, ¶m)) return posix_error(); - result = PyStructSequence_New(SchedParamType); + PyObject *SchedParamType = _posixstate_global->SchedParamType; + result = PyStructSequence_New((PyTypeObject *)SchedParamType); if (!result) return NULL; priority = PyLong_FromLong(param.sched_priority); @@ -7492,8 +7589,7 @@ static PyObject * wait_helper(pid_t pid, int status, struct rusage *ru) { PyObject *result; - static PyObject *struct_rusage; - _Py_IDENTIFIER(struct_rusage); + PyObject *struct_rusage; if (pid == -1) return posix_error(); @@ -7504,15 +7600,13 @@ wait_helper(pid_t pid, int status, struct rusage *ru) memset(ru, 0, sizeof(*ru)); } - if (struct_rusage == NULL) { - PyObject *m = PyImport_ImportModuleNoBlock("resource"); - if (m == NULL) - return NULL; - struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage); - Py_DECREF(m); - if (struct_rusage == NULL) - return NULL; - } + PyObject *m = PyImport_ImportModuleNoBlock("resource"); + if (m == NULL) + return NULL; + struct_rusage = PyObject_GetAttr(m, _posixstate_global->struct_rusage); + Py_DECREF(m); + if (struct_rusage == NULL) + return NULL; /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */ result = PyStructSequence_New((PyTypeObject*) struct_rusage); @@ -7666,7 +7760,8 @@ os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options) if (si.si_pid == 0) Py_RETURN_NONE; - result = PyStructSequence_New(WaitidResultType); + PyObject *WaitidResultType = _posixstate(module)->WaitidResultType; + result = PyStructSequence_New((PyTypeObject *)WaitidResultType); if (!result) return NULL; @@ -8117,8 +8212,6 @@ static PyStructSequence_Desc times_result_desc = { 5 }; -static PyTypeObject* TimesResultType; - #ifdef MS_WINDOWS #define HAVE_TIMES /* mandatory, for the method table */ #endif @@ -8130,7 +8223,8 @@ build_times_result(double user, double system, double children_user, double children_system, double elapsed) { - PyObject *value = PyStructSequence_New(TimesResultType); + PyObject *TimesResultType = _posixstate_global->TimesResultType; + PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType); if (value == NULL) return NULL; @@ -9928,10 +10022,6 @@ os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset, #ifdef HAVE_PUTENV -/* Save putenv() parameters as values here, so we can collect them when they - * get re-set with another call for the same key. */ -static PyObject *posix_putenv_garbage; - static void posix_putenv_garbage_setitem(PyObject *name, PyObject *value) { @@ -9939,7 +10029,7 @@ posix_putenv_garbage_setitem(PyObject *name, PyObject *value) * this will cause previous value to be collected. This has to * happen after the real putenv() call because the old value * was still accessible until then. */ - if (PyDict_SetItem(posix_putenv_garbage, name, value)) + if (PyDict_SetItem(_posixstate_global->posix_putenv_garbage, name, value)) /* really not much we can do; just leak */ PyErr_Clear(); else @@ -10076,7 +10166,7 @@ os_unsetenv_impl(PyObject *module, PyObject *name) * happen after the real unsetenv() call because the * old value was still accessible until then. */ - if (PyDict_DelItem(posix_putenv_garbage, name)) { + if (PyDict_DelItem(_posixstate(module)->posix_putenv_garbage, name)) { /* really not much we can do; just leak */ if (!PyErr_ExceptionMatches(PyExc_KeyError)) { return NULL; @@ -10287,7 +10377,8 @@ os_WSTOPSIG_impl(PyObject *module, int status) static PyObject* _pystatvfs_fromstructstatvfs(struct statvfs st) { - PyObject *v = PyStructSequence_New(StatVFSResultType); + PyObject *StatVFSResultType = _posixstate_global->StatVFSResultType; + PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType); if (v == NULL) return NULL; @@ -12066,8 +12157,6 @@ os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags) /* Terminal size querying */ -static PyTypeObject* TerminalSizeType; - PyDoc_STRVAR(TerminalSize_docstring, "A tuple of (columns, lines) for holding terminal window size"); @@ -12158,7 +12247,8 @@ get_terminal_size(PyObject *self, PyObject *args) } #endif /* TERMSIZE_USE_CONIO */ - termsize = PyStructSequence_New(TerminalSizeType); + PyObject *TerminalSizeType = _posixstate(self)->TerminalSizeType; + termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType); if (termsize == NULL) return NULL; PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns)); @@ -12542,7 +12632,6 @@ DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits #ifdef MS_WINDOWS unsigned long dir_bits; #endif - _Py_IDENTIFIER(st_mode); #ifdef MS_WINDOWS is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK; @@ -12565,7 +12654,7 @@ DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits } goto error; } - st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode); + st_mode = PyObject_GetAttr(stat, _posixstate_global->st_mode); if (!st_mode) goto error; @@ -12730,8 +12819,6 @@ static PyType_Spec DirEntryType_spec = { DirEntryType_slots }; -static PyTypeObject* DirEntryType; - #ifdef MS_WINDOWS static wchar_t * @@ -12775,7 +12862,8 @@ DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW) ULONG reparse_tag; wchar_t *joined_path; - entry = PyObject_New(DirEntry, DirEntryType); + PyObject *DirEntryType = _posixstate(self)->DirEntryType; + entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType); if (!entry) return NULL; entry->name = NULL; @@ -12862,7 +12950,8 @@ DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len, DirEntry *entry; char *joined_path; - entry = PyObject_New(DirEntry, DirEntryType); + PyObject *DirEntryType = _posixstate_global->DirEntryType; + entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType); if (!entry) return NULL; entry->name = NULL; @@ -13166,8 +13255,6 @@ static PyType_Spec ScandirIteratorType_spec = { ScandirIteratorType_slots }; -static PyTypeObject* ScandirIteratorType; - /*[clinic input] os.scandir @@ -13201,7 +13288,8 @@ os_scandir_impl(PyObject *module, path_t *path) return NULL; } - iterator = PyObject_New(ScandirIterator, ScandirIteratorType); + PyObject *ScandirIteratorType = _posixstate(module)->ScandirIteratorType; + iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType); if (!iterator) return NULL; @@ -13291,7 +13379,6 @@ PyOS_FSPath(PyObject *path) { /* For error message reasons, this function is manually inlined in path_converter(). */ - _Py_IDENTIFIER(__fspath__); PyObject *func = NULL; PyObject *path_repr = NULL; @@ -13300,7 +13387,7 @@ PyOS_FSPath(PyObject *path) return path; } - func = _PyObject_LookupSpecial(path, &PyId___fspath__); + func = fspath_lookup_special(path); if (NULL == func) { return PyErr_Format(PyExc_TypeError, "expected str, bytes or os.PathLike object, " @@ -13514,7 +13601,7 @@ os__remove_dll_directory_impl(PyObject *module, PyObject *cookie) #endif -#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) static PyMethodDef SchedParamType_dunder_new = { "__new__", (PyCFunction)os_sched_param, METH_VARARGS | METH_KEYWORDS }; @@ -14231,12 +14318,12 @@ static struct PyModuleDef posixmodule = { PyModuleDef_HEAD_INIT, MODNAME, posix__doc__, - -1, + sizeof(_posixstate), posix_methods, NULL, - NULL, - NULL, - NULL + _posix_traverse, + _posix_clear, + _posix_free, }; @@ -14381,6 +14468,12 @@ INITFUNC(void) PyObject *list; const char * const *trace; + m = PyState_FindModule(&posixmodule); + if (m != NULL) { + Py_INCREF(m); + return m; + } + m = PyModule_Create(&posixmodule); if (m == NULL) return NULL; @@ -14402,102 +14495,111 @@ INITFUNC(void) PyModule_AddObject(m, "error", PyExc_OSError); #ifdef HAVE_PUTENV - if (posix_putenv_garbage == NULL) - posix_putenv_garbage = PyDict_New(); + /* Save putenv() parameters as values here, so we can collect them when they + * get re-set with another call for the same key. */ + _posixstate(m)->posix_putenv_garbage = PyDict_New(); #endif - if (!initialized) { #if defined(HAVE_WAITID) && !defined(__APPLE__) - waitid_result_desc.name = MODNAME ".waitid_result"; - WaitidResultType = PyStructSequence_NewType(&waitid_result_desc); - if (WaitidResultType == NULL) { - return NULL; - } + waitid_result_desc.name = MODNAME ".waitid_result"; + PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc); + if (WaitidResultType == NULL) { + return NULL; + } + Py_INCREF(WaitidResultType); + PyModule_AddObject(m, "waitid_result", WaitidResultType); + _posixstate(m)->WaitidResultType = WaitidResultType; #endif - stat_result_desc.name = "os.stat_result"; /* see issue #19209 */ - stat_result_desc.fields[7].name = PyStructSequence_UnnamedField; - stat_result_desc.fields[8].name = PyStructSequence_UnnamedField; - stat_result_desc.fields[9].name = PyStructSequence_UnnamedField; - StatResultType = PyStructSequence_NewType(&stat_result_desc); - if (StatResultType == NULL) { - return NULL; - } - /* Add a custom __new__ to the structsequence */ - structseq_new = (newfunc)PyType_GetSlot((PyTypeObject *)StatResultType, Py_tp_new); - dunder_new = PyDescr_NewClassMethod((PyTypeObject *)StatResultType, &StatResultType_dunder_new); - PyObject_SetAttrString((PyObject *)StatResultType, "__new__", dunder_new); - Py_DECREF(dunder_new); + stat_result_desc.name = "os.stat_result"; /* see issue #19209 */ + stat_result_desc.fields[7].name = PyStructSequence_UnnamedField; + stat_result_desc.fields[8].name = PyStructSequence_UnnamedField; + stat_result_desc.fields[9].name = PyStructSequence_UnnamedField; + PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc); + if (StatResultType == NULL) { + return NULL; + } + Py_INCREF(StatResultType); + PyModule_AddObject(m, "stat_result", StatResultType); + _posixstate(m)->StatResultType = StatResultType; - statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ - StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc); - if (StatVFSResultType == NULL) { - return NULL; - } + /* Add a custom __new__ to the structsequence */ + _posixstate(m)->structseq_new = (newfunc)PyType_GetSlot((PyTypeObject *)StatResultType, Py_tp_new); + dunder_new = PyDescr_NewClassMethod((PyTypeObject *)StatResultType, &StatResultType_dunder_new); + PyObject_SetAttrString(StatResultType, "__new__", dunder_new); + Py_DECREF(dunder_new); + + statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ + PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc); + if (StatVFSResultType == NULL) { + return NULL; + } + Py_INCREF(StatVFSResultType); + PyModule_AddObject(m, "statvfs_result", StatVFSResultType); + _posixstate(m)->StatVFSResultType = StatVFSResultType; #ifdef NEED_TICKS_PER_SECOND # if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) - ticks_per_second = sysconf(_SC_CLK_TCK); + ticks_per_second = sysconf(_SC_CLK_TCK); # elif defined(HZ) - ticks_per_second = HZ; + ticks_per_second = HZ; # else - ticks_per_second = 60; /* magic fallback value; may be bogus */ + ticks_per_second = 60; /* magic fallback value; may be bogus */ # endif #endif #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) - sched_param_desc.name = MODNAME ".sched_param"; - SchedParamType = PyStructSequence_NewType(&sched_param_desc); - if (SchedParamType == NULL) { - return NULL; - } - /* Add a custom __new__ to the structsequence */ - dunder_new = PyDescr_NewClassMethod((PyTypeObject *)SchedParamType, &SchedParamType_dunder_new); - PyObject_SetAttrString((PyObject *)SchedParamType, "__new__", dunder_new); - Py_DECREF(dunder_new); + sched_param_desc.name = MODNAME ".sched_param"; + PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc); + if (SchedParamType == NULL) { + return NULL; + } + Py_INCREF(SchedParamType); + PyModule_AddObject(m, "sched_param", SchedParamType); + _posixstate(m)->SchedParamType = SchedParamType; + /* Add a custom __new__ to the structsequence */ + dunder_new = PyDescr_NewClassMethod((PyTypeObject *)SchedParamType, &SchedParamType_dunder_new); + PyObject_SetAttrString((PyObject *)SchedParamType, "__new__", dunder_new); + Py_DECREF(dunder_new); #endif - /* initialize TerminalSize_info */ - TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc); - if (TerminalSizeType == NULL) { - return NULL; - } - - /* initialize scandir types */ - ScandirIteratorType = (PyTypeObject *)PyType_FromSpec(&ScandirIteratorType_spec); - if (ScandirIteratorType == NULL) - return NULL; - DirEntryType = (PyTypeObject *)PyType_FromSpec(&DirEntryType_spec); - if (DirEntryType == NULL) - return NULL; + /* initialize TerminalSize_info */ + PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc); + if (TerminalSizeType == NULL) { + return NULL; } -#if defined(HAVE_WAITID) && !defined(__APPLE__) - Py_INCREF((PyObject*) WaitidResultType); - PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType); -#endif - Py_INCREF((PyObject*) StatResultType); - PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType); - Py_INCREF((PyObject*) StatVFSResultType); - PyModule_AddObject(m, "statvfs_result", - (PyObject*) StatVFSResultType); + Py_INCREF(TerminalSizeType); + PyModule_AddObject(m, "terminal_size", TerminalSizeType); + _posixstate(m)->TerminalSizeType = TerminalSizeType; -#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) - Py_INCREF(SchedParamType); - PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType); -#endif + /* initialize scandir types */ + PyObject *ScandirIteratorType = PyType_FromSpec(&ScandirIteratorType_spec); + if (ScandirIteratorType == NULL) + return NULL; + _posixstate(m)->ScandirIteratorType = ScandirIteratorType; + + PyObject *DirEntryType = PyType_FromSpec(&DirEntryType_spec); + if (DirEntryType == NULL) + return NULL; + Py_INCREF(DirEntryType); + PyModule_AddObject(m, "DirEntry", DirEntryType); + _posixstate(m)->DirEntryType = DirEntryType; times_result_desc.name = MODNAME ".times_result"; - TimesResultType = PyStructSequence_NewType(×_result_desc); + PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(×_result_desc); if (TimesResultType == NULL) { return NULL; } - PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType); + Py_INCREF(TimesResultType); + PyModule_AddObject(m, "times_result", TimesResultType); + _posixstate(m)->TimesResultType = TimesResultType; - uname_result_desc.name = MODNAME ".uname_result"; - UnameResultType = PyStructSequence_NewType(&uname_result_desc); + PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc); if (UnameResultType == NULL) { return NULL; } + Py_INCREF(UnameResultType); PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType); + _posixstate(m)->UnameResultType = (PyObject *)UnameResultType; #ifdef __APPLE__ /* @@ -14537,11 +14639,17 @@ INITFUNC(void) #endif /* __APPLE__ */ - Py_INCREF(TerminalSizeType); - PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType); - - billion = PyLong_FromLong(1000000000); - if (!billion) + if ((_posixstate(m)->billion = PyLong_FromLong(1000000000)) == NULL) + return NULL; +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) + if ((_posixstate(m)->struct_rusage = PyUnicode_FromString("struct_rusage")) == NULL) + return NULL; +#endif + if ((_posixstate(m)->st_mode = PyUnicode_FromString("st_mode")) == NULL) + return NULL; + if ((_posixstate(m)->fspath = PyUnicode_FromString("__fspath__")) == NULL) + return NULL; + if ((_posixstate(m)->dunderget = PyUnicode_FromString("__get__")) == NULL) return NULL; /* suppress "function not used" warnings */ @@ -14571,11 +14679,7 @@ INITFUNC(void) } PyModule_AddObject(m, "_have_functions", list); - Py_INCREF((PyObject *) DirEntryType); - PyModule_AddObject(m, "DirEntry", (PyObject *)DirEntryType); - - initialized = 1; - + PyState_AddModule(m, &posixmodule); return m; } From a723d1cc4b33a445acc2b872b59ecbed496b4949 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Thu, 12 Sep 2019 11:14:52 -0700 Subject: [PATCH 22/39] Address Comments --- Modules/posixmodule.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index d3522c53f17fdf..17b1cd51fcf523 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2104,7 +2104,14 @@ statresult_new(PyTypeObject *type, PyObject *args) /* Remove the cls object from the argument list */ sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + if (!sequence) { + return NULL; + } kwds = PyDict_New(); + if (!kwds) { + Py_DECREF(sequence); + return NULL; + } result = (PyStructSequence*)_posixstate_global->structseq_new(type, sequence, kwds); Py_DECREF(sequence); Py_DECREF(kwds); @@ -4595,7 +4602,7 @@ or via the attributes sysname, nodename, release, version, and machine.\n\ See os.uname for more information."); static PyStructSequence_Desc uname_result_desc = { - "uname_result", /* name */ + MODNAME ".uname_result", /* name */ uname_result__doc__, /* doc */ uname_result_fields, 5 @@ -6260,7 +6267,6 @@ PyDoc_STRVAR(os_sched_param__doc__, "sched_param(sched_priority)\n" "--\n" "\n" -"Current has only one field: sched_priority\");\n" "\n" " sched_priority\n" " A scheduling parameter."); @@ -6274,6 +6280,9 @@ os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) /* Remove the cls object from the argument list */ sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + if (!sequence) { + return NULL; + } int result = PyArg_ParseTupleAndKeywords(sequence, kwargs, _format, _keywords, &sched_priority); Py_DECREF(sequence); @@ -6281,8 +6290,9 @@ os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) return NULL; } res = PyStructSequence_New((PyTypeObject *)type); - if (!res) + if (!res) { return NULL; + } Py_INCREF(sched_priority); PyStructSequence_SET_ITEM(res, 0, sched_priority); return res; @@ -12819,6 +12829,7 @@ static PyType_Spec DirEntryType_spec = { DirEntryType_slots }; + #ifdef MS_WINDOWS static wchar_t * From e91096a9268f675a98f6ac0bc53a2fe5fd706795 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Thu, 12 Sep 2019 11:18:23 -0700 Subject: [PATCH 23/39] Address Comments --- Modules/posixmodule.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 17b1cd51fcf523..0532df94b92b4c 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -14537,6 +14537,9 @@ INITFUNC(void) /* Add a custom __new__ to the structsequence */ _posixstate(m)->structseq_new = (newfunc)PyType_GetSlot((PyTypeObject *)StatResultType, Py_tp_new); dunder_new = PyDescr_NewClassMethod((PyTypeObject *)StatResultType, &StatResultType_dunder_new); + if (dunder_new == NULL) { + return NULL; + } PyObject_SetAttrString(StatResultType, "__new__", dunder_new); Py_DECREF(dunder_new); @@ -14569,6 +14572,9 @@ INITFUNC(void) _posixstate(m)->SchedParamType = SchedParamType; /* Add a custom __new__ to the structsequence */ dunder_new = PyDescr_NewClassMethod((PyTypeObject *)SchedParamType, &SchedParamType_dunder_new); + if (dunder_new == NULL) { + return NULL; + } PyObject_SetAttrString((PyObject *)SchedParamType, "__new__", dunder_new); Py_DECREF(dunder_new); #endif From 3cf259e6fcd574f5fb01a0c4f2ad08016d0e56a2 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Thu, 12 Sep 2019 12:26:46 -0700 Subject: [PATCH 24/39] Fix Windows build --- Modules/posixmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 0532df94b92b4c..87d180c72fff76 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12873,7 +12873,7 @@ DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW) ULONG reparse_tag; wchar_t *joined_path; - PyObject *DirEntryType = _posixstate(self)->DirEntryType; + PyObject *DirEntryType = _posixstate_global->DirEntryType; entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType); if (!entry) return NULL; From 925a41e9725fb2d131d052b16ad7854fa0e5dc11 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 13 Sep 2019 10:44:08 +0100 Subject: [PATCH 25/39] Use interned strings for constants in module state --- Modules/posixmodule.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 87d180c72fff76..6d08606a09d6a8 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -14659,14 +14659,18 @@ INITFUNC(void) if ((_posixstate(m)->billion = PyLong_FromLong(1000000000)) == NULL) return NULL; #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) - if ((_posixstate(m)->struct_rusage = PyUnicode_FromString("struct_rusage")) == NULL) + _posixstate(m)->struct_rusage = PyUnicode_InternFromString("struct_rusage"); + if (_posixstate(m)->struct_rusage == NULL) return NULL; #endif - if ((_posixstate(m)->st_mode = PyUnicode_FromString("st_mode")) == NULL) + _posixstate(m)->st_mode = PyUnicode_InternFromString("st_mode"); + if (_posixstate(m)->st_mode == NULL) return NULL; - if ((_posixstate(m)->fspath = PyUnicode_FromString("__fspath__")) == NULL) + _posixstate(m)->fspath = PyUnicode_InternFromString("__fspath__"); + if (_posixstate(m)->fspath == NULL) return NULL; - if ((_posixstate(m)->dunderget = PyUnicode_FromString("__get__")) == NULL) + _posixstate(m)->dunderget = PyUnicode_InternFromString("__get__"); + if (_posixstate(m)->dunderget == NULL) return NULL; /* suppress "function not used" warnings */ From ad7359b66e57cd509a338bafb9aa488d235bb36f Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 13 Sep 2019 11:11:49 +0100 Subject: [PATCH 26/39] Use descriptor directly, rather than look it up by name --- Modules/posixmodule.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 6d08606a09d6a8..ab7c1e05f072b0 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -836,7 +836,6 @@ typedef struct { #endif PyObject *st_mode; PyObject *fspath; - PyObject *dunderget; newfunc structseq_new; } _posixstate; @@ -963,7 +962,7 @@ fspath_lookup_special(PyObject *self) { PyTypeObject *path_type = Py_TYPE(self); func = _PyType_Lookup(path_type, _posixstate_global->fspath); if (func != NULL) { - getter = _PyType_Lookup(Py_TYPE(func), _posixstate_global->dunderget); + getter = Py_TYPE(func)->tp_descr_get; if (getter == NULL) { Py_INCREF(func); } else { @@ -2153,7 +2152,6 @@ _posix_clear(PyObject *module) #endif Py_CLEAR(_posixstate(module)->st_mode); Py_CLEAR(_posixstate(module)->fspath); - Py_CLEAR(_posixstate(module)->dunderget); return 0; } @@ -2180,7 +2178,6 @@ _posix_traverse(PyObject *module, visitproc visit, void *arg) #endif Py_VISIT(_posixstate(module)->st_mode); Py_VISIT(_posixstate(module)->fspath); - Py_VISIT(_posixstate(module)->dunderget); return 0; } @@ -14669,9 +14666,6 @@ INITFUNC(void) _posixstate(m)->fspath = PyUnicode_InternFromString("__fspath__"); if (_posixstate(m)->fspath == NULL) return NULL; - _posixstate(m)->dunderget = PyUnicode_InternFromString("__get__"); - if (_posixstate(m)->dunderget == NULL) - return NULL; /* suppress "function not used" warnings */ { From 5de545dad772680af53c93e5a8064ddb4edb0614 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 13 Sep 2019 11:18:48 +0100 Subject: [PATCH 27/39] Bring _Py_IDENTIFIER(__fspath__) back CPython doesn't yet have a good replacement for _Py_IDENTIFIER, but reimplementing _PyObject_LookupSpecial in each module that needs it is not the way to go. This will need to be changed after we figure out _Py_IDENTIFIER more systematically. --- Modules/posixmodule.c | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index ab7c1e05f072b0..53aecbec674951 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -217,6 +217,7 @@ corresponding Unix manual entries for more information on calls."); #endif /* _MSC_VER */ #endif /* ! __WATCOMC__ || __QNX__ */ +_Py_IDENTIFIER(__fspath__); /*[clinic input] # one of the few times we lie about this name! @@ -835,7 +836,6 @@ typedef struct { PyObject *struct_rusage; #endif PyObject *st_mode; - PyObject *fspath; newfunc structseq_new; } _posixstate; @@ -955,24 +955,6 @@ typedef struct { {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL} #endif -// _PyType_LookupSpecial with PyObject* rather than _Py_Identifier -static PyObject* -fspath_lookup_special(PyObject *self) { - PyObject *func, *getter; - PyTypeObject *path_type = Py_TYPE(self); - func = _PyType_Lookup(path_type, _posixstate_global->fspath); - if (func != NULL) { - getter = Py_TYPE(func)->tp_descr_get; - if (getter == NULL) { - Py_INCREF(func); - } else { - func = PyObject_CallFunctionObjArgs( - getter, func, self, (PyObject *)path_type, NULL); - } - } - return func; -} - static void path_cleanup(path_t *path) { @@ -1032,7 +1014,7 @@ path_converter(PyObject *o, void *p) /* Inline PyOS_FSPath() for better error messages. */ PyObject *func, *res; - func = fspath_lookup_special(o); + func = _PyObject_LookupSpecial(o, &PyId___fspath__); if (NULL == func) { goto error_format; } @@ -2151,7 +2133,6 @@ _posix_clear(PyObject *module) Py_CLEAR(_posixstate(module)->struct_rusage); #endif Py_CLEAR(_posixstate(module)->st_mode); - Py_CLEAR(_posixstate(module)->fspath); return 0; } @@ -2177,7 +2158,6 @@ _posix_traverse(PyObject *module, visitproc visit, void *arg) Py_VISIT(_posixstate(module)->struct_rusage); #endif Py_VISIT(_posixstate(module)->st_mode); - Py_VISIT(_posixstate(module)->fspath); return 0; } @@ -13395,7 +13375,7 @@ PyOS_FSPath(PyObject *path) return path; } - func = fspath_lookup_special(path); + func = _PyObject_LookupSpecial(path, &PyId___fspath__); if (NULL == func) { return PyErr_Format(PyExc_TypeError, "expected str, bytes or os.PathLike object, " @@ -14663,9 +14643,6 @@ INITFUNC(void) _posixstate(m)->st_mode = PyUnicode_InternFromString("st_mode"); if (_posixstate(m)->st_mode == NULL) return NULL; - _posixstate(m)->fspath = PyUnicode_InternFromString("__fspath__"); - if (_posixstate(m)->fspath == NULL) - return NULL; /* suppress "function not used" warnings */ { From 3ada29818a428fb373fba7156e5794c539295047 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 13 Sep 2019 11:46:55 +0100 Subject: [PATCH 28/39] Use the tp_free slot directly --- Modules/posixmodule.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 53aecbec674951..db9c3a2cd3b4b5 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12488,8 +12488,7 @@ DirEntry_dealloc(DirEntry *entry) Py_XDECREF(entry->path); Py_XDECREF(entry->stat); Py_XDECREF(entry->lstat); - freefunc entry_free = PyType_GetSlot(Py_TYPE(entry), Py_tp_free); - entry_free((PyObject *)entry); + tp->tp_free(entry); Py_DECREF(tp); } @@ -13213,8 +13212,7 @@ ScandirIterator_dealloc(ScandirIterator *iterator) if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0) return; - freefunc iterator_free = PyType_GetSlot(Py_TYPE(iterator), Py_tp_free); - iterator_free((PyObject *)iterator); + tp->tp_free((PyObject *)iterator); Py_DECREF(tp); } From 4c80b065976a44e43f0b32e71b0f7493ced6b223 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 13 Sep 2019 11:52:08 +0100 Subject: [PATCH 29/39] Remove duplicate function --- Modules/posixmodule.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index db9c3a2cd3b4b5..f75634840e2c2e 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12473,7 +12473,7 @@ typedef struct { } DirEntry; static PyObject * -DirEntry_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyErr_Format(PyExc_TypeError, "cannot create '%.100s' instances", _PyType_Name(type)); @@ -12789,7 +12789,7 @@ static PyMethodDef DirEntry_methods[] = { }; static PyType_Slot DirEntryType_slots[] = { - {Py_tp_new, DirEntry_new}, + {Py_tp_new, _disabled_new}, {Py_tp_dealloc, DirEntry_dealloc}, {Py_tp_repr, DirEntry_repr}, {Py_tp_methods, DirEntry_methods}, @@ -13197,14 +13197,6 @@ ScandirIterator_finalize(ScandirIterator *iterator) PyErr_Restore(error_type, error_value, error_traceback); } -static PyObject * -ScandirIterator_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyErr_Format(PyExc_TypeError, - "cannot create '%.100s' instances", _PyType_Name(type)); - return NULL; -} - static void ScandirIterator_dealloc(ScandirIterator *iterator) { @@ -13224,7 +13216,7 @@ static PyMethodDef ScandirIterator_methods[] = { }; static PyType_Slot ScandirIteratorType_slots[] = { - {Py_tp_new, ScandirIterator_new}, + {Py_tp_new, _disabled_new}, {Py_tp_dealloc, ScandirIterator_dealloc}, {Py_tp_finalize, ScandirIterator_finalize}, {Py_tp_iter, PyObject_SelfIter}, From 6e505ac8e73a40ff11369cda494114368c23d74e Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 13 Sep 2019 12:08:46 +0100 Subject: [PATCH 30/39] Use tp_new directly --- Modules/posixmodule.c | 66 ++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index f75634840e2c2e..9110d8be9191c6 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2077,12 +2077,16 @@ static PyStructSequence_Desc waitid_result_desc = { #endif static PyObject * -statresult_new(PyTypeObject *type, PyObject *args) +statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *sequence, *kwds; PyStructSequence *result; int i; + if (!_PyArg_NoKeywords("StatResult", kwargs)) { + return NULL; + } + /* Remove the cls object from the argument list */ sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); if (!sequence) { @@ -6249,24 +6253,20 @@ PyDoc_STRVAR(os_sched_param__doc__, " A scheduling parameter."); static PyObject * -os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) +os_sched_param(PyObject *module, PyObject *args, PyObject *kwargs) { static char* _keywords[] = {"sched_priority", NULL}; static const char * _format = "O:sched_param"; - PyObject *sequence, *sched_priority, *res; + PyObject *sched_priority, *res; - /* Remove the cls object from the argument list */ - sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); - if (!sequence) { - return NULL; - } - int result = PyArg_ParseTupleAndKeywords(sequence, kwargs, _format, _keywords, + int result = PyArg_ParseTupleAndKeywords(args, kwargs, _format, _keywords, &sched_priority); - Py_DECREF(sequence); if (!result) { return NULL; } - res = PyStructSequence_New((PyTypeObject *)type); + res = PyStructSequence_New( + (PyTypeObject*)_posixstate(module)->SchedParamType + ); if (!res) { return NULL; } @@ -6275,7 +6275,21 @@ os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) return res; } -PyDoc_VAR(os_sched_param__doc__); +static PyObject * +sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { + PyObject *module = PyState_FindModule(&posixmodule); + if (!module) { + return NULL; + } + /* Remove the cls object from the argument list */ + PyObject *sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + if (!sequence) { + return NULL; + } + PyObject *result = os_sched_param(module, args, kwargs); + Py_DECREF(sequence); + return result; +} static PyStructSequence_Field sched_param_fields[] = { {"sched_priority", "the scheduling priority"}, @@ -13579,16 +13593,6 @@ os__remove_dll_directory_impl(PyObject *module, PyObject *cookie) #endif -#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) -static PyMethodDef SchedParamType_dunder_new = { - "__new__", (PyCFunction)os_sched_param, METH_VARARGS | METH_KEYWORDS -}; -#endif - -static PyMethodDef StatResultType_dunder_new = { - "__new__", (PyCFunction)statresult_new, METH_VARARGS -}; - static PyMethodDef posix_methods[] = { OS_STAT_METHODDEF @@ -14442,7 +14446,7 @@ static const char * const have_functions[] = { PyMODINIT_FUNC INITFUNC(void) { - PyObject *m, *v, *dunder_new; + PyObject *m, *v; PyObject *list; const char * const *trace; @@ -14502,13 +14506,8 @@ INITFUNC(void) _posixstate(m)->StatResultType = StatResultType; /* Add a custom __new__ to the structsequence */ - _posixstate(m)->structseq_new = (newfunc)PyType_GetSlot((PyTypeObject *)StatResultType, Py_tp_new); - dunder_new = PyDescr_NewClassMethod((PyTypeObject *)StatResultType, &StatResultType_dunder_new); - if (dunder_new == NULL) { - return NULL; - } - PyObject_SetAttrString(StatResultType, "__new__", dunder_new); - Py_DECREF(dunder_new); + _posixstate(m)->structseq_new = ((PyTypeObject *)StatResultType)->tp_new; + ((PyTypeObject *)StatResultType)->tp_new = statresult_new; statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc); @@ -14538,12 +14537,7 @@ INITFUNC(void) PyModule_AddObject(m, "sched_param", SchedParamType); _posixstate(m)->SchedParamType = SchedParamType; /* Add a custom __new__ to the structsequence */ - dunder_new = PyDescr_NewClassMethod((PyTypeObject *)SchedParamType, &SchedParamType_dunder_new); - if (dunder_new == NULL) { - return NULL; - } - PyObject_SetAttrString((PyObject *)SchedParamType, "__new__", dunder_new); - Py_DECREF(dunder_new); + ((PyTypeObject *)SchedParamType)->tp_new = sched_param_new; #endif /* initialize TerminalSize_info */ From b9a49aa33fc722c36e9624b90f179c7577139dc6 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 13 Sep 2019 14:12:56 +0100 Subject: [PATCH 31/39] Don't call PyState_AddModule I'm proposing a PyState_AddModule doc update to make things clearer: https://github.com/python/cpython/pull/16101 --- Modules/posixmodule.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 9110d8be9191c6..67f5835351147b 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -14655,7 +14655,6 @@ INITFUNC(void) } PyModule_AddObject(m, "_have_functions", list); - PyState_AddModule(m, &posixmodule); return m; } From c1a6d030b199aba4fb7599ff8bc5191ffbdc7e37 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Mon, 16 Sep 2019 23:31:34 -0700 Subject: [PATCH 32/39] Add __new__ changes --- Modules/posixmodule.c | 65 ++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 67f5835351147b..fd3664c8072e07 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2077,16 +2077,12 @@ static PyStructSequence_Desc waitid_result_desc = { #endif static PyObject * -statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +statresult_new(PyTypeObject *type, PyObject *args) { PyObject *sequence, *kwds; PyStructSequence *result; int i; - if (!_PyArg_NoKeywords("StatResult", kwargs)) { - return NULL; - } - /* Remove the cls object from the argument list */ sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); if (!sequence) { @@ -6253,20 +6249,24 @@ PyDoc_STRVAR(os_sched_param__doc__, " A scheduling parameter."); static PyObject * -os_sched_param(PyObject *module, PyObject *args, PyObject *kwargs) +os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) { static char* _keywords[] = {"sched_priority", NULL}; static const char * _format = "O:sched_param"; - PyObject *sched_priority, *res; + PyObject *sequence, *sched_priority, *res; + /* Remove the cls object from the argument list */ + sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + if (!sequence) { + return NULL; + } int result = PyArg_ParseTupleAndKeywords(args, kwargs, _format, _keywords, &sched_priority); + Py_DECREF(sequence); if (!result) { return NULL; } - res = PyStructSequence_New( - (PyTypeObject*)_posixstate(module)->SchedParamType - ); + res = PyStructSequence_New((PyTypeObject *)type); if (!res) { return NULL; } @@ -6275,22 +6275,6 @@ os_sched_param(PyObject *module, PyObject *args, PyObject *kwargs) return res; } -static PyObject * -sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - PyObject *module = PyState_FindModule(&posixmodule); - if (!module) { - return NULL; - } - /* Remove the cls object from the argument list */ - PyObject *sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); - if (!sequence) { - return NULL; - } - PyObject *result = os_sched_param(module, args, kwargs); - Py_DECREF(sequence); - return result; -} - static PyStructSequence_Field sched_param_fields[] = { {"sched_priority", "the scheduling priority"}, {0} @@ -13593,6 +13577,16 @@ os__remove_dll_directory_impl(PyObject *module, PyObject *cookie) #endif +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) +static PyMethodDef SchedParamType_dunder_new = { + "__new__", (PyCFunction)os_sched_param, METH_VARARGS | METH_KEYWORDS +}; +#endif + +static PyMethodDef StatResultType_dunder_new = { + "__new__", (PyCFunction)statresult_new, METH_VARARGS +}; + static PyMethodDef posix_methods[] = { OS_STAT_METHODDEF @@ -14446,7 +14440,7 @@ static const char * const have_functions[] = { PyMODINIT_FUNC INITFUNC(void) { - PyObject *m, *v; + PyObject *m, *v, *dunder_new; PyObject *list; const char * const *trace; @@ -14504,10 +14498,14 @@ INITFUNC(void) Py_INCREF(StatResultType); PyModule_AddObject(m, "stat_result", StatResultType); _posixstate(m)->StatResultType = StatResultType; - /* Add a custom __new__ to the structsequence */ - _posixstate(m)->structseq_new = ((PyTypeObject *)StatResultType)->tp_new; - ((PyTypeObject *)StatResultType)->tp_new = statresult_new; + _posixstate(m)->structseq_new = (newfunc)PyType_GetSlot((PyTypeObject *)StatResultType, Py_tp_new); + dunder_new = PyDescr_NewClassMethod((PyTypeObject *)StatResultType, &StatResultType_dunder_new); + if (dunder_new == NULL) { + return NULL; + } + PyObject_SetAttrString(StatResultType, "__new__", dunder_new); + Py_DECREF(dunder_new); statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc); @@ -14537,7 +14535,12 @@ INITFUNC(void) PyModule_AddObject(m, "sched_param", SchedParamType); _posixstate(m)->SchedParamType = SchedParamType; /* Add a custom __new__ to the structsequence */ - ((PyTypeObject *)SchedParamType)->tp_new = sched_param_new; + dunder_new = PyDescr_NewClassMethod((PyTypeObject *)SchedParamType, &SchedParamType_dunder_new); + if (dunder_new == NULL) { + return NULL; + } + PyObject_SetAttrString((PyObject *)SchedParamType, "__new__", dunder_new); + Py_DECREF(dunder_new); #endif /* initialize TerminalSize_info */ From 4a6d4ec581394c0e8de208152d416e02df44d2f0 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Wed, 18 Sep 2019 00:01:09 -0700 Subject: [PATCH 33/39] Regenerate clinic --- Modules/clinic/posixmodule.c.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 68a06040766e1c..bd054e6dcb3160 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -8685,4 +8685,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ -/*[clinic end generated code: output=5edce0087b201e5f input=a9049054013a1b77]*/ \ No newline at end of file +/*[clinic end generated code: output=8b2437e5e733a2eb input=a9049054013a1b77]*/ From 138ffb6894caaf3b90c60a51b3cf099324478683 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Mon, 23 Sep 2019 11:10:08 -0700 Subject: [PATCH 34/39] Nits --- Modules/posixmodule.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index c75ae8561cc5b1..36e429aebe1461 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6260,7 +6260,7 @@ os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (!sequence) { return NULL; } - int result = PyArg_ParseTupleAndKeywords(args, kwargs, _format, _keywords, + int result = PyArg_ParseTupleAndKeywords(sequence, kwargs, _format, _keywords, &sched_priority); Py_DECREF(sequence); if (!result) { @@ -12493,7 +12493,8 @@ DirEntry_dealloc(DirEntry *entry) Py_XDECREF(entry->path); Py_XDECREF(entry->stat); Py_XDECREF(entry->lstat); - tp->tp_free(entry); + freefunc free_func = PyType_GetSlot(tp, Py_tp_free); + free_func(entry); Py_DECREF(tp); } @@ -13209,7 +13210,8 @@ ScandirIterator_dealloc(ScandirIterator *iterator) if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0) return; - tp->tp_free((PyObject *)iterator); + freefunc free_func = PyType_GetSlot(tp, Py_tp_free); + free_func(iterator); Py_DECREF(tp); } From 1b57f3a76b48a58514c7175f49857d05bf694288 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Sun, 3 Nov 2019 10:34:04 -0800 Subject: [PATCH 35/39] Revert tp_new changes --- Modules/clinic/posixmodule.c.h | 40 +++++++++++++++++- Modules/posixmodule.c | 75 +++++++++++----------------------- 2 files changed, 62 insertions(+), 53 deletions(-) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 2bc985cfc25ecc..561cbb0ca82ab3 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -2832,6 +2832,44 @@ os_sched_getscheduler(PyObject *module, PyObject *arg) #endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETSCHEDULER) */ +#if defined(HAVE_SCHED_H) && (defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)) + +PyDoc_STRVAR(os_sched_param__doc__, +"sched_param(sched_priority)\n" +"--\n" +"\n" +"Current has only one field: sched_priority\");\n" +"\n" +" sched_priority\n" +" A scheduling parameter."); + +static PyObject * +os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority); + +static PyObject * +os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sched_priority", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "sched_param", 0}; + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *sched_priority; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + sched_priority = fastargs[0]; + return_value = os_sched_param_impl(type, sched_priority); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SCHED_H) && (defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)) */ + #if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETSCHEDULER) PyDoc_STRVAR(os_sched_setscheduler__doc__, @@ -8693,4 +8731,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ -/*[clinic end generated code: output=b999b313f97b4875 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=fe7897441fed5402 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index a7d07a88478ee0..9375cf3d2484af 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2077,12 +2077,16 @@ static PyStructSequence_Desc waitid_result_desc = { #endif static PyObject * -statresult_new(PyTypeObject *type, PyObject *args) +statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *sequence, *kwds; PyStructSequence *result; int i; + if (!_PyArg_NoKeywords("StatResult", kwargs)) { + return NULL; + } + /* Remove the cls object from the argument list */ sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); if (!sequence) { @@ -6251,41 +6255,31 @@ os_sched_getscheduler_impl(PyObject *module, pid_t pid) #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) -PyDoc_STRVAR(os_sched_param__doc__, -"sched_param(sched_priority)\n" -"--\n" -"\n" -"\n" -" sched_priority\n" -" A scheduling parameter."); +/*[clinic input] +class os.sched_param "PyObject *" "SchedParamType" +@classmethod +os.sched_param.__new__ + sched_priority: object + A scheduling parameter. +Current has only one field: sched_priority"); +[clinic start generated code]*/ static PyObject * -os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) +os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) +/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/ { - static char* _keywords[] = {"sched_priority", NULL}; - static const char * _format = "O:sched_param"; - PyObject *sequence, *sched_priority, *res; + PyObject *res; - /* Remove the cls object from the argument list */ - sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); - if (!sequence) { - return NULL; - } - int result = PyArg_ParseTupleAndKeywords(sequence, kwargs, _format, _keywords, - &sched_priority); - Py_DECREF(sequence); - if (!result) { - return NULL; - } - res = PyStructSequence_New((PyTypeObject *)type); - if (!res) { + res = PyStructSequence_New(type); + if (!res) return NULL; - } Py_INCREF(sched_priority); PyStructSequence_SET_ITEM(res, 0, sched_priority); return res; } +PyDoc_VAR(os_sched_param__doc__); + static PyStructSequence_Field sched_param_fields[] = { {"sched_priority", "the scheduling priority"}, {0} @@ -13595,16 +13589,6 @@ os__remove_dll_directory_impl(PyObject *module, PyObject *cookie) #endif -#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) -static PyMethodDef SchedParamType_dunder_new = { - "__new__", (PyCFunction)os_sched_param, METH_VARARGS | METH_KEYWORDS -}; -#endif - -static PyMethodDef StatResultType_dunder_new = { - "__new__", (PyCFunction)statresult_new, METH_VARARGS -}; - static PyMethodDef posix_methods[] = { OS_STAT_METHODDEF @@ -14464,7 +14448,7 @@ static const char * const have_functions[] = { PyMODINIT_FUNC INITFUNC(void) { - PyObject *m, *v, *dunder_new; + PyObject *m, *v; PyObject *list; const char * const *trace; @@ -14522,14 +14506,7 @@ INITFUNC(void) Py_INCREF(StatResultType); PyModule_AddObject(m, "stat_result", StatResultType); _posixstate(m)->StatResultType = StatResultType; - /* Add a custom __new__ to the structsequence */ - _posixstate(m)->structseq_new = (newfunc)PyType_GetSlot((PyTypeObject *)StatResultType, Py_tp_new); - dunder_new = PyDescr_NewClassMethod((PyTypeObject *)StatResultType, &StatResultType_dunder_new); - if (dunder_new == NULL) { - return NULL; - } - PyObject_SetAttrString(StatResultType, "__new__", dunder_new); - Py_DECREF(dunder_new); + ((PyTypeObject *)StatResultType)->tp_new = statresult_new; statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc); @@ -14558,13 +14535,7 @@ INITFUNC(void) Py_INCREF(SchedParamType); PyModule_AddObject(m, "sched_param", SchedParamType); _posixstate(m)->SchedParamType = SchedParamType; - /* Add a custom __new__ to the structsequence */ - dunder_new = PyDescr_NewClassMethod((PyTypeObject *)SchedParamType, &SchedParamType_dunder_new); - if (dunder_new == NULL) { - return NULL; - } - PyObject_SetAttrString((PyObject *)SchedParamType, "__new__", dunder_new); - Py_DECREF(dunder_new); + ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param; #endif /* initialize TerminalSize_info */ From e7e96344cad1be1279d797d8d47acc7561772103 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Sun, 3 Nov 2019 10:47:46 -0800 Subject: [PATCH 36/39] Rerun argument clinit --- Modules/posixmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 9375cf3d2484af..7e0b4d558a4908 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6266,7 +6266,7 @@ Current has only one field: sched_priority"); static PyObject * os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) -/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/ +/*[clinic end generated code: output=48f4067d60f48c13 input=723cdcfa7788714f]*/ { PyObject *res; From 3bf99bf1c388498df0cbee3dbb0a140cba497dd9 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Sun, 3 Nov 2019 11:12:24 -0800 Subject: [PATCH 37/39] More fixes --- Modules/posixmodule.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 7e0b4d558a4908..2bb091cde600d2 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -836,7 +836,6 @@ typedef struct { PyObject *struct_rusage; #endif PyObject *st_mode; - newfunc structseq_new; } _posixstate; static struct PyModuleDef posixmodule; @@ -2075,31 +2074,15 @@ static PyStructSequence_Desc waitid_result_desc = { 5 }; #endif +static newfunc structseq_new; static PyObject * -statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *sequence, *kwds; PyStructSequence *result; int i; - if (!_PyArg_NoKeywords("StatResult", kwargs)) { - return NULL; - } - - /* Remove the cls object from the argument list */ - sequence = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); - if (!sequence) { - return NULL; - } - kwds = PyDict_New(); - if (!kwds) { - Py_DECREF(sequence); - return NULL; - } - result = (PyStructSequence*)_posixstate_global->structseq_new(type, sequence, kwds); - Py_DECREF(sequence); - Py_DECREF(kwds); + result = (PyStructSequence*)structseq_new(type, args, kwds); if (!result) return NULL; /* If we have been initialized from a tuple, @@ -14506,6 +14489,7 @@ INITFUNC(void) Py_INCREF(StatResultType); PyModule_AddObject(m, "stat_result", StatResultType); _posixstate(m)->StatResultType = StatResultType; + structseq_new = ((PyTypeObject *)StatResultType)->tp_new; ((PyTypeObject *)StatResultType)->tp_new = statresult_new; statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ From afb249c4ba9dbc1568c76fc4e3bfa3aea68de33f Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 5 Nov 2019 13:50:54 +0100 Subject: [PATCH 38/39] Re-add newlines and fix docstring for os.sched_param.__new__ --- Modules/clinic/posixmodule.c.h | 4 ++-- Modules/posixmodule.c | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 561cbb0ca82ab3..3dada674fbab0d 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -2838,7 +2838,7 @@ PyDoc_STRVAR(os_sched_param__doc__, "sched_param(sched_priority)\n" "--\n" "\n" -"Current has only one field: sched_priority\");\n" +"Currently has only one field: sched_priority\n" "\n" " sched_priority\n" " A scheduling parameter."); @@ -8731,4 +8731,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ -/*[clinic end generated code: output=fe7897441fed5402 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c6e67d475eef00c4 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 2bb091cde600d2..b01c291de78666 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6240,16 +6240,19 @@ os_sched_getscheduler_impl(PyObject *module, pid_t pid) #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) /*[clinic input] class os.sched_param "PyObject *" "SchedParamType" + @classmethod os.sched_param.__new__ + sched_priority: object A scheduling parameter. -Current has only one field: sched_priority"); + +Currently has only one field: sched_priority [clinic start generated code]*/ static PyObject * os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) -/*[clinic end generated code: output=48f4067d60f48c13 input=723cdcfa7788714f]*/ +/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/ { PyObject *res; From 187b5d4d7c0a93d7cc944d87bbebaff8a37b350f Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 5 Nov 2019 14:02:43 +0100 Subject: [PATCH 39/39] Code style nitpicks See https://www.python.org/dev/peps/pep-0007/ --- Modules/posixmodule.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index b01c291de78666..6d837c6552f490 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -14536,13 +14536,15 @@ INITFUNC(void) /* initialize scandir types */ PyObject *ScandirIteratorType = PyType_FromSpec(&ScandirIteratorType_spec); - if (ScandirIteratorType == NULL) + if (ScandirIteratorType == NULL) { return NULL; + } _posixstate(m)->ScandirIteratorType = ScandirIteratorType; PyObject *DirEntryType = PyType_FromSpec(&DirEntryType_spec); - if (DirEntryType == NULL) + if (DirEntryType == NULL) { return NULL; + } Py_INCREF(DirEntryType); PyModule_AddObject(m, "DirEntry", DirEntryType); _posixstate(m)->DirEntryType = DirEntryType;