pyquadp 2.0.2__tar.gz → 2.0.3__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.
Files changed (82) hide show
  1. {pyquadp-2.0.2 → pyquadp-2.0.3}/PKG-INFO +1 -1
  2. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/constant.py +1 -0
  3. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qiarray.c +27 -4
  4. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qint.c +33 -22
  5. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp.egg-info/PKG-INFO +1 -1
  6. {pyquadp-2.0.2 → pyquadp-2.0.3}/tests/qiarray_test.py +22 -0
  7. {pyquadp-2.0.2 → pyquadp-2.0.3}/tests/qint_test.py +10 -0
  8. {pyquadp-2.0.2 → pyquadp-2.0.3}/.gitattributes +0 -0
  9. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/copilot-instructions.md +0 -0
  10. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/dependabot.yml +0 -0
  11. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/bandit.yml +0 -0
  12. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/black.yml +0 -0
  13. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/codeql.yml +0 -0
  14. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/coveralls.yml +0 -0
  15. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/isort.yml +0 -0
  16. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/linux-arm.yml +0 -0
  17. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/linux.yml +0 -0
  18. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/macos.yml +0 -0
  19. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/mypy.yml +0 -0
  20. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/old-numpy.yml +0 -0
  21. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/pypi.yml +0 -0
  22. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/pypy.yml +0 -0
  23. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/windows.yml +0 -0
  24. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/workflows/zizmor.yml +0 -0
  25. {pyquadp-2.0.2 → pyquadp-2.0.3}/.github/zizmor.yml +0 -0
  26. {pyquadp-2.0.2 → pyquadp-2.0.3}/.gitignore +0 -0
  27. {pyquadp-2.0.2 → pyquadp-2.0.3}/.pre-commit-config.yaml +0 -0
  28. {pyquadp-2.0.2 → pyquadp-2.0.3}/COPYING.txt +0 -0
  29. {pyquadp-2.0.2 → pyquadp-2.0.3}/MANIFEST.in +0 -0
  30. {pyquadp-2.0.2 → pyquadp-2.0.3}/README.md +0 -0
  31. {pyquadp-2.0.2 → pyquadp-2.0.3}/build.sh +0 -0
  32. {pyquadp-2.0.2 → pyquadp-2.0.3}/build_and_test.sh +0 -0
  33. {pyquadp-2.0.2 → pyquadp-2.0.3}/coverage.sh +0 -0
  34. {pyquadp-2.0.2 → pyquadp-2.0.3}/lint.sh +0 -0
  35. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyproject.toml +0 -0
  36. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/__init__.py +0 -0
  37. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/__init__.pyi +0 -0
  38. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/constant.pyi +0 -0
  39. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/py.typed +0 -0
  40. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/pyquadp.h +0 -0
  41. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qarray.pyi +0 -0
  42. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qcarray.c +0 -0
  43. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qcarray.h +0 -0
  44. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qcarray.pyi +0 -0
  45. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qcmath.py +0 -0
  46. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qcmath.pyi +0 -0
  47. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qcmathc.c +0 -0
  48. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qcmathc.h +0 -0
  49. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qcmplx.c +0 -0
  50. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qcmplx.h +0 -0
  51. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qfloat.c +0 -0
  52. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qfloat.h +0 -0
  53. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qfloatarray.c +0 -0
  54. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qfloatarray.h +0 -0
  55. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qiarray.h +0 -0
  56. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qiarray.pyi +0 -0
  57. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qint.h +0 -0
  58. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qmath.py +0 -0
  59. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qmath.pyi +0 -0
  60. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qmathc.c +0 -0
  61. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qmathc.h +0 -0
  62. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qmcmplx.pyi +0 -0
  63. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qmfloat.pyi +0 -0
  64. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp/qmint.pyi +0 -0
  65. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp.egg-info/SOURCES.txt +0 -0
  66. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp.egg-info/dependency_links.txt +0 -0
  67. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp.egg-info/requires.txt +0 -0
  68. {pyquadp-2.0.2 → pyquadp-2.0.3}/pyquadp.egg-info/top_level.txt +0 -0
  69. {pyquadp-2.0.2 → pyquadp-2.0.3}/setup.cfg +0 -0
  70. {pyquadp-2.0.2 → pyquadp-2.0.3}/setup.py +0 -0
  71. {pyquadp-2.0.2 → pyquadp-2.0.3}/tests/Makefile +0 -0
  72. {pyquadp-2.0.2 → pyquadp-2.0.3}/tests/conftest.py +0 -0
  73. {pyquadp-2.0.2 → pyquadp-2.0.3}/tests/fortran_test.py +0 -0
  74. {pyquadp-2.0.2 → pyquadp-2.0.3}/tests/import_order_test.py +0 -0
  75. {pyquadp-2.0.2 → pyquadp-2.0.3}/tests/qarray_test.py +0 -0
  76. {pyquadp-2.0.2 → pyquadp-2.0.3}/tests/qcarray_test.py +0 -0
  77. {pyquadp-2.0.2 → pyquadp-2.0.3}/tests/qcmath_test.py +0 -0
  78. {pyquadp-2.0.2 → pyquadp-2.0.3}/tests/qcmplx_test.py +0 -0
  79. {pyquadp-2.0.2 → pyquadp-2.0.3}/tests/qfloat_test.py +0 -0
  80. {pyquadp-2.0.2 → pyquadp-2.0.3}/tests/qmath_test.py +0 -0
  81. {pyquadp-2.0.2 → pyquadp-2.0.3}/tests/quad.f90 +0 -0
  82. {pyquadp-2.0.2 → pyquadp-2.0.3}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyquadp
3
- Version: 2.0.2
3
+ Version: 2.0.3
4
4
  Summary: Python's bindings for gcc's libquadmath
5
5
  Author-email: Robert Farmer <robert.j.farmer37@gmail.com>
6
6
  License-Expression: GPL-2.0-or-later
@@ -51,6 +51,7 @@ nanj = qcmplx(0.0, qfloat("nan"))
51
51
 
52
52
  # Ctype data
53
53
  c_qfloat = _ctypes.c_byte * 16
54
+ c_qint = _ctypes.c_byte * 16
54
55
 
55
56
 
56
57
  class c_qcmplx(_ctypes.Structure):
@@ -1573,18 +1573,41 @@ static int
1573
1573
  QuadIArray_setitem(PyObject *item, __int128 *data, void *array)
1574
1574
  {
1575
1575
  QuadIObject tmp;
1576
+ PyObject *index_obj = NULL;
1576
1577
 
1577
1578
  (void)array;
1578
1579
 
1579
1580
  if (PyObject_to_QuadIObject(item, &tmp, false)) {
1580
1581
  *data = tmp.value;
1581
- } else {
1582
- if (!PyErr_Occurred()) {
1583
- PyErr_SetString(PyExc_TypeError, "Failed to setitem in QuadIArray");
1582
+ return 0;
1583
+ }
1584
+
1585
+ if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1586
+ PyErr_Clear();
1587
+ } else if (PyErr_Occurred()) {
1588
+ return -1;
1589
+ }
1590
+
1591
+ index_obj = PyNumber_Index(item);
1592
+ if (index_obj != NULL) {
1593
+ if (PyObject_to_QuadIObject(index_obj, &tmp, false)) {
1594
+ *data = tmp.value;
1595
+ Py_DECREF(index_obj);
1596
+ return 0;
1584
1597
  }
1598
+
1599
+ Py_DECREF(index_obj);
1585
1600
  return -1;
1586
1601
  }
1587
- return 0;
1602
+
1603
+ if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1604
+ PyErr_Clear();
1605
+ PyErr_SetString(PyExc_TypeError, "Failed to setitem in QuadIArray");
1606
+ } else if (!PyErr_Occurred()) {
1607
+ PyErr_SetString(PyExc_TypeError, "Failed to setitem in QuadIArray");
1608
+ }
1609
+
1610
+ return -1;
1588
1611
  }
1589
1612
 
1590
1613
  static PyObject *
@@ -1049,6 +1049,8 @@ static __int128 QuadIObject_int128(QuadIObject * out) {
1049
1049
  bool
1050
1050
  PyObject_to_QuadIObject(PyObject * in, QuadIObject * out, const bool alloc)
1051
1051
  {
1052
+ PyObject *int_obj;
1053
+
1052
1054
  (void)alloc;
1053
1055
 
1054
1056
  if(QuadIObject_Check(in)){
@@ -1073,32 +1075,41 @@ PyObject_to_QuadIObject(PyObject * in, QuadIObject * out, const bool alloc)
1073
1075
  return true;
1074
1076
  }
1075
1077
 
1076
- if(PyNumber_Check(in)) {
1077
- // Is a number
1078
- if(PyLong_Check(in)){
1079
- // int
1080
- // Convert to string as we may be to big for PyLong
1081
- PyObject * str = PyUnicode_FromFormat("%S",in);
1082
- if (str == NULL) {
1083
- return false;
1084
- }
1085
- Py_ssize_t len;
1086
- const char *buf = PyUnicode_AsUTF8AndSize(str, &len);
1087
- if (buf==NULL){
1088
- Py_DECREF(str);
1089
- return false;
1090
- }
1091
-
1092
- if(!str_to_int128(buf,len,&out->value)){
1093
- Py_DECREF(str);
1094
- PyErr_SetString(PyExc_TypeError, "Could not convert int to integer quad precision.");
1095
- return false;
1096
- }
1078
+ int_obj = PyNumber_Index(in);
1079
+ if (int_obj != NULL) {
1080
+ // Convert integer-like values (including numpy integer scalars)
1081
+ // to string first so values outside C long long still parse correctly.
1082
+ PyObject *str = PyUnicode_FromFormat("%S", int_obj);
1083
+ if (str == NULL) {
1084
+ Py_DECREF(int_obj);
1085
+ return false;
1086
+ }
1097
1087
 
1088
+ Py_ssize_t len;
1089
+ const char *buf = PyUnicode_AsUTF8AndSize(str, &len);
1090
+ if (buf == NULL) {
1098
1091
  Py_DECREF(str);
1092
+ Py_DECREF(int_obj);
1093
+ return false;
1094
+ }
1099
1095
 
1100
- return true;
1096
+ if (!str_to_int128(buf, len, &out->value)) {
1097
+ Py_DECREF(str);
1098
+ Py_DECREF(int_obj);
1099
+ PyErr_SetString(PyExc_TypeError, "Could not convert int to integer quad precision.");
1100
+ return false;
1101
1101
  }
1102
+
1103
+ Py_DECREF(str);
1104
+ Py_DECREF(int_obj);
1105
+ return true;
1106
+ }
1107
+
1108
+ // Non-integral numerics (e.g., float, numpy floating scalars) are not valid qint inputs.
1109
+ if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1110
+ PyErr_Clear();
1111
+ } else if (PyErr_Occurred()) {
1112
+ return false;
1102
1113
  }
1103
1114
 
1104
1115
  return false;
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyquadp
3
- Version: 2.0.2
3
+ Version: 2.0.3
4
4
  Summary: Python's bindings for gcc's libquadmath
5
5
  Author-email: Robert Farmer <robert.j.farmer37@gmail.com>
6
6
  License-Expression: GPL-2.0-or-later
@@ -100,6 +100,28 @@ class TestQIArrayConstructors:
100
100
  np.asarray(arr, dtype=np.int64), np.array([1, 2, -3], dtype=np.int64)
101
101
  )
102
102
 
103
+ def test_from_list_accepts_numpy_integer_scalars(self):
104
+ qiarray = pytest.importorskip("pyquadp.qiarray")
105
+ arr = qiarray.from_list([np.int64(1), np.int32(-2), np.int64(3)])
106
+
107
+ assert isinstance(arr, np.ndarray)
108
+ assert arr.dtype == qiarray.dtype
109
+ np.testing.assert_array_equal(
110
+ np.asarray(arr, dtype=np.int64), np.array([1, -2, 3], dtype=np.int64)
111
+ )
112
+
113
+ def test_setitem_accepts_numpy_integer_scalars(self):
114
+ qiarray = pytest.importorskip("pyquadp.qiarray")
115
+ arr = qiarray.zeros(3)
116
+
117
+ arr[0] = np.int64(9)
118
+ arr[1] = np.int32(-4)
119
+ arr[2] = np.int64(7)
120
+
121
+ np.testing.assert_array_equal(
122
+ np.asarray(arr, dtype=np.int64), np.array([9, -4, 7], dtype=np.int64)
123
+ )
124
+
103
125
  def test_from_array_constructor(self):
104
126
  qiarray = pytest.importorskip("pyquadp.qiarray")
105
127
  src = np.array([[1, 2], [3, 4]], dtype=np.int64)
@@ -319,3 +319,13 @@ class Testqint:
319
319
  def test_index_method(self):
320
320
  q1 = pq.qint(7)
321
321
  assert q1.__index__() == 7
322
+
323
+ def test_np_types(self):
324
+ q1 = pq.qint(1234567890)
325
+ q3 = np.int64(1234567890)
326
+ assert q1 == q3
327
+ assert hash(q1) == hash(q3)
328
+
329
+ assert pq.qint(q3) == q3
330
+
331
+ assert pq.qint(np.int32(1234567890)) == q3
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
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
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