python ast.literal_eval and datetime

后端 未结 6 1316
终归单人心
终归单人心 2020-12-09 18:26

I have a string \"{\'datetime\': datetime.datetime(2010, 11, 21, 0, 56, 58)}\" and I want to convert this to the object it represents. Using ast.literal_

6条回答
  •  感情败类
    2020-12-09 19:31

    Following up on Ignacio Vazquez-Abrams' idea:

    import ast
    import datetime
    
    def parse_datetime_dict(astr,debug=False):
        try: tree=ast.parse(astr)
        except SyntaxError: raise ValueError(astr)
        for node in ast.walk(tree):
            if isinstance(node,(ast.Module,ast.Expr,ast.Dict,ast.Str,
                                ast.Attribute,ast.Num,ast.Name,ast.Load, ast.Tuple)): continue
            if (isinstance(node,ast.Call)
                    and isinstance(node.func, ast.Attribute)
                    and node.func.attr == 'datetime'): continue
            if debug:
                attrs=[attr for attr in dir(node) if not attr.startswith('__')]
                print(node)
                for attrname in attrs:
                    print('    {k} ==> {v}'.format(k=attrname,v=getattr(node,attrname)))
            raise ValueError(astr)
        return eval(astr)
    
    good_strings=["{'the_datetime': datetime.datetime(2010, 11, 21, 0, 56, 58)}"]
    bad_strings=["__import__('os'); os.unlink",
                 "import os; os.unlink",
                 "import(os)", # SyntaxError
                 ]
    
    for astr in good_strings:
        result=parse_datetime_dict(astr)    
        print('{s} ... [PASSED]'.format(s=astr))
    
    for astr in bad_strings:
        try:
            result=parse_datetime_dict(astr)
        except ValueError:
            print('{s} ... [REJECTED]'.format(s=astr))
        else:
            sys.exit('ERROR: failed to catch {s!r}'.format(s=astr))
    

    yields

    {'the_datetime': datetime.datetime(2010, 11, 21, 0, 56, 58)} ... [PASSED]
    __import__('os'); os.unlink ... [REJECTED]
    import os; os.unlink ... [REJECTED]
    import(os) ... [REJECTED]
    

提交回复
热议问题