def parse_prop(prop):
    if prop.startswith('*'):
        key, dummy, val = prop[1:].partition(' ')
        
        if not val and ('code', 'gentext') not in key:
            error('%s must be followed by a value' % (key,))
            return None
        
        if key == 'portlist':
            plistkey, dummy, val = val.partition(' ')
            res = {'type':'portlist', 'plistkey':plistkey,
                   '_templist':[]}
            if 'single' in val.split():
                res['focus'] = True
            return res
        
        if key == 'move':
            val = sluggify(val.strip())
            return {'type':'move', 'loc':val}
        elif key == 'focus':
            val = sluggify(val.strip())
            return {'type':'focus', 'key':val}
        elif key == 'event':
            return {'type':'event', 'text':val}
        elif key == 'panic':
            return {'type':'panic', 'text':val} # theoretically the text is optional
        elif key == 'text':
            return {'type':'text', 'text':val}
        elif key == 'gentext':
            return {'type':'gentext', 'text':val}
        elif key == 'code':
            return {'type':'code', 'text':val}
        elif key == 'selfdesc':
            return {'type':'selfdesc', 'text':val}
        elif key == 'editstr':
            return {'type':'editstr', 'key':val}
        elif key == 'datetime':
            val = datetime.datetime.strptime(val, '%Y-%m-%d')
            return datetime.datetime(year=val.year, month=val.month, day=val.day, tzinfo=datetime.timezone.utc)
        else:
            error('Unknown special property type: *%s' % (key,))
            return None

    try:
        propval = ast.literal_eval(prop)
        # We test-encode the new value to bson, so that we can be strict
        # and catch errors.
        dummy = bson.BSON.encode({'val':propval}, check_keys=True)
        return propval
    except:
        pass
        
    return {'type':'text', 'text':prop}
dataset/ETHPy150Open erkyrath/tworld/twloadworld.py/parse_prop/swapped operands of `not in`