Direct answer
NumPy 1.26+ does not emit a warning for most precision-loss conversions when ndarray.astype is called with casting='unsafe' (the default). However, complex-to-real casts do raise a ComplexWarning even under casting='unsafe'. This exception is documented and long-standing; other lossy conversions (float→int, wider→narrower float, etc.) remain silent.
Confirmed behavior
- Default is
'unsafe' – For backward compatibility, astype defaults to casting='unsafe'. Existing code that relied on silent truncation continues to work unchanged.
- Complex → real emits
ComplexWarning – np.array([1+2j]).astype(float) (or casting='unsafe') produces a ComplexWarning: Casting complex values to real discards the imaginary part. This occurs regardless of the casting argument.
- Other lossy casts are silent – Float→int truncation, float64→float32 rounding, int64→int32 overflow, and similar conversions execute without any Python warning when
casting='unsafe' is used or implied.
- Overflow behavior is not guaranteed to wrap – Out-of-range float→int or int→narrower-int conversions follow C-style casting rules; the result is implementation-defined and may raise
RuntimeWarning in some builds, but NumPy does not promise modular wrapping.
How to detect or prevent silent loss
Because NumPy only warns for complex→real, users who need guarantees for other conversions must add their own checks:
import numpy as np
import warnings
def safe_astype(arr, dtype, casting='same_kind'):
"""Cast with a stricter rule; raise if loss would occur."""
if not np.can_cast(arr.dtype, dtype, casting=casting):
raise TypeError(f"Cannot cast {arr.dtype} to {dtype} with casting={casting!r}")
return arr.astype(dtype, casting=casting)
# Example: float → int with explicit validation
arr = np.array([1.7, 2.3, 300.0], dtype=np.float64)
try:
result = safe_astype(arr, np.int16, casting='safe')
except TypeError as e:
warnings.warn(str(e), RuntimeWarning)
# fallback or handle
result = arr.astype(np.int16, casting='unsafe') # explicit unsafe if you accept loss
Use casting='same_kind' (allows float→float, int→int, but not float→int) or casting='safe' (only widening conversions) to let NumPy raise a TypeError instead of silently losing data.
Version-specific policy
- NumPy 1.26+: The
casting parameter is part of the public API. The default remains 'unsafe' for backward compatibility; no new warnings are added for non-complex lossy casts.
- Future releases: Any change to default casting or warning behavior would follow NumPy's deprecation policy (likely a
FutureWarning first) and be announced in release notes.
Verification you can run today
import numpy as np
import warnings
# Capture all warnings
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
# float64 → int16 (300.0 fits in int16)
a = np.array([1.5, 2.9, 300.0], dtype=np.float64)
b = a.astype(np.int16, casting='unsafe')
print("float→int16 result:", b)
# complex → float (should warn)
c = np.array([1+2j, 3-4j])
d = c.astype(np.float64, casting='unsafe')
print("complex→float result:", d)
print("Warnings captured:", len(w))
for warning in w:
print(" ", warning.category.__name__, ":", warning.message)
Expected output on NumPy 1.26+ (warning count may vary by build):
float→int16 result: [1 2 300]
complex→float result: [1. 3.]
Warnings captured: 1
ComplexWarning : Casting complex values to real discards the imaginary part
One missing detail that could change the recommendation
If you are using a downstream library (e.g., a JIT compiler, a GPU array backend, or a custom __array_function__ override) that wraps astype, its own warning policy may differ. Please confirm the exact NumPy version (np.__version__) and whether any array subclasses or third‑party backends are involved.