opendate 0.1.19__tar.gz → 0.1.20__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of opendate might be problematic. Click here for more details.
- {opendate-0.1.19 → opendate-0.1.20}/PKG-INFO +1 -1
- {opendate-0.1.19 → opendate-0.1.20}/pyproject.toml +1 -1
- {opendate-0.1.19 → opendate-0.1.20}/src/date/__init__.py +3 -1
- {opendate-0.1.19 → opendate-0.1.20}/src/date/date.py +73 -22
- {opendate-0.1.19 → opendate-0.1.20}/LICENSE +0 -0
- {opendate-0.1.19 → opendate-0.1.20}/README.md +0 -0
- {opendate-0.1.19 → opendate-0.1.20}/src/date/extras.py +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = '0.1.
|
|
1
|
+
__version__ = '0.1.20'
|
|
2
2
|
|
|
3
3
|
import datetime as _datetime
|
|
4
4
|
|
|
@@ -26,6 +26,7 @@ from date.date import WEEKDAY_SHORTNAME
|
|
|
26
26
|
from date.date import expect_date
|
|
27
27
|
from date.date import expect_datetime
|
|
28
28
|
from date.date import expect_time
|
|
29
|
+
from date.date import expect_date_or_datetime
|
|
29
30
|
from date.date import expect_native_timezone
|
|
30
31
|
from date.date import expect_utc_timezone
|
|
31
32
|
from date.date import prefer_native_timezone
|
|
@@ -128,6 +129,7 @@ __all__ = [
|
|
|
128
129
|
'expect_date',
|
|
129
130
|
'expect_datetime',
|
|
130
131
|
'expect_time',
|
|
132
|
+
'expect_date_or_datetime',
|
|
131
133
|
'expect_native_timezone',
|
|
132
134
|
'expect_utc_timezone',
|
|
133
135
|
'instance',
|
|
@@ -40,6 +40,7 @@ __all__ = [
|
|
|
40
40
|
'expect_date',
|
|
41
41
|
'expect_datetime',
|
|
42
42
|
'expect_time',
|
|
43
|
+
'expect_date_or_datetime',
|
|
43
44
|
'Entity',
|
|
44
45
|
'NYSE',
|
|
45
46
|
'WEEKDAY_SHORTNAME',
|
|
@@ -113,17 +114,34 @@ def isdateish(x) -> bool:
|
|
|
113
114
|
|
|
114
115
|
|
|
115
116
|
def parse_arg(typ, arg):
|
|
116
|
-
|
|
117
|
-
|
|
117
|
+
"""Parse argument to specified type or 'smart' to preserve Date/DateTime.
|
|
118
|
+
"""
|
|
119
|
+
if not isdateish(arg):
|
|
120
|
+
return arg
|
|
121
|
+
|
|
122
|
+
if typ == 'smart':
|
|
123
|
+
if isinstance(arg, Date | DateTime):
|
|
124
|
+
return arg
|
|
125
|
+
if isinstance(arg, _datetime.datetime | pd.Timestamp | np.datetime64):
|
|
118
126
|
return DateTime.instance(arg)
|
|
119
|
-
if
|
|
127
|
+
if isinstance(arg, _datetime.date):
|
|
120
128
|
return Date.instance(arg)
|
|
121
|
-
if
|
|
129
|
+
if isinstance(arg, _datetime.time):
|
|
122
130
|
return Time.instance(arg)
|
|
131
|
+
return arg
|
|
132
|
+
|
|
133
|
+
if typ == _datetime.datetime:
|
|
134
|
+
return DateTime.instance(arg)
|
|
135
|
+
if typ == _datetime.date:
|
|
136
|
+
return Date.instance(arg)
|
|
137
|
+
if typ == _datetime.time:
|
|
138
|
+
return Time.instance(arg)
|
|
123
139
|
return arg
|
|
124
140
|
|
|
125
141
|
|
|
126
142
|
def parse_args(typ, *args):
|
|
143
|
+
"""Parse args to specified type or 'smart' mode.
|
|
144
|
+
"""
|
|
127
145
|
this = []
|
|
128
146
|
for a in args:
|
|
129
147
|
if isinstance(a, Sequence) and not isinstance(a, str):
|
|
@@ -133,30 +151,31 @@ def parse_args(typ, *args):
|
|
|
133
151
|
return this
|
|
134
152
|
|
|
135
153
|
|
|
136
|
-
def expect(func, typ: type[_datetime.date], exclkw: bool = False) -> Callable:
|
|
137
|
-
"""Decorator to force input type of date/datetime inputs
|
|
154
|
+
def expect(func=None, *, typ: type[_datetime.date] | str = None, exclkw: bool = False) -> Callable:
|
|
155
|
+
"""Decorator to force input type of date/datetime inputs.
|
|
156
|
+
|
|
157
|
+
typ can be _datetime.date, _datetime.datetime, _datetime.time, or 'smart'
|
|
138
158
|
"""
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if
|
|
146
|
-
kwargs[k] =
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
return func(*args, **kwargs)
|
|
154
|
-
return wrapper
|
|
159
|
+
def decorator(func):
|
|
160
|
+
@wraps(func)
|
|
161
|
+
def wrapper(*args, **kwargs):
|
|
162
|
+
args = parse_args(typ, *args)
|
|
163
|
+
if not exclkw:
|
|
164
|
+
for k, v in kwargs.items():
|
|
165
|
+
if isdateish(v):
|
|
166
|
+
kwargs[k] = parse_arg(typ, v)
|
|
167
|
+
return func(*args, **kwargs)
|
|
168
|
+
return wrapper
|
|
169
|
+
|
|
170
|
+
if func is None:
|
|
171
|
+
return decorator
|
|
172
|
+
return decorator(func)
|
|
155
173
|
|
|
156
174
|
|
|
157
175
|
expect_date = partial(expect, typ=_datetime.date)
|
|
158
176
|
expect_datetime = partial(expect, typ=_datetime.datetime)
|
|
159
177
|
expect_time = partial(expect, typ=_datetime.time)
|
|
178
|
+
expect_date_or_datetime = partial(expect, typ='smart')
|
|
160
179
|
|
|
161
180
|
|
|
162
181
|
def type_class(typ, obj):
|
|
@@ -218,6 +237,34 @@ def reset_business(func):
|
|
|
218
237
|
return wrapper
|
|
219
238
|
|
|
220
239
|
|
|
240
|
+
def normalize_date_datetime_pairs(func):
|
|
241
|
+
"""Decorator to normalize mixed Date/DateTime pairs to DateTime.
|
|
242
|
+
"""
|
|
243
|
+
@wraps(func)
|
|
244
|
+
def wrapper(*args, **kwargs):
|
|
245
|
+
if len(args) >= 3:
|
|
246
|
+
cls_or_self, begdate, enddate = args[0], args[1], args[2]
|
|
247
|
+
rest_args = args[3:]
|
|
248
|
+
|
|
249
|
+
tz = UTC
|
|
250
|
+
if isinstance(begdate, DateTime) and begdate.tzinfo:
|
|
251
|
+
tz = begdate.tzinfo
|
|
252
|
+
elif isinstance(enddate, DateTime) and enddate.tzinfo:
|
|
253
|
+
tz = enddate.tzinfo
|
|
254
|
+
|
|
255
|
+
if isinstance(begdate, Date) and not isinstance(begdate, DateTime):
|
|
256
|
+
if isinstance(enddate, DateTime):
|
|
257
|
+
begdate = DateTime(begdate.year, begdate.month, begdate.day, tzinfo=tz)
|
|
258
|
+
elif isinstance(enddate, Date) and not isinstance(enddate, DateTime):
|
|
259
|
+
if isinstance(begdate, DateTime):
|
|
260
|
+
enddate = DateTime(enddate.year, enddate.month, enddate.day, tzinfo=tz)
|
|
261
|
+
|
|
262
|
+
args = (cls_or_self, begdate, enddate) + rest_args
|
|
263
|
+
|
|
264
|
+
return func(*args, **kwargs)
|
|
265
|
+
return wrapper
|
|
266
|
+
|
|
267
|
+
|
|
221
268
|
def prefer_utc_timezone(func, force:bool = False) -> Callable:
|
|
222
269
|
"""Return datetime as UTC.
|
|
223
270
|
"""
|
|
@@ -1436,11 +1483,15 @@ class Interval(_pendulum.Interval):
|
|
|
1436
1483
|
_business: bool = False
|
|
1437
1484
|
_entity: type[NYSE] = NYSE
|
|
1438
1485
|
|
|
1486
|
+
@expect_date_or_datetime
|
|
1487
|
+
@normalize_date_datetime_pairs
|
|
1439
1488
|
def __new__(cls, begdate: Date | DateTime, enddate: Date | DateTime) -> Self:
|
|
1440
1489
|
assert begdate and enddate, 'Interval dates cannot be None'
|
|
1441
1490
|
instance = super().__new__(cls, begdate, enddate, False)
|
|
1442
1491
|
return instance
|
|
1443
1492
|
|
|
1493
|
+
@expect_date_or_datetime
|
|
1494
|
+
@normalize_date_datetime_pairs
|
|
1444
1495
|
def __init__(self, begdate: Date | DateTime, enddate: Date | DateTime) -> None:
|
|
1445
1496
|
super().__init__(begdate, enddate, False)
|
|
1446
1497
|
self._sign = 1 if begdate <= enddate else -1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|