naming model factory functions
Non-standard but supported use case in FactoryBoy is using a factory function for the 'model' definition, e.g.:
def _some_factory_func(*args, **kwargs):
# do some cleanup/advanced logic around the args, e.g.
if "foo" in kwargs:
def kwargs["bar"] # contrived example
return MyModel(*args, **kwargs)
@register
@register(_name="my_model") # has no effect
class MyModelFactory(Factory):
class Meta:
model: _some_factory_func # this line
prop1 = ...
prop2 = ...
elsewhere I have register(MyModelFactory) in a conftest.py file
What pytest sees as registered fixtures include:
-
_some_factory_func -
_some_factory_func__prop1 -
_some_factory_func__prop2 -
my_model_factory
This does not seem to change even if I use @register(_name="my_model"); the name ultimately renames _some_factory_func.
Similarly, named_model does not succeed as it assumes the model is a type.
Request here is to support a factory function with a model name.
We use model.__name__ to determine the fixture name.
try reassigning _ some_factory_func.__name__ = “MyModel”, it may solve your use case.
I will reopen this if unresolved.
Can you expand on your solution?
In python, you cannot set .__name__ on a top-level function, or else imports would fail.
I've attempted to wrap this one layer:
def _mk_factory():
def factory(*args, **kwargs) -> MyModel:
# ...
return MyModel(...)
factory.__name__ = "MyModel"
return factory
renamed = _mk_factory()
class MyModelFactory(Factory):
class Meta:
model: renamed
But this fails in pytest with TypeError: issubclass() arg 1 must be a class. I've tried something similar using types.FunctionType(_some_factory_func.__code__, _some_factory_func.__globals__, name="MyModel") to the same effect.
Regardless, I don't feel like this ticket should necessarily be 'closed' even if this thread results in a usable syntax (which it thus far has not). At the least this behavior was non-obvious, but it also feels inconsistent. There is built-in support for this for dict using named_model; it would be nice to have a similar utility with function. It also feels awkward at best that @register(_name="...") did not have any effect when using a function.