How to create a datetime object with PyYAML

10,214

I think this example achieves what you're looking for:

dt = yaml.load("""dt: !!python/object/apply:apply
    - !!python/object/apply:getattr
        - !!python/name:datetime.datetime
        - now
    - []
""")

However, I think it is too far-fetched because the !!python/object syntax supported by PyYAML is not supposed to call class methods (datetime.datetime.now is actually like a "static" factory method for datetime objects). As you said, this is simpler (though not what you're looking for):

dt = yaml.load("dt: !!python/object/apply:time.gmtime []")
dt = yaml.load("dt: !!python/object/apply:time.time []")

Another possible work-around would be to create a custom helper function that wraps the call to datetime.datetime.now so that it is easily serialized with !!python/object/apply. The cons is that this serialization would not be portable to an environment where this custom function is not found.

Anyway, in my opinion it does not make too much sense to serialize a value that always returns the current datetime (which would actually be the time when the YAML was parsed). PyYAML provides this shortcut for serializing a certain timestamp:

dt = yaml.load("""dt: !!timestamp '2010-11-17 13:12:11'""")
Share:
10,214
brianz
Author by

brianz

Updated on July 05, 2022

Comments

  • brianz
    brianz almost 2 years

    I'd like to be able to create a datetime object with datetime.datetime.now() PyYAML. It's easy to call some functions:

    >>> y = """#YAML
    ... description: Something
    ... ts: !!python/object/apply:time.time []"""
    >>> yaml.load(y)
    {'description': 'Something', 'ts': 1289955567.940973}
    >>> 
    

    However, I can't seem to figure out how to get a datetime.now(). I've tried as many permutations with calls to that using the various python yaml tags.

    These all fail:

    tests = [ 
            'dt: !!python/object:datetime.datetime.now []',
            'dt: !!python/object/new:datetime.datetime.now []',
            'dt: !!python/object/apply:datetime.datetime.now []',
    ]
    
    for y in tests:
        try:
            print yaml.load(y)
        except Exception, err:
            print '==>', err
    
  • brianz
    brianz over 13 years
    Very nice. I agree that this is a somewhat convoluted use case, but your solution looks like the easiest way to accomplish. For context, I'm investigating using YAML to generate test data which will get loaded via Django. Having data generated when the file is loaded would be a huge benefit for many tests. Thanks for the answer!
  • anthony sottile
    anthony sottile about 7 years
    fwiw, with apply removed in python 3 the example no longer works. That said, I'm not actually looking to do this just stumbled on this answer while doing some research :) (wow pyyaml is insane!)
  • Yann Dìnendal
    Yann Dìnendal over 3 years
    !!timestamp is what I was looking for, great! :)