54
54
)
55
55
from polyfactory .exceptions import ConfigurationException , MissingBuildKwargException , ParameterException
56
56
from polyfactory .field_meta import Null
57
- from polyfactory .fields import Fixture , Ignore , PostGenerated , Require , Use
57
+ from polyfactory .fields import Fixture , Ignore , NeverNone , PostGenerated , Require , Use
58
58
from polyfactory .utils .helpers import (
59
59
flatten_annotation ,
60
60
get_collection_type ,
@@ -334,6 +334,7 @@ def _handle_factory_field( # noqa: PLR0911
334
334
if isinstance (field_value , Fixture ):
335
335
return field_value .to_value ()
336
336
337
+ # if a raw lambda is passed, invoke it
337
338
if callable (field_value ):
338
339
return field_value ()
339
340
@@ -942,8 +943,12 @@ def should_set_none_value(cls, field_meta: FieldMeta) -> bool:
942
943
:returns: A boolean determining whether 'None' should be set for the given field_meta.
943
944
944
945
"""
946
+ field_value = hasattr (cls , field_meta .name ) and getattr (cls , field_meta .name )
947
+ never_none = field_value and isinstance (field_value , NeverNone )
948
+
945
949
return (
946
950
cls .__allow_none_optionals__
951
+ and not never_none
947
952
and is_optional (field_meta .annotation )
948
953
and create_random_boolean (random = cls .__random__ )
949
954
)
@@ -1017,13 +1022,15 @@ def _check_declared_fields_exist_in_model(cls) -> None:
1017
1022
f"{ field_name } is declared on the factory { cls .__name__ } "
1018
1023
f" but it is not part of the model { cls .__model__ .__name__ } "
1019
1024
)
1020
- if isinstance (field_value , (Use , PostGenerated , Ignore , Require )):
1025
+ if isinstance (field_value , (Use , PostGenerated , Ignore , Require , NeverNone )):
1021
1026
raise ConfigurationException (error_message )
1022
1027
1023
1028
@classmethod
1024
1029
def process_kwargs (cls , ** kwargs : Any ) -> dict [str , Any ]:
1025
1030
"""Process the given kwargs and generate values for the factory's model.
1026
1031
1032
+ If you need to deeply customize field values, you'll want to override this method.
1033
+
1027
1034
:param kwargs: Any build kwargs.
1028
1035
1029
1036
:returns: A dictionary of build results.
@@ -1034,8 +1041,11 @@ def process_kwargs(cls, **kwargs: Any) -> dict[str, Any]:
1034
1041
for field_meta in cls .get_model_fields ():
1035
1042
field_build_parameters = cls .extract_field_build_parameters (field_meta = field_meta , build_args = kwargs )
1036
1043
if cls .should_set_field_value (field_meta , ** kwargs ) and not cls .should_use_default_value (field_meta ):
1037
- if hasattr (cls , field_meta .name ) and not hasattr (BaseFactory , field_meta .name ):
1038
- field_value = getattr (cls , field_meta .name )
1044
+ field_value = getattr (cls , field_meta .name , None )
1045
+
1046
+ # TODO why do we need the BaseFactory check here, only dunder methods which are ignored would trigger this?
1047
+ # NeverNone should be treated as a normally-generated field
1048
+ if field_value and not hasattr (BaseFactory , field_meta .name ) and not isinstance (field_value , NeverNone ):
1039
1049
if isinstance (field_value , Ignore ):
1040
1050
continue
1041
1051
0 commit comments