Skip to content

Properly handles overflow integers. #51

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

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
54f53d5
Properly handles overflow integers.
chaburkland Jun 8, 2021
d3b188e
Removes specific bytes size from test.
chaburkland Jun 8, 2021
93a91ff
More tweaks to int sizes.
chaburkland Jun 8, 2021
38d4fc6
Adds 2**32 test.
chaburkland Jun 8, 2021
4769f0f
Fixes unhelpful comments.
chaburkland Jun 8, 2021
91c4aee
Makes implicit type coercion explicit.
chaburkland Jun 9, 2021
ca8b822
Update test/test_util.py
chaburkland Jun 9, 2021
3f67876
Update src/_arraykit.c
chaburkland Jun 9, 2021
f916fdd
Update src/_arraykit.c
chaburkland Jun 9, 2021
f2a14eb
Update src/_arraykit.c
chaburkland Jun 9, 2021
5d24633
Update src/_arraykit.c
chaburkland Jun 10, 2021
83618f1
Update src/_arraykit.c
chaburkland Jun 10, 2021
910b978
Update src/_arraykit.c
chaburkland Jun 10, 2021
34309ef
Update src/_arraykit.c
chaburkland Jun 10, 2021
135d10b
Update src/_arraykit.c
chaburkland Jun 10, 2021
086c6ba
Update src/_arraykit.c
chaburkland Jun 10, 2021
54bd85f
Fixes syntax bug from merge suggestion.
chaburkland Jun 10, 2021
021518d
Fixes incorrect mid-range boundaries.
chaburkland Jun 10, 2021
dcf9244
Yet another attempt to fix this cursed test.
chaburkland Jun 10, 2021
33cc3c2
Another attempt >:|
chaburkland Jun 10, 2021
078a00a
Attempt to be inclusive of 32bit architectures.
chaburkland Jun 10, 2021
cc9d8f7
Updates error message. Why does anyone have 32bit machines?
chaburkland Jun 10, 2021
b22f42a
More commits to use github to debug 32bit errors since I cant do it l…
chaburkland Jun 10, 2021
5c8d496
:|
chaburkland Jun 10, 2021
2710778
This will fail. I need more iinfo.
chaburkland Jun 10, 2021
600b2cc
Another attempt
chaburkland Jun 10, 2021
be291a0
Another attempt
chaburkland Jun 10, 2021
692dfab
:|
chaburkland Jun 10, 2021
351e87f
Another change.
chaburkland Jun 10, 2021
2da3699
int
chaburkland Jun 10, 2021
7706a70
longlonglonglong
chaburkland Jun 10, 2021
af11253
ulululululul
chaburkland Jun 10, 2021
6908380
ugh
chaburkland Jun 10, 2021
547c0ad
Cleans up test_dtype_from_element_overflow
chaburkland Jun 10, 2021
d037448
Adds another test.
chaburkland Jun 10, 2021
7720dc3
Update test to show me exactly how I am wrong.
chaburkland Jun 10, 2021
711f4ab
npy_long npy_int. :|
chaburkland Jun 10, 2021
c2e43e3
36 does not have fstrings.
chaburkland Jun 10, 2021
3a932d3
Updates test and code. Wont work.
chaburkland Jun 10, 2021
561773b
Caves into the tyrant that is numpy. Cleans up unit tests.
chaburkland Jun 10, 2021
983c6bd
Fixes an implicit cast.
chaburkland Jun 10, 2021
4e7ef55
The cast went both ways.
chaburkland Jun 10, 2021
dea6894
Tries Brandts suggestion.
chaburkland Jun 10, 2021
6fcd1a9
Apparantly this was his suggestion, not the last commit.
chaburkland Jun 10, 2021
cda8836
I messed it up again.
chaburkland Jun 10, 2021
46f50f6
That did not work. Go back to np.array(val).dtype
chaburkland Jun 10, 2021
5c73856
Adds negative numbers back!
chaburkland Jun 10, 2021
92b8bb4
Uses PyArray_DescrFromObject instead. It is also faster
chaburkland Jun 10, 2021
6d4fefd
Update src/_arraykit.c
chaburkland Jun 10, 2021
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
3 changes: 2 additions & 1 deletion src/_arraykit.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,8 @@ dtype_from_element(PyObject *Py_UNUSED(m), PyObject *arg)

// Integers
if (PyLong_CheckExact(arg)) {
return (PyObject*)PyArray_DescrFromType(NPY_LONG);
// It turned out to be very complex to determine the dtype from manually examining the integer, as numpy is rather inscrutable
return (PyObject*)PyArray_DescrFromObject(arg, NULL);
}

// Bool
Expand Down
64 changes: 42 additions & 22 deletions test/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,38 +323,40 @@ def test_dtype_from_element_core_dtypes(self) -> None:
np.bool_,
]
for dtype in dtypes:
self.assertEqual(dtype, dtype_from_element(dtype()))
self.assertEqual(dtype, dtype_from_element(dtype()), dtype)

def test_dtype_from_element_str_and_misc_dtypes(self) -> None:
dtype_obj_pairs = [
(np.dtype('<U1'), np.str_('1')),
(np.dtype('<U1'), np.unicode_('1')),
(np.dtype('V1'), np.void(1)),
(np.dtype('O'), np.object()),
(np.dtype('<M8'), np.datetime64('NaT')),
(np.dtype('<m8'), np.timedelta64('NaT')),
(np.float_, np.nan),
np.str_('1'),
np.unicode_('1'),
np.void(1),
np.object(),
np.datetime64('NaT'),
np.timedelta64('NaT'),
np.nan,
]
for dtype, obj in dtype_obj_pairs:
self.assertEqual(dtype, dtype_from_element(obj))
for obj in dtype_obj_pairs:
self.assertEqual(np.array(obj).dtype, dtype_from_element(obj), obj)

def test_dtype_from_element_obj_dtypes(self) -> None:
NT = collections.namedtuple('NT', tuple('abc'))

dtype_obj_pairs = [
(np.int_, 12),
(np.float_, 12.0),
(np.bool_, True),
(np.dtype('O'), None),
(np.float_, float('NaN')),
(np.dtype('O'), object()),
(np.dtype('O'), (1, 2, 3)),
(np.dtype('O'), NT(1, 2, 3)),
(np.dtype('O'), datetime.date(2020, 12, 31)),
(np.dtype('O'), datetime.timedelta(14)),
12,
12.0,
True,
None,
float('NaN'),
object(),
datetime.date(2020, 12, 31),
datetime.timedelta(14),
]
for dtype, obj in dtype_obj_pairs:
self.assertEqual(dtype, dtype_from_element(obj))
for obj in dtype_obj_pairs:
self.assertEqual(np.array(obj).dtype, dtype_from_element(obj), obj)

# Tuples
self.assertEqual(np.object, dtype_from_element((1, 2, 3)), obj)
self.assertEqual(np.object, dtype_from_element(NT(1, 2, 3)), obj)

def test_dtype_from_element_time_dtypes(self) -> None:
# Datetime & Timedelta
Expand All @@ -363,6 +365,24 @@ def test_dtype_from_element_time_dtypes(self) -> None:
obj = ctor(12, precision)
self.assertEqual(np.dtype(f'<{kind}8[{precision}]'), dtype_from_element(obj))

def test_dtype_from_element_int_boundaries(self) -> None:
failed = False
for offset, power in itertools.product((-1, 0, 1), range(-65, 66)):
val = 2**power + offset

actual = dtype_from_element(val)
expected = np.array(val).dtype

if actual != expected:
print(str(val) + '. actual=' + str(actual) + ' expected=' + str(expected))
failed = True
else:
# Check doesn't raise Overflow error
self.assertEqual(np.array(val, dtype=actual).item(), val)
self.assertEqual(np.array(val, dtype=expected).item(), val)

self.assertTrue(not failed)

def test_dtype_from_element_str_and_bytes_dtypes(self) -> None:
for size in (1, 8, 16, 32, 64, 128, 256, 512):
self.assertEqual(np.dtype(f'|S{size}'), dtype_from_element(bytes(size)))
Expand Down