From e9d395122929962fa9b83498609674ab2cda0f19 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 25 Sep 2020 14:08:50 -0400 Subject: [PATCH 1/6] Fix logging error message (GH-22410) Same changes as #22276 squashed to a single commit. Just hoping to get Travis to cooperate by opening a new PR... Automerge-Triggered-By: @vsajip --- Lib/logging/__init__.py | 3 ++- Lib/test/test_logging.py | 33 ++++++++++++++++++++------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 94361ca75f4f31..d8a88db378436b 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -194,7 +194,8 @@ def _checkLevel(level): raise ValueError("Unknown level: %r" % level) rv = _nameToLevel[level] else: - raise TypeError("Level not an integer or a valid string: %r" % level) + raise TypeError("Level not an integer or a valid string: %r" + % (level,)) return rv #--------------------------------------------------------------------------- diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index d23fbfb4fe281b..4cd8c7e25daa93 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -3720,7 +3720,15 @@ def tzname(self, dt): utc = UTC() -class FormatterTest(unittest.TestCase): +class AssertErrorMessage: + + def assert_error_message(self, exception, message, *args, **kwargs): + try: + self.assertRaises((), *args, **kwargs) + except exception as e: + self.assertEqual(message, str(e)) + +class FormatterTest(unittest.TestCase, AssertErrorMessage): def setUp(self): self.common = { 'name': 'formatter.test', @@ -3744,12 +3752,6 @@ def get_record(self, name=None): result.update(self.variants[name]) return logging.makeLogRecord(result) - def assert_error_message(self, exception, message, *args, **kwargs): - try: - self.assertRaises(exception, *args, **kwargs) - except exception as e: - self.assertEqual(message, e.message) - def test_percent(self): # Test %-formatting r = self.get_record() @@ -3868,7 +3870,7 @@ def test_format_validate(self): # Testing failure for '-' in field name self.assert_error_message( ValueError, - "invalid field name/expression: 'name-thing'", + "invalid format: invalid field name/expression: 'name-thing'", logging.Formatter, "{name-thing}", style="{" ) # Testing failure for style mismatch @@ -3891,7 +3893,7 @@ def test_format_validate(self): # Testing failure for invalid spec self.assert_error_message( ValueError, - "bad specifier: '.2ff'", + "invalid format: bad specifier: '.2ff'", logging.Formatter, '{process:.2ff}', style='{' ) self.assertRaises(ValueError, logging.Formatter, '{process:.2Z}', style='{') @@ -3901,12 +3903,12 @@ def test_format_validate(self): # Testing failure for mismatch braces self.assert_error_message( ValueError, - "invalid format: unmatched '{' in format spec", + "invalid format: expected '}' before end of string", logging.Formatter, '{process', style='{' ) self.assert_error_message( ValueError, - "invalid format: unmatched '{' in format spec", + "invalid format: Single '}' encountered in format string", logging.Formatter, 'process}', style='{' ) self.assertRaises(ValueError, logging.Formatter, '{{foo!r:4.2}', style='{') @@ -4867,7 +4869,7 @@ def process(self, msg, kwargs): self.assertIs(self.logger.manager, orig_manager) -class LoggerTest(BaseTest): +class LoggerTest(BaseTest, AssertErrorMessage): def setUp(self): super(LoggerTest, self).setUp() @@ -4879,7 +4881,12 @@ def setUp(self): self.addCleanup(logging.shutdown) def test_set_invalid_level(self): - self.assertRaises(TypeError, self.logger.setLevel, object()) + self.assert_error_message( + TypeError, 'Level not an integer or a valid string: None', + self.logger.setLevel, None) + self.assert_error_message( + TypeError, 'Level not an integer or a valid string: (0, 0)', + self.logger.setLevel, (0, 0)) def test_exception(self): msg = 'testing exception: %r' From d6a7cf1a9d852feed8d723ebb06ae3655779845f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 26 Sep 2020 12:48:41 +0200 Subject: [PATCH 2/6] bpo-41428: Fix compiler warning in unionobject.c (GH-22416) Use Py_ssize_t type rather than int, to store lengths in unionobject.c. Fix the warning: Objects\unionobject.c(205,1): warning C4244: 'initializing': conversion from 'Py_ssize_t' to 'int', possible loss of data --- Objects/unionobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Objects/unionobject.c b/Objects/unionobject.c index e055a55e91715c..8cfb2a664753f8 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -202,8 +202,8 @@ flatten_args(PyObject* args) PyTypeObject* arg_type = Py_TYPE(arg); if (arg_type == &_Py_UnionType) { PyObject* nested_args = ((unionobject*)arg)->args; - int nested_arg_length = PyTuple_GET_SIZE(nested_args); - for (int j = 0; j < nested_arg_length; j++) { + Py_ssize_t nested_arg_length = PyTuple_GET_SIZE(nested_args); + for (Py_ssize_t j = 0; j < nested_arg_length; j++) { PyObject* nested_arg = PyTuple_GET_ITEM(nested_args, j); Py_INCREF(nested_arg); PyTuple_SET_ITEM(flattened_args, pos, nested_arg); @@ -231,7 +231,7 @@ dedup_and_flatten_args(PyObject* args) return NULL; } // Add unique elements to an array. - int added_items = 0; + Py_ssize_t added_items = 0; for (Py_ssize_t i = 0; i < arg_length; i++) { int is_duplicate = 0; PyObject* i_element = PyTuple_GET_ITEM(args, i); From b78823c0792c5854bce2b13d602bdddf3feb2ad8 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sat, 26 Sep 2020 19:56:26 +0900 Subject: [PATCH 3/6] bpo-1635741: Port _bisect module to multi-phase init (GH-22415) --- .../2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst | 1 + Modules/_bisectmodule.c | 14 +++++--------- 2 files changed, 6 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst b/Misc/NEWS.d/next/Core and Builtins/2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst new file mode 100644 index 00000000000000..252dab35a1368a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-09-26-14-43-30.bpo-1635741.aJS9B3.rst @@ -0,0 +1 @@ +Port the :mod:`_bisect` module to the multi-phase initialization API (:pep:`489`). diff --git a/Modules/_bisectmodule.c b/Modules/_bisectmodule.c index 82d800d9a8790f..277e9755f27211 100644 --- a/Modules/_bisectmodule.c +++ b/Modules/_bisectmodule.c @@ -237,18 +237,14 @@ common approach.\n"); static struct PyModuleDef _bisectmodule = { PyModuleDef_HEAD_INIT, - "_bisect", - module_doc, - -1, - bisect_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "_bisect", + .m_doc = module_doc, + .m_methods = bisect_methods, + .m_size = 0 }; PyMODINIT_FUNC PyInit__bisect(void) { - return PyModule_Create(&_bisectmodule); + return PyModuleDef_Init(&_bisectmodule); } From 510929696aa5738d1b24d6a28af4147fbdf832a9 Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Sat, 26 Sep 2020 21:47:25 -0300 Subject: [PATCH 4/6] Revert "Fix all Python Cookbook links (#22205)" (GH-22424) This commit reverts commit ac0333e1e117b7f61ed7ef1dbcdb6e515ada603b as the original links are working again and they provide extended features such as comments and alternative versions. --- Doc/faq/programming.rst | 2 +- Doc/howto/urllib2.rst | 2 +- Doc/library/bisect.rst | 2 +- Doc/library/collections.abc.rst | 2 +- Doc/library/collections.rst | 4 ++-- Doc/library/difflib.rst | 2 +- Doc/library/math.rst | 2 +- Doc/library/random.rst | 2 +- Doc/library/shelve.rst | 2 +- Doc/library/stdtypes.rst | 2 +- Doc/library/sys.rst | 2 +- Doc/tutorial/whatnow.rst | 2 +- Doc/whatsnew/3.2.rst | 4 ++-- Lib/collections/__init__.py | 2 +- Lib/heapq.py | 2 +- Lib/test/test_math.py | 2 +- Tools/peg_generator/pegen/sccutils.py | 4 ++-- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index fd0adc378bfa6f..4f4ea8b18176c2 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1141,7 +1141,7 @@ How do you remove duplicates from a list? See the Python Cookbook for a long discussion of many ways to do this: - https://github.com/ActiveState/code/tree/master/recipes/Python/52560_Remove_duplicates/recipe-52560.py + https://code.activestate.com/recipes/52560/ If you don't mind reordering the list, sort it and then scan from the end of the list, deleting duplicates as you go:: diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index 38623371fbabff..046a88af62f0b3 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -601,5 +601,5 @@ This document was reviewed and revised by John Lee. scripts with a localhost server, I have to prevent urllib from using the proxy. .. [#] urllib opener for SSL proxy (CONNECT method): `ASPN Cookbook Recipe - `_. + `_. diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index 6666d55abe2e50..6bf7814b257f4a 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -60,7 +60,7 @@ The following functions are provided: .. seealso:: `SortedCollection recipe - `_ that uses + `_ that uses bisect to build a full-featured collection class with straight-forward search methods and support for a key-function. The keys are precomputed to save unnecessary calls to the key function during searches. diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst index a6038098675da2..db0e25bb0772eb 100644 --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -308,7 +308,7 @@ Notes on using :class:`Set` and :class:`MutableSet` as a mixin: .. seealso:: - * `OrderedSet recipe `_ for an + * `OrderedSet recipe `_ for an example built on :class:`MutableSet`. * For more about ABCs, see the :mod:`abc` module and :pep:`3119`. diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index a7d01b3f397a70..f538da5e1c9faa 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -135,12 +135,12 @@ The class can be used to simulate nested scopes and is useful in templating. :attr:`~collections.ChainMap.parents` property. * The `Nested Contexts recipe - `_ has options to control + `_ has options to control whether writes and other mutations apply only to the first mapping or to any mapping in the chain. * A `greatly simplified read-only version of Chainmap - `_. + `_. :class:`ChainMap` Examples and Recipes diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index 009b7976dff15f..aa08988c8b36f7 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -633,7 +633,7 @@ If you want to know how to change the first sequence into the second, use work. * `Simple version control recipe - `_ for a small application + `_ for a small application built with :class:`SequenceMatcher`. diff --git a/Doc/library/math.rst b/Doc/library/math.rst index f152c45a87aa37..bbf64643ff59fc 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -123,7 +123,7 @@ Number-theoretic and representation functions For further discussion and two alternative approaches, see the `ASPN cookbook recipes for accurate floating point summation - `_\. + `_\. .. function:: gcd(*integers) diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 4e97b1dbad85c1..0cdf0a6ac4a477 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -57,7 +57,7 @@ from sources provided by the operating system. `Complementary-Multiply-with-Carry recipe - `_ for a compatible alternative + `_ for a compatible alternative random number generator with a long period and comparatively simple update operations. diff --git a/Doc/library/shelve.rst b/Doc/library/shelve.rst index a94255bbf698e9..f08c58179a2f9f 100644 --- a/Doc/library/shelve.rst +++ b/Doc/library/shelve.rst @@ -75,7 +75,7 @@ Two additional methods are supported: .. seealso:: - `Persistent dictionary recipe `_ + `Persistent dictionary recipe `_ with widely supported storage formats and having the speed of native dictionaries. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 2eee22c79af769..0ffe7b7526fa76 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1404,7 +1404,7 @@ objects that compare equal might have different :attr:`~range.start`, .. seealso:: - * The `linspace recipe `_ + * The `linspace recipe `_ shows how to implement a lazy version of range suitable for floating point applications. diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index aa417ede402286..d201d7061f9801 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -679,7 +679,7 @@ always available. additional garbage collector overhead if the object is managed by the garbage collector. - See `recursive sizeof recipe `_ + See `recursive sizeof recipe `_ for an example of using :func:`getsizeof` recursively to find the size of containers and all their contents. diff --git a/Doc/tutorial/whatnow.rst b/Doc/tutorial/whatnow.rst index 38ce9f0a900c28..3208201312b871 100644 --- a/Doc/tutorial/whatnow.rst +++ b/Doc/tutorial/whatnow.rst @@ -43,7 +43,7 @@ More Python resources: for download. Once you begin releasing code, you can register it here so that others can find it. -* https://github.com/ActiveState/code/tree/master/recipes/Python: The Python Cookbook is a +* https://code.activestate.com/recipes/langs/python/: The Python Cookbook is a sizable collection of code examples, larger modules, and useful scripts. Particularly notable contributions are collected in a book also titled Python Cookbook (O'Reilly & Associates, ISBN 0-596-00797-3.) diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index 37bae34ce74adc..06bee9966c0be2 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -781,8 +781,8 @@ functools (Contributed by Raymond Hettinger and incorporating design ideas from Jim Baker, Miki Tebeka, and Nick Coghlan; see `recipe 498245 - `_\, `recipe 577479 - `_\, :issue:`10586`, and + `_\, `recipe 577479 + `_\, :issue:`10586`, and :issue:`10593`.) * The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index f4da9d0cefd6bf..5d75501645fc4a 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -574,7 +574,7 @@ class Counter(dict): # http://en.wikipedia.org/wiki/Multiset # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm - # https://github.com/ActiveState/code/tree/master/recipes/Python/259174_bag_collection_class/recipe-259174.py + # http://code.activestate.com/recipes/259174/ # Knuth, TAOCP Vol. II section 4.6.3 def __init__(self, iterable=None, /, **kwds): diff --git a/Lib/heapq.py b/Lib/heapq.py index 5895562db4142b..fabefd87f8bf8c 100644 --- a/Lib/heapq.py +++ b/Lib/heapq.py @@ -456,7 +456,7 @@ def merge(*iterables, key=None, reverse=False): # 2) Made multiple passes over the data. # 3) Made more comparisons in common cases (small k, large n, semi-random input). # See the more detailed comparison of approach at: -# https://github.com/ActiveState/code/tree/master/recipes/Python/577573_Compare_algorithms/recipe-577573.py +# http://code.activestate.com/recipes/577573-compare-algorithms-for-heapqsmallest def nsmallest(n, iterable, key=None): """Find the n smallest elements in a dataset. diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 2abe5b028b355d..a6f6483f55d897 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -611,7 +611,7 @@ def testFsum(self): def msum(iterable): """Full precision summation. Compute sum(iterable) without any intermediate accumulation of error. Based on the 'lsum' function - at https://github.com/ActiveState/code/tree/master/recipes/Python/393090_Binary_floating_point_summatiaccurate_full/recipe-393090.py + at http://code.activestate.com/recipes/393090/ """ tmant, texp = 0, 0 diff --git a/Tools/peg_generator/pegen/sccutils.py b/Tools/peg_generator/pegen/sccutils.py index 0c295196607ec8..1f0586bb2f7d6d 100644 --- a/Tools/peg_generator/pegen/sccutils.py +++ b/Tools/peg_generator/pegen/sccutils.py @@ -18,7 +18,7 @@ def strongly_connected_components( exactly once; vertices not part of a SCC are returned as singleton sets. - From https://github.com/ActiveState/code/tree/master/recipes/Python/578507_Strongly_connected_components_directed/recipe-578507.py. + From http://code.activestate.com/recipes/578507/. """ identified: Set[str] = set() stack: List[str] = [] @@ -81,7 +81,7 @@ def topsort( {B, C} {A} - From https://github.com/ActiveState/code/tree/master/recipes/Python/577413_Topological_Sort/recipe-577413.py. + From http://code.activestate.com/recipes/577413/. """ # TODO: Use a faster algorithm? for k, v in data.items(): From 23e8b569f4e525f204197acf407aa7e0f1f8db09 Mon Sep 17 00:00:00 2001 From: Emmanuel Arias Date: Sun, 27 Sep 2020 00:43:18 -0300 Subject: [PATCH 5/6] bpo-41858: Clarify line in optparse doc (GH-22407) The existing line is easily read as being incomplete. --- Doc/library/optparse.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index c1a18e01474319..b1094198f4c844 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -55,7 +55,7 @@ equivalent to the above example:: -q -foutfile -qfoutfile -Additionally, users can run one of :: +Additionally, users can run one of the following :: -h --help From 237565711a03c66ba75c94e760df4050ecabfa42 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Sun, 27 Sep 2020 14:14:50 +0200 Subject: [PATCH 6/6] bpo-41861: Convert _sqlite3 cache and node static types to heap types (GH-22417) --- Modules/_sqlite/cache.c | 137 +++++++++++------------------------ Modules/_sqlite/cache.h | 6 +- Modules/_sqlite/connection.c | 2 +- Modules/_sqlite/module.c | 2 +- 4 files changed, 48 insertions(+), 99 deletions(-) diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 758fc022f78108..c417ce872d368d 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -29,7 +29,7 @@ pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data) { pysqlite_Node* node; - node = (pysqlite_Node*) (pysqlite_NodeType.tp_alloc(&pysqlite_NodeType, 0)); + node = (pysqlite_Node*) (pysqlite_NodeType->tp_alloc(pysqlite_NodeType, 0)); if (!node) { return NULL; } @@ -48,10 +48,13 @@ pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data) void pysqlite_node_dealloc(pysqlite_Node* self) { + PyTypeObject *tp = Py_TYPE(self); + Py_DECREF(self->key); Py_DECREF(self->data); - Py_TYPE(self)->tp_free((PyObject*)self); + tp->tp_free(self); + Py_DECREF(tp); } int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) @@ -88,6 +91,7 @@ int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) void pysqlite_cache_dealloc(pysqlite_Cache* self) { + PyTypeObject *tp = Py_TYPE(self); pysqlite_Node* node; pysqlite_Node* delete_node; @@ -109,7 +113,8 @@ void pysqlite_cache_dealloc(pysqlite_Cache* self) } Py_DECREF(self->mapping); - Py_TYPE(self)->tp_free((PyObject*)self); + tp->tp_free(self); + Py_DECREF(tp); } PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* key) @@ -253,6 +258,20 @@ PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args) Py_RETURN_NONE; } +static PyType_Slot pysqlite_NodeType_slots[] = { + {Py_tp_dealloc, pysqlite_node_dealloc}, + {Py_tp_new, PyType_GenericNew}, + {0, NULL}, +}; + +static PyType_Spec pysqlite_NodeType_spec = { + .name = MODULE_NAME ".Node", + .basicsize = sizeof(pysqlite_Node), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, + .slots = pysqlite_NodeType_slots, +}; +PyTypeObject *pysqlite_NodeType = NULL; + static PyMethodDef cache_methods[] = { {"get", (PyCFunction)pysqlite_cache_get, METH_O, PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")}, @@ -261,102 +280,32 @@ static PyMethodDef cache_methods[] = { {NULL, NULL} }; -PyTypeObject pysqlite_NodeType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME "Node", /* tp_name */ - sizeof(pysqlite_Node), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_node_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|Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Slot pysqlite_CacheType_slots[] = { + {Py_tp_dealloc, pysqlite_cache_dealloc}, + {Py_tp_methods, cache_methods}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_init, pysqlite_cache_init}, + {0, NULL}, }; -PyTypeObject pysqlite_CacheType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Cache", /* tp_name */ - sizeof(pysqlite_Cache), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_cache_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|Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - cache_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 */ - (initproc)pysqlite_cache_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Spec pysqlite_CacheType_spec = { + .name = MODULE_NAME ".Cache", + .basicsize = sizeof(pysqlite_Cache), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, + .slots = pysqlite_CacheType_slots, }; +PyTypeObject *pysqlite_CacheType = NULL; -extern int pysqlite_cache_setup_types(void) +extern int pysqlite_cache_setup_types(PyObject *mod) { - int rc; - - pysqlite_NodeType.tp_new = PyType_GenericNew; - pysqlite_CacheType.tp_new = PyType_GenericNew; - - rc = PyType_Ready(&pysqlite_NodeType); - if (rc < 0) { - return rc; + pysqlite_NodeType = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &pysqlite_NodeType_spec, NULL); + if (pysqlite_NodeType == NULL) { + return -1; } - rc = PyType_Ready(&pysqlite_CacheType); - return rc; + pysqlite_CacheType = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &pysqlite_CacheType_spec, NULL); + if (pysqlite_CacheType == NULL) { + return -1; + } + return 0; } diff --git a/Modules/_sqlite/cache.h b/Modules/_sqlite/cache.h index 529010967c4f3a..0afdf7f09b65c7 100644 --- a/Modules/_sqlite/cache.h +++ b/Modules/_sqlite/cache.h @@ -59,8 +59,8 @@ typedef struct int decref_factory; } pysqlite_Cache; -extern PyTypeObject pysqlite_NodeType; -extern PyTypeObject pysqlite_CacheType; +extern PyTypeObject *pysqlite_NodeType; +extern PyTypeObject *pysqlite_CacheType; int pysqlite_node_init(pysqlite_Node* self, PyObject* args, PyObject* kwargs); void pysqlite_node_dealloc(pysqlite_Node* self); @@ -69,6 +69,6 @@ int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs); void pysqlite_cache_dealloc(pysqlite_Cache* self); PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args); -int pysqlite_cache_setup_types(void); +int pysqlite_cache_setup_types(PyObject *module); #endif diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 81fc1335371a6f..121850ae7e1f32 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -133,7 +133,7 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject } Py_DECREF(isolation_level); - self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "Oi", self, cached_statements); + self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)pysqlite_CacheType, "Oi", self, cached_statements); if (PyErr_Occurred()) { return -1; } diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 82f58eb2480261..625d065a317bab 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -355,7 +355,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void) (pysqlite_row_setup_types() < 0) || (pysqlite_cursor_setup_types() < 0) || (pysqlite_connection_setup_types() < 0) || - (pysqlite_cache_setup_types() < 0) || + (pysqlite_cache_setup_types(module) < 0) || (pysqlite_statement_setup_types() < 0) || (pysqlite_prepare_protocol_setup_types() < 0) ) {