tea-bond 0.4.3__cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

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.
@@ -0,0 +1,186 @@
1
+ import ctypes
2
+
3
+ from .lib import lib
4
+
5
+ # TfEvaluator creation and destruction
6
+ create_tf_evaluator = lib.create_tf_evaluator
7
+ create_tf_evaluator.argtypes = [
8
+ ctypes.c_void_p, # future_code_ptr
9
+ ctypes.c_size_t, # future_code_len
10
+ ctypes.c_double, # future_price
11
+ ctypes.c_void_p, # bond_code_ptr
12
+ ctypes.c_size_t, # bond_code_len
13
+ ctypes.c_double, # bond_ytm
14
+ ctypes.c_double, # capital_rate
15
+ ctypes.c_uint32, # year
16
+ ctypes.c_uint32, # month
17
+ ctypes.c_uint32, # day
18
+ ]
19
+ create_tf_evaluator.restype = ctypes.c_void_p
20
+
21
+ create_tf_evaluator_with_reinvest = lib.create_tf_evaluator_with_reinvest
22
+ create_tf_evaluator_with_reinvest.argtypes = [
23
+ ctypes.c_void_p, # future_code_ptr
24
+ ctypes.c_size_t, # future_code_len
25
+ ctypes.c_double, # future_price
26
+ ctypes.c_void_p, # bond_code_ptr
27
+ ctypes.c_size_t, # bond_code_len
28
+ ctypes.c_double, # bond_ytm
29
+ ctypes.c_double, # capital_rate
30
+ ctypes.c_double, # reinvest_rate
31
+ ctypes.c_uint32, # year
32
+ ctypes.c_uint32, # month
33
+ ctypes.c_uint32, # day
34
+ ]
35
+ create_tf_evaluator_with_reinvest.restype = ctypes.c_void_p
36
+
37
+ free_tf_evaluator = lib.free_tf_evaluator
38
+ free_tf_evaluator.argtypes = [ctypes.c_void_p]
39
+ free_tf_evaluator.restype = None
40
+
41
+ # Basic properties
42
+ tf_evaluator_is_deliverable = lib.tf_evaluator_is_deliverable
43
+ tf_evaluator_is_deliverable.argtypes = [ctypes.c_void_p]
44
+ tf_evaluator_is_deliverable.restype = ctypes.c_int
45
+
46
+ tf_evaluator_bond_code = lib.tf_evaluator_bond_code
47
+ tf_evaluator_bond_code.argtypes = [ctypes.c_void_p]
48
+ tf_evaluator_bond_code.restype = ctypes.c_char_p
49
+
50
+ tf_evaluator_future_code = lib.tf_evaluator_future_code
51
+ tf_evaluator_future_code.argtypes = [ctypes.c_void_p]
52
+ tf_evaluator_future_code.restype = ctypes.c_char_p
53
+
54
+ tf_evaluator_bond_ytm = lib.tf_evaluator_bond_ytm
55
+ tf_evaluator_bond_ytm.argtypes = [ctypes.c_void_p]
56
+ tf_evaluator_bond_ytm.restype = ctypes.c_double
57
+
58
+ tf_evaluator_future_price = lib.tf_evaluator_future_price
59
+ tf_evaluator_future_price.argtypes = [ctypes.c_void_p]
60
+ tf_evaluator_future_price.restype = ctypes.c_double
61
+
62
+ tf_evaluator_capital_rate = lib.tf_evaluator_capital_rate
63
+ tf_evaluator_capital_rate.argtypes = [ctypes.c_void_p]
64
+ tf_evaluator_capital_rate.restype = ctypes.c_double
65
+
66
+ tf_evaluator_reinvest_rate = lib.tf_evaluator_reinvest_rate
67
+ tf_evaluator_reinvest_rate.argtypes = [ctypes.c_void_p]
68
+ tf_evaluator_reinvest_rate.restype = ctypes.c_double
69
+
70
+ # Date functions
71
+ tf_evaluator_get_date = lib.tf_evaluator_get_date
72
+ tf_evaluator_get_date.argtypes = [
73
+ ctypes.c_void_p,
74
+ ctypes.POINTER(ctypes.c_uint32),
75
+ ctypes.POINTER(ctypes.c_uint32),
76
+ ctypes.POINTER(ctypes.c_uint32),
77
+ ]
78
+ tf_evaluator_get_date.restype = None
79
+
80
+ tf_evaluator_get_deliver_date = lib.tf_evaluator_get_deliver_date
81
+ tf_evaluator_get_deliver_date.argtypes = [
82
+ ctypes.c_void_p,
83
+ ctypes.POINTER(ctypes.c_uint32),
84
+ ctypes.POINTER(ctypes.c_uint32),
85
+ ctypes.POINTER(ctypes.c_uint32),
86
+ ]
87
+ tf_evaluator_get_deliver_date.restype = ctypes.c_int
88
+
89
+ # Calculation functions
90
+ tf_evaluator_accrued_interest = lib.tf_evaluator_accrued_interest
91
+ tf_evaluator_accrued_interest.argtypes = [ctypes.c_void_p]
92
+ tf_evaluator_accrued_interest.restype = ctypes.c_double
93
+
94
+ tf_evaluator_deliver_accrued_interest = lib.tf_evaluator_deliver_accrued_interest
95
+ tf_evaluator_deliver_accrued_interest.argtypes = [ctypes.c_void_p]
96
+ tf_evaluator_deliver_accrued_interest.restype = ctypes.c_double
97
+
98
+ tf_evaluator_cf = lib.tf_evaluator_cf
99
+ tf_evaluator_cf.argtypes = [ctypes.c_void_p]
100
+ tf_evaluator_cf.restype = ctypes.c_double
101
+
102
+ tf_evaluator_dirty_price = lib.tf_evaluator_dirty_price
103
+ tf_evaluator_dirty_price.argtypes = [ctypes.c_void_p]
104
+ tf_evaluator_dirty_price.restype = ctypes.c_double
105
+
106
+ tf_evaluator_clean_price = lib.tf_evaluator_clean_price
107
+ tf_evaluator_clean_price.argtypes = [ctypes.c_void_p]
108
+ tf_evaluator_clean_price.restype = ctypes.c_double
109
+
110
+ tf_evaluator_future_dirty_price = lib.tf_evaluator_future_dirty_price
111
+ tf_evaluator_future_dirty_price.argtypes = [ctypes.c_void_p]
112
+ tf_evaluator_future_dirty_price.restype = ctypes.c_double
113
+
114
+ tf_evaluator_deliver_cost = lib.tf_evaluator_deliver_cost
115
+ tf_evaluator_deliver_cost.argtypes = [ctypes.c_void_p]
116
+ tf_evaluator_deliver_cost.restype = ctypes.c_double
117
+
118
+ tf_evaluator_basis_spread = lib.tf_evaluator_basis_spread
119
+ tf_evaluator_basis_spread.argtypes = [ctypes.c_void_p]
120
+ tf_evaluator_basis_spread.restype = ctypes.c_double
121
+
122
+ tf_evaluator_f_b_spread = lib.tf_evaluator_f_b_spread
123
+ tf_evaluator_f_b_spread.argtypes = [ctypes.c_void_p]
124
+ tf_evaluator_f_b_spread.restype = ctypes.c_double
125
+
126
+ tf_evaluator_carry = lib.tf_evaluator_carry
127
+ tf_evaluator_carry.argtypes = [ctypes.c_void_p]
128
+ tf_evaluator_carry.restype = ctypes.c_double
129
+
130
+ tf_evaluator_net_basis_spread = lib.tf_evaluator_net_basis_spread
131
+ tf_evaluator_net_basis_spread.argtypes = [ctypes.c_void_p]
132
+ tf_evaluator_net_basis_spread.restype = ctypes.c_double
133
+
134
+ tf_evaluator_duration = lib.tf_evaluator_duration
135
+ tf_evaluator_duration.argtypes = [ctypes.c_void_p]
136
+ tf_evaluator_duration.restype = ctypes.c_double
137
+
138
+ tf_evaluator_irr = lib.tf_evaluator_irr
139
+ tf_evaluator_irr.argtypes = [ctypes.c_void_p]
140
+ tf_evaluator_irr.restype = ctypes.c_double
141
+
142
+ tf_evaluator_future_ytm = lib.tf_evaluator_future_ytm
143
+ tf_evaluator_future_ytm.argtypes = [ctypes.c_void_p]
144
+ tf_evaluator_future_ytm.restype = ctypes.c_double
145
+
146
+ tf_evaluator_remain_days_to_deliver = lib.tf_evaluator_remain_days_to_deliver
147
+ tf_evaluator_remain_days_to_deliver.argtypes = [ctypes.c_void_p]
148
+ tf_evaluator_remain_days_to_deliver.restype = ctypes.c_int
149
+
150
+ tf_evaluator_remain_cp_num = lib.tf_evaluator_remain_cp_num
151
+ tf_evaluator_remain_cp_num.argtypes = [ctypes.c_void_p]
152
+ tf_evaluator_remain_cp_num.restype = ctypes.c_int
153
+
154
+ tf_evaluator_remain_cp_to_deliver = lib.tf_evaluator_remain_cp_to_deliver
155
+ tf_evaluator_remain_cp_to_deliver.argtypes = [ctypes.c_void_p]
156
+ tf_evaluator_remain_cp_to_deliver.restype = ctypes.c_double
157
+
158
+ tf_evaluator_remain_cp_to_deliver_wm = lib.tf_evaluator_remain_cp_to_deliver_wm
159
+ tf_evaluator_remain_cp_to_deliver_wm.argtypes = [ctypes.c_void_p]
160
+ tf_evaluator_remain_cp_to_deliver_wm.restype = ctypes.c_double
161
+
162
+ tf_evaluator_calc_all = lib.tf_evaluator_calc_all
163
+ tf_evaluator_calc_all.argtypes = [ctypes.c_void_p]
164
+ tf_evaluator_calc_all.restype = ctypes.c_int
165
+
166
+ # Update function
167
+ tf_evaluator_update_info = lib.tf_evaluator_update_info
168
+ tf_evaluator_update_info.argtypes = [
169
+ ctypes.c_void_p, # evaluator
170
+ ctypes.c_void_p, # future_code_ptr
171
+ ctypes.c_size_t, # future_code_len
172
+ ctypes.c_double, # future_price
173
+ ctypes.c_void_p, # bond_code_ptr
174
+ ctypes.c_size_t, # bond_code_len
175
+ ctypes.c_double, # bond_ytm
176
+ ctypes.c_double, # capital_rate
177
+ ctypes.c_uint32, # year
178
+ ctypes.c_uint32, # month
179
+ ctypes.c_uint32, # day
180
+ ]
181
+ tf_evaluator_update_info.restype = ctypes.c_int
182
+
183
+ # Utility function
184
+ free_string = lib.free_string
185
+ free_string.argtypes = [ctypes.c_char_p]
186
+ free_string.restype = None
pybond/ffi/lib.py ADDED
@@ -0,0 +1,8 @@
1
+ import ctypes
2
+
3
+ import llvmlite.binding
4
+
5
+ from pybond import pybond
6
+
7
+ lib = ctypes.cdll.LoadLibrary(pybond.__file__)
8
+ llvmlite.binding.load_library_permanently(pybond.__file__)
pybond/nb/__init__.py ADDED
@@ -0,0 +1,31 @@
1
+ # from datetime import date, datetime, time
2
+
3
+ from .nb_bond import Bond, BondType, bond_type
4
+ from .nb_date import DateType, date_type
5
+ from .nb_datetime import DateTime, DateTimeType, datetime_type
6
+ from .nb_duration import Duration, DurationType, duration_type
7
+ from .nb_evaluators import TfEvaluator, TfEvaluatorType, tf_evaluator_type
8
+ from .nb_time import Time, TimeType, time_type
9
+
10
+ __all__ = [
11
+ "Bond",
12
+ "BondType",
13
+ "DateTime",
14
+ "DateTimeType",
15
+ "DateType",
16
+ "Duration",
17
+ "DurationType",
18
+ "TfEvaluator",
19
+ "TfEvaluatorType",
20
+ "Time",
21
+ "TimeType",
22
+ "bond_type",
23
+ # "date",
24
+ "date_type",
25
+ # "datetime",
26
+ "datetime_type",
27
+ "duration_type",
28
+ "tf_evaluator_type",
29
+ # "time",
30
+ "time_type",
31
+ ]
pybond/nb/ir_utils.py ADDED
@@ -0,0 +1,47 @@
1
+ from llvmlite import ir
2
+ from numba.core import cgutils
3
+
4
+
5
+ def ir_isinstance(pyapi, obj, typ):
6
+ fnty = ir.FunctionType(ir.IntType(1), [pyapi.pyobj, pyapi.pyobj])
7
+ fn = cgutils.get_or_insert_function(
8
+ pyapi.builder.module, fnty, name="PyObject_IsInstance"
9
+ )
10
+ return pyapi.builder.call(fn, (obj, typ))
11
+
12
+
13
+ def ir_build_datetime(val, builder, *, from_utc: bool = False):
14
+ mod = builder.module
15
+ fnty = ir.FunctionType(ir.PointerType(ir.IntType(8)), [ir.IntType(64)])
16
+ if not from_utc:
17
+ build_datetime_ns_fn = cgutils.get_or_insert_function(
18
+ mod, fnty, "build_datetime_ns"
19
+ )
20
+ else:
21
+ build_datetime_ns_fn = cgutils.get_or_insert_function(
22
+ mod, fnty, "build_datetime_from_utc_ns"
23
+ )
24
+ ptr = builder.call(build_datetime_ns_fn, [val])
25
+ return ptr
26
+
27
+
28
+ def ir_timestamp_nanos(ptr, builder):
29
+ mod = builder.module
30
+ fnty = ir.FunctionType(ir.IntType(64), [ir.PointerType(ir.IntType(8))])
31
+ fn = cgutils.get_or_insert_function(mod, fnty, "timestamp_nanos")
32
+ ptr = builder.call(fn, [ptr])
33
+ return ptr
34
+
35
+
36
+ def ir_local_timestamp_nanos(ptr, builder):
37
+ mod = builder.module
38
+ fnty = ir.FunctionType(ir.IntType(64), [ir.PointerType(ir.IntType(8))])
39
+ fn = cgutils.get_or_insert_function(mod, fnty, "local_timestamp_nanos")
40
+ ptr = builder.call(fn, [ptr])
41
+ return ptr
42
+
43
+
44
+ def long_as_ulong(pyapi, numobj):
45
+ fnty = ir.FunctionType(pyapi.ulong, [pyapi.pyobj])
46
+ fn = pyapi._get_function(fnty, name="PyLong_AsUnsignedLong")
47
+ return pyapi.builder.call(fn, [numobj])
pybond/nb/nb_bond.py ADDED
@@ -0,0 +1,213 @@
1
+ from llvmlite import ir
2
+ from numba import types
3
+ from numba.core import cgutils, utils
4
+ from numba.cpython.hashing import _Py_hash_t
5
+ from numba.extending import (
6
+ as_numba_type,
7
+ box,
8
+ intrinsic,
9
+ lower_builtin,
10
+ make_attribute_wrapper,
11
+ models,
12
+ overload_attribute,
13
+ overload_method,
14
+ register_model,
15
+ type_callable,
16
+ typeof_impl,
17
+ )
18
+
19
+ from pybond import Bond
20
+ from pybond.ffi import (
21
+ bond_accrued_interest,
22
+ bond_calc_ytm,
23
+ bond_clean_price,
24
+ bond_coupon_rate,
25
+ bond_dirty_price,
26
+ bond_duration,
27
+ )
28
+ from pybond.nb.nb_datetime import DateTimeType # , create_bond
29
+
30
+ from .nb_date import DateType
31
+
32
+
33
+ class BondType(types.Type):
34
+ def __init__(self):
35
+ super().__init__(name="Bond")
36
+
37
+
38
+ bond_type = BondType()
39
+ as_numba_type.register(Bond, bond_type)
40
+
41
+
42
+ @typeof_impl.register(Bond)
43
+ def typeof_bond(val, c):
44
+ return bond_type
45
+
46
+
47
+ @type_callable(Bond)
48
+ def type_bond(context):
49
+ def typer(val):
50
+ return bond_type
51
+
52
+ return typer
53
+
54
+
55
+ @register_model(BondType)
56
+ class BondModel(models.StructModel):
57
+ def __init__(self, dmm, fe_type):
58
+ members = [
59
+ ("ptr", types.voidptr),
60
+ ]
61
+ models.StructModel.__init__(self, dmm, fe_type, members)
62
+
63
+
64
+ make_attribute_wrapper(BondType, "ptr", "ptr")
65
+
66
+
67
+ @lower_builtin(Bond, types.string)
68
+ def impl_bond_builder(context, builder, sig, args):
69
+ typ = sig.return_type
70
+ (val,) = args
71
+ # Get string data from Numba string
72
+ code = context.make_helper(builder, types.string, val)
73
+ fn = cgutils.get_or_insert_function(
74
+ builder.module,
75
+ ir.FunctionType(
76
+ ir.PointerType(ir.IntType(8)),
77
+ [ir.PointerType(ir.IntType(8)), ir.IntType(utils.MACHINE_BITS)],
78
+ ),
79
+ name="create_bond",
80
+ )
81
+ ptr = builder.call(fn, [code.data, code.length])
82
+ # Create Bond object
83
+ bond = cgutils.create_struct_proxy(typ)(context, builder)
84
+ bond.ptr = ptr
85
+ return bond._getvalue()
86
+
87
+
88
+ @overload_attribute(BondType, "coupon_rate")
89
+ def bond_attr_coupon_rate(bond):
90
+ def impl(bond):
91
+ return bond_coupon_rate(bond.ptr)
92
+
93
+ return impl
94
+
95
+
96
+ def ir_get_bond_full_code(ptr, context, builder):
97
+ """根据Bond的指针获取bond的代码(包括交易所信息)"""
98
+ fn = cgutils.get_or_insert_function(
99
+ builder.module,
100
+ ir.FunctionType(ir.PointerType(ir.IntType(8)), [ir.PointerType(ir.IntType(8))]),
101
+ name="bond_full_code",
102
+ )
103
+ cstr = builder.call(fn, [ptr])
104
+ # 使用 LLVM strlen
105
+ strlen_fn = cgutils.get_or_insert_function(
106
+ builder.module,
107
+ ir.FunctionType(ir.IntType(64), [ir.PointerType(ir.IntType(8))]),
108
+ name="strlen",
109
+ )
110
+ length = builder.call(strlen_fn, [cstr])
111
+ uni_str = cgutils.create_struct_proxy(types.unicode_type)(context, builder)
112
+ uni_str.data = cstr
113
+ uni_str.length = length
114
+ uni_str.kind = ir.Constant(ir.IntType(32), 1) # kind=1 is PY_UNICODE_1BYTE_KIND
115
+ uni_str.is_ascii = ir.Constant(ir.IntType(32), 1)
116
+ uni_str.meminfo = context.get_constant_null(types.voidptr)
117
+ # Set hash to -1 to indicate that it should be computed.
118
+ # We cannot bake in the hash value because of hashseed randomization.
119
+ uni_str.hash = context.get_constant(_Py_hash_t, -1)
120
+ uni_str.parent = cgutils.get_null_value(uni_str.parent.type)
121
+ return uni_str._getvalue()
122
+
123
+
124
+ @intrinsic
125
+ def get_bond_full_code(typingctx, bond_ptr):
126
+ """根据Bond的指针获取bond的代码(包括交易所信息)"""
127
+
128
+ def codegen(context, builder, sig, args):
129
+ return ir_get_bond_full_code(args[0], context, builder)
130
+
131
+ sig = types.unicode_type(bond_ptr)
132
+ return sig, codegen
133
+
134
+
135
+ @overload_attribute(BondType, "full_code")
136
+ def get_full_code_attr(bond):
137
+ if isinstance(bond, BondType):
138
+
139
+ def impl(bond):
140
+ return get_bond_full_code(bond.ptr)
141
+
142
+ return impl
143
+
144
+
145
+ @overload_method(BondType, "duration")
146
+ def bond_calc_duration(bond, ytm, date):
147
+ if not isinstance(date, (DateType, DateTimeType)):
148
+ return
149
+
150
+ def impl(bond, ytm, date):
151
+ return bond_duration(bond.ptr, ytm, date.year, date.month, date.day)
152
+
153
+ return impl
154
+
155
+
156
+ @overload_method(BondType, "accrued_interest")
157
+ def bond_calc_accrued_interest(bond, date):
158
+ if not isinstance(date, (DateType, DateTimeType)):
159
+ return
160
+
161
+ def impl(bond, date):
162
+ return bond_accrued_interest(bond.ptr, date.year, date.month, date.day)
163
+
164
+ return impl
165
+
166
+
167
+ @overload_method(BondType, "dirty_price")
168
+ def bond_calc_dirty_price(bond, ytm, date):
169
+ if not isinstance(date, (DateType, DateTimeType)):
170
+ return
171
+
172
+ def impl(bond, ytm, date):
173
+ return bond_dirty_price(bond.ptr, ytm, date.year, date.month, date.day)
174
+
175
+ return impl
176
+
177
+
178
+ @overload_method(BondType, "clean_price")
179
+ def bond_calc_clean_price(bond, ytm, date):
180
+ if not isinstance(date, (DateType, DateTimeType)):
181
+ return
182
+
183
+ def impl(bond, ytm, date):
184
+ return bond_clean_price(bond.ptr, ytm, date.year, date.month, date.day)
185
+
186
+ return impl
187
+
188
+
189
+ @overload_method(BondType, "calc_ytm_with_price")
190
+ def bond_ytm_with_price(bond, dirty_price, date):
191
+ if not isinstance(date, (DateType, DateTimeType)):
192
+ return
193
+
194
+ def impl(bond, dirty_price, date):
195
+ return bond_calc_ytm(bond.ptr, dirty_price, date.year, date.month, date.day)
196
+
197
+ return impl
198
+
199
+
200
+ @box(BondType)
201
+ def box_bond(typ, val, c):
202
+ """
203
+ Convert a native Bond structure to python Bond.
204
+ """
205
+ bond = cgutils.create_struct_proxy(typ)(c.context, c.builder, value=val)
206
+ bond_code = ir_get_bond_full_code(bond.ptr, c.context, c.builder)
207
+ # Call Bond new to create a new Bond object
208
+ val_obj = c.pyapi.from_native_value(types.unicode_type, bond_code)
209
+ class_obj = c.pyapi.unserialize(c.pyapi.serialize_object(Bond))
210
+ res = c.pyapi.call_function_objargs(class_obj, (val_obj,))
211
+ c.pyapi.decref(val_obj)
212
+ c.pyapi.decref(class_obj)
213
+ return res
pybond/nb/nb_date.py ADDED
@@ -0,0 +1,209 @@
1
+ import datetime
2
+ import operator
3
+
4
+ from llvmlite import ir
5
+ from numba import types
6
+ from numba.core import cgutils
7
+ from numba.extending import (
8
+ NativeValue,
9
+ as_numba_type,
10
+ box,
11
+ lower_builtin,
12
+ make_attribute_wrapper,
13
+ models,
14
+ overload,
15
+ register_model,
16
+ type_callable,
17
+ typeof_impl,
18
+ unbox,
19
+ )
20
+
21
+ from .ir_utils import long_as_ulong
22
+
23
+
24
+ class DateType(types.Type):
25
+ def __init__(self):
26
+ super().__init__(name="Date")
27
+
28
+
29
+ date_type = DateType()
30
+ as_numba_type.register(datetime.date, date_type)
31
+
32
+
33
+ @typeof_impl.register(datetime.date)
34
+ def typeof_datetime_date(val, c):
35
+ return date_type
36
+
37
+
38
+ @type_callable(datetime.date)
39
+ def type_date(context):
40
+ def typer(year, month, day):
41
+ return date_type
42
+
43
+ return typer
44
+
45
+
46
+ @register_model(DateType)
47
+ class DateModel(models.StructModel):
48
+ def __init__(self, dmm, fe_type):
49
+ members = [
50
+ ("year", types.uint32),
51
+ ("month", types.uint32),
52
+ ("day", types.uint32),
53
+ ]
54
+ models.StructModel.__init__(self, dmm, fe_type, members)
55
+
56
+
57
+ make_attribute_wrapper(DateType, "year", "year")
58
+ make_attribute_wrapper(DateType, "month", "month")
59
+ make_attribute_wrapper(DateType, "day", "day")
60
+
61
+
62
+ @lower_builtin(datetime.date, types.uint32, types.uint32, types.uint32)
63
+ @lower_builtin(datetime.date, types.int32, types.int32, types.int32)
64
+ def datetime_date_constructor_u32(context, builder, sig, args):
65
+ date_type = sig.return_type
66
+ date = cgutils.create_struct_proxy(date_type)(context, builder)
67
+ date.year = args[0]
68
+ date.month = args[1]
69
+ date.day = args[2]
70
+ return date._getvalue()
71
+
72
+
73
+ @lower_builtin(datetime.date, types.int64, types.int64, types.int64)
74
+ def datetime_date_constructor_i64(context, builder, sig, args):
75
+ date_type = sig.return_type
76
+ date = cgutils.create_struct_proxy(date_type)(context, builder)
77
+ date.year = builder.trunc(args[0], ir.IntType(32))
78
+ date.month = builder.trunc(args[1], ir.IntType(32))
79
+ date.day = builder.trunc(args[2], ir.IntType(32))
80
+ return date._getvalue()
81
+
82
+
83
+ @unbox(DateType)
84
+ def unbox_date(typ, obj, c):
85
+ year_obj = c.pyapi.object_getattr_string(obj, "year")
86
+ year = long_as_ulong(c.pyapi, year_obj)
87
+ month_obj = c.pyapi.object_getattr_string(obj, "month")
88
+ month = long_as_ulong(c.pyapi, month_obj)
89
+ day_obj = c.pyapi.object_getattr_string(obj, "day")
90
+ second = long_as_ulong(c.pyapi, day_obj)
91
+ c.pyapi.decref(year_obj)
92
+ c.pyapi.decref(month_obj)
93
+ c.pyapi.decref(day_obj)
94
+
95
+ date = cgutils.create_struct_proxy(typ)(c.context, c.builder)
96
+ date.year = c.builder.trunc(year, ir.IntType(32))
97
+ date.month = c.builder.trunc(month, ir.IntType(32))
98
+ date.day = c.builder.trunc(second, ir.IntType(32))
99
+ # Check for errors
100
+ is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
101
+ return NativeValue(date._getvalue(), is_error=is_error)
102
+
103
+
104
+ @box(DateType)
105
+ def box_date(typ, val, c):
106
+ """
107
+ Box a native date object into a Python datetime.date object.
108
+ """
109
+ date = cgutils.create_struct_proxy(typ)(c.context, c.builder, value=val)
110
+ year_obj = c.pyapi.long_from_unsigned_int(date.year)
111
+ month_obj = c.pyapi.long_from_unsigned_int(date.month)
112
+ day_obj = c.pyapi.long_from_unsigned_int(date.day)
113
+
114
+ class_obj = c.pyapi.unserialize(c.pyapi.serialize_object(datetime.date))
115
+ date_obj = c.pyapi.call_function_objargs(class_obj, (year_obj, month_obj, day_obj))
116
+ c.pyapi.decref(year_obj)
117
+ c.pyapi.decref(month_obj)
118
+ c.pyapi.decref(day_obj)
119
+ return date_obj
120
+
121
+
122
+ @overload(operator.ge)
123
+ def impl_ge(dt, dt2):
124
+ if not isinstance(dt, DateType) or not isinstance(dt, DateType):
125
+ return
126
+
127
+ def impl(dt, dt2):
128
+ if dt.year == dt2.year:
129
+ if dt.month == dt2.month:
130
+ return dt.day >= dt2.day
131
+ else:
132
+ return dt.month >= dt2.month
133
+ else:
134
+ return dt.year >= dt2.year
135
+
136
+ return impl
137
+
138
+
139
+ @overload(operator.gt)
140
+ def impl_gt(dt, dt2):
141
+ if not isinstance(dt, DateType) or not isinstance(dt, DateType):
142
+ return
143
+
144
+ def impl(dt, dt2):
145
+ if dt.year == dt2.year:
146
+ if dt.month == dt2.month:
147
+ return dt.day > dt2.day
148
+ else:
149
+ return dt.month > dt2.month
150
+ else:
151
+ return dt.year > dt2.year
152
+
153
+ return impl
154
+
155
+
156
+ @overload(operator.le)
157
+ def impl_le(dt, dt2):
158
+ if not isinstance(dt, DateType) or not isinstance(dt, DateType):
159
+ return
160
+
161
+ def impl(dt, dt2):
162
+ if dt.year == dt2.year:
163
+ if dt.month == dt2.month:
164
+ return dt.day <= dt2.day
165
+ else:
166
+ return dt.month <= dt2.month
167
+ else:
168
+ return dt.year <= dt2.year
169
+
170
+ return impl
171
+
172
+
173
+ @overload(operator.lt)
174
+ def impl_lt(dt, dt2):
175
+ if not isinstance(dt, DateType) or not isinstance(dt, DateType):
176
+ return
177
+
178
+ def impl(dt, dt2):
179
+ if dt.year == dt2.year:
180
+ if dt.month == dt2.month:
181
+ return dt.day < dt2.day
182
+ else:
183
+ return dt.month < dt2.month
184
+ else:
185
+ return dt.year < dt2.year
186
+
187
+ return impl
188
+
189
+
190
+ @overload(operator.eq)
191
+ def impl_eq(dt, dt2):
192
+ if not isinstance(dt, DateType) or not isinstance(dt, DateType):
193
+ return
194
+
195
+ def impl(dt, dt2):
196
+ return dt.year == dt2.year and dt.month == dt2.month and dt.day == dt2.day
197
+
198
+ return impl
199
+
200
+
201
+ @overload(operator.ne)
202
+ def impl_ne(dt, dt2):
203
+ if not isinstance(dt, DateType) or not isinstance(dt, DateType):
204
+ return
205
+
206
+ def impl(dt, dt2):
207
+ return dt.year != dt2.year or dt.month != dt2.month or dt.day != dt2.day
208
+
209
+ return impl