mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
gh-53502: add a new option aware_datetime in plistlib to loads or dumps aware datetime. (#113363)
* add options to loads and dumps aware datetime in plistlib
This commit is contained in:
parent
d0b0e3d2ef
commit
b4b2cc1012
4 changed files with 134 additions and 23 deletions
|
@ -13,6 +13,8 @@ import codecs
|
|||
import subprocess
|
||||
import binascii
|
||||
import collections
|
||||
import time
|
||||
import zoneinfo
|
||||
from test import support
|
||||
from test.support import os_helper
|
||||
from io import BytesIO
|
||||
|
@ -838,6 +840,54 @@ class TestPlistlib(unittest.TestCase):
|
|||
"XML entity declarations are not supported"):
|
||||
plistlib.loads(XML_PLIST_WITH_ENTITY, fmt=plistlib.FMT_XML)
|
||||
|
||||
def test_load_aware_datetime(self):
|
||||
dt = plistlib.loads(b"<plist><date>2023-12-10T08:03:30Z</date></plist>",
|
||||
aware_datetime=True)
|
||||
self.assertEqual(dt.tzinfo, datetime.UTC)
|
||||
|
||||
@unittest.skipUnless("America/Los_Angeles" in zoneinfo.available_timezones(),
|
||||
"Can't find timezone datebase")
|
||||
def test_dump_aware_datetime(self):
|
||||
dt = datetime.datetime(2345, 6, 7, 8, 9, 10,
|
||||
tzinfo=zoneinfo.ZoneInfo("America/Los_Angeles"))
|
||||
for fmt in ALL_FORMATS:
|
||||
s = plistlib.dumps(dt, fmt=fmt, aware_datetime=True)
|
||||
loaded_dt = plistlib.loads(s, fmt=fmt, aware_datetime=True)
|
||||
self.assertEqual(loaded_dt.tzinfo, datetime.UTC)
|
||||
self.assertEqual(loaded_dt, dt)
|
||||
|
||||
def test_dump_utc_aware_datetime(self):
|
||||
dt = datetime.datetime(2345, 6, 7, 8, 9, 10, tzinfo=datetime.UTC)
|
||||
for fmt in ALL_FORMATS:
|
||||
s = plistlib.dumps(dt, fmt=fmt, aware_datetime=True)
|
||||
loaded_dt = plistlib.loads(s, fmt=fmt, aware_datetime=True)
|
||||
self.assertEqual(loaded_dt.tzinfo, datetime.UTC)
|
||||
self.assertEqual(loaded_dt, dt)
|
||||
|
||||
@unittest.skipUnless("America/Los_Angeles" in zoneinfo.available_timezones(),
|
||||
"Can't find timezone datebase")
|
||||
def test_dump_aware_datetime_without_aware_datetime_option(self):
|
||||
dt = datetime.datetime(2345, 6, 7, 8,
|
||||
tzinfo=zoneinfo.ZoneInfo("America/Los_Angeles"))
|
||||
s = plistlib.dumps(dt, fmt=plistlib.FMT_XML, aware_datetime=False)
|
||||
self.assertIn(b"2345-06-07T08:00:00Z", s)
|
||||
|
||||
def test_dump_utc_aware_datetime_without_aware_datetime_option(self):
|
||||
dt = datetime.datetime(2345, 6, 7, 8, tzinfo=datetime.UTC)
|
||||
s = plistlib.dumps(dt, fmt=plistlib.FMT_XML, aware_datetime=False)
|
||||
self.assertIn(b"2345-06-07T08:00:00Z", s)
|
||||
|
||||
def test_dump_naive_datetime_with_aware_datetime_option(self):
|
||||
# Save a naive datetime with aware_datetime set to true. This will lead
|
||||
# to having different time as compared to the current machine's
|
||||
# timezone, which is UTC.
|
||||
dt = datetime.datetime(2345, 6, 7, 8, tzinfo=None)
|
||||
for fmt in ALL_FORMATS:
|
||||
s = plistlib.dumps(dt, fmt=fmt, aware_datetime=True)
|
||||
parsed = plistlib.loads(s, aware_datetime=False)
|
||||
expected = dt + datetime.timedelta(seconds=time.timezone)
|
||||
self.assertEqual(parsed, expected)
|
||||
|
||||
|
||||
class TestBinaryPlistlib(unittest.TestCase):
|
||||
|
||||
|
@ -962,6 +1012,28 @@ class TestBinaryPlistlib(unittest.TestCase):
|
|||
with self.assertRaises(plistlib.InvalidFileException):
|
||||
plistlib.loads(b'bplist00' + data, fmt=plistlib.FMT_BINARY)
|
||||
|
||||
def test_load_aware_datetime(self):
|
||||
data = (b'bplist003B\x04>\xd0d\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00'
|
||||
b'\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11')
|
||||
self.assertEqual(plistlib.loads(data, aware_datetime=True),
|
||||
datetime.datetime(2345, 6, 7, 8, tzinfo=datetime.UTC))
|
||||
|
||||
@unittest.skipUnless("America/Los_Angeles" in zoneinfo.available_timezones(),
|
||||
"Can't find timezone datebase")
|
||||
def test_dump_aware_datetime_without_aware_datetime_option(self):
|
||||
dt = datetime.datetime(2345, 6, 7, 8,
|
||||
tzinfo=zoneinfo.ZoneInfo("America/Los_Angeles"))
|
||||
msg = "can't subtract offset-naive and offset-aware datetimes"
|
||||
with self.assertRaisesRegex(TypeError, msg):
|
||||
plistlib.dumps(dt, fmt=plistlib.FMT_BINARY, aware_datetime=False)
|
||||
|
||||
def test_dump_utc_aware_datetime_without_aware_datetime_option(self):
|
||||
dt = datetime.datetime(2345, 6, 7, 8, tzinfo=datetime.UTC)
|
||||
msg = "can't subtract offset-naive and offset-aware datetimes"
|
||||
with self.assertRaisesRegex(TypeError, msg):
|
||||
plistlib.dumps(dt, fmt=plistlib.FMT_BINARY, aware_datetime=False)
|
||||
|
||||
|
||||
class TestKeyedArchive(unittest.TestCase):
|
||||
def test_keyed_archive_data(self):
|
||||
|
@ -1072,5 +1144,6 @@ class TestPlutil(unittest.TestCase):
|
|||
self.assertEqual(p.get("HexType"), 16777228)
|
||||
self.assertEqual(p.get("IntType"), 83)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue