DiscreteArray checks overflow by comparing np.min_scalar_type(maximum) with the requested dtype. Dtype ordering does not establish whether a positive value fits a signed integer type.
Reproduction on master at 91b46797fea731f80eab8cd2c8352a0674141d89:
import numpy as np
from dm_env import specs
spec = specs.DiscreteArray(129, dtype=np.int8)
print(spec.minimum, spec.maximum)
spec.validate(spec.generate_value())
With NumPy 1.26.4 this creates a spec with minimum 0 and maximum -128; its generated value fails validation. With NumPy 2.5.3, construction instead reaches NumPy's cast and raises OverflowError, bypassing the documented ValueError and its dtype/count diagnostic. The boundary problem also affects int16, int32 and int64.
Comparing num_values - 1 directly with np.iinfo(dtype).max uses the actual representable limit. Valid full-range signed and unsigned specs should remain accepted, including uint64's maximum.
A one-line correction passes 38 regression/control cases covering all eight integer dtypes, exact endpoints, dtype strings, NumPy integer counts, replacement and pickle round trips. The original implementation fails 14 cases. The existing package tests pass unchanged. A focused PR is being prepared.
DiscreteArraychecks overflow by comparingnp.min_scalar_type(maximum)with the requested dtype. Dtype ordering does not establish whether a positive value fits a signed integer type.Reproduction on
masterat91b46797fea731f80eab8cd2c8352a0674141d89:With NumPy 1.26.4 this creates a spec with minimum 0 and maximum -128; its generated value fails validation. With NumPy 2.5.3, construction instead reaches NumPy's cast and raises
OverflowError, bypassing the documentedValueErrorand its dtype/count diagnostic. The boundary problem also affects int16, int32 and int64.Comparing
num_values - 1directly withnp.iinfo(dtype).maxuses the actual representable limit. Valid full-range signed and unsigned specs should remain accepted, including uint64's maximum.A one-line correction passes 38 regression/control cases covering all eight integer dtypes, exact endpoints, dtype strings, NumPy integer counts, replacement and pickle round trips. The original implementation fails 14 cases. The existing package tests pass unchanged. A focused PR is being prepared.