Open drobert opened 3 days ago
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.
Non-standard but supported use case in FactoryBoy is using a factory function for the 'model' definition, e.g.:
elsewhere I have
register(MyModelFactory)
in aconftest.py
fileWhat 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.