uWSGI and datetime.now

March 25 2016

This is just a little PSA about Python datetime's "now" method when used with uWSGI in class definitions.

When you use uWSGI and declare classes, uWSGI will try to make things more efficient by saving the class definition and instantiation method defaults in memory at compile time which means that anything in your default parameters will also be saved along with it. This normally wouldn't be cause for concern, but if you have a call to something executable like datetime.now() as a default parameter it will evaluate that once at compile time and return that result for every new object created instead of re-evaluating the default parameter. This confused me big time yesterday so I thought it would be useful to write a little post about it.

This code...

from datetime import datetime

class Thing(object):
    def __init__(self, made=datetime.now()):
        self.made = made

...will always return a new Thing with Thing.made being the date at which your code was last compiled (the last time uWSGI was started) if a "made" is not supplied when the Thing is created.

This code...

from datetime import datetime

class Thing(object):
    def __init__(self, made=None):
        if made is None:
            self.made = datetime.now()
        else:
            self.made = made

...will behave as expected. If a made parameter is not passed at the time of instantiation of a new Thing, the made date will be the current OS time.

Hope that helps anyone who's run into this bug and is scratching their head like I was yesterday 🙃