Skip to content

Convert between Python integers and C integer types correctly #754

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 30 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
775de6f
fix
juliannguyen4 Mar 24, 2025
f3639f8
on windows, as_integer will be truncated if val > 32 bits
juliannguyen4 Mar 24, 2025
d811ce7
add test
juliannguyen4 Mar 24, 2025
dd052f0
fix
juliannguyen4 Mar 24, 2025
5c4dd06
Revert "fix"
juliannguyen4 Mar 24, 2025
e5e39f1
Revert "add test"
juliannguyen4 Mar 24, 2025
ebfb669
add test
juliannguyen4 Mar 24, 2025
7444c2e
add cleanup, comment
juliannguyen4 Mar 24, 2025
4343883
Merge remote-tracking branch 'origin/dev' into CLIENT-3380-windows-32…
juliannguyen4 Apr 2, 2025
a8e4f37
reuse pyobject_to_val
juliannguyen4 Apr 2, 2025
9ef61bd
fix
juliannguyen4 Apr 2, 2025
1d6a06f
Merge remote-tracking branch 'origin/dev' into CLIENT-3380-windows-32…
juliannguyen4 Apr 3, 2025
3ed6b8c
Fix naming to make less confusing...
juliannguyen4 Apr 3, 2025
a994bd0
finish refactor
juliannguyen4 Apr 3, 2025
31b2ba5
dont need nested if
juliannguyen4 Apr 7, 2025
f8d9798
improve naming
juliannguyen4 Apr 7, 2025
9ae5b9a
do the same for pyobj to val
juliannguyen4 Apr 7, 2025
5b7dde6
neg case
juliannguyen4 Apr 7, 2025
2678e65
fix naming
juliannguyen4 Apr 7, 2025
190a421
rename, add missing err handling from original code
juliannguyen4 Apr 7, 2025
6c8dc1b
prevent truncating int values
juliannguyen4 Apr 7, 2025
c85993e
fix
juliannguyen4 Apr 7, 2025
7845979
properly check for overflow. move func description to decl
juliannguyen4 Apr 8, 2025
ea9f6f9
add test to check for mem errors/undef behavior
juliannguyen4 Apr 9, 2025
3a15e4d
fix
juliannguyen4 Apr 9, 2025
e8f6e11
raise native exc
juliannguyen4 Apr 9, 2025
4fcb6af
null can be put()
juliannguyen4 Apr 9, 2025
4bbf3ec
Merge remote-tracking branch 'origin/dev' into CLIENT-3380-windows-32…
juliannguyen4 Apr 10, 2025
e185d42
Merge remote-tracking branch 'origin/dev' into CLIENT-3380-windows-32…
juliannguyen4 Apr 10, 2025
0de81ea
fix for one
juliannguyen4 Apr 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions src/include/conversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,11 @@ as_status as_user_info_array_to_pyobject(as_error *err, as_user **users,
as_status pyobject_to_strArray(as_error *err, PyObject *py_list, char **arr,
uint32_t max_len);

as_status pyobject_to_val(AerospikeClient *self, as_error *err,
PyObject *py_obj, as_val **val,
as_static_pool *static_pool, int serializer_type);
// On success, heap allocates a new as_val object and assigns its address to val
as_status as_val_new_from_pyobject(AerospikeClient *self, as_error *err,
PyObject *py_obj, as_val **val,
as_static_pool *static_pool,
int serializer_type);

as_status pyobject_to_map(AerospikeClient *self, as_error *err,
PyObject *py_dict, as_map **map,
Expand All @@ -102,10 +104,10 @@ as_status pyobject_to_key(as_error *err, PyObject *py_key, as_key *key);
as_status pyobject_to_index(AerospikeClient *self, as_error *err,
PyObject *py_value, long *long_val);

as_status pyobject_to_record(AerospikeClient *self, as_error *err,
PyObject *py_rec, PyObject *py_meta,
as_record *rec, int serializer_option,
as_static_pool *static_pool);
as_status as_record_init_from_pyobject(AerospikeClient *self, as_error *err,
PyObject *py_rec, PyObject *py_meta,
as_record *rec, int serializer_option,
as_static_pool *static_pool);

as_status val_to_pyobject(AerospikeClient *self, as_error *err,
const as_val *val, PyObject **py_map);
Expand Down
7 changes: 6 additions & 1 deletion src/main/client/batch_operate.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,12 @@ static PyObject *AerospikeClient_Batch_Operate_Invoke(
ops.ttl = AS_RECORD_CLIENT_DEFAULT_TTL;
}
else {
ops.ttl = (uint32_t)PyLong_AsLong(py_ttl);
unsigned long ttl = PyLong_AsUnsignedLong(py_ttl);
if (ttl == (unsigned long)-1 && PyErr_Occurred()) {
// We assume br_instance = NULL
goto CLEANUP;
}
ops.ttl = (uint32_t)ttl;
}

// import batch_records helper
Expand Down
6 changes: 3 additions & 3 deletions src/main/client/cdt_operation_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ as_status get_asval(AerospikeClient *self, as_error *err, char *key,
*val = NULL;
return AEROSPIKE_OK;
}
return pyobject_to_val(self, err, py_val, val, static_pool,
serializer_type);
return as_val_new_from_pyobject(self, err, py_val, val, static_pool,
serializer_type);
}

as_status get_val_list(AerospikeClient *self, as_error *err,
Expand Down Expand Up @@ -136,7 +136,7 @@ as_status get_optional_int64_t(as_error *err, const char *key,
}

if (PyLong_Check(py_val)) {
*i64_valptr = (int64_t)PyLong_AsLong(py_val);
*i64_valptr = (int64_t)PyLong_AsLongLong(py_val);
if (PyErr_Occurred()) {
if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
return as_error_update(err, AEROSPIKE_ERR_PARAM, "%s too large",
Expand Down
2 changes: 1 addition & 1 deletion src/main/client/get_key_partition_id.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ PyObject *AerospikeClient_Get_Key_PartitionID_Invoke(AerospikeClient *self,

uint32_t id =
as_partition_getid(key.digest.value, self->as->cluster->n_partitions);
py_value = PyLong_FromLong(id);
py_value = PyLong_FromUnsignedLong(id);

if (key_initialised == true) {
// Destroy key only if it is initialised.
Expand Down
12 changes: 6 additions & 6 deletions src/main/client/operate.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ static inline bool isExprOp(int op);
}

#define CONVERT_VAL_TO_AS_VAL() \
if (pyobject_to_val(self, err, py_value, &put_val, static_pool, \
SERIALIZER_PYTHON) != AEROSPIKE_OK) { \
if (as_val_new_from_pyobject(self, err, py_value, &put_val, static_pool, \
SERIALIZER_PYTHON) != AEROSPIKE_OK) { \
return err->code; \
}

#define CONVERT_KEY_TO_AS_VAL() \
if (pyobject_to_val(self, err, py_key, &put_key, static_pool, \
SERIALIZER_PYTHON) != AEROSPIKE_OK) { \
if (as_val_new_from_pyobject(self, err, py_key, &put_key, static_pool, \
SERIALIZER_PYTHON) != AEROSPIKE_OK) { \
return err->code; \
}

Expand All @@ -123,8 +123,8 @@ static inline bool isExprOp(int op);
}

#define CONVERT_RANGE_TO_AS_VAL() \
if (pyobject_to_val(self, err, py_range, &put_range, static_pool, \
SERIALIZER_PYTHON) != AEROSPIKE_OK) { \
if (as_val_new_from_pyobject(self, err, py_range, &put_range, static_pool, \
SERIALIZER_PYTHON) != AEROSPIKE_OK) { \
return err->code; \
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/client/put.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ PyObject *AerospikeClient_Put_Invoke(AerospikeClient *self, PyObject *py_key,
key_initialised = true;

// Convert python bins and metadata objects to as_record
pyobject_to_record(self, &err, py_bins, py_meta, &rec, serializer_option,
&static_pool);
as_record_init_from_pyobject(self, &err, py_bins, py_meta, &rec,
serializer_option, &static_pool);
if (err.code != AEROSPIKE_OK) {
goto CLEANUP;
}
Expand Down
6 changes: 3 additions & 3 deletions src/main/client/query.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ static PyObject *AerospikeClient_QueryApply_Invoke(
return NULL;
}

return PyLong_FromLong(query_id);
return PyLong_FromUnsignedLongLong(query_id);
}

/**
Expand Down Expand Up @@ -589,10 +589,10 @@ PyObject *AerospikeClient_JobInfo(AerospikeClient *self, PyObject *args,

if (retObj) {
PyObject *py_longobject = NULL;
py_longobject = PyLong_FromLong(job_info.progress_pct);
py_longobject = PyLong_FromUnsignedLong(job_info.progress_pct);
PyDict_SetItemString(retObj, PROGRESS_PCT, py_longobject);
Py_XDECREF(py_longobject);
py_longobject = PyLong_FromLong(job_info.records_read);
py_longobject = PyLong_FromUnsignedLong(job_info.records_read);
PyDict_SetItemString(retObj, RECORDS_READ, py_longobject);
Py_XDECREF(py_longobject);
py_longobject = PyLong_FromLong(job_info.status);
Expand Down
3 changes: 2 additions & 1 deletion src/main/client/remove_bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,14 @@ AerospikeClient_RemoveBin_Invoke(AerospikeClient *self, PyObject *py_key,
}
}

// TODO: already have a helper function to parse this
if (py_meta && PyDict_Check(py_meta)) {
PyObject *py_gen = PyDict_GetItemString(py_meta, "gen");
PyObject *py_ttl = PyDict_GetItemString(py_meta, "ttl");

if (py_ttl) {
if (PyLong_Check(py_ttl)) {
rec.ttl = (uint32_t)PyLong_AsLong(py_ttl);
rec.ttl = (uint32_t)PyLong_AsUnsignedLong(py_ttl);
if ((uint32_t)-1 == rec.ttl && PyErr_Occurred()) {
as_error_update(
err, AEROSPIKE_ERR_PARAM,
Expand Down
3 changes: 2 additions & 1 deletion src/main/client/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ static PyObject *AerospikeClient_ScanApply_Invoke(
return NULL;
}

return PyLong_FromLong(scan_id);
// TODO: Doesn't match api
return PyLong_FromUnsignedLongLong(scan_id);
}

/**
Expand Down
53 changes: 30 additions & 23 deletions src/main/client/type.c
Original file line number Diff line number Diff line change
Expand Up @@ -688,23 +688,25 @@ static int AerospikeClient_Type_Init(AerospikeClient *self, PyObject *args,
PyObject *py_shm_max_nodes =
PyDict_GetItemString(py_shm, "shm_max_nodes");
if (py_shm_max_nodes && PyLong_Check(py_shm_max_nodes)) {
config.shm_max_nodes = PyLong_AsLong(py_shm_max_nodes);
config.shm_max_nodes = PyLong_AsUnsignedLong(py_shm_max_nodes);
}
py_shm_max_nodes = PyDict_GetItemString(py_shm, "max_nodes");
if (py_shm_max_nodes && PyLong_Check(py_shm_max_nodes)) {
config.shm_max_nodes = PyLong_AsLong(py_shm_max_nodes);
config.shm_max_nodes = PyLong_AsUnsignedLong(py_shm_max_nodes);
}

// This does not match documentation (wrong name and location in dict),
// but leave it for now for customers who may be using it
PyObject *py_shm_max_namespaces =
PyDict_GetItemString(py_shm, "shm_max_namespaces");
if (py_shm_max_namespaces && PyLong_Check(py_shm_max_namespaces)) {
config.shm_max_namespaces = PyLong_AsLong(py_shm_max_namespaces);
config.shm_max_namespaces =
PyLong_AsUnsignedLong(py_shm_max_namespaces);
}
py_shm_max_namespaces = PyDict_GetItemString(py_shm, "max_namespaces");
if (py_shm_max_namespaces && PyLong_Check(py_shm_max_namespaces)) {
config.shm_max_namespaces = PyLong_AsLong(py_shm_max_namespaces);
config.shm_max_namespaces =
PyLong_AsUnsignedLong(py_shm_max_namespaces);
}

// This does not match documentation (wrong name and location in dict),
Expand All @@ -714,14 +716,14 @@ static int AerospikeClient_Type_Init(AerospikeClient *self, PyObject *args,
if (py_shm_takeover_threshold_sec &&
PyLong_Check(py_shm_takeover_threshold_sec)) {
config.shm_takeover_threshold_sec =
PyLong_AsLong(py_shm_takeover_threshold_sec);
PyLong_AsUnsignedLong(py_shm_takeover_threshold_sec);
}
py_shm_takeover_threshold_sec =
PyDict_GetItemString(py_shm, "takeover_threshold_sec");
if (py_shm_takeover_threshold_sec &&
PyLong_Check(py_shm_takeover_threshold_sec)) {
config.shm_takeover_threshold_sec =
PyLong_AsLong(py_shm_takeover_threshold_sec);
PyLong_AsUnsignedLong(py_shm_takeover_threshold_sec);
}

PyObject *py_shm_cluster_key = PyDict_GetItemString(py_shm, "shm_key");
Expand Down Expand Up @@ -872,15 +874,16 @@ static int AerospikeClient_Type_Init(AerospikeClient *self, PyObject *args,
PyObject *py_max_threads =
PyDict_GetItemString(py_policies, "max_threads");
if (py_max_threads && PyLong_Check(py_max_threads)) {
config.max_conns_per_node = PyLong_AsLong(py_max_threads);
config.max_conns_per_node = PyLong_AsUnsignedLong(py_max_threads);
}

// This does not match documentation (should not be in policies),
// but leave it for now for customers who may be using it
PyObject *py_thread_pool_size =
PyDict_GetItemString(py_policies, "thread_pool_size");
if (py_thread_pool_size && PyLong_Check(py_thread_pool_size)) {
config.thread_pool_size = PyLong_AsLong(py_thread_pool_size);
config.thread_pool_size =
PyLong_AsUnsignedLong(py_thread_pool_size);
}

/*
Expand All @@ -900,7 +903,7 @@ static int AerospikeClient_Type_Init(AerospikeClient *self, PyObject *args,
PyObject *py_login_timeout =
PyDict_GetItemString(py_policies, "login_timeout_ms");
if (py_login_timeout && PyLong_Check(py_login_timeout)) {
config.login_timeout_ms = PyLong_AsLong(py_login_timeout);
config.login_timeout_ms = PyLong_AsUnsignedLong(py_login_timeout);
}

PyObject *py_auth_mode = PyDict_GetItemString(py_policies, "auth_mode");
Expand Down Expand Up @@ -930,34 +933,35 @@ static int AerospikeClient_Type_Init(AerospikeClient *self, PyObject *args,
PyObject *py_thread_pool_size =
PyDict_GetItemString(py_config, "thread_pool_size");
if (py_thread_pool_size && PyLong_Check(py_thread_pool_size)) {
config.thread_pool_size = PyLong_AsLong(py_thread_pool_size);
config.thread_pool_size = PyLong_AsUnsignedLong(py_thread_pool_size);
}

// max_threads (backward compatibility)
PyObject *py_max_threads = PyDict_GetItemString(py_config, "max_threads");
if (py_max_threads && PyLong_Check(py_max_threads)) {
config.max_conns_per_node = PyLong_AsLong(py_max_threads);
config.max_conns_per_node = PyLong_AsUnsignedLong(py_max_threads);
}

PyObject *py_min_conns_per_node =
PyDict_GetItemString(py_config, "min_conns_per_node");
if (py_min_conns_per_node && PyLong_Check(py_min_conns_per_node)) {
config.min_conns_per_node = PyLong_AsLong(py_min_conns_per_node);
config.min_conns_per_node =
PyLong_AsUnsignedLong(py_min_conns_per_node);
}

// max_conns_per_node
PyObject *py_max_conns =
PyDict_GetItemString(py_config, "max_conns_per_node");
if (py_max_conns && PyLong_Check(py_max_conns)) {
config.max_conns_per_node = PyLong_AsLong(py_max_conns);
config.max_conns_per_node = PyLong_AsUnsignedLong(py_max_conns);
}

// max_error_rate
PyObject *py_max_error_rate =
PyDict_GetItemString(py_config, "max_error_rate");
Py_XINCREF(py_max_error_rate);
if (py_max_error_rate && PyLong_Check(py_max_error_rate)) {
config.max_error_rate = PyLong_AsLong(py_max_error_rate);
config.max_error_rate = PyLong_AsUnsignedLong(py_max_error_rate);
}
Py_XDECREF(py_max_error_rate);

Expand All @@ -966,15 +970,15 @@ static int AerospikeClient_Type_Init(AerospikeClient *self, PyObject *args,
PyDict_GetItemString(py_config, "error_rate_window");
Py_XINCREF(py_error_rate_window);
if (py_error_rate_window && PyLong_Check(py_error_rate_window)) {
config.error_rate_window = PyLong_AsLong(py_error_rate_window);
config.error_rate_window = PyLong_AsUnsignedLong(py_error_rate_window);
}
Py_XDECREF(py_error_rate_window);

//conn_timeout_ms
PyObject *py_connect_timeout =
PyDict_GetItemString(py_config, "connect_timeout");
if (py_connect_timeout && PyLong_Check(py_connect_timeout)) {
config.conn_timeout_ms = PyLong_AsLong(py_connect_timeout);
config.conn_timeout_ms = PyLong_AsUnsignedLong(py_connect_timeout);
}

//Whether to utilize shared connection
Expand All @@ -997,20 +1001,20 @@ static int AerospikeClient_Type_Init(AerospikeClient *self, PyObject *args,
PyObject *py_compression_threshold =
PyDict_GetItemString(py_config, "compression_threshold");
if (py_compression_threshold && PyLong_Check(py_compression_threshold)) {
int compression_value = PyLong_AsLong(py_compression_threshold);
if (compression_value >= 0) {
config.policies.write.compression_threshold = compression_value;
unsigned long compression_value =
PyLong_AsUnsignedLong(py_compression_threshold);
if (compression_value == (unsigned long)-1 && PyErr_Occurred()) {
goto RAISE_EXCEPTION_WITHOUT_AS_ERROR;
}
else {
error_code = INIT_COMPRESSION_ERR;
goto CONSTRUCTOR_ERROR;
config.policies.write.compression_threshold = compression_value;
}
}

PyObject *py_tend_interval =
PyDict_GetItemString(py_config, "tend_interval");
if (py_tend_interval && PyLong_Check(py_tend_interval)) {
config.tender_interval = PyLong_AsLong(py_tend_interval);
config.tender_interval = PyLong_AsUnsignedLong(py_tend_interval);
}

PyObject *py_cluster_name = PyDict_GetItemString(py_config, "cluster_name");
Expand Down Expand Up @@ -1040,7 +1044,8 @@ static int AerospikeClient_Type_Init(AerospikeClient *self, PyObject *args,
PyObject *py_max_socket_idle = NULL;
py_max_socket_idle = PyDict_GetItemString(py_config, "max_socket_idle");
if (py_max_socket_idle && PyLong_Check(py_max_socket_idle)) {
long max_socket_idle = PyLong_AsLong(py_max_socket_idle);
unsigned long max_socket_idle =
PyLong_AsUnsignedLong(py_max_socket_idle);
if (max_socket_idle >= 0) {
config.max_socket_idle = (uint32_t)max_socket_idle;
}
Expand Down Expand Up @@ -1145,6 +1150,8 @@ static int AerospikeClient_Type_Init(AerospikeClient *self, PyObject *args,
}

raise_exception(&constructor_err);

RAISE_EXCEPTION_WITHOUT_AS_ERROR:
return -1;
}

Expand Down
Loading