@@ -2,7 +2,7 @@ use pyo3::intern;
22use pyo3:: prelude:: * ;
33use pyo3:: types:: { PyDict , PySet , PyType } ;
44
5- use crate :: build_tools:: SchemaDict ;
5+ use crate :: build_tools:: { py_err , SchemaDict } ;
66use crate :: errors:: { ErrorKind , ValError , ValResult } ;
77use crate :: input:: { Input , JsonType } ;
88use crate :: recursion_guard:: RecursionGuard ;
@@ -12,7 +12,7 @@ use super::{BuildContext, BuildValidator, CombinedValidator, Extra, Validator};
1212
1313#[ derive( Debug , Clone ) ]
1414pub struct IsInstanceValidator {
15- class : Py < PyType > ,
15+ class : PyObject ,
1616 json_types : u8 ,
1717 json_function : Option < PyObject > ,
1818 class_repr : String ,
@@ -28,8 +28,23 @@ impl BuildValidator for IsInstanceValidator {
2828 _build_context : & mut BuildContext ,
2929 ) -> PyResult < CombinedValidator > {
3030 let py = schema. py ( ) ;
31- let class: & PyType = schema. get_as_req ( intern ! ( py, "cls" ) ) ?;
32- let class_repr = class. name ( ) ?. to_string ( ) ;
31+ let cls_key = intern ! ( py, "cls" ) ;
32+ let class: & PyAny = schema. get_as_req ( cls_key) ?;
33+
34+ // test that class works with isinstance to avoid errors at call time, reuse cls_key since it doesn't
35+ // matter what object is being checked
36+ let test_value: & PyAny = cls_key. as_ref ( ) ;
37+ if test_value. input_is_instance ( class, 0 ) . is_err ( ) {
38+ return py_err ! ( "'cls' must be valid as the first argument to 'isinstance'" ) ;
39+ }
40+
41+ let class_repr = match schema. get_as ( intern ! ( py, "cls_repr" ) ) ? {
42+ Some ( s) => s,
43+ None => match class. extract :: < & PyType > ( ) {
44+ Ok ( t) => t. name ( ) ?. to_string ( ) ,
45+ Err ( _) => class. repr ( ) ?. extract ( ) ?,
46+ } ,
47+ } ;
3348 let name = format ! ( "{}[{}]" , Self :: EXPECTED_TYPE , class_repr) ;
3449 let json_types = match schema. get_as :: < & PySet > ( intern ! ( py, "json_types" ) ) ? {
3550 Some ( s) => JsonType :: combine ( s) ?,
@@ -55,7 +70,7 @@ impl Validator for IsInstanceValidator {
5570 _slots : & ' data [ CombinedValidator ] ,
5671 _recursion_guard : & ' s mut RecursionGuard ,
5772 ) -> ValResult < ' data , PyObject > {
58- match input. is_instance ( self . class . as_ref ( py) , self . json_types ) ? {
73+ match input. input_is_instance ( self . class . as_ref ( py) , self . json_types ) ? {
5974 true => {
6075 if input. get_type ( ) . is_json ( ) {
6176 if let Some ( ref json_function) = self . json_function {
0 commit comments