Skip to content

Commit

Permalink
Fix older version objects unpickling problem.
Browse files Browse the repository at this point in the history
  • Loading branch information
hramezani committed Jan 24, 2022
1 parent 88f551a commit a3af59e
Show file tree
Hide file tree
Showing 7 changed files with 301 additions and 32 deletions.
64 changes: 32 additions & 32 deletions jdatetime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,36 @@
MINYEAR = 1
MAXYEAR = 9377

STRFTIME_MAPPING = {
# A mapping between symbol to it's helper function and function kwargs
# symbol: (helper_function_name, {kwargs})
"%a": ("_strftime_get_method_value", {"attr": "jweekday_short", "fmt": "%s"}),
"%A": ("_strftime_get_method_value", {"attr": "jweekday", "fmt": "%s"}),
"%b": ("_strftime_get_method_value", {"attr": "jmonth_short", "fmt": "%s"}),
"%B": ("_strftime_get_method_value", {"attr": "jmonth", "fmt": "%s"}),
"%d": ("_strftime_get_attr_value", {"attr": "day", "fmt": "%02.d"}),
"%-d": ("_strftime_get_attr_value", {"attr": "day", "fmt": "%d"}),
"%j": ("_strftime_get_method_value", {"attr": "yday", "fmt": "%03.d"}),
"%m": ("_strftime_get_attr_value", {"attr": "month", "fmt": "%02.d"}),
"%-m": ("_strftime_get_attr_value", {"attr": "month", "fmt": "%d"}),
"%w": ("_strftime_get_method_value", {"attr": "weekday", "fmt": "%d"}),
"%W": ("_strftime_get_method_value", {"attr": "weeknumber", "fmt": "%d"}),
"%Y": ("_strftime_get_attr_value", {"attr": "year", "fmt": "%d"}),
"%y": ("_strftime_get_attr_value", {"attr": "cyear", "fmt": "%02.d"}),
"%f": ("_strftime_get_attr_value", {"attr": "microsecond", "fmt": "%06.d", "fb": "000000"}),
"%H": ("_strftime_get_attr_value", {"attr": "hour", "fmt": "%02.d", "fb": "00"}),
"%-H": ("_strftime_get_attr_value", {"attr": "hour", "fmt": "%d", "fb": "0"}),
"%I": ("_strftime_get_attr_value", {"attr": "hour", "fmt": "%02.d", "fb": "12"}),
"%-I": ("_strftime_get_attr_value", {"attr": "hour", "fmt": "%d", "fb": "12"}),
"%M": ("_strftime_get_attr_value", {"attr": "minute", "fmt": "%02.d", "fb": "00"}),
"%-M": ("_strftime_get_attr_value", {"attr": "minute", "fmt": "%d", "fb": "0"}),
"%S": ("_strftime_get_attr_value", {"attr": "second", "fmt": "%02.d", "fb": "00"}),
"%-S": ("_strftime_get_attr_value", {"attr": "second", "fmt": "%d", "fb": "0"}),
"%p": ("_strftime_p", {}),
"%z": ("_strftime_z", {}),
"%Z": ("_strftime_cap_z", {}),
}

timedelta = py_datetime.timedelta
tzinfo = py_datetime.tzinfo

Expand Down Expand Up @@ -264,36 +294,6 @@ def __init__(self, year, month, day, **kwargs):
self.j_weekdays_short = self.j_weekdays_short_en
self.j_ampm = self.j_ampm_en

self._strftime_mapping = {
# A mapping between symbol to it's helper function and function kwargs
# symbol: (helper_function_name, {kwargs})
"%a": ("_strftime_get_method_value", {"attr": "jweekday_short", "fmt": "%s"}),
"%A": ("_strftime_get_method_value", {"attr": "jweekday", "fmt": "%s"}),
"%b": ("_strftime_get_method_value", {"attr": "jmonth_short", "fmt": "%s"}),
"%B": ("_strftime_get_method_value", {"attr": "jmonth", "fmt": "%s"}),
"%d": ("_strftime_get_attr_value", {"attr": "day", "fmt": "%02.d"}),
"%-d": ("_strftime_get_attr_value", {"attr": "day", "fmt": "%d"}),
"%j": ("_strftime_get_method_value", {"attr": "yday", "fmt": "%03.d"}),
"%m": ("_strftime_get_attr_value", {"attr": "month", "fmt": "%02.d"}),
"%-m": ("_strftime_get_attr_value", {"attr": "month", "fmt": "%d"}),
"%w": ("_strftime_get_method_value", {"attr": "weekday", "fmt": "%d"}),
"%W": ("_strftime_get_method_value", {"attr": "weeknumber", "fmt": "%d"}),
"%Y": ("_strftime_get_attr_value", {"attr": "year", "fmt": "%d"}),
"%y": ("_strftime_get_attr_value", {"attr": "cyear", "fmt": "%02.d"}),
"%f": ("_strftime_get_attr_value", {"attr": "microsecond", "fmt": "%06.d", "fb": "000000"}),
"%H": ("_strftime_get_attr_value", {"attr": "hour", "fmt": "%02.d", "fb": "00"}),
"%-H": ("_strftime_get_attr_value", {"attr": "hour", "fmt": "%d", "fb": "0"}),
"%I": ("_strftime_get_attr_value", {"attr": "hour", "fmt": "%02.d", "fb": "12"}),
"%-I": ("_strftime_get_attr_value", {"attr": "hour", "fmt": "%d", "fb": "12"}),
"%M": ("_strftime_get_attr_value", {"attr": "minute", "fmt": "%02.d", "fb": "00"}),
"%-M": ("_strftime_get_attr_value", {"attr": "minute", "fmt": "%d", "fb": "0"}),
"%S": ("_strftime_get_attr_value", {"attr": "second", "fmt": "%02.d", "fb": "00"}),
"%-S": ("_strftime_get_attr_value", {"attr": "second", "fmt": "%d", "fb": "0"}),
"%p": ("_strftime_p", {}),
"%z": ("_strftime_z", {}),
"%Z": ("_strftime_cap_z", {}),
}

def _is_fa_locale(self):
if self.__locale and self.__locale == FA_LOCALE:
return True
Expand Down Expand Up @@ -647,8 +647,8 @@ def strftime(self, format):
format = format.replace(s, r)

for symbol in _re.findall("\%-?[a-zA-z-]", format):
if symbol in self._strftime_mapping:
replace_method_name, kwargs = self._strftime_mapping[symbol]
if symbol in STRFTIME_MAPPING:
replace_method_name, kwargs = STRFTIME_MAPPING[symbol]
kwargs.update({"format": format, "symbol": symbol})
format = getattr(self, replace_method_name)(**kwargs)
return format
Expand Down
119 changes: 119 additions & 0 deletions tests/pickled_objects/jdate_py2_jdatetime3.7.pickle
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
ccopy_reg
_reconstructor
p0
(cjdatetime
date
p1
c__builtin__
object
p2
Ntp3
Rp4
(dp5
S'_date__day'
p6
I11
sS'j_weekdays'
p7
(lp8
VSaturday
p9
aVSunday
p10
aVMonday
p11
aVTuesday
p12
aVWednesday
p13
aVThursday
p14
aVFriday
p15
asS'_date__month'
p16
I10
sS'j_weekdays_short'
p17
(lp18
VSat
p19
aVSun
p20
aVMon
p21
aVTue
p22
aVWed
p23
aVThu
p24
aVFri
p25
asS'j_months_short'
p26
(lp27
VFar
p28
aVOrd
p29
aVKho
p30
aVTir
p31
aVMor
p32
aVSha
p33
aVMeh
p34
aVAba
p35
aVAza
p36
aVDey
p37
aVBah
p38
aVEsf
p39
asS'_date__locale'
p40
NsS'j_ampm'
p41
(dp42
VAM
p43
g43
sVPM
p44
g44
ssS'j_months'
p45
(lp46
VFarvardin
p47
aVOrdibehesht
p48
aVKhordad
p49
ag31
aVMordad
p50
aVShahrivar
p51
aVMehr
p52
aVAban
p53
aVAzar
p54
ag37
aVBahman
p55
aVEsfand
p56
asS'_date__year'
p57
I1400
sb.
Binary file added tests/pickled_objects/jdate_py3_jdatetime3.7.pickle
Binary file not shown.
128 changes: 128 additions & 0 deletions tests/pickled_objects/jdatetime_py2_jdatetime3.7.pickle
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
ccopy_reg
_reconstructor
p0
(cjdatetime
datetime
p1
c__builtin__
object
p2
Ntp3
Rp4
(dp5
S'_datetime__time'
p6
cjdatetime
time
p7
(S'\x01\x02\x03\x00\x00\x1e'
p8
tp9
Rp10
sS'_date__day'
p11
I11
sS'j_weekdays'
p12
(lp13
VSaturday
p14
aVSunday
p15
aVMonday
p16
aVTuesday
p17
aVWednesday
p18
aVThursday
p19
aVFriday
p20
asS'_date__month'
p21
I10
sS'j_weekdays_short'
p22
(lp23
VSat
p24
aVSun
p25
aVMon
p26
aVTue
p27
aVWed
p28
aVThu
p29
aVFri
p30
asS'j_months_short'
p31
(lp32
VFar
p33
aVOrd
p34
aVKho
p35
aVTir
p36
aVMor
p37
aVSha
p38
aVMeh
p39
aVAba
p40
aVAza
p41
aVDey
p42
aVBah
p43
aVEsf
p44
asS'_date__locale'
p45
NsS'j_ampm'
p46
(dp47
VAM
p48
g48
sVPM
p49
g49
ssS'j_months'
p50
(lp51
VFarvardin
p52
aVOrdibehesht
p53
aVKhordad
p54
ag36
aVMordad
p55
aVShahrivar
p56
aVMehr
p57
aVAban
p58
aVAzar
p59
ag42
aVBahman
p60
aVEsfand
p61
asS'_date__year'
p62
I1400
sb.
Binary file not shown.
11 changes: 11 additions & 0 deletions tests/test_jdate.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import datetime
import pickle
import sys
import time
from unittest import TestCase

Expand Down Expand Up @@ -127,3 +128,13 @@ def test_min_year(self):
def test_pickle(self):
d = jdatetime.date.today()
self.assertEqual(pickle.loads(pickle.dumps(d)), d)

def test_unpickle_older_date_object(self):
if sys.version_info[0] >= 3: # py3
pickled_object_file = 'jdate_py3_jdatetime3.7.pickle'
else:
pickled_object_file = 'jdate_py2_jdatetime3.7.pickle'

with open('tests/pickled_objects/%s' % pickled_object_file, 'rb') as f:
d = pickle.load(f)
assert d == jdatetime.date(1400, 10, 11)
11 changes: 11 additions & 0 deletions tests/test_jdatetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import locale
import pickle
import platform
import sys
import threading
import time
from unittest import TestCase, skipIf, skipUnless
Expand Down Expand Up @@ -644,6 +645,16 @@ def test_pickle(self):
dt = jdatetime.datetime.now()
self.assertEqual(pickle.loads(pickle.dumps(dt)), dt)

def test_unpickle_older_datetime_object(self):
if sys.version_info[0] >= 3: # py3
pickled_object_file = 'jdatetime_py3_jdatetime3.7.pickle'
else:
pickled_object_file = 'jdatetime_py2_jdatetime3.7.pickle'

with open('tests/pickled_objects/%s' % pickled_object_file, 'rb') as f:
dt = pickle.load(f)
assert dt == jdatetime.datetime(1400, 10, 11, 1, 2, 3, 30)


class TestJdatetimeGetSetLocale(TestCase):
@staticmethod
Expand Down

0 comments on commit a3af59e

Please sign in to comment.