summaryrefslogtreecommitdiffstats
path: root/Lib/test/datetimetester.py
diff options
context:
space:
mode:
authorPaul Ganssle <pganssle@users.noreply.github.com>2018-01-24 22:29:30 (GMT)
committerAlexander Belopolsky <abalkin@users.noreply.github.com>2018-01-24 22:29:30 (GMT)
commit04af5b1ba9eb546a29735fac6cb5298159069b53 (patch)
tree12e50adcc6ee03a3a4a80cb0a9b37bff4b58901b /Lib/test/datetimetester.py
parentccbe5818af20f8c12043f5c30c277a74714405e0 (diff)
downloadcpython-04af5b1ba9eb546a29735fac6cb5298159069b53.zip
cpython-04af5b1ba9eb546a29735fac6cb5298159069b53.tar.gz
cpython-04af5b1ba9eb546a29735fac6cb5298159069b53.tar.bz2
bpo-10381: Add timezone to datetime C API (#5032)
* Add timezone to datetime C API * Add documentation for timezone C API macros * Add dedicated tests for datetime type check macros * Remove superfluous C API test * Drop support for TimeZoneType in datetime C API * Expose UTC singleton to the datetime C API * Update datetime C-API documentation to include links * Add reference count information for timezone constructors
Diffstat (limited to 'Lib/test/datetimetester.py')
-rw-r--r--Lib/test/datetimetester.py181
1 files changed, 181 insertions, 0 deletions
diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py
index e8ed79e..a0883b9 100644
--- a/Lib/test/datetimetester.py
+++ b/Lib/test/datetimetester.py
@@ -31,6 +31,8 @@ from datetime import timezone
from datetime import date, datetime
import time as _time
+import _testcapi
+
# Needed by test_datetime
import _strptime
#
@@ -5443,6 +5445,185 @@ class ZoneInfoCompleteTest(unittest.TestSuite):
class IranTest(ZoneInfoTest):
zonename = 'Asia/Tehran'
+
+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'):
+ self.skipTest('Not relevant in pure Python')
+
+ # 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()
+
+ def test_utc_capi(self):
+ for use_macro in (True, False):
+ capi_utc = _testcapi.get_timezone_utc_capi(use_macro)
+
+ with self.subTest(use_macro=use_macro):
+ self.assertIs(capi_utc, timezone.utc)
+
+ def test_timezones_capi(self):
+ est_capi, est_macro, est_macro_nn = _testcapi.make_timezones_capi()
+
+ exp_named = timezone(timedelta(hours=-5), "EST")
+ exp_unnamed = timezone(timedelta(hours=-5))
+
+ cases = [
+ ('est_capi', est_capi, exp_named),
+ ('est_macro', est_macro, exp_named),
+ ('est_macro_nn', est_macro_nn, exp_unnamed)
+ ]
+
+ for name, tz_act, tz_exp in cases:
+ with self.subTest(name=name):
+ self.assertEqual(tz_act, tz_exp)
+
+ dt1 = datetime(2000, 2, 4, tzinfo=tz_act)
+ dt2 = datetime(2000, 2, 4, tzinfo=tz_exp)
+
+ self.assertEqual(dt1, dt2)
+ self.assertEqual(dt1.tzname(), dt2.tzname())
+
+ dt_utc = datetime(2000, 2, 4, 5, tzinfo=timezone.utc)
+
+ self.assertEqual(dt1.astimezone(timezone.utc), dt_utc)
+
+ def test_check_date(self):
+ class DateSubclass(date):
+ pass
+
+ d = date(2011, 1, 1)
+ ds = DateSubclass(2011, 1, 1)
+ dt = datetime(2011, 1, 1)
+
+ is_date = _testcapi.datetime_check_date
+
+ # Check the ones that should be valid
+ self.assertTrue(is_date(d))
+ self.assertTrue(is_date(dt))
+ self.assertTrue(is_date(ds))
+ self.assertTrue(is_date(d, True))
+
+ # Check that the subclasses do not match exactly
+ self.assertFalse(is_date(dt, True))
+ self.assertFalse(is_date(ds, True))
+
+ # Check that various other things are not dates at all
+ args = [tuple(), list(), 1, '2011-01-01',
+ timedelta(1), timezone.utc, time(12, 00)]
+ for arg in args:
+ for exact in (True, False):
+ with self.subTest(arg=arg, exact=exact):
+ self.assertFalse(is_date(arg, exact))
+
+ def test_check_time(self):
+ class TimeSubclass(time):
+ pass
+
+ t = time(12, 30)
+ ts = TimeSubclass(12, 30)
+
+ is_time = _testcapi.datetime_check_time
+
+ # Check the ones that should be valid
+ self.assertTrue(is_time(t))
+ self.assertTrue(is_time(ts))
+ self.assertTrue(is_time(t, True))
+
+ # Check that the subclass does not match exactly
+ self.assertFalse(is_time(ts, True))
+
+ # Check that various other things are not times
+ args = [tuple(), list(), 1, '2011-01-01',
+ timedelta(1), timezone.utc, date(2011, 1, 1)]
+
+ for arg in args:
+ for exact in (True, False):
+ with self.subTest(arg=arg, exact=exact):
+ self.assertFalse(is_time(arg, exact))
+
+ def test_check_datetime(self):
+ class DateTimeSubclass(datetime):
+ pass
+
+ dt = datetime(2011, 1, 1, 12, 30)
+ dts = DateTimeSubclass(2011, 1, 1, 12, 30)
+
+ is_datetime = _testcapi.datetime_check_datetime
+
+ # Check the ones that should be valid
+ self.assertTrue(is_datetime(dt))
+ self.assertTrue(is_datetime(dts))
+ self.assertTrue(is_datetime(dt, True))
+
+ # Check that the subclass does not match exactly
+ self.assertFalse(is_datetime(dts, True))
+
+ # Check that various other things are not datetimes
+ args = [tuple(), list(), 1, '2011-01-01',
+ timedelta(1), timezone.utc, date(2011, 1, 1)]
+
+ for arg in args:
+ for exact in (True, False):
+ with self.subTest(arg=arg, exact=exact):
+ self.assertFalse(is_datetime(arg, exact))
+
+ def test_check_delta(self):
+ class TimeDeltaSubclass(timedelta):
+ pass
+
+ td = timedelta(1)
+ tds = TimeDeltaSubclass(1)
+
+ is_timedelta = _testcapi.datetime_check_delta
+
+ # Check the ones that should be valid
+ self.assertTrue(is_timedelta(td))
+ self.assertTrue(is_timedelta(tds))
+ self.assertTrue(is_timedelta(td, True))
+
+ # Check that the subclass does not match exactly
+ self.assertFalse(is_timedelta(tds, True))
+
+ # Check that various other things are not timedeltas
+ args = [tuple(), list(), 1, '2011-01-01',
+ timezone.utc, date(2011, 1, 1), datetime(2011, 1, 1)]
+
+ for arg in args:
+ for exact in (True, False):
+ with self.subTest(arg=arg, exact=exact):
+ self.assertFalse(is_timedelta(arg, exact))
+
+ def test_check_tzinfo(self):
+ class TZInfoSubclass(tzinfo):
+ pass
+
+ tzi = tzinfo()
+ tzis = TZInfoSubclass()
+ tz = timezone(timedelta(hours=-5))
+
+ is_tzinfo = _testcapi.datetime_check_tzinfo
+
+ # Check the ones that should be valid
+ self.assertTrue(is_tzinfo(tzi))
+ self.assertTrue(is_tzinfo(tz))
+ self.assertTrue(is_tzinfo(tzis))
+ self.assertTrue(is_tzinfo(tzi, True))
+
+ # Check that the subclasses do not match exactly
+ self.assertFalse(is_tzinfo(tz, True))
+ self.assertFalse(is_tzinfo(tzis, True))
+
+ # Check that various other things are not tzinfos
+ args = [tuple(), list(), 1, '2011-01-01',
+ date(2011, 1, 1), datetime(2011, 1, 1)]
+
+ for arg in args:
+ for exact in (True, False):
+ with self.subTest(arg=arg, exact=exact):
+ self.assertFalse(is_tzinfo(arg, exact))
+
def load_tests(loader, standard_tests, pattern):
standard_tests.addTest(ZoneInfoCompleteTest())
return standard_tests