numexpr 2.8.8__tar.gz → 2.10.0__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 (57) hide show
  1. {numexpr-2.8.8 → numexpr-2.10.0}/ANNOUNCE.rst +12 -14
  2. {numexpr-2.8.8 → numexpr-2.10.0}/AUTHORS.txt +5 -1
  3. {numexpr-2.8.8 → numexpr-2.10.0}/PKG-INFO +6 -7
  4. {numexpr-2.8.8 → numexpr-2.10.0}/README.rst +2 -3
  5. {numexpr-2.8.8 → numexpr-2.10.0}/RELEASE_NOTES.rst +29 -3
  6. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/interpreter.cpp +3 -3
  7. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/necompiler.py +2 -1
  8. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/tests/test_numexpr.py +41 -17
  9. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/utils.py +5 -4
  10. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/version.py +2 -2
  11. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr.egg-info/PKG-INFO +6 -7
  12. numexpr-2.10.0/numexpr.egg-info/requires.txt +1 -0
  13. numexpr-2.10.0/pyproject.toml +7 -0
  14. numexpr-2.10.0/requirements.txt +1 -0
  15. {numexpr-2.8.8 → numexpr-2.10.0}/setup.cfg +3 -3
  16. {numexpr-2.8.8 → numexpr-2.10.0}/setup.py +4 -1
  17. numexpr-2.8.8/numexpr.egg-info/requires.txt +0 -1
  18. numexpr-2.8.8/pyproject.toml +0 -3
  19. numexpr-2.8.8/requirements.txt +0 -1
  20. {numexpr-2.8.8 → numexpr-2.10.0}/LICENSE.txt +0 -0
  21. {numexpr-2.8.8 → numexpr-2.10.0}/MANIFEST.in +0 -0
  22. {numexpr-2.8.8 → numexpr-2.10.0}/bench/boolean_timing.py +0 -0
  23. {numexpr-2.8.8 → numexpr-2.10.0}/bench/issue-36.py +0 -0
  24. {numexpr-2.8.8 → numexpr-2.10.0}/bench/issue-47.py +0 -0
  25. {numexpr-2.8.8 → numexpr-2.10.0}/bench/multidim.py +0 -0
  26. {numexpr-2.8.8 → numexpr-2.10.0}/bench/poly.py +0 -0
  27. {numexpr-2.8.8 → numexpr-2.10.0}/bench/timing.py +0 -0
  28. {numexpr-2.8.8 → numexpr-2.10.0}/bench/unaligned-simple.py +0 -0
  29. {numexpr-2.8.8 → numexpr-2.10.0}/bench/varying-expr.py +0 -0
  30. {numexpr-2.8.8 → numexpr-2.10.0}/bench/vml_timing.py +0 -0
  31. {numexpr-2.8.8 → numexpr-2.10.0}/bench/vml_timing2.py +0 -0
  32. {numexpr-2.8.8 → numexpr-2.10.0}/bench/vml_timing3.py +0 -0
  33. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/__init__.py +0 -0
  34. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/complex_functions.hpp +0 -0
  35. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/cpuinfo.py +0 -0
  36. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/expressions.py +0 -0
  37. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/functions.hpp +0 -0
  38. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/interp_body.cpp +0 -0
  39. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/interpreter.hpp +0 -0
  40. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/missing_posix_functions.hpp +0 -0
  41. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/module.cpp +0 -0
  42. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/module.hpp +0 -0
  43. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/msvc_function_stubs.hpp +0 -0
  44. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/numexpr_config.hpp +0 -0
  45. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/numexpr_object.cpp +0 -0
  46. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/numexpr_object.hpp +0 -0
  47. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/opcodes.hpp +0 -0
  48. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/str-two-way.hpp +0 -0
  49. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/tests/__init__.py +0 -0
  50. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/win32/pthread.c +0 -0
  51. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/win32/pthread.h +0 -0
  52. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr/win32/stdint.h +0 -0
  53. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr.egg-info/SOURCES.txt +0 -0
  54. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr.egg-info/dependency_links.txt +0 -0
  55. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr.egg-info/not-zip-safe +0 -0
  56. {numexpr-2.8.8 → numexpr-2.10.0}/numexpr.egg-info/top_level.txt +0 -0
  57. {numexpr-2.8.8 → numexpr-2.10.0}/site.cfg.example +0 -0
@@ -1,31 +1,29 @@
1
1
  ========================
2
- Announcing NumExpr 2.8.8
2
+ Announcing NumExpr 2.9.0
3
3
  ========================
4
4
 
5
5
  Hi everyone,
6
6
 
7
- NumExpr 2.8.8 is a release to deal mainly with issues appearing with
8
- upcoming `NumPy` 2.0. Also, some small fixes (support for simple complex
9
- expressions like `ne.evaluate('1.5j')`) and improvements are included.
7
+ NumExpr 2.9.0 is a release offering support for latest versions of PyPy.
8
+ The full test suite should pass now, at least for the Python 3.10 version.
9
+ Thanks to @27rabbitlt for most of the work and @mgorny and @mattip for
10
+ providing help and additional fixes.
10
11
 
11
12
  Project documentation is available at:
12
13
 
13
14
  http://numexpr.readthedocs.io/
14
15
 
15
- Changes from 2.8.7 to 2.8.8
16
+ Changes from 2.8.8 to 2.9.0
16
17
  ---------------------------
17
18
 
18
- * Fix re_evaluate not taking global_dict as argument. Thanks to Teng Liu
19
- (@27rabbitlt).
19
+ * Support for PyPy (see PRs #467 and #740). The full test suite
20
+ should pass now, at least for the 3.10 version. Thanks to
21
+ @27rabbitlt for most of the work and @mgorny and @mattip for
22
+ providing help and additional fixes. Fixes #463.
20
23
 
21
- * Fix parsing of simple complex numbers. Now, `ne.evaluate('1.5j')` works.
22
- Thanks to Teng Liu (@27rabbitlt).
24
+ * Fixed more sanitizer issues (see PR #469). Thanks to @27rabbitlt.
23
25
 
24
- * Fixes for upcoming NumPy 2.0:
25
-
26
- * Replace npy_cdouble with C++ complex. Thanks to Teng Liu (@27rabbitlt).
27
- * Add NE_MAXARGS for future numpy change NPY_MAXARGS. Now it is set to 64
28
- to match NumPy 2.0 value. Thanks to Teng Liu (@27rabbitlt).
26
+ * Modernized the test suite to avoid some warnings.
29
27
 
30
28
  What's Numexpr?
31
29
  ---------------
@@ -24,4 +24,8 @@ Google Inc. contributed bug fixes.
24
24
  David Cox improved readability of the Readme.
25
25
 
26
26
  Robert A. McLeod contributed bug fixes and ported the documentation to
27
- numexpr.readthedocs.io. He is the maintainer of the package since 2016.
27
+ numexpr.readthedocs.io. He has served as the maintainer of the package
28
+ since 2016 to 2023.
29
+
30
+ Teng Liu fixed many bugs, and in particular, contributed valuable fixes
31
+ to the new regex sanitizer for expressions.
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: numexpr
3
- Version: 2.8.8
3
+ Version: 2.10.0
4
4
  Summary: Fast numerical expression evaluator for NumPy
5
5
  Home-page: https://github.com/pydata/numexpr
6
6
  Author: David M. Cooke, Francesc Alted, and others
7
- Maintainer: Robert A. McLeod
8
- Maintainer-email: robbmcleod@gmail.com
7
+ Maintainer: Francesc Alted
8
+ Maintainer-email: faltet@gmail.com
9
9
  License: MIT
10
10
  Classifier: Development Status :: 6 - Mature
11
11
  Classifier: Intended Audience :: Financial and Insurance Industry
@@ -23,7 +23,7 @@ Requires-Python: >=3.9
23
23
  Description-Content-Type: text/x-rst
24
24
  License-File: LICENSE.txt
25
25
  License-File: AUTHORS.txt
26
- Requires-Dist: numpy>=1.13.3
26
+ Requires-Dist: numpy>=1.19.3
27
27
 
28
28
  ======================================================
29
29
  NumExpr: Fast numerical expression evaluator for NumPy
@@ -34,7 +34,6 @@ NumExpr: Fast numerical expression evaluator for NumPy
34
34
  :Contact: faltet@gmail.com
35
35
  :URL: https://github.com/pydata/numexpr
36
36
  :Documentation: http://numexpr.readthedocs.io/en/latest/
37
- :Travis CI: |travis|
38
37
  :GitHub Actions: |actions|
39
38
  :PyPi: |version|
40
39
  :DOI: |doi|
@@ -48,7 +47,7 @@ NumExpr: Fast numerical expression evaluator for NumPy
48
47
  :target: http://numexpr.readthedocs.io/en/latest
49
48
  .. |doi| image:: https://zenodo.org/badge/doi/10.5281/zenodo.2483274.svg
50
49
  :target: https://doi.org/10.5281/zenodo.2483274
51
- .. |version| image:: https://img.shields.io/pypi/v/numexpr.png
50
+ .. |version| image:: https://img.shields.io/pypi/v/numexpr
52
51
  :target: https://pypi.python.org/pypi/numexpr
53
52
 
54
53
 
@@ -175,7 +174,7 @@ Usage
175
174
  array([ 1.00000000e+00, 2.00000000e+00, 3.00000000e+00, ...,
176
175
  9.99998000e+05, 9.99999000e+05, 1.00000000e+06])
177
176
 
178
- >>> ne.evaluate('a*b-4.1*a > 2.5*b') # a more complex one
177
+ >>> ne.evaluate("a * b - 4.1 * a > 2.5 * b") # a more complex one
179
178
  array([False, False, False, ..., True, True, True], dtype=bool)
180
179
 
181
180
  >>> ne.evaluate("sin(a) + arcsinh(a/b)") # you can also use functions
@@ -7,7 +7,6 @@ NumExpr: Fast numerical expression evaluator for NumPy
7
7
  :Contact: faltet@gmail.com
8
8
  :URL: https://github.com/pydata/numexpr
9
9
  :Documentation: http://numexpr.readthedocs.io/en/latest/
10
- :Travis CI: |travis|
11
10
  :GitHub Actions: |actions|
12
11
  :PyPi: |version|
13
12
  :DOI: |doi|
@@ -21,7 +20,7 @@ NumExpr: Fast numerical expression evaluator for NumPy
21
20
  :target: http://numexpr.readthedocs.io/en/latest
22
21
  .. |doi| image:: https://zenodo.org/badge/doi/10.5281/zenodo.2483274.svg
23
22
  :target: https://doi.org/10.5281/zenodo.2483274
24
- .. |version| image:: https://img.shields.io/pypi/v/numexpr.png
23
+ .. |version| image:: https://img.shields.io/pypi/v/numexpr
25
24
  :target: https://pypi.python.org/pypi/numexpr
26
25
 
27
26
 
@@ -148,7 +147,7 @@ Usage
148
147
  array([ 1.00000000e+00, 2.00000000e+00, 3.00000000e+00, ...,
149
148
  9.99998000e+05, 9.99999000e+05, 1.00000000e+06])
150
149
 
151
- >>> ne.evaluate('a*b-4.1*a > 2.5*b') # a more complex one
150
+ >>> ne.evaluate("a * b - 4.1 * a > 2.5 * b") # a more complex one
152
151
  array([False, False, False, ..., True, True, True], dtype=bool)
153
152
 
154
153
  >>> ne.evaluate("sin(a) + arcsinh(a/b)") # you can also use functions
@@ -1,6 +1,32 @@
1
- ====================================
2
- Release notes for NumExpr 2.8 series
3
- ====================================
1
+ =====================================
2
+ Release notes for NumExpr 2.10 series
3
+ =====================================
4
+
5
+ Changes from 2.9.0 to 2.10.0
6
+ ----------------------------
7
+
8
+ * Support for NumPy 2.0.0. This is still experimental, so please
9
+ report any issues you find. Thanks to Clément Robert and Thomas
10
+ Caswell for the work.
11
+
12
+ * Avoid erroring when OMP_NUM_THREADS is empty string. Thanks to
13
+ Patrick Hoefler.
14
+
15
+ * Do not warn if OMP_NUM_THREAD set.
16
+
17
+
18
+ Changes from 2.8.8 to 2.9.0
19
+ ---------------------------
20
+
21
+ * Support for PyPy (see PRs #467 and #740). The full test suite
22
+ should pass now, at least for the 3.10 version. Thanks to
23
+ @27rabbitlt for most of the work and @mgorny and @mattip for
24
+ providing help and additional fixes. Fixes #463.
25
+
26
+ * Fixed more sanitizer issues (see PR #469). Thanks to @27rabbitlt.
27
+
28
+ * Modernized the test suite to avoid some warnings.
29
+
4
30
 
5
31
  Changes from 2.8.7 to 2.8.8
6
32
  ---------------------------
@@ -1029,7 +1029,7 @@ NumExpr_run(NumExprObject *self, PyObject *args, PyObject *kwds)
1029
1029
  memset(operands, 0, sizeof(operands));
1030
1030
  memset(dtypes, 0, sizeof(dtypes));
1031
1031
 
1032
- if (kwds) {
1032
+ if (kwds && PyDict_Size(kwds) > 0) {
1033
1033
  tmp = PyDict_GetItemString(kwds, "casting"); // borrowed ref
1034
1034
  if (tmp != NULL && !PyArray_CastingConverter(tmp, &casting)) {
1035
1035
  return NULL;
@@ -1203,7 +1203,7 @@ NumExpr_run(NumExprObject *self, PyObject *args, PyObject *kwds)
1203
1203
  Py_INCREF(dtypes[0]);
1204
1204
  } else { // constant, like in '"foo"'
1205
1205
  dtypes[0] = PyArray_DescrNewFromType(NPY_STRING);
1206
- dtypes[0]->elsize = (int)self->memsizes[1];
1206
+ PyDataType_SET_ELSIZE(dtypes[0], (npy_intp)self->memsizes[1]);
1207
1207
  } // no string temporaries, so no third case
1208
1208
  }
1209
1209
  if (dtypes[0] == NULL) {
@@ -1449,7 +1449,7 @@ NumExpr_run(NumExprObject *self, PyObject *args, PyObject *kwds)
1449
1449
  /* Get the sizes of all the operands */
1450
1450
  dtypes_tmp = NpyIter_GetDescrArray(iter);
1451
1451
  for (i = 0; i < n_inputs+1; ++i) {
1452
- self->memsizes[i] = dtypes_tmp[i]->elsize;
1452
+ self->memsizes[i] = PyDataType_ELSIZE(dtypes_tmp[i]);
1453
1453
  }
1454
1454
 
1455
1455
  /* For small calculations, just use 1 thread */
@@ -278,7 +278,8 @@ def stringToExpression(s, types, context, sanitize: bool=True):
278
278
  # We also cannot ban `.\d*j`, where `\d*` is some digits (or none), e.g. 1.5j, 1.j
279
279
  if sanitize:
280
280
  no_whitespace = re.sub(r'\s+', '', s)
281
- if _blacklist_re.search(no_whitespace) is not None:
281
+ skip_quotes = re.sub(r'(\'[^\']*\')', '', no_whitespace)
282
+ if _blacklist_re.search(skip_quotes) is not None:
282
283
  raise ValueError(f'Expression {s} has forbidden control characters.')
283
284
 
284
285
  old_ctx = expressions._context.get_current_context()
@@ -19,7 +19,7 @@ import subprocess
19
19
 
20
20
  import numpy as np
21
21
  from numpy import (
22
- array, arange, empty, zeros, int32, int64, uint16, complex_, float64, rec,
22
+ array, arange, empty, zeros, int32, int64, uint16, cdouble, float64, rec,
23
23
  copy, ones_like, where, all as alltrue, linspace,
24
24
  sum, prod, sqrt, fmod, floor, ceil,
25
25
  sin, cos, tan, arcsin, arccos, arctan, arctan2,
@@ -33,6 +33,7 @@ from numpy import shape, allclose, array_equal, ravel, isnan, isinf
33
33
  import numexpr
34
34
  from numexpr import E, NumExpr, evaluate, re_evaluate, validate, disassemble, use_vml
35
35
  from numexpr.expressions import ConstantNode
36
+ from numexpr.utils import detect_number_of_cores
36
37
 
37
38
  import unittest
38
39
 
@@ -296,7 +297,7 @@ class test_numexpr(TestCase):
296
297
  b = b'a' * 40
297
298
  res = evaluate('contains(a, b)')
298
299
  assert_equal(res, True)
299
-
300
+
300
301
  def test_where_scalar_bool(self):
301
302
  a = True
302
303
  b = array([1, 2])
@@ -307,7 +308,8 @@ class test_numexpr(TestCase):
307
308
  res = evaluate('where(a, b, c)')
308
309
  assert_array_equal(res, c)
309
310
 
310
-
311
+ @unittest.skipIf(hasattr(sys, "pypy_version_info"),
312
+ "PyPy does not have sys.getrefcount()")
311
313
  def test_refcount(self):
312
314
  # Regression test for issue #310
313
315
  a = array([1])
@@ -317,7 +319,7 @@ class test_numexpr(TestCase):
317
319
 
318
320
  def test_locals_clears_globals(self):
319
321
  # Check for issue #313, whereby clearing f_locals also clear f_globals
320
- # if in the top-frame. This cannot be done inside `unittest` as it is always
322
+ # if in the top-frame. This cannot be done inside `unittest` as it is always
321
323
  # executing code in a child frame.
322
324
  script = r';'.join([
323
325
  r"import numexpr as ne",
@@ -333,7 +335,7 @@ class test_numexpr(TestCase):
333
335
  ])
334
336
  # Raises CalledProcessError on a non-normal exit
335
337
  check = subprocess.check_call([sys.executable, '-c', script])
336
- # Ideally this test should also be done against ipython but it's not
338
+ # Ideally this test should also be done against ipython but it's not
337
339
  # a requirement.
338
340
 
339
341
 
@@ -443,7 +445,7 @@ class test_evaluate(TestCase):
443
445
 
444
446
  def test_complex_expr(self):
445
447
  def complex(a, b):
446
- c = zeros(a.shape, dtype=complex_)
448
+ c = zeros(a.shape, dtype=cdouble)
447
449
  c.real = a
448
450
  c.imag = b
449
451
  return c
@@ -520,7 +522,7 @@ class test_evaluate(TestCase):
520
522
  self.fail()
521
523
 
522
524
  # Forbid colon for lambda funcs
523
- try:
525
+ try:
524
526
  evaluate('lambda x: x')
525
527
  except ValueError:
526
528
  pass
@@ -576,7 +578,15 @@ class test_evaluate(TestCase):
576
578
  evaluate('c.real')
577
579
  evaluate('c.imag')
578
580
 
579
-
581
+ # pass imaginary unit j
582
+ evaluate('1.5j')
583
+ evaluate('3.j')
584
+
585
+ # pass forbidden characters within quotes
586
+ x = np.array(['a', 'b'], dtype=bytes)
587
+ evaluate("x == 'b:'")
588
+
589
+
580
590
  def test_no_sanitize(self):
581
591
  try: # Errors on compile() after eval()
582
592
  evaluate('import os;', sanitize=False)
@@ -596,7 +606,7 @@ class test_evaluate(TestCase):
596
606
  def test_disassemble(self):
597
607
  assert_equal(disassemble(NumExpr(
598
608
  "where(m, a, -1)", [('m', bool), ('a', float)])),
599
- [[b'where_fbff', b'r0', b'r1[m]', b'r2[a]', b'c3[-1.0]'],
609
+ [[b'where_fbff', b'r0', b'r1[m]', b'r2[a]', b'c3[-1.0]'],
600
610
  [b'noop', None, None, None]])
601
611
 
602
612
  def test_constant_deduplication(self):
@@ -615,18 +625,18 @@ class test_evaluate(TestCase):
615
625
  assert_equal(ConstantNode(numpy.float32(1)).astKind, "float")
616
626
  assert_equal(ConstantNode(numpy.float32("nan")).astKind, "float")
617
627
  assert_equal(ConstantNode(numpy.float32(3)).value.dtype, numpy.dtype("float32"))
618
- assert_array_equal(NumExpr(ConstantNode(numpy.float32(1))).run(),
628
+ assert_array_equal(NumExpr(ConstantNode(numpy.float32(1))).run(),
619
629
  numpy.array(1, dtype="float32"))
620
630
 
621
631
  def test_unaligned_singleton(self):
622
- # Test for issue #397 whether singletons outputs assigned to consts must be
632
+ # Test for issue #397 whether singletons outputs assigned to consts must be
623
633
  # aligned or not.
624
634
  a = np.empty(5, dtype=np.uint8)[1:].view(np.int32)
625
635
  evaluate('3', out=a)
626
636
  assert_equal(a, 3)
627
637
 
628
638
  def test_negative_mod(self):
629
- # Test for issue #413, modulus of negative integers. C modulus is
639
+ # Test for issue #413, modulus of negative integers. C modulus is
630
640
  # actually remainder op, and hence different from Python modulus.
631
641
  a = np.array([-500, -135, 0, 0, 135, 500], dtype=np.int32)
632
642
  n = np.array([-360, -360, -360, 360, 360, 360], dtype=np.int32)
@@ -641,11 +651,11 @@ class test_evaluate(TestCase):
641
651
  def test_negative_power_scalar(self):
642
652
  # Test for issue #428, where the power is negative and the base is an
643
653
  # integer. This was running afoul in the precomputation in `expressions.py:pow_op()`
644
- base = np.array([-2, -1, 0, 1, 2, 3], dtype=np.int32)
654
+ base = np.array([-2, -1, 1, 2, 3], dtype=np.int32)
645
655
  out_i = evaluate('base ** -1.0')
646
656
  assert_equal(out_i, np.power(base, -1.0))
647
657
 
648
- base = np.array([-2, -1, 0, 1, 2, 3], dtype=np.int64)
658
+ base = np.array([-2, -1, 1, 2, 3], dtype=np.int64)
649
659
  out_l = evaluate('base ** -1.0')
650
660
  assert_equal(out_l, np.power(base, -1.0))
651
661
 
@@ -1111,7 +1121,7 @@ def _environment(key, value):
1111
1121
  # Test cases for the threading configuration
1112
1122
  class test_threading_config(TestCase):
1113
1123
  def test_max_threads_unset(self):
1114
- # Has to be done in a subprocess as `importlib.reload` doesn't let us
1124
+ # Has to be done in a subprocess as `importlib.reload` doesn't let us
1115
1125
  # re-initialize the threadpool
1116
1126
  script = '\n'.join([
1117
1127
  "import os",
@@ -1123,7 +1133,7 @@ class test_threading_config(TestCase):
1123
1133
  subprocess.check_call([sys.executable, '-c', script])
1124
1134
 
1125
1135
  def test_max_threads_set(self):
1126
- # Has to be done in a subprocess as `importlib.reload` doesn't let us
1136
+ # Has to be done in a subprocess as `importlib.reload` doesn't let us
1127
1137
  # re-initialize the threadpool
1128
1138
  script = '\n'.join([
1129
1139
  "import os",
@@ -1149,6 +1159,20 @@ class test_threading_config(TestCase):
1149
1159
  else:
1150
1160
  self.assertEqual(5, numexpr._init_num_threads())
1151
1161
 
1162
+ def test_omp_num_threads_empty_string(self):
1163
+ with _environment('OMP_NUM_THREADS', ''):
1164
+ if 'sparc' in platform.machine():
1165
+ self.assertEqual(1, numexpr._init_num_threads())
1166
+ else:
1167
+ self.assertEqual(detect_number_of_cores(), numexpr._init_num_threads())
1168
+
1169
+ def test_numexpr_max_threads_empty_string(self):
1170
+ with _environment('NUMEXPR_MAX_THREADS', ''):
1171
+ if 'sparc' in platform.machine():
1172
+ self.assertEqual(1, numexpr._init_num_threads())
1173
+ else:
1174
+ self.assertEqual(detect_number_of_cores(), numexpr._init_num_threads())
1175
+
1152
1176
  def test_vml_threads_round_trip(self):
1153
1177
  n_threads = 3
1154
1178
  if use_vml:
@@ -1238,7 +1262,7 @@ def print_versions():
1238
1262
  (sysname, nodename, release, os_version, machine, processor) = platform.uname()
1239
1263
  print('Platform: %s-%s-%s' % (sys.platform, machine, os_version))
1240
1264
  try:
1241
- # cpuinfo doesn't work on OSX well it seems, so protect these outputs
1265
+ # cpuinfo doesn't work on OSX well it seems, so protect these outputs
1242
1266
  # with a try block
1243
1267
  cpu_info = cpu.info[0]
1244
1268
  print('CPU vendor: %s' % cpu_info.get('VendorIdentifier', ''))
@@ -13,7 +13,6 @@ log = logging.getLogger(__name__)
13
13
 
14
14
  import os
15
15
  import subprocess
16
- import platform
17
16
 
18
17
  from numexpr.interpreter import _set_num_threads, _get_num_threads, MAX_THREADS
19
18
  from numexpr import use_vml
@@ -134,7 +133,8 @@ def _init_num_threads():
134
133
 
135
134
  env_configured = False
136
135
  n_cores = detect_number_of_cores()
137
- if 'NUMEXPR_MAX_THREADS' in os.environ:
136
+ if ('NUMEXPR_MAX_THREADS' in os.environ and os.environ['NUMEXPR_MAX_THREADS'] != '' or
137
+ 'OMP_NUM_THREADS' in os.environ and os.environ['OMP_NUM_THREADS'] != ''):
138
138
  # The user has configured NumExpr in the expected way, so suppress logs.
139
139
  env_configured = True
140
140
  n_cores = MAX_THREADS
@@ -150,9 +150,10 @@ def _init_num_threads():
150
150
 
151
151
  # Now we check for 'NUMEXPR_NUM_THREADS' or 'OMP_NUM_THREADS' to set the
152
152
  # actual number of threads used.
153
- if 'NUMEXPR_NUM_THREADS' in os.environ:
153
+ if 'NUMEXPR_NUM_THREADS' in os.environ and os.environ['NUMEXPR_NUM_THREADS'] != '':
154
154
  requested_threads = int(os.environ['NUMEXPR_NUM_THREADS'])
155
- elif 'OMP_NUM_THREADS' in os.environ:
155
+ elif 'OMP_NUM_THREADS' in os.environ and os.environ['OMP_NUM_THREADS'] != '':
156
+ # Empty string is commonly used to unset the variable
156
157
  requested_threads = int(os.environ['OMP_NUM_THREADS'])
157
158
  else:
158
159
  requested_threads = n_cores
@@ -1,4 +1,4 @@
1
1
  # THIS FILE IS GENERATED BY `SETUP.PY`
2
- version = '2.8.8'
3
- numpy_build_version = '1.26.1'
2
+ version = '2.10.0'
3
+ numpy_build_version = '2.0.0rc1'
4
4
  platform_machine = 'AMD64'
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: numexpr
3
- Version: 2.8.8
3
+ Version: 2.10.0
4
4
  Summary: Fast numerical expression evaluator for NumPy
5
5
  Home-page: https://github.com/pydata/numexpr
6
6
  Author: David M. Cooke, Francesc Alted, and others
7
- Maintainer: Robert A. McLeod
8
- Maintainer-email: robbmcleod@gmail.com
7
+ Maintainer: Francesc Alted
8
+ Maintainer-email: faltet@gmail.com
9
9
  License: MIT
10
10
  Classifier: Development Status :: 6 - Mature
11
11
  Classifier: Intended Audience :: Financial and Insurance Industry
@@ -23,7 +23,7 @@ Requires-Python: >=3.9
23
23
  Description-Content-Type: text/x-rst
24
24
  License-File: LICENSE.txt
25
25
  License-File: AUTHORS.txt
26
- Requires-Dist: numpy>=1.13.3
26
+ Requires-Dist: numpy>=1.19.3
27
27
 
28
28
  ======================================================
29
29
  NumExpr: Fast numerical expression evaluator for NumPy
@@ -34,7 +34,6 @@ NumExpr: Fast numerical expression evaluator for NumPy
34
34
  :Contact: faltet@gmail.com
35
35
  :URL: https://github.com/pydata/numexpr
36
36
  :Documentation: http://numexpr.readthedocs.io/en/latest/
37
- :Travis CI: |travis|
38
37
  :GitHub Actions: |actions|
39
38
  :PyPi: |version|
40
39
  :DOI: |doi|
@@ -48,7 +47,7 @@ NumExpr: Fast numerical expression evaluator for NumPy
48
47
  :target: http://numexpr.readthedocs.io/en/latest
49
48
  .. |doi| image:: https://zenodo.org/badge/doi/10.5281/zenodo.2483274.svg
50
49
  :target: https://doi.org/10.5281/zenodo.2483274
51
- .. |version| image:: https://img.shields.io/pypi/v/numexpr.png
50
+ .. |version| image:: https://img.shields.io/pypi/v/numexpr
52
51
  :target: https://pypi.python.org/pypi/numexpr
53
52
 
54
53
 
@@ -175,7 +174,7 @@ Usage
175
174
  array([ 1.00000000e+00, 2.00000000e+00, 3.00000000e+00, ...,
176
175
  9.99998000e+05, 9.99999000e+05, 1.00000000e+06])
177
176
 
178
- >>> ne.evaluate('a*b-4.1*a > 2.5*b') # a more complex one
177
+ >>> ne.evaluate("a * b - 4.1 * a > 2.5 * b") # a more complex one
179
178
  array([False, False, False, ..., True, True, True], dtype=bool)
180
179
 
181
180
  >>> ne.evaluate("sin(a) + arcsinh(a/b)") # you can also use functions
@@ -0,0 +1 @@
1
+ numpy>=1.19.3
@@ -0,0 +1,7 @@
1
+ [build-system]
2
+ requires = [
3
+ "setuptools",
4
+ "wheel",
5
+ "numpy>=2.0.0rc1",
6
+ ]
7
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1 @@
1
+ numpy >= 1.19.3 # keep in sync with NPY_TARGET_VERSION (setup.py)
@@ -1,10 +1,10 @@
1
1
  [metadata]
2
2
  name = numexpr
3
- version = 2.8.8
3
+ version = 2.10.0
4
4
  description = Fast numerical expression evaluator for NumPy
5
5
  author = David M. Cooke, Francesc Alted, and others
6
- maintainer = Robert A. McLeod
7
- maintainer_email = robbmcleod@gmail.com
6
+ maintainer = Francesc Alted
7
+ maintainer_email = faltet@gmail.com
8
8
  url = https://github.com/pydata/numexpr
9
9
  long_description = file: README.rst
10
10
  long_description_content_type = text/x-rst
@@ -33,7 +33,10 @@ lib_dirs = []
33
33
  inc_dirs = [np.get_include()]
34
34
  libs = [] # Pre-built libraries ONLY, like python36.so
35
35
  clibs = []
36
- def_macros = []
36
+ def_macros = [
37
+ # keep in sync with minimal runtime requirement (requirements.txt)
38
+ ('NPY_TARGET_VERSION', 'NPY_1_19_API_VERSION')
39
+ ]
37
40
  sources = ['numexpr/interpreter.cpp',
38
41
  'numexpr/module.cpp',
39
42
  'numexpr/numexpr_object.cpp']
@@ -1 +0,0 @@
1
- numpy>=1.13.3
@@ -1,3 +0,0 @@
1
- [build-system]
2
- requires = ["setuptools", "wheel", "oldest-supported-numpy"]
3
- build-backend = "setuptools.build_meta"
@@ -1 +0,0 @@
1
- numpy >= 1.13.3
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