From 3254d908927e372961d563cf07e7cb9be1fbefa0 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Mon, 18 May 2026 14:52:18 -0700 Subject: [PATCH 1/4] Directly inspect types instead of using strings in literals test This avoids breakage with Python 3.14 which changes the string representation of unions from `typing.Union[a,b]` to `a | b`. Signed-off-by: Danila Fedorin --- tests/numpy/dtypes_test.py | 61 ++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/tests/numpy/dtypes_test.py b/tests/numpy/dtypes_test.py index e2e127d8a7a..5bbdd939dd9 100644 --- a/tests/numpy/dtypes_test.py +++ b/tests/numpy/dtypes_test.py @@ -1,3 +1,5 @@ +import typing + import numpy as np import pytest @@ -181,32 +183,41 @@ def test_SeriesDTypes(self): for dt in "bool", "": assert dtypes.SeriesDTypes[dt] == np.bool_ - def test_scalars(self): - assert "typing.Union[bool, numpy.bool]" == str(ak.bool_scalars) - assert "typing.Union[bool, numpy.bool]" == str(ak.bool_scalars) - assert "typing.Union[float, numpy.float64, numpy.float32]" == str(ak.float_scalars) - assert ( - "typing.Union[int, numpy.int8, numpy.int16, numpy.int32, numpy.int64, " - + "numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64]" - ) == str(ak.int_scalars) - - assert ( - "typing.Union[float, numpy.float64, numpy.float32, int, numpy.int8, numpy.int16, " - + "numpy.int32, numpy.int64, numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64]" - ) == str(ak.numeric_scalars) - - assert "typing.Union[str, numpy.str_]" == str(ak.str_scalars) - assert ( - "typing.Union[numpy.float64, numpy.float32, numpy.int8, numpy.int16, numpy.int32, " - + "numpy.int64, numpy.bool, numpy.str_, numpy.uint8, numpy.uint16, numpy.uint32, " - + "numpy.uint64]" - ) == str(ak.numpy_scalars) + def _assert_union(self, type_alias, *expected_types): + """Check that a TypeAlias is a Union containing exactly the expected types.""" + assert typing.get_origin(type_alias) is typing.Union + assert set(typing.get_args(type_alias)) == set(expected_types) - assert ( - "typing.Union[bool, numpy.bool, float, numpy.float64, numpy.float32, int, numpy.int8, " - + "numpy.int16, numpy.int32, numpy.int64, numpy.uint8, numpy.uint16, numpy.uint32," - + " numpy.uint64, numpy.str_, str]" - ) == str(ak.all_scalars) + def test_scalars(self): + self._assert_union(ak.bool_scalars, bool, np.bool_) + self._assert_union(ak.float_scalars, float, np.float64, np.float32) + self._assert_union( + ak.int_scalars, + int, np.int8, np.int16, np.int32, np.int64, + np.uint8, np.uint16, np.uint32, np.uint64, + ) + self._assert_union( + ak.numeric_scalars, + float, np.float64, np.float32, + int, np.int8, np.int16, np.int32, np.int64, + np.uint8, np.uint16, np.uint32, np.uint64, + ) + self._assert_union(ak.str_scalars, str, np.str_) + self._assert_union( + ak.numpy_scalars, + np.float64, np.float32, + np.int8, np.int16, np.int32, np.int64, + np.bool_, np.str_, + np.uint8, np.uint16, np.uint32, np.uint64, + ) + self._assert_union( + ak.all_scalars, + bool, np.bool_, + float, np.float64, np.float32, + int, np.int8, np.int16, np.int32, np.int64, + np.uint8, np.uint16, np.uint32, np.uint64, + np.str_, str, + ) def test_number_format_strings(self): assert "{}" == dtypes.NUMBER_FORMAT_STRINGS["bool"] From 411a79919caab9763f2c4f4b7cc0b21040997262 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Mon, 18 May 2026 14:53:14 -0700 Subject: [PATCH 2/4] Expand whitespace literal list with Unicode 16 Also adds a script for re-generating update_numeric_unicodes.py Signed-off-by: Danila Fedorin --- scripts/update_numeric_unicodes.py | 31 ++++++++++++++++++++++++++++++ src/NumericUnicodes.chpl | 20 +++++++++++++------ 2 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 scripts/update_numeric_unicodes.py diff --git a/scripts/update_numeric_unicodes.py b/scripts/update_numeric_unicodes.py new file mode 100644 index 00000000000..c73f8c74129 --- /dev/null +++ b/scripts/update_numeric_unicodes.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +""" +Regenerate src/NumericUnicodes.chpl to match the current Python interpreter's +definition of isnumeric(). Run as: + + $CHPL_HOME/util/config/run-in-venv-with-python-bindings.bash \ + python3 scripts/update_numeric_unicodes.py --in-place src/NumericUnicodes.chpl +""" + +from chapel import Variable, each_matching +from chapel.replace import run + + +def _build_set_literal() -> str: + """Return a Chapel set literal containing every codepoint chr(i).isnumeric() accepts.""" + codepoints = sorted(i for i in range(0x110000) if chr(i).isnumeric()) + lines = ["const allNumericUnicodes = {"] + for i in range(0, len(codepoints), 10): + chunk = codepoints[i : i + 10] + lines.append(" " + ", ".join(f"0x{c:x}" for c in chunk) + " ,") + lines.append(" }") + return "\n".join(lines) + + +def replace_numeric_unicodes(rc, root): + for (var, _) in each_matching(root, Variable): + if var.name() == "allNumericUnicodes": + yield (var, _build_set_literal()) + + +run(replace_numeric_unicodes) diff --git a/src/NumericUnicodes.chpl b/src/NumericUnicodes.chpl index c189f90a6bd..cebfbbf9dad 100644 --- a/src/NumericUnicodes.chpl +++ b/src/NumericUnicodes.chpl @@ -117,7 +117,8 @@ const allNumericUnicodes = { 0x10b58, 0x10b59, 0x10b5a, 0x10b5b, 0x10b5c, 0x10b5d, 0x10b5e, 0x10b5f, 0x10b78, 0x10b79 , 0x10b7a, 0x10b7b, 0x10b7c, 0x10b7d, 0x10b7e, 0x10b7f, 0x10ba9, 0x10baa, 0x10bab, 0x10bac , 0x10bad, 0x10bae, 0x10baf, 0x10cfa, 0x10cfb, 0x10cfc, 0x10cfd, 0x10cfe, 0x10cff, 0x10d30 , - 0x10d31, 0x10d32, 0x10d33, 0x10d34, 0x10d35, 0x10d36, 0x10d37, 0x10d38, 0x10d39, 0x10e60 , + 0x10d31, 0x10d32, 0x10d33, 0x10d34, 0x10d35, 0x10d36, 0x10d37, 0x10d38, 0x10d39, 0x10d40 , + 0x10d41, 0x10d42, 0x10d43, 0x10d44, 0x10d45, 0x10d46, 0x10d47, 0x10d48, 0x10d49, 0x10e60 , 0x10e61, 0x10e62, 0x10e63, 0x10e64, 0x10e65, 0x10e66, 0x10e67, 0x10e68, 0x10e69, 0x10e6a , 0x10e6b, 0x10e6c, 0x10e6d, 0x10e6e, 0x10e6f, 0x10e70, 0x10e71, 0x10e72, 0x10e73, 0x10e74 , 0x10e75, 0x10e76, 0x10e77, 0x10e78, 0x10e79, 0x10e7a, 0x10e7b, 0x10e7c, 0x10e7d, 0x10e7e , @@ -136,11 +137,14 @@ const allNumericUnicodes = { 0x11459, 0x114d0, 0x114d1, 0x114d2, 0x114d3, 0x114d4, 0x114d5, 0x114d6, 0x114d7, 0x114d8 , 0x114d9, 0x11650, 0x11651, 0x11652, 0x11653, 0x11654, 0x11655, 0x11656, 0x11657, 0x11658 , 0x11659, 0x116c0, 0x116c1, 0x116c2, 0x116c3, 0x116c4, 0x116c5, 0x116c6, 0x116c7, 0x116c8 , - 0x116c9, 0x11730, 0x11731, 0x11732, 0x11733, 0x11734, 0x11735, 0x11736, 0x11737, 0x11738 , + 0x116c9, 0x116d0, 0x116d1, 0x116d2, 0x116d3, 0x116d4, 0x116d5, 0x116d6, 0x116d7, 0x116d8 , + 0x116d9, 0x116da, 0x116db, 0x116dc, 0x116dd, 0x116de, 0x116df, 0x116e0, 0x116e1, 0x116e2 , + 0x116e3, 0x11730, 0x11731, 0x11732, 0x11733, 0x11734, 0x11735, 0x11736, 0x11737, 0x11738 , 0x11739, 0x1173a, 0x1173b, 0x118e0, 0x118e1, 0x118e2, 0x118e3, 0x118e4, 0x118e5, 0x118e6 , 0x118e7, 0x118e8, 0x118e9, 0x118ea, 0x118eb, 0x118ec, 0x118ed, 0x118ee, 0x118ef, 0x118f0 , 0x118f1, 0x118f2, 0x11950, 0x11951, 0x11952, 0x11953, 0x11954, 0x11955, 0x11956, 0x11957 , - 0x11958, 0x11959, 0x11c50, 0x11c51, 0x11c52, 0x11c53, 0x11c54, 0x11c55, 0x11c56, 0x11c57 , + 0x11958, 0x11959, 0x11bf0, 0x11bf1, 0x11bf2, 0x11bf3, 0x11bf4, 0x11bf5, 0x11bf6, 0x11bf7 , + 0x11bf8, 0x11bf9, 0x11c50, 0x11c51, 0x11c52, 0x11c53, 0x11c54, 0x11c55, 0x11c56, 0x11c57 , 0x11c58, 0x11c59, 0x11c5a, 0x11c5b, 0x11c5c, 0x11c5d, 0x11c5e, 0x11c5f, 0x11c60, 0x11c61 , 0x11c62, 0x11c63, 0x11c64, 0x11c65, 0x11c66, 0x11c67, 0x11c68, 0x11c69, 0x11c6a, 0x11c6b , 0x11c6c, 0x11d50, 0x11d51, 0x11d52, 0x11d53, 0x11d54, 0x11d55, 0x11d56, 0x11d57, 0x11d58 , @@ -159,13 +163,16 @@ const allNumericUnicodes = { 0x1244e, 0x1244f, 0x12450, 0x12451, 0x12452, 0x12453, 0x12454, 0x12455, 0x12456, 0x12457 , 0x12458, 0x12459, 0x1245a, 0x1245b, 0x1245c, 0x1245d, 0x1245e, 0x1245f, 0x12460, 0x12461 , 0x12462, 0x12463, 0x12464, 0x12465, 0x12466, 0x12467, 0x12468, 0x12469, 0x1246a, 0x1246b , - 0x1246c, 0x1246d, 0x1246e, 0x16a60, 0x16a61, 0x16a62, 0x16a63, 0x16a64, 0x16a65, 0x16a66 , + 0x1246c, 0x1246d, 0x1246e, 0x16130, 0x16131, 0x16132, 0x16133, 0x16134, 0x16135, 0x16136 , + 0x16137, 0x16138, 0x16139, 0x16a60, 0x16a61, 0x16a62, 0x16a63, 0x16a64, 0x16a65, 0x16a66 , 0x16a67, 0x16a68, 0x16a69, 0x16ac0, 0x16ac1, 0x16ac2, 0x16ac3, 0x16ac4, 0x16ac5, 0x16ac6 , 0x16ac7, 0x16ac8, 0x16ac9, 0x16b50, 0x16b51, 0x16b52, 0x16b53, 0x16b54, 0x16b55, 0x16b56 , 0x16b57, 0x16b58, 0x16b59, 0x16b5b, 0x16b5c, 0x16b5d, 0x16b5e, 0x16b5f, 0x16b60, 0x16b61 , + 0x16d70, 0x16d71, 0x16d72, 0x16d73, 0x16d74, 0x16d75, 0x16d76, 0x16d77, 0x16d78, 0x16d79 , 0x16e80, 0x16e81, 0x16e82, 0x16e83, 0x16e84, 0x16e85, 0x16e86, 0x16e87, 0x16e88, 0x16e89 , 0x16e8a, 0x16e8b, 0x16e8c, 0x16e8d, 0x16e8e, 0x16e8f, 0x16e90, 0x16e91, 0x16e92, 0x16e93 , - 0x16e94, 0x16e95, 0x16e96, 0x1d2c0, 0x1d2c1, 0x1d2c2, 0x1d2c3, 0x1d2c4, 0x1d2c5, 0x1d2c6 , + 0x16e94, 0x16e95, 0x16e96, 0x1ccf0, 0x1ccf1, 0x1ccf2, 0x1ccf3, 0x1ccf4, 0x1ccf5, 0x1ccf6 , + 0x1ccf7, 0x1ccf8, 0x1ccf9, 0x1d2c0, 0x1d2c1, 0x1d2c2, 0x1d2c3, 0x1d2c4, 0x1d2c5, 0x1d2c6 , 0x1d2c7, 0x1d2c8, 0x1d2c9, 0x1d2ca, 0x1d2cb, 0x1d2cc, 0x1d2cd, 0x1d2ce, 0x1d2cf, 0x1d2d0 , 0x1d2d1, 0x1d2d2, 0x1d2d3, 0x1d2e0, 0x1d2e1, 0x1d2e2, 0x1d2e3, 0x1d2e4, 0x1d2e5, 0x1d2e6 , 0x1d2e7, 0x1d2e8, 0x1d2e9, 0x1d2ea, 0x1d2eb, 0x1d2ec, 0x1d2ed, 0x1d2ee, 0x1d2ef, 0x1d2f0 , @@ -179,7 +186,8 @@ const allNumericUnicodes = { 0x1d7f8, 0x1d7f9, 0x1d7fa, 0x1d7fb, 0x1d7fc, 0x1d7fd, 0x1d7fe, 0x1d7ff, 0x1e140, 0x1e141 , 0x1e142, 0x1e143, 0x1e144, 0x1e145, 0x1e146, 0x1e147, 0x1e148, 0x1e149, 0x1e2f0, 0x1e2f1 , 0x1e2f2, 0x1e2f3, 0x1e2f4, 0x1e2f5, 0x1e2f6, 0x1e2f7, 0x1e2f8, 0x1e2f9, 0x1e4f0, 0x1e4f1 , - 0x1e4f2, 0x1e4f3, 0x1e4f4, 0x1e4f5, 0x1e4f6, 0x1e4f7, 0x1e4f8, 0x1e4f9, 0x1e8c7, 0x1e8c8 , + 0x1e4f2, 0x1e4f3, 0x1e4f4, 0x1e4f5, 0x1e4f6, 0x1e4f7, 0x1e4f8, 0x1e4f9, 0x1e5f1, 0x1e5f2 , + 0x1e5f3, 0x1e5f4, 0x1e5f5, 0x1e5f6, 0x1e5f7, 0x1e5f8, 0x1e5f9, 0x1e5fa, 0x1e8c7, 0x1e8c8 , 0x1e8c9, 0x1e8ca, 0x1e8cb, 0x1e8cc, 0x1e8cd, 0x1e8ce, 0x1e8cf, 0x1e950, 0x1e951, 0x1e952 , 0x1e953, 0x1e954, 0x1e955, 0x1e956, 0x1e957, 0x1e958, 0x1e959, 0x1ec71, 0x1ec72, 0x1ec73 , 0x1ec74, 0x1ec75, 0x1ec76, 0x1ec77, 0x1ec78, 0x1ec79, 0x1ec7a, 0x1ec7b, 0x1ec7c, 0x1ec7d , From 8b391ca6c71cddb489ebe60ccab7519b4546a1cb Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Mon, 18 May 2026 15:21:34 -0700 Subject: [PATCH 3/4] Apply UnattachedCurly autofix to fix linter failures Signed-off-by: Danila Fedorin --- src/Repartition.chpl | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/src/Repartition.chpl b/src/Repartition.chpl index cab1ec41e9f..08385b8b409 100644 --- a/src/Repartition.chpl +++ b/src/Repartition.chpl @@ -1,5 +1,4 @@ -module Repartition -{ +module Repartition { // The goal of this module is to provide helper functions to facilitate redistributing data between // locales. @@ -27,8 +26,7 @@ module Repartition // Note, the arrays passed here must have PrivateSpace domains. proc repartitionByHashString(const ref strOffsets: [] list(int), const ref strBytes: [] list(uint(8))): - ([PrivateSpace] list(int), [PrivateSpace] list(uint(8))) - { + ([PrivateSpace] list(int), [PrivateSpace] list(uint(8))) { var destLocales: [PrivateSpace] list(int); coforall loc in Locales do on loc { @@ -53,8 +51,7 @@ module Repartition // Note, the arrays passed here must have PrivateSpace domains. proc repartitionByHashStringArray(const ref strOffsets: [] innerArray(int), const ref strBytes: [] innerArray(uint(8))): - ([PrivateSpace] innerArray(int), [PrivateSpace] innerArray(uint(8))) - { + ([PrivateSpace] innerArray(int), [PrivateSpace] innerArray(uint(8))) { var destLocales: [PrivateSpace] innerArray(int); coforall loc in Locales do on loc { @@ -76,8 +73,7 @@ module Repartition } // Note, the arrays passed here must have PrivateSpace domains. - proc repartitionByHashArray(type t, const ref vals: [] innerArray(t)) - { + proc repartitionByHashArray(type t, const ref vals: [] innerArray(t)) { type eltType = vals.eltType.t; var destLocales: [PrivateSpace] innerArray(int); @@ -103,8 +99,7 @@ module Repartition proc repartitionByLocaleString(const ref destLocales: [] list(int), const ref strOffsets: [] list(int), const ref strBytes: [] list(uint(8))): - ([PrivateSpace] list(int), [PrivateSpace] list(uint(8))) - { + ([PrivateSpace] list(int), [PrivateSpace] list(uint(8))) { var maxBytesPerLocale: int; var maxStringsPerLocale: int; var numBytesReceivingByLocale: [PrivateSpace] [0..#numLocales] int; @@ -116,8 +111,7 @@ module Repartition coforall loc in Locales with (max reduce maxBytesPerLocale, max reduce maxStringsPerLocale) - do on loc - { + do on loc { const myDestLocales = destLocales[here.id].toArray(); const myStrOffsets = strOffsets[here.id].toArray(); const myStrBytesSize = strBytes[here.id].size; @@ -246,8 +240,7 @@ module Repartition proc repartitionByLocaleStringArray(const ref destLocales: [] innerArray(int), const ref strOffsets: [] innerArray(int), const ref strBytes: [] innerArray(uint(8))): - ([PrivateSpace] innerArray(int), [PrivateSpace] innerArray(uint(8))) - { + ([PrivateSpace] innerArray(int), [PrivateSpace] innerArray(uint(8))) { var numBytesSendingByLocale: [PrivateSpace] [0..#numLocales] int; var numStringsSendingByLocale: [PrivateSpace] [0..#numLocales] int; var allStrSizes: [PrivateSpace] innerArray(int); @@ -257,8 +250,7 @@ module Repartition // First we need to figure out how many bytes and strings are getting transferred. // Also calculating the sizes of each string so that indexing is easier down the road. - coforall loc in Locales do on loc - { + coforall loc in Locales do on loc { const ref myDestLocales = destLocales[here.id].Arr; const ref myStrOffsets = strOffsets[here.id].Arr; const ref myStrBytes = strBytes[here.id].Arr; @@ -383,8 +375,7 @@ module Repartition // Note, the arrays passed here must have PrivateSpace domains. proc repartitionByLocale(type t, const ref destLocales: [] list(int), - const ref vals: [] list(t)) - { + const ref vals: [] list(t)) { type eltType = vals.eltType.eltType; var maxValsPerLocale: int; @@ -392,8 +383,7 @@ module Repartition coforall loc in Locales with (max reduce maxValsPerLocale) - do on loc - { + do on loc { const ref myDestLocales = destLocales[here.id]; const ref myVals = vals[here.id]; var valsPerLocale: [0..#numLocales] int = 0; @@ -481,15 +471,13 @@ module Repartition proc repartitionByLocaleArray(type t, const ref destLocales: [] innerArray(int), - const ref vals: [] innerArray(t)) - { + const ref vals: [] innerArray(t)) { type eltType = vals.eltType.t; var numValsSendingByLocale: [PrivateSpace] [0..#numLocales] int; var sendVals: [PrivateSpace] [0..#numLocales] innerArray(t); - coforall loc in Locales do on loc - { + coforall loc in Locales do on loc { const ref myDestLocales = destLocales[here.id].Arr; const ref myVals = vals[here.id].Arr; @@ -575,8 +563,7 @@ module Repartition proc repartitionByLocaleMultiArray(type t, const ref destLocales: [] innerArray(int), - const ref vals: [] [] innerArray(t)) - { + const ref vals: [] [] innerArray(t)) { // Notes: // - We assume `vals` is indexed as [field][PrivateSpace], i.e., vals[k][here.id] // - `innerArray(t)` is your existing wrapper with `.Arr` and From 664f91ac8e787d95e80a795fd4ff3ee8378354d0 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Mon, 18 May 2026 15:33:57 -0700 Subject: [PATCH 4/4] Apply ruff's suggestions Signed-off-by: Danila Fedorin --- scripts/update_numeric_unicodes.py | 2 +- tests/numpy/dtypes_test.py | 63 +++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/scripts/update_numeric_unicodes.py b/scripts/update_numeric_unicodes.py index c73f8c74129..e865930a9bf 100644 --- a/scripts/update_numeric_unicodes.py +++ b/scripts/update_numeric_unicodes.py @@ -23,7 +23,7 @@ def _build_set_literal() -> str: def replace_numeric_unicodes(rc, root): - for (var, _) in each_matching(root, Variable): + for var, _ in each_matching(root, Variable): if var.name() == "allNumericUnicodes": yield (var, _build_set_literal()) diff --git a/tests/numpy/dtypes_test.py b/tests/numpy/dtypes_test.py index 5bbdd939dd9..f0fce709b52 100644 --- a/tests/numpy/dtypes_test.py +++ b/tests/numpy/dtypes_test.py @@ -193,30 +193,65 @@ def test_scalars(self): self._assert_union(ak.float_scalars, float, np.float64, np.float32) self._assert_union( ak.int_scalars, - int, np.int8, np.int16, np.int32, np.int64, - np.uint8, np.uint16, np.uint32, np.uint64, + int, + np.int8, + np.int16, + np.int32, + np.int64, + np.uint8, + np.uint16, + np.uint32, + np.uint64, ) self._assert_union( ak.numeric_scalars, - float, np.float64, np.float32, - int, np.int8, np.int16, np.int32, np.int64, - np.uint8, np.uint16, np.uint32, np.uint64, + float, + np.float64, + np.float32, + int, + np.int8, + np.int16, + np.int32, + np.int64, + np.uint8, + np.uint16, + np.uint32, + np.uint64, ) self._assert_union(ak.str_scalars, str, np.str_) self._assert_union( ak.numpy_scalars, - np.float64, np.float32, - np.int8, np.int16, np.int32, np.int64, - np.bool_, np.str_, - np.uint8, np.uint16, np.uint32, np.uint64, + np.float64, + np.float32, + np.int8, + np.int16, + np.int32, + np.int64, + np.bool_, + np.str_, + np.uint8, + np.uint16, + np.uint32, + np.uint64, ) self._assert_union( ak.all_scalars, - bool, np.bool_, - float, np.float64, np.float32, - int, np.int8, np.int16, np.int32, np.int64, - np.uint8, np.uint16, np.uint32, np.uint64, - np.str_, str, + bool, + np.bool_, + float, + np.float64, + np.float32, + int, + np.int8, + np.int16, + np.int32, + np.int64, + np.uint8, + np.uint16, + np.uint32, + np.uint64, + np.str_, + str, ) def test_number_format_strings(self):