bare-script 5.0.4__tar.gz → 5.0.5__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.
- {bare_script-5.0.4/src/bare_script.egg-info → bare_script-5.0.5}/PKG-INFO +1 -1
- {bare_script-5.0.4 → bare_script-5.0.5}/setup.cfg +1 -1
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script/runtime.py +17 -32
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script/runtime_c.c +64 -26
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script/value.py +25 -33
- {bare_script-5.0.4 → bare_script-5.0.5/src/bare_script.egg-info}/PKG-INFO +1 -1
- {bare_script-5.0.4 → bare_script-5.0.5}/LICENSE +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/README.md +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/pyproject.toml +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/setup.py +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script/__init__.py +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script/__main__.py +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script/bare.py +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script/include.py +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script/include_source.py +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script/library.py +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script/lint.py +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script/model.py +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script/options.py +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script/parser.py +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script.egg-info/SOURCES.txt +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script.egg-info/dependency_links.txt +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script.egg-info/entry_points.txt +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script.egg-info/requires.txt +0 -0
- {bare_script-5.0.4 → bare_script-5.0.5}/src/bare_script.egg-info/top_level.txt +0 -0
|
@@ -337,18 +337,16 @@ def _evaluate_expression_helper(expr, options, globals_, locals_, builtins, scri
|
|
|
337
337
|
if func_args_length < 1:
|
|
338
338
|
raise ValueArgsError('array', None)
|
|
339
339
|
array_value = func_args[0]
|
|
340
|
-
|
|
341
|
-
if array_type is not list:
|
|
340
|
+
if not isinstance(array_value, list):
|
|
342
341
|
raise ValueArgsError('array', array_value)
|
|
343
342
|
if func_args_length < 2:
|
|
344
343
|
raise ValueArgsError('index', None)
|
|
345
344
|
index_value = func_args[1]
|
|
346
|
-
|
|
347
|
-
if index_type is float:
|
|
345
|
+
if isinstance(index_value, float):
|
|
348
346
|
if index_value < 0 or not index_value.is_integer():
|
|
349
347
|
raise ValueArgsError('index', index_value)
|
|
350
348
|
index_value = int(index_value)
|
|
351
|
-
elif
|
|
349
|
+
elif isinstance(index_value, int) and not isinstance(index_value, bool):
|
|
352
350
|
if index_value < 0:
|
|
353
351
|
raise ValueArgsError('index', index_value)
|
|
354
352
|
else:
|
|
@@ -362,8 +360,7 @@ def _evaluate_expression_helper(expr, options, globals_, locals_, builtins, scri
|
|
|
362
360
|
if func_args_length < 1:
|
|
363
361
|
raise ValueArgsError('array', None, 0)
|
|
364
362
|
array_value = func_args[0]
|
|
365
|
-
|
|
366
|
-
if array_type is not list:
|
|
363
|
+
if not isinstance(array_value, list):
|
|
367
364
|
raise ValueArgsError('array', array_value, 0)
|
|
368
365
|
if func_args_length > 1:
|
|
369
366
|
raise ValueArgsError(None, func_args_length, 0)
|
|
@@ -372,8 +369,7 @@ def _evaluate_expression_helper(expr, options, globals_, locals_, builtins, scri
|
|
|
372
369
|
if func_args_length < 1:
|
|
373
370
|
raise ValueArgsError('array', None)
|
|
374
371
|
array_value = func_args[0]
|
|
375
|
-
|
|
376
|
-
if array_type is not list:
|
|
372
|
+
if not isinstance(array_value, list):
|
|
377
373
|
raise ValueArgsError('array', array_value)
|
|
378
374
|
array_value.extend(func_args[1:])
|
|
379
375
|
return array_value
|
|
@@ -381,18 +377,16 @@ def _evaluate_expression_helper(expr, options, globals_, locals_, builtins, scri
|
|
|
381
377
|
if func_args_length < 1:
|
|
382
378
|
raise ValueArgsError('array', None)
|
|
383
379
|
array_value = func_args[0]
|
|
384
|
-
|
|
385
|
-
if array_type is not list:
|
|
380
|
+
if not isinstance(array_value, list):
|
|
386
381
|
raise ValueArgsError('array', array_value)
|
|
387
382
|
if func_args_length < 2:
|
|
388
383
|
raise ValueArgsError('index', None)
|
|
389
384
|
index_value = func_args[1]
|
|
390
|
-
|
|
391
|
-
if index_type is float:
|
|
385
|
+
if isinstance(index_value, float):
|
|
392
386
|
if index_value < 0 or not index_value.is_integer():
|
|
393
387
|
raise ValueArgsError('index', index_value)
|
|
394
388
|
index_value = int(index_value)
|
|
395
|
-
elif
|
|
389
|
+
elif isinstance(index_value, int) and not isinstance(index_value, bool):
|
|
396
390
|
if index_value < 0:
|
|
397
391
|
raise ValueArgsError('index', index_value)
|
|
398
392
|
else:
|
|
@@ -408,8 +402,7 @@ def _evaluate_expression_helper(expr, options, globals_, locals_, builtins, scri
|
|
|
408
402
|
if func_args_length < 1:
|
|
409
403
|
raise ValueArgsError('x', None)
|
|
410
404
|
x_value = func_args[0]
|
|
411
|
-
|
|
412
|
-
if (x_type is not int and x_type is not float) or not x_value >= 0:
|
|
405
|
+
if not isinstance(x_value, (int, float)) or isinstance(x_value, bool) or not x_value >= 0:
|
|
413
406
|
raise ValueArgsError('x', x_value)
|
|
414
407
|
if func_args_length > 1:
|
|
415
408
|
raise ValueArgsError(None, func_args_length)
|
|
@@ -419,14 +412,12 @@ def _evaluate_expression_helper(expr, options, globals_, locals_, builtins, scri
|
|
|
419
412
|
if func_args_length < 1:
|
|
420
413
|
raise ValueArgsError('object', None, default_value)
|
|
421
414
|
object_value = func_args[0]
|
|
422
|
-
|
|
423
|
-
if object_type is not dict:
|
|
415
|
+
if not isinstance(object_value, dict):
|
|
424
416
|
raise ValueArgsError('object', object_value, default_value)
|
|
425
417
|
if func_args_length < 2:
|
|
426
418
|
raise ValueArgsError('key', None, default_value)
|
|
427
419
|
key_value = func_args[1]
|
|
428
|
-
|
|
429
|
-
if key_type is not str:
|
|
420
|
+
if not isinstance(key_value, str):
|
|
430
421
|
raise ValueArgsError('key', key_value, default_value)
|
|
431
422
|
if func_args_length > 3:
|
|
432
423
|
raise ValueArgsError(None, func_args_length, default_value)
|
|
@@ -435,14 +426,12 @@ def _evaluate_expression_helper(expr, options, globals_, locals_, builtins, scri
|
|
|
435
426
|
if func_args_length < 1:
|
|
436
427
|
raise ValueArgsError('object', None, False)
|
|
437
428
|
object_value = func_args[0]
|
|
438
|
-
|
|
439
|
-
if object_type is not dict:
|
|
429
|
+
if not isinstance(object_value, dict):
|
|
440
430
|
raise ValueArgsError('object', object_value, False)
|
|
441
431
|
if func_args_length < 2:
|
|
442
432
|
raise ValueArgsError('key', None, False)
|
|
443
433
|
key_value = func_args[1]
|
|
444
|
-
|
|
445
|
-
if key_type is not str:
|
|
434
|
+
if not isinstance(key_value, str):
|
|
446
435
|
raise ValueArgsError('key', key_value, False)
|
|
447
436
|
if func_args_length > 2:
|
|
448
437
|
raise ValueArgsError(None, func_args_length, False)
|
|
@@ -451,8 +440,7 @@ def _evaluate_expression_helper(expr, options, globals_, locals_, builtins, scri
|
|
|
451
440
|
if func_args_length < 1:
|
|
452
441
|
raise ValueArgsError('object', None)
|
|
453
442
|
object_value = func_args[0]
|
|
454
|
-
|
|
455
|
-
if object_type is not dict:
|
|
443
|
+
if not isinstance(object_value, dict):
|
|
456
444
|
raise ValueArgsError('object', object_value)
|
|
457
445
|
if func_args_length > 1:
|
|
458
446
|
raise ValueArgsError(None, func_args_length)
|
|
@@ -461,14 +449,12 @@ def _evaluate_expression_helper(expr, options, globals_, locals_, builtins, scri
|
|
|
461
449
|
if func_args_length < 1:
|
|
462
450
|
raise ValueArgsError('object', None)
|
|
463
451
|
object_value = func_args[0]
|
|
464
|
-
|
|
465
|
-
if object_type is not dict:
|
|
452
|
+
if not isinstance(object_value, dict):
|
|
466
453
|
raise ValueArgsError('object', object_value)
|
|
467
454
|
if func_args_length < 2:
|
|
468
455
|
raise ValueArgsError('key', None)
|
|
469
456
|
key_value = func_args[1]
|
|
470
|
-
|
|
471
|
-
if key_type is not str:
|
|
457
|
+
if not isinstance(key_value, str):
|
|
472
458
|
raise ValueArgsError('key', key_value)
|
|
473
459
|
if func_args_length > 3:
|
|
474
460
|
raise ValueArgsError(None, func_args_length)
|
|
@@ -479,8 +465,7 @@ def _evaluate_expression_helper(expr, options, globals_, locals_, builtins, scri
|
|
|
479
465
|
if func_args_length < 1:
|
|
480
466
|
raise ValueArgsError('string', None, 0)
|
|
481
467
|
string_value = func_args[0]
|
|
482
|
-
|
|
483
|
-
if string_type is not str:
|
|
468
|
+
if not isinstance(string_value, str):
|
|
484
469
|
raise ValueArgsError('string', string_value, 0)
|
|
485
470
|
if func_args_length > 1:
|
|
486
471
|
raise ValueArgsError(None, func_args_length, 0)
|
|
@@ -265,6 +265,26 @@ static int obj_setitem(PyObject *obj, PyObject *key, PyObject *value)
|
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
|
|
268
|
+
// key in mapping semantics: 1 = found, 0 = missing, -1 = error
|
|
269
|
+
static int obj_contains(PyObject *obj, PyObject *key)
|
|
270
|
+
{
|
|
271
|
+
if (PyDict_CheckExact(obj)) {
|
|
272
|
+
return PyDict_Contains(obj, key);
|
|
273
|
+
}
|
|
274
|
+
return PySequence_Contains(obj, key);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
// del mapping[key] semantics: 0 = success, -1 = error
|
|
279
|
+
static int obj_delitem(PyObject *obj, PyObject *key)
|
|
280
|
+
{
|
|
281
|
+
if (PyDict_CheckExact(obj)) {
|
|
282
|
+
return PyDict_DelItem(obj, key);
|
|
283
|
+
}
|
|
284
|
+
return PyObject_DelItem(obj, key);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
|
|
268
288
|
//
|
|
269
289
|
// Execution context
|
|
270
290
|
//
|
|
@@ -576,18 +596,17 @@ static int value_boolean_c(PyObject *value)
|
|
|
576
596
|
if (value == Py_False || value == Py_None) {
|
|
577
597
|
return 0;
|
|
578
598
|
}
|
|
579
|
-
|
|
580
|
-
if (type == &PyFloat_Type) {
|
|
599
|
+
if (PyFloat_Check(value)) {
|
|
581
600
|
// NaN != 0 is true, matching the reference implementation
|
|
582
601
|
return PyFloat_AS_DOUBLE(value) != 0.;
|
|
583
602
|
}
|
|
584
|
-
if (
|
|
603
|
+
if (PyLong_Check(value)) {
|
|
585
604
|
return PyObject_IsTrue(value);
|
|
586
605
|
}
|
|
587
|
-
if (
|
|
606
|
+
if (PyUnicode_Check(value)) {
|
|
588
607
|
return PyUnicode_GetLength(value) != 0;
|
|
589
608
|
}
|
|
590
|
-
if (
|
|
609
|
+
if (PyList_Check(value)) {
|
|
591
610
|
return PyList_GET_SIZE(value) != 0;
|
|
592
611
|
}
|
|
593
612
|
|
|
@@ -597,12 +616,21 @@ static int value_boolean_c(PyObject *value)
|
|
|
597
616
|
|
|
598
617
|
|
|
599
618
|
// Is the value an exact int or float (bool is a subclass of int but has its own exact type)?
|
|
619
|
+
// This is the binary-operator fast-path check, mirroring the reference runtime's exact checks.
|
|
600
620
|
static inline int is_number(PyObject *value)
|
|
601
621
|
{
|
|
602
622
|
return PyLong_CheckExact(value) || PyFloat_CheckExact(value);
|
|
603
623
|
}
|
|
604
624
|
|
|
605
625
|
|
|
626
|
+
// Is the value a number per the value model (int/float subclasses count, bool is excluded)?
|
|
627
|
+
// This is the argument-validation check, mirroring value.value_args_validate's isinstance checks.
|
|
628
|
+
static inline int is_number_arg(PyObject *value)
|
|
629
|
+
{
|
|
630
|
+
return !PyBool_Check(value) && (PyLong_Check(value) || PyFloat_Check(value));
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
|
|
606
634
|
// Convert an int, or a float with an integral value, to a new int reference. Returns NULL with no
|
|
607
635
|
// exception set if the value is not an integral number.
|
|
608
636
|
static PyObject *integral_long(PyObject *value)
|
|
@@ -810,12 +838,12 @@ static void intrinsic_count_error(Py_ssize_t nargs, PyObject *return_value)
|
|
|
810
838
|
static PyObject *intrinsic_one_number(PyObject *args, const char *name, int constraint, PyObject *error_return)
|
|
811
839
|
{
|
|
812
840
|
PyObject *value = (PyList_GET_SIZE(args) >= 1) ? PyList_GET_ITEM(args, 0) : NULL;
|
|
813
|
-
if (value == NULL || value == Py_None || !
|
|
841
|
+
if (value == NULL || value == Py_None || !is_number_arg(value)) {
|
|
814
842
|
intrinsic_args_error(name, value, error_return);
|
|
815
843
|
return NULL;
|
|
816
844
|
}
|
|
817
845
|
if (constraint != 0) {
|
|
818
|
-
if (
|
|
846
|
+
if (PyFloat_Check(value)) {
|
|
819
847
|
// NaN fails both constraints, mirroring the reference's "not (value >= 0)"
|
|
820
848
|
double number = PyFloat_AS_DOUBLE(value);
|
|
821
849
|
if ((constraint == 1) ? !(number >= 0.) : !(number > 0.)) {
|
|
@@ -846,20 +874,25 @@ static PyObject *intrinsic_one_number(PyObject *args, const char *name, int cons
|
|
|
846
874
|
// like passing the int to a math-module function). Returns -1. with an exception set on error.
|
|
847
875
|
static double intrinsic_number_as_double(PyObject *value)
|
|
848
876
|
{
|
|
849
|
-
if (
|
|
877
|
+
if (PyFloat_Check(value)) {
|
|
850
878
|
return PyFloat_AS_DOUBLE(value);
|
|
851
879
|
}
|
|
852
880
|
return PyFloat_AsDouble(value);
|
|
853
881
|
}
|
|
854
882
|
|
|
855
883
|
|
|
856
|
-
// Validate
|
|
857
|
-
// 's' = string.
|
|
884
|
+
// Validate a typed argument at position ix: 'a' = array (list), 'o' = object (dict),
|
|
885
|
+
// 's' = string. Subclasses are accepted, mirroring value.value_args_validate's isinstance
|
|
886
|
+
// checks. Dict subclass values must be accessed through the obj_* mapping helpers (subclasses
|
|
887
|
+
// like OrderedDict keep state that direct PyDict_* mutation corrupts); list/str subclass values
|
|
888
|
+
// are accessed directly (PyList_*/PyUnicode_* operate on the shared base storage, bypassing any
|
|
889
|
+
// overridden methods). Returns the argument (borrowed from args) or NULL with ValueArgsError
|
|
890
|
+
// raised.
|
|
858
891
|
static PyObject *intrinsic_typed_arg(PyObject *args, Py_ssize_t ix, char type, const char *name, PyObject *error_return)
|
|
859
892
|
{
|
|
860
893
|
PyObject *value = (PyList_GET_SIZE(args) > ix) ? PyList_GET_ITEM(args, ix) : NULL;
|
|
861
894
|
int type_ok = (value != NULL) &&
|
|
862
|
-
((type == 'a') ?
|
|
895
|
+
((type == 'a') ? PyList_Check(value) : (type == 'o') ? PyDict_Check(value) : PyUnicode_Check(value));
|
|
863
896
|
if (!type_ok) {
|
|
864
897
|
intrinsic_args_error(name, value, error_return);
|
|
865
898
|
return NULL;
|
|
@@ -879,7 +912,7 @@ static int intrinsic_index_validate(PyObject *args, Py_ssize_t ix, const char *n
|
|
|
879
912
|
intrinsic_args_error(name, value, NULL);
|
|
880
913
|
return -1;
|
|
881
914
|
}
|
|
882
|
-
if (
|
|
915
|
+
if (PyLong_Check(value) && !PyBool_Check(value)) {
|
|
883
916
|
int overflow = 0;
|
|
884
917
|
long long index = PyLong_AsLongLongAndOverflow(value, &overflow);
|
|
885
918
|
if (index == -1 && !overflow && PyErr_Occurred()) {
|
|
@@ -892,7 +925,7 @@ static int intrinsic_index_validate(PyObject *args, Py_ssize_t ix, const char *n
|
|
|
892
925
|
*index_out = (overflow > 0 || index > (long long)PY_SSIZE_T_MAX) ? PY_SSIZE_T_MAX : (Py_ssize_t)index;
|
|
893
926
|
return 0;
|
|
894
927
|
}
|
|
895
|
-
if (
|
|
928
|
+
if (PyFloat_Check(value)) {
|
|
896
929
|
double number = PyFloat_AS_DOUBLE(value);
|
|
897
930
|
// int(value) raises for NaN and infinity, exactly like the reference's integer check
|
|
898
931
|
if (isnan(number)) {
|
|
@@ -920,7 +953,7 @@ static void intrinsic_index_bounds_error(PyObject *args, Py_ssize_t ix, const ch
|
|
|
920
953
|
{
|
|
921
954
|
PyObject *value = PyList_GET_ITEM(args, ix);
|
|
922
955
|
PyObject *normalized =
|
|
923
|
-
|
|
956
|
+
PyLong_Check(value) ? Py_NewRef(value) : PyLong_FromDouble(PyFloat_AS_DOUBLE(value));
|
|
924
957
|
if (normalized != NULL) {
|
|
925
958
|
intrinsic_args_error(name, normalized, NULL);
|
|
926
959
|
Py_DECREF(normalized);
|
|
@@ -962,7 +995,7 @@ static PyObject *intrinsic_math_abs(PyObject *args)
|
|
|
962
995
|
if (x == NULL) {
|
|
963
996
|
return NULL;
|
|
964
997
|
}
|
|
965
|
-
if (
|
|
998
|
+
if (PyFloat_Check(x)) {
|
|
966
999
|
return PyFloat_FromDouble(fabs(PyFloat_AS_DOUBLE(x)));
|
|
967
1000
|
}
|
|
968
1001
|
return PyNumber_Absolute(x);
|
|
@@ -977,7 +1010,7 @@ static PyObject *intrinsic_math_ceil(PyObject *args)
|
|
|
977
1010
|
if (x == NULL) {
|
|
978
1011
|
return NULL;
|
|
979
1012
|
}
|
|
980
|
-
if (
|
|
1013
|
+
if (PyFloat_Check(x)) {
|
|
981
1014
|
return PyLong_FromDouble(ceil(PyFloat_AS_DOUBLE(x)));
|
|
982
1015
|
}
|
|
983
1016
|
return Py_NewRef(x);
|
|
@@ -990,7 +1023,7 @@ static PyObject *intrinsic_math_floor(PyObject *args)
|
|
|
990
1023
|
if (x == NULL) {
|
|
991
1024
|
return NULL;
|
|
992
1025
|
}
|
|
993
|
-
if (
|
|
1026
|
+
if (PyFloat_Check(x)) {
|
|
994
1027
|
return PyLong_FromDouble(floor(PyFloat_AS_DOUBLE(x)));
|
|
995
1028
|
}
|
|
996
1029
|
return Py_NewRef(x);
|
|
@@ -1005,7 +1038,7 @@ static PyObject *intrinsic_math_sign(PyObject *args)
|
|
|
1005
1038
|
return NULL;
|
|
1006
1039
|
}
|
|
1007
1040
|
long sign;
|
|
1008
|
-
if (
|
|
1041
|
+
if (PyFloat_Check(x)) {
|
|
1009
1042
|
double number = PyFloat_AS_DOUBLE(x);
|
|
1010
1043
|
sign = (number < 0.) ? -1 : ((number == 0.) ? 0 : 1);
|
|
1011
1044
|
} else {
|
|
@@ -1169,6 +1202,9 @@ static PyObject *intrinsic_object_get(PyObject *args)
|
|
|
1169
1202
|
return NULL;
|
|
1170
1203
|
}
|
|
1171
1204
|
PyObject *value;
|
|
1205
|
+
// dict_get_ref reads the shared dict storage, matching the reference's object.get(key) - the
|
|
1206
|
+
// inherited dict.get - for dict subclasses too (PyObject_GetItem would call __getitem__,
|
|
1207
|
+
// which e.g. triggers defaultdict.__missing__)
|
|
1172
1208
|
int found = dict_get_ref(object, key, &value);
|
|
1173
1209
|
if (found < 0) {
|
|
1174
1210
|
return NULL;
|
|
@@ -1189,7 +1225,7 @@ static PyObject *intrinsic_object_set(PyObject *args)
|
|
|
1189
1225
|
return NULL;
|
|
1190
1226
|
}
|
|
1191
1227
|
PyObject *value = (PyList_GET_SIZE(args) > 2) ? PyList_GET_ITEM(args, 2) : Py_None;
|
|
1192
|
-
if (
|
|
1228
|
+
if (obj_setitem(object, key, value) < 0) {
|
|
1193
1229
|
return NULL;
|
|
1194
1230
|
}
|
|
1195
1231
|
return Py_NewRef(value);
|
|
@@ -1207,7 +1243,7 @@ static PyObject *intrinsic_object_has(PyObject *args)
|
|
|
1207
1243
|
if (key == NULL || intrinsic_count_check(args, 2, Py_False) < 0) {
|
|
1208
1244
|
return NULL;
|
|
1209
1245
|
}
|
|
1210
|
-
int has_key =
|
|
1246
|
+
int has_key = obj_contains(object, key);
|
|
1211
1247
|
if (has_key < 0) {
|
|
1212
1248
|
return NULL;
|
|
1213
1249
|
}
|
|
@@ -1222,7 +1258,8 @@ static PyObject *intrinsic_object_keys(PyObject *args)
|
|
|
1222
1258
|
if (object == NULL || intrinsic_count_check(args, 1, NULL) < 0) {
|
|
1223
1259
|
return NULL;
|
|
1224
1260
|
}
|
|
1225
|
-
|
|
1261
|
+
// Call keys() for dict subclasses (e.g. OrderedDict iteration order can differ from the dict's)
|
|
1262
|
+
return PyDict_CheckExact(object) ? PyDict_Keys(object) : PyMapping_Keys(object);
|
|
1226
1263
|
}
|
|
1227
1264
|
|
|
1228
1265
|
|
|
@@ -1237,11 +1274,11 @@ static PyObject *intrinsic_object_delete(PyObject *args)
|
|
|
1237
1274
|
if (key == NULL || intrinsic_count_check(args, 2, NULL) < 0) {
|
|
1238
1275
|
return NULL;
|
|
1239
1276
|
}
|
|
1240
|
-
int has_key =
|
|
1277
|
+
int has_key = obj_contains(object, key);
|
|
1241
1278
|
if (has_key < 0) {
|
|
1242
1279
|
return NULL;
|
|
1243
1280
|
}
|
|
1244
|
-
if (has_key &&
|
|
1281
|
+
if (has_key && obj_delitem(object, key) < 0) {
|
|
1245
1282
|
return NULL;
|
|
1246
1283
|
}
|
|
1247
1284
|
Py_RETURN_NONE;
|
|
@@ -1255,7 +1292,8 @@ static PyObject *intrinsic_object_copy(PyObject *args)
|
|
|
1255
1292
|
if (object == NULL || intrinsic_count_check(args, 1, NULL) < 0) {
|
|
1256
1293
|
return NULL;
|
|
1257
1294
|
}
|
|
1258
|
-
|
|
1295
|
+
// Call dict(object) for dict subclasses, exactly like the reference implementation
|
|
1296
|
+
return PyDict_CheckExact(object) ? PyDict_Copy(object) : PyObject_CallOneArg((PyObject *)&PyDict_Type, object);
|
|
1259
1297
|
}
|
|
1260
1298
|
|
|
1261
1299
|
|
|
@@ -1340,7 +1378,7 @@ static PyObject *intrinsic_string_from_char_code(PyObject *args)
|
|
|
1340
1378
|
for (Py_ssize_t ix = 0; ix < nargs; ix++) {
|
|
1341
1379
|
PyObject *code = PyList_GET_ITEM(args, ix);
|
|
1342
1380
|
double number;
|
|
1343
|
-
if (
|
|
1381
|
+
if (PyFloat_Check(code)) {
|
|
1344
1382
|
number = PyFloat_AS_DOUBLE(code);
|
|
1345
1383
|
// The reference's int(code) conversion raises for NaN and infinity (of either sign)
|
|
1346
1384
|
// before the integral and sign checks
|
|
@@ -1356,7 +1394,7 @@ static PyObject *intrinsic_string_from_char_code(PyObject *args)
|
|
|
1356
1394
|
intrinsic_args_error("charCodes", code, NULL);
|
|
1357
1395
|
goto done;
|
|
1358
1396
|
}
|
|
1359
|
-
} else if (
|
|
1397
|
+
} else if (PyLong_Check(code) && !PyBool_Check(code)) {
|
|
1360
1398
|
int overflow = 0;
|
|
1361
1399
|
long long code_ll = PyLong_AsLongLongAndOverflow(code, &overflow);
|
|
1362
1400
|
if (code_ll == -1 && !overflow && PyErr_Occurred()) {
|
|
@@ -23,18 +23,17 @@ def value_type(value):
|
|
|
23
23
|
|
|
24
24
|
if value is None:
|
|
25
25
|
return 'null'
|
|
26
|
-
|
|
27
|
-
if t is str:
|
|
26
|
+
elif isinstance(value, str):
|
|
28
27
|
return 'string'
|
|
29
|
-
elif
|
|
28
|
+
elif isinstance(value, bool):
|
|
30
29
|
return 'boolean'
|
|
31
|
-
elif
|
|
30
|
+
elif isinstance(value, (int, float)):
|
|
32
31
|
return 'number'
|
|
33
32
|
elif isinstance(value, datetime.date):
|
|
34
33
|
return 'datetime'
|
|
35
|
-
elif
|
|
34
|
+
elif isinstance(value, dict):
|
|
36
35
|
return 'object'
|
|
37
|
-
elif
|
|
36
|
+
elif isinstance(value, list):
|
|
38
37
|
return 'array'
|
|
39
38
|
elif callable(value):
|
|
40
39
|
return 'function'
|
|
@@ -59,14 +58,13 @@ def value_string(value):
|
|
|
59
58
|
|
|
60
59
|
if value is None:
|
|
61
60
|
return 'null'
|
|
62
|
-
|
|
63
|
-
if t is str:
|
|
61
|
+
elif isinstance(value, str):
|
|
64
62
|
return value
|
|
65
|
-
elif
|
|
63
|
+
elif isinstance(value, bool):
|
|
66
64
|
return 'true' if value else 'false'
|
|
67
|
-
elif
|
|
65
|
+
elif isinstance(value, int):
|
|
68
66
|
return str(value)
|
|
69
|
-
elif
|
|
67
|
+
elif isinstance(value, float):
|
|
70
68
|
return R_NUMBER_CLEANUP.sub('', str(value))
|
|
71
69
|
elif isinstance(value, datetime.date):
|
|
72
70
|
iso = value_normalize_datetime(value).astimezone().isoformat()
|
|
@@ -76,9 +74,9 @@ def value_string(value):
|
|
|
76
74
|
millisecond = int(iso[microsecond_begin + 1:microsecond_end]) // 1000
|
|
77
75
|
iso = f'{iso[0:microsecond_begin]}.{millisecond:0{3}d}{iso[microsecond_end:]}'
|
|
78
76
|
return _R_DATETIME_TZ_CLEANUP.sub(r'\1', iso)
|
|
79
|
-
elif
|
|
77
|
+
elif isinstance(value, dict):
|
|
80
78
|
return value_json(value)
|
|
81
|
-
elif
|
|
79
|
+
elif isinstance(value, list):
|
|
82
80
|
return value_json(value)
|
|
83
81
|
elif callable(value):
|
|
84
82
|
return '<function>'
|
|
@@ -143,14 +141,13 @@ def value_boolean(value):
|
|
|
143
141
|
:rtype: bool
|
|
144
142
|
"""
|
|
145
143
|
|
|
146
|
-
|
|
147
|
-
if t is bool:
|
|
144
|
+
if isinstance(value, bool):
|
|
148
145
|
return value
|
|
149
|
-
elif
|
|
146
|
+
elif isinstance(value, str):
|
|
150
147
|
return value != ''
|
|
151
|
-
elif
|
|
148
|
+
elif isinstance(value, (int, float)):
|
|
152
149
|
return value != 0
|
|
153
|
-
elif
|
|
150
|
+
elif isinstance(value, list):
|
|
154
151
|
return len(value) != 0
|
|
155
152
|
|
|
156
153
|
# Everything else non-null is true
|
|
@@ -188,25 +185,24 @@ def value_compare(left, right):
|
|
|
188
185
|
return 0 if right is None else -1
|
|
189
186
|
elif right is None:
|
|
190
187
|
return 1
|
|
191
|
-
|
|
192
|
-
right_type = type(right)
|
|
193
|
-
if left_type is str and right_type is str:
|
|
188
|
+
if isinstance(left, str) and isinstance(right, str):
|
|
194
189
|
return -1 if left < right else (0 if left == right else 1)
|
|
195
|
-
elif
|
|
190
|
+
elif isinstance(left, bool) and isinstance(right, bool):
|
|
196
191
|
return -1 if left < right else (0 if left == right else 1)
|
|
197
|
-
elif (
|
|
192
|
+
elif isinstance(left, (int, float)) and not isinstance(left, bool) and \
|
|
193
|
+
isinstance(right, (int, float)) and not isinstance(right, bool):
|
|
198
194
|
return -1 if left < right else (0 if left == right else 1)
|
|
199
195
|
elif isinstance(left, datetime.date) and isinstance(right, datetime.date):
|
|
200
196
|
left_dt = value_normalize_datetime(left)
|
|
201
197
|
right_dt = value_normalize_datetime(right)
|
|
202
198
|
return -1 if left_dt < right_dt else (0 if left_dt == right_dt else 1)
|
|
203
|
-
elif
|
|
199
|
+
elif isinstance(left, list) and isinstance(right, list):
|
|
204
200
|
for ix in range(min(len(left), len(right))):
|
|
205
201
|
item_compare = value_compare(left[ix], right[ix])
|
|
206
202
|
if item_compare != 0:
|
|
207
203
|
return item_compare
|
|
208
204
|
return -1 if len(left) < len(right) else (0 if len(left) == len(right) else 1)
|
|
209
|
-
elif
|
|
205
|
+
elif isinstance(left, dict) and isinstance(right, dict):
|
|
210
206
|
left_key_values = sorted(left.items())
|
|
211
207
|
right_key_values = sorted(right.items())
|
|
212
208
|
for ix in range(min(len(left_key_values), len(right_key_values))):
|
|
@@ -297,8 +293,7 @@ def value_args_validate(fn_args, args, error_return_value=None):
|
|
|
297
293
|
|
|
298
294
|
# Type-specific validation
|
|
299
295
|
if arg_type == 'number':
|
|
300
|
-
|
|
301
|
-
if not (arg_value_type is int or arg_value_type is float):
|
|
296
|
+
if not isinstance(arg_value, (int, float)) or isinstance(arg_value, bool):
|
|
302
297
|
raise ValueArgsError(fn_arg['name'], arg_value, error_return_value)
|
|
303
298
|
arg_lt = fn_arg.get('lt')
|
|
304
299
|
arg_lte = fn_arg.get('lte')
|
|
@@ -316,16 +311,13 @@ def value_args_validate(fn_args, args, error_return_value=None):
|
|
|
316
311
|
if arg_integer:
|
|
317
312
|
args[ix] = int(arg_value)
|
|
318
313
|
elif arg_type == 'string':
|
|
319
|
-
|
|
320
|
-
if arg_value_type is not str:
|
|
314
|
+
if not isinstance(arg_value, str):
|
|
321
315
|
raise ValueArgsError(fn_arg['name'], arg_value, error_return_value)
|
|
322
316
|
elif arg_type == 'array':
|
|
323
|
-
|
|
324
|
-
if arg_value_type is not list:
|
|
317
|
+
if not isinstance(arg_value, list):
|
|
325
318
|
raise ValueArgsError(fn_arg['name'], arg_value, error_return_value)
|
|
326
319
|
elif arg_type == 'object':
|
|
327
|
-
|
|
328
|
-
if arg_value_type is not dict:
|
|
320
|
+
if not isinstance(arg_value, dict):
|
|
329
321
|
raise ValueArgsError(fn_arg['name'], arg_value, error_return_value)
|
|
330
322
|
elif arg_type == 'datetime':
|
|
331
323
|
if not isinstance(arg_value, datetime.date):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|