Skip to content

Commit

Permalink
fix big int subclass extraction (pydantic#919)
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelcolvin committed Aug 23, 2023
1 parent e414a12 commit e34a5eb
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 4 deletions.
6 changes: 2 additions & 4 deletions src/input/input_python.rs
Expand Up @@ -304,8 +304,7 @@ impl<'a> Input<'a> for PyAny {
Err(ValError::new(ErrorTypeDefaults::IntType, self))
} else {
// force to an int to upcast to a pure python int
let int = self.extract::<i64>()?;
Ok(EitherInt::I64(int))
EitherInt::upcast(self)
}
} else {
Err(ValError::new(ErrorTypeDefaults::IntType, self))
Expand All @@ -320,8 +319,7 @@ impl<'a> Input<'a> for PyAny {
str_as_int(self, &cow_str)
} else if PyInt::is_type_of(self) {
// force to an int to upcast to a pure python int to maintain current behaviour
let int = self.extract::<i64>()?;
Ok(EitherInt::I64(int))
EitherInt::upcast(self)
} else if let Ok(float) = self.extract::<f64>() {
float_as_int(self, float)
} else {
Expand Down
9 changes: 9 additions & 0 deletions src/input/return_enums.rs
Expand Up @@ -820,6 +820,15 @@ pub enum EitherInt<'a> {
}

impl<'a> EitherInt<'a> {
pub fn upcast(py_any: &'a PyAny) -> ValResult<Self> {
// Safety: we know that py_any is a python int
if let Ok(int_64) = py_any.extract::<i64>() {
Ok(Self::I64(int_64))
} else {
let big_int: BigInt = py_any.extract()?;
Ok(Self::BigInt(big_int))
}
}
pub fn into_i64(self, py: Python<'a>) -> ValResult<'a, i64> {
match self {
EitherInt::I64(i) => Ok(i),
Expand Down
2 changes: 2 additions & 0 deletions tests/validators/test_int.py
Expand Up @@ -421,7 +421,9 @@ def test_int_subclass() -> None:
assert type(v_strict) == int

assert v.validate_python(IntSubclass(1136885225876639845)) == 1136885225876639845
assert v.validate_python(IntSubclass(i64_max + 7)) == i64_max + 7
assert v.validate_python(IntSubclass(1136885225876639845), strict=True) == 1136885225876639845
assert v.validate_python(IntSubclass(i64_max + 7), strict=True) == i64_max + 7


def test_int_subclass_constraint() -> None:
Expand Down

0 comments on commit e34a5eb

Please sign in to comment.