Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-132413: Extend datetime C-API tests for subinterpreters#133111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
neonene wants to merge15 commits intopython:mainfromneonene:crashtester
Closed
Changes from1 commit
Commits
Show all changes
15 commits
Select commitHold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
Update datetimetester.py
  • Loading branch information
@neonene
neonene authoredApr 28, 2025
commit9c118439d2269d5024ed4188fbdee6cb02c52a55
141 changes: 114 additions & 27 deletionsLib/test/datetimetester.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -7155,48 +7155,76 @@ def test_datetime_from_timestamp(self):

self.assertEqual(dt_orig, dt_rt)

def test_type_check_in_subinterp(self):
def assert_python_in_subinterp(self, check_if_ok: bool, script,
setup='_testcapi.test_datetime_capi()',
config='isolated'):
# iOS requires the use of the custom framework loader,
# not the ExtensionFileLoader.
if sys.platform == "ios":
extension_loader = "AppleFrameworkLoader"
else:
extension_loader = "ExtensionFileLoader"

script = textwrap.dedent(f"""
code = textwrap.dedent(f'''
import textwrap
from test import support

subcode = textwrap.dedent("""
if {_interpreters is None}:
import _testcapi
else:
import importlib.machinery
import importlib.util
fullname = '_testcapi_datetime'
origin = importlib.util.find_spec('_testcapi').origin
loader = importlib.machinery.{extension_loader}(fullname, origin)
spec = importlib.util.spec_from_loader(fullname, loader)
_testcapi = importlib.util.module_from_spec(spec)
spec.loader.exec_module(_testcapi)

$SCRIPT$
""")

import _testcapi
$SETUP$

if {_interpreters is None}:
import _testcapi as module
module.test_datetime_capi()
ret = support.run_in_subinterp(subcode)
else:
import importlib.machinery
import importlib.util
fullname = '_testcapi_datetime'
origin = importlib.util.find_spec('_testcapi').origin
loader = importlib.machinery.{extension_loader}(fullname, origin)
spec = importlib.util.spec_from_loader(fullname, loader)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
import _interpreters
config = _interpreters.new_config('{config}').__dict__
ret = support.run_in_subinterp_with_config(subcode, **config)

assert ret == 0

''').rstrip()
code = code.replace('$SETUP$', setup)
code = code.replace('$SCRIPT$', textwrap.indent(script, '\x20'*4))

if check_if_ok:
res = script_helper.assert_python_ok('-c', code)
else:
res = script_helper.assert_python_failure('-c', code)
return res

def test_type_check_in_subinterp(self):
script = textwrap.dedent(f"""
def run(type_checker, obj):
if not type_checker(obj, True):
raise TypeError(f'{{type(obj)}} is not C API type')

_testcapi.test_datetime_capi()
import _datetime
run(module.datetime_check_date, _datetime.date.today())
run(module.datetime_check_datetime, _datetime.datetime.now())
run(module.datetime_check_time, _datetime.time(12, 30))
run(module.datetime_check_delta, _datetime.timedelta(1))
run(module.datetime_check_tzinfo, _datetime.tzinfo())
""")
if _interpreters is None:
ret = support.run_in_subinterp(script)
self.assertEqual(ret, 0)
else:
for name in ('isolated', 'legacy'):
with self.subTest(name):
config = _interpreters.new_config(name).__dict__
ret = support.run_in_subinterp_with_config(script, **config)
self.assertEqual(ret, 0)
run(_testcapi.datetime_check_date, _datetime.date.today())
run(_testcapi.datetime_check_datetime, _datetime.datetime.now())
run(_testcapi.datetime_check_time, _datetime.time(12, 30))
run(_testcapi.datetime_check_delta, _datetime.timedelta(1))
run(_testcapi.datetime_check_tzinfo, _datetime.tzinfo())
""")
self.assert_python_in_subinterp(True, script, '')
if _interpreters is not None:
with self.subTest(name := 'legacy'):
self.assert_python_in_subinterp(True, script, '', name)


class ExtensionModuleTests(unittest.TestCase):
Expand All@@ -7205,6 +7233,9 @@ def setUp(self):
if self.__class__.__name__.endswith('Pure'):
self.skipTest('Not relevant in pure Python')

def assert_python_in_subinterp(self, *args, **kwargs):
return CapiTest.assert_python_in_subinterp(self, *args, **kwargs)

@support.cpython_only
def test_gh_120161(self):
with self.subTest('simple'):
Expand DownExpand Up@@ -7270,8 +7301,64 @@ def test_update_type_cache(self):
assert isinstance(_datetime.timezone.utc, _datetime.tzinfo)
del sys.modules['_datetime']
""")
res = script_helper.assert_python_ok('-c', script)
self.assertFalse(res.err)

def test_module_free(self):
script = textwrap.dedent("""
import sys
import gc
import weakref
ws = weakref.WeakSet()
for _ in range(3):
import _datetime
timedelta = _datetime.timedelta # static type
ws.add(_datetime)
del sys.modules['_datetime']
del _datetime
gc.collect()
assert len(ws) == 0
""")
script_helper.assert_python_ok('-c', script)

@unittest.skipIf(not support.Py_DEBUG, "Debug builds only")
def test_no_leak(self):
script = textwrap.dedent("""
import datetime
datetime.datetime.strptime('20000101', '%Y%m%d').strftime('%Y%m%d')
""")
res = script_helper.assert_python_ok('-X', 'showrefcount', '-c', script)
self.assertIn(b'[0 refs, 0 blocks]', res.err)

def test_static_type_on_subinterp(self):
script = textwrap.dedent("""
date = _testcapi.get_capi_types()['date']
date.today
""")
# Test the script fails
with self.subTest('[PyDateTime_IMPORT] main: yes, sub: no'):
self.assert_python_in_subinterp(False, script)

# Test the script succeeds
script2 = '_testcapi.test_datetime_capi()' + script
with self.subTest('[PyDateTime_IMPORT] main: no, sub: yes'):
self.assert_python_in_subinterp(True, script2, setup='')

with self.subTest('[PyDateTime_IMPORT] main: yes, sub: yes'):
# Check if PyDateTime_IMPORT is invoked not only once
self.assert_python_in_subinterp(True, script2)

script3 = 'import _datetime' + script
with self.subTest('Explicit import'):
self.assert_python_in_subinterp(True, script3)

script4 = textwrap.dedent("""
timedelta = _testcapi.get_capi_types()['timedelta']
timedelta(days=1)
""") + script
with self.subTest('Implicit import'):
self.assert_python_in_subinterp(True, script4)


def load_tests(loader, standard_tests, pattern):
standard_tests.addTest(ZoneInfoCompleteTest())
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp