Allow functions as models
Hi,
in our project, we're using factories for our models:
# domain/factories.py
from . import model, events
def item_factory(sku: str, price: float):
obj = model.Item(sku, price)
obj.events.append(events.ItemCreated())
return obj
Now, in our tests we want factory boy to call those factories instead of the model classes directly, which works perfectly except in this case:
# tests/factories.py
class ItemFactory(factory.Factory):
class Meta:
model = factories.item_factory
sku = ...
price = ...
class SpecialItemFactory(ItemFactory): # Inherits from the factory above
sku = "special"
When a factory inherits from another factory, FactoryOptions._get_counter_reference expects the assigned model to be a class, because issubclass raises:
TypeError: issubclass() arg 1 must be a class
We couldn't find a fix for this case so I've opened this PR. If my solution is wrong or if anything is missing in my commit, please don't hesitate to let me know.
BR
Hello,
Thanks for the feedback! That's indeed likely to be a bug.
Would it be possible to have a minimal example of code where this breaks, to add to our test suite?
NB: This is one of the reasons why I prefer to see an issue first, before jumping in the code — our issue templates make it easier for us to gather all details we need to move forward ;)
Hey, sorry for the late reply. You mean something like this?
import factory
class Item:
def __init__(self, sku, price):
self.sku = sku
self.price = price
def item_factory(sku, price):
obj = model.Item(sku, price)
return obj
class ItemFactory(factory.Factory):
class Meta:
model = item_factory
sku = "foo"
price = "bar"
class SpecialItemFactory(ItemFactory):
sku = "special"
item = SpecialItemFactory() # TypeError: issubclass() arg 1 must be a class
Should I add a test case to the test suite?
BR
Yes please! That's exactly what I had in mind ;)
Done @rbarrois
@rbarrois Could you please merge this when you have a chance? Thank you.
Hi @rbarrois, let me know if there's anything left to do for me in order to get this merged 🙏