Skip to content

Commit 2c710aa

Browse files
committed
hand zero division error through
1 parent 5f66a65 commit 2c710aa

File tree

3 files changed

+20
-20
lines changed

3 files changed

+20
-20
lines changed

python/pydantic_core/core_schema.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4165,6 +4165,7 @@ def definition_reference_schema(
41654165
IntSchema,
41664166
FloatSchema,
41674167
DecimalSchema,
4168+
FractionSchema,
41684169
StringSchema,
41694170
BytesSchema,
41704171
DateSchema,
@@ -4224,6 +4225,7 @@ def definition_reference_schema(
42244225
'int',
42254226
'float',
42264227
'decimal',
4228+
'fraction',
42274229
'str',
42284230
'bytes',
42294231
'date',
@@ -4374,6 +4376,8 @@ def definition_reference_schema(
43744376
'uuid_version',
43754377
'decimal_type',
43764378
'decimal_parsing',
4379+
'fraction_type',
4380+
'fraction_parsing',
43774381
'decimal_max_digits',
43784382
'decimal_max_places',
43794383
'decimal_whole_digits',

src/errors/types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -582,8 +582,8 @@ impl ErrorType {
582582
Self::DecimalMaxDigits {..} => "Decimal input should have no more than {max_digits} digit{expected_plural} in total",
583583
Self::DecimalMaxPlaces {..} => "Decimal input should have no more than {decimal_places} decimal place{expected_plural}",
584584
Self::DecimalWholeDigits {..} => "Decimal input should have no more than {whole_digits} digit{expected_plural} before the decimal point",
585-
Self::FractionParsing {..} => "Fraction input should be an integer, float, string or Fraction object",
586-
Self::FractionType {..} => "Fraction input should be an integer, float, string or Fraction object",
585+
Self::FractionParsing {..} => "Fraction input should be a tuple of two integers, a string or a Fraction object",
586+
Self::FractionType {..} => "Fraction input should be a tuple of two integers, or a string or Fraction object",
587587
Self::ComplexType {..} => "Input should be a valid python complex object, a number, or a valid complex string following the rules at https://docs.python.org/3/library/functions.html#complex",
588588
Self::ComplexStrParsing {..} => "Input should be a valid complex string following the rules at https://docs.python.org/3/library/functions.html#complex",
589589
}

src/validators/fraction.rs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::sync::Arc;
22

3-
use pyo3::exceptions::{PyTypeError, PyValueError};
3+
use pyo3::exceptions::{PyTypeError, PyValueError, PyZeroDivisionError};
44
use pyo3::intern;
55
use pyo3::sync::PyOnceLock;
66
use pyo3::types::{PyDict, PyString, PyType};
@@ -148,24 +148,20 @@ impl Validator for FractionValidator {
148148
pub(crate) fn create_fraction<'py>(arg: &Bound<'py, PyAny>, input: impl ToErrorValue) -> ValResult<Bound<'py, PyAny>> {
149149
let py = arg.py();
150150
get_fraction_type(py).call1((arg,)).map_err(|e| {
151-
let fraction_exception = match py
152-
.import("fractions")
153-
.and_then(|fraction_module| fraction_module.getattr("FractionException"))
154-
{
155-
Ok(fraction_exception) => fraction_exception,
156-
Err(e) => return ValError::InternalErr(e),
157-
};
158-
handle_fraction_new_error(input, e, fraction_exception)
151+
handle_fraction_new_error(input, e)
159152
})
160153
}
161154

162-
fn handle_fraction_new_error(input: impl ToErrorValue, error: PyErr, fraction_exception: Bound<'_, PyAny>) -> ValError {
163-
let py = fraction_exception.py();
164-
if error.matches(py, fraction_exception).unwrap_or(false) {
165-
ValError::new(ErrorTypeDefaults::FractionParsing, input)
166-
} else if error.matches(py, PyTypeError::type_object(py)).unwrap_or(false) {
167-
ValError::new(ErrorTypeDefaults::FractionType, input)
168-
} else {
169-
ValError::InternalErr(error)
170-
}
155+
fn handle_fraction_new_error(input: impl ToErrorValue, error: PyErr) -> ValError {
156+
Python::with_gil(|py| {
157+
if error.matches(py, PyValueError::type_object(py)).unwrap_or(false) {
158+
ValError::new(ErrorTypeDefaults::FractionParsing, input)
159+
} else if error.matches(py, PyTypeError::type_object(py)).unwrap_or(false) {
160+
ValError::new(ErrorTypeDefaults::FractionType, input)
161+
} else {
162+
// Let ZeroDivisionError and other exceptions bubble up as InternalErr
163+
// which will be shown to the user with the original Python error message
164+
ValError::InternalErr(error)
165+
}
166+
})
171167
}

0 commit comments

Comments
 (0)