A fellow Pythonaut had a simple problem...
How to test code with dependencies on the date? Specifically, a Django project with models that have DateTimeFields with auto_now=True.
The chosen approach was to monkey-patch datetime.date.today() in order to return a constant value.
The first snag: datetime.date is a C class. This means it is not monkey-patchable.
This can be solved by monkey-patching the entire datetime.date class. The most straightforward thing to replace datetime.date with is a new subclass of datetime.date, whose only change is to override the today() function.
The second problem: there are now two kinds of datetime.date's floating around the system. Those by datetime.date.today(), and those created by every other function, which being C code will still return the same class.
Specifically, DateTimeField validates isinstance(data, datetime.date) before saving to the database.
A class which is simultaneously a super and subclass of datetime.date is required.
Override __subclasshook__ so that isinstance(super(datetime.date)(), datetime.date) is True.
>>> class DateProxy(datetime.date):
... __metaclass__ = abc.ABCMeta
... @classmethod
... def __subclasshook__(cls, C): return True
... @classmethod
... def today(cls): return datetime.date(2011,9,20)
...
>>> datetime.date = DateProxy
In other words, the superclass is also a subclass. The parent of the parent being the grandparent, this class is it's own grandpa.
I get why it has to be a _subclass_ of date, but why would it have to be a superclass??
ReplyDelete