From 7211eb1f879b76b453b780e33f215a2cd4773ac4 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 21 May 2024 23:08:58 -0400 Subject: [PATCH 1/5] gh-117398: Add multiphase support to _datetime --- Modules/_datetimemodule.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 9a66f0358179b5..653931d569c451 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -6992,30 +6992,26 @@ _datetime_exec(PyObject *module) } #undef DATETIME_ADD_MACRO -static struct PyModuleDef datetimemodule = { +static PyModuleDef_Slot module_slots[] = { + {Py_mod_exec, _datetime_exec}, + {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED}, + {Py_mod_gil, Py_MOD_GIL_NOT_USED}, + {0, NULL}, +}; + +static PyModuleDef datetimemodule = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "_datetime", .m_doc = "Fast implementation of the datetime type.", - .m_size = -1, + .m_size = 0, .m_methods = module_methods, + .m_slots = module_slots, }; PyMODINIT_FUNC PyInit__datetime(void) { - PyObject *mod = PyModule_Create(&datetimemodule); - if (mod == NULL) - return NULL; -#ifdef Py_GIL_DISABLED - PyUnstable_Module_SetGIL(mod, Py_MOD_GIL_NOT_USED); -#endif - - if (_datetime_exec(mod) < 0) { - Py_DECREF(mod); - return NULL; - } - - return mod; + return PyModuleDef_Init(&datetimemodule); } /* --------------------------------------------------------------------------- From 863ecd71d302896cdb964d4ae2e6b117c2a90eae Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 22 May 2024 10:02:13 -0400 Subject: [PATCH 2/5] Kinda fix the C API tests --- Lib/test/datetimetester.py | 6 +++++- Modules/_testcapi/datetime.c | 34 +++++++++++++++------------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index b3838d5b406e94..5806ff7f0dcaee 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -6384,6 +6384,7 @@ class IranTest(ZoneInfoTest): @unittest.skipIf(_testcapi is None, 'need _testcapi module') class CapiTest(unittest.TestCase): + def setUp(self): # Since the C API is not present in the _Pure tests, skip all tests if self.__class__.__name__.endswith('Pure'): @@ -6391,7 +6392,10 @@ def setUp(self): # This *must* be called, and it must be called first, so until either # restriction is loosened, we'll call it as part of test setup - _testcapi.test_datetime_capi() + _testcapi.setup_capi() + + def tearDown(self): + _testcapi.teardown_capi() def test_utc_capi(self): for use_macro in (True, False): diff --git a/Modules/_testcapi/datetime.c b/Modules/_testcapi/datetime.c index b1796039f0d83a..325a4a971a85a0 100644 --- a/Modules/_testcapi/datetime.c +++ b/Modules/_testcapi/datetime.c @@ -6,26 +6,21 @@ static int test_run_counter = 0; static PyObject * -test_datetime_capi(PyObject *self, PyObject *args) +setup_capi(PyObject *self, PyObject *args) { - if (PyDateTimeAPI) { - if (test_run_counter) { - /* Probably regrtest.py -R */ - Py_RETURN_NONE; - } - else { - PyErr_SetString(PyExc_AssertionError, - "PyDateTime_CAPI somehow initialized"); - return NULL; - } - } - test_run_counter++; - PyDateTime_IMPORT; - - if (PyDateTimeAPI) { - Py_RETURN_NONE; + if (!test_run_counter++) { + PyDateTime_IMPORT; } - return NULL; + assert(PyDateTimeAPI); + Py_RETURN_NONE; +} + +static PyObject * +teardown_capi(PyObject *self, PyObject *args) +{ + test_run_counter--; + assert(test_run_counter >= 0); + Py_RETURN_NONE; } /* Functions exposing the C API type checking for testing */ @@ -467,7 +462,8 @@ static PyMethodDef test_methods[] = { {"get_timezone_utc_capi", get_timezone_utc_capi, METH_VARARGS}, {"get_timezones_offset_zero", get_timezones_offset_zero, METH_NOARGS}, {"make_timezones_capi", make_timezones_capi, METH_NOARGS}, - {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, + {"setup_capi", setup_capi, METH_NOARGS}, + {"teardown_capi", teardown_capi, METH_NOARGS}, {NULL}, }; From 8de63177e7a503cbaa44c328707d938d2ae690f3 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 22 May 2024 11:27:57 -0400 Subject: [PATCH 3/5] Revert "Kinda fix the C API tests" This reverts commit 863ecd71d302896cdb964d4ae2e6b117c2a90eae. --- Lib/test/datetimetester.py | 6 +----- Modules/_testcapi/datetime.c | 34 +++++++++++++++++++--------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 5806ff7f0dcaee..b3838d5b406e94 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -6384,7 +6384,6 @@ class IranTest(ZoneInfoTest): @unittest.skipIf(_testcapi is None, 'need _testcapi module') class CapiTest(unittest.TestCase): - def setUp(self): # Since the C API is not present in the _Pure tests, skip all tests if self.__class__.__name__.endswith('Pure'): @@ -6392,10 +6391,7 @@ def setUp(self): # This *must* be called, and it must be called first, so until either # restriction is loosened, we'll call it as part of test setup - _testcapi.setup_capi() - - def tearDown(self): - _testcapi.teardown_capi() + _testcapi.test_datetime_capi() def test_utc_capi(self): for use_macro in (True, False): diff --git a/Modules/_testcapi/datetime.c b/Modules/_testcapi/datetime.c index 325a4a971a85a0..b1796039f0d83a 100644 --- a/Modules/_testcapi/datetime.c +++ b/Modules/_testcapi/datetime.c @@ -6,21 +6,26 @@ static int test_run_counter = 0; static PyObject * -setup_capi(PyObject *self, PyObject *args) +test_datetime_capi(PyObject *self, PyObject *args) { - if (!test_run_counter++) { - PyDateTime_IMPORT; + if (PyDateTimeAPI) { + if (test_run_counter) { + /* Probably regrtest.py -R */ + Py_RETURN_NONE; + } + else { + PyErr_SetString(PyExc_AssertionError, + "PyDateTime_CAPI somehow initialized"); + return NULL; + } + } + test_run_counter++; + PyDateTime_IMPORT; + + if (PyDateTimeAPI) { + Py_RETURN_NONE; } - assert(PyDateTimeAPI); - Py_RETURN_NONE; -} - -static PyObject * -teardown_capi(PyObject *self, PyObject *args) -{ - test_run_counter--; - assert(test_run_counter >= 0); - Py_RETURN_NONE; + return NULL; } /* Functions exposing the C API type checking for testing */ @@ -462,8 +467,7 @@ static PyMethodDef test_methods[] = { {"get_timezone_utc_capi", get_timezone_utc_capi, METH_VARARGS}, {"get_timezones_offset_zero", get_timezones_offset_zero, METH_NOARGS}, {"make_timezones_capi", make_timezones_capi, METH_NOARGS}, - {"setup_capi", setup_capi, METH_NOARGS}, - {"teardown_capi", teardown_capi, METH_NOARGS}, + {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, {NULL}, }; From 0c091eb0abb10b3d0734c67a9395e879197af83a Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 22 May 2024 11:31:22 -0400 Subject: [PATCH 4/5] Skip encapsulated C API tests on reruns --- Lib/test/datetimetester.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index b3838d5b406e94..ddadef154bd289 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -23,6 +23,7 @@ from test import support from test.support import is_resource_enabled, ALWAYS_EQ, LARGEST, SMALLEST from test.support import warnings_helper +from test.test_import import no_rerun import datetime as datetime_module from datetime import MINYEAR, MAXYEAR @@ -6383,6 +6384,7 @@ class IranTest(ZoneInfoTest): @unittest.skipIf(_testcapi is None, 'need _testcapi module') +@no_rerun("the encapsulated datetime C API does not support reloading") class CapiTest(unittest.TestCase): def setUp(self): # Since the C API is not present in the _Pure tests, skip all tests From 90ff7d6835449afa4a5a11a196aa7dee2801d983 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 27 May 2024 14:05:41 -0600 Subject: [PATCH 5/5] Copy no_rerun(). --- Lib/test/datetimetester.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index ddadef154bd289..ba7f185a092629 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -23,7 +23,6 @@ from test import support from test.support import is_resource_enabled, ALWAYS_EQ, LARGEST, SMALLEST from test.support import warnings_helper -from test.test_import import no_rerun import datetime as datetime_module from datetime import MINYEAR, MAXYEAR @@ -48,6 +47,26 @@ pass # +# This is copied from test_import/__init__.py. +# XXX Move it to support/__init__.py. +def no_rerun(reason): + """Skip rerunning for a particular test. + + WARNING: Use this decorator with care; skipping rerunning makes it + impossible to find reference leaks. Provide a clear reason for skipping the + test using the 'reason' parameter. + """ + def deco(func): + _has_run = False + def wrapper(self): + nonlocal _has_run + if _has_run: + self.skipTest(reason) + func(self) + _has_run = True + return wrapper + return deco + pickle_loads = {pickle.loads, pickle._loads} pickle_choices = [(pickle, pickle, proto) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy