def get_type(x):
    ' Return the most specific type in the type hierarchy that applies to x\n    and a boolean indicating whether x is an AST. If the type cannot be\n    determined, return TYPE_OBJECT as the type. '
    if isinstance(x, (int, long)):
        return (TYPE_INT, False)
    elif isinstance(x, float):
        return (TYPE_FLOAT, False)
    elif isinstance(x, basestring):
        if (len(x) == 1):
            return (TYPE_CHAR, False)
        try:
            float(x)
        except ValueError:
            return (TYPE_STRING, False)
        else:
            return (TYPE_NUMERIC_STRING, False)
    elif isinstance(x, Color):
        return (TYPE_COLOR, False)
    elif isinstance(x, Media):
        return (TYPE_MEDIA, False)
    elif isinstance(x, Vector):
        return (TYPE_VECTOR, False)
    elif hasattr(x, 'return_type'):
        return (x.return_type, False)
    elif isinstance(x, ast.Num):
        return (get_type(x.n)[0], True)
    elif isinstance(x, ast.Str):
        return (get_type(x.s)[0], True)
    elif isinstance(x, ast.Name):
        try:
            value = eval(x.id)
        except NameError:
            return (TYPE_OBJECT, True)
        else:
            return (get_type(value)[0], True)
    elif isinstance(x, ast.Subscript):
        if (x.value == BOX_AST):
            return (TYPE_BOX, True)
    elif isinstance(x, ast.Call):
        if isinstance(x.func, ast.Name):
            if (x.func.id == 'float'):
                return (TYPE_FLOAT, True)
            elif (x.func.id in ('int', 'ord')):
                return (TYPE_INT, True)
            elif (x.func.id == 'chr'):
                return (TYPE_CHAR, True)
            elif (x.func.id in ('repr', 'str', 'unicode')):
                return (TYPE_STRING, True)
            elif (x.func.id == 'Color'):
                return (TYPE_COLOR, True)
            elif (x.func.id == 'Media'):
                return (TYPE_MEDIA, True)
    elif isinstance(x, ast.UnaryOp):
        if issubclass(x.op, ast.Not):
            return (TYPE_BOOL, True)
        else:
            return get_type(x.operand)
    if isinstance(x, (ast.BoolOp, ast.Compare)):
        return (TYPE_BOOL, True)
    elif isinstance(x, ast.BinOp):
        type_left = get_type(x.left)[0]
        type_right = get_type(x.right)[0]
        if ((type_left == TYPE_STRING) or (type_right == TYPE_STRING)):
            return (TYPE_STRING, True)
        if (type_left == type_right == TYPE_INT):
            return (TYPE_INT, True)
        else:
            return (TYPE_FLOAT, True)
    return (TYPE_OBJECT, isinstance(x, ast.AST))
Return the most specific type in the type hierarchy that applies to x
and a boolean indicating whether x is an AST. If the type cannot be
determined, return TYPE_OBJECT as the type.
def get_type(x):
    ' Return the most specific type in the type hierarchy that applies to x\n    and a boolean indicating whether x is an AST. If the type cannot be\n    determined, return TYPE_OBJECT as the type. '
    if isinstance(x, (int, long)):
        return (TYPE_INT, False)
    elif isinstance(x, float):
        return (TYPE_FLOAT, False)
    elif isinstance(x, basestring):
        if (len(x) == 1):
            return (TYPE_CHAR, False)
        try:
            float(x)
        except ValueError:
            return (TYPE_STRING, False)
        else:
            return (TYPE_NUMERIC_STRING, False)
    elif isinstance(x, Color):
        return (TYPE_COLOR, False)
    elif isinstance(x, Media):
        return (TYPE_MEDIA, False)
    elif isinstance(x, Vector):
        return (TYPE_VECTOR, False)
    elif hasattr(x, 'return_type'):
        return (x.return_type, False)
    elif isinstance(x, ast.Num):
        return (get_type(x.n)[0], True)
    elif isinstance(x, ast.Str):
        return (get_type(x.s)[0], True)
    elif isinstance(x, ast.Name):
        try:
            value = eval(x.id)
        except NameError:
            return (TYPE_OBJECT, True)
        else:
            return (get_type(value)[0], True)
    elif isinstance(x, ast.Subscript):
        if (x.value == BOX_AST):
            return (TYPE_BOX, True)
    elif isinstance(x, ast.Call):
        if isinstance(x.func, ast.Name):
            if (x.func.id == 'float'):
                return (TYPE_FLOAT, True)
            elif (x.func.id in ('int', 'ord')):
                return (TYPE_INT, True)
            elif (x.func.id == 'chr'):
                return (TYPE_CHAR, True)
            elif (x.func.id in ('repr', 'str', 'unicode')):
                return (TYPE_STRING, True)
            elif (x.func.id == 'Color'):
                return (TYPE_COLOR, True)
            elif (x.func.id == 'Media'):
                return (TYPE_MEDIA, True)
    elif isinstance(x, ast.UnaryOp):
        if issubclass(x.op, ast.Not):
            return (TYPE_BOOL, True)
        else:
            return get_type(x.operand)
    if isinstance(x, (ast.BoolOp, ast.Compare)):
        return (TYPE_BOOL, True)
    elif isinstance(x, ast.BinOp):
        type_left = get_type(x.left)[0]
        type_right = get_type(x.right)[0]
        if ((type_left == TYPE_STRING) or (type_right == TYPE_STRING)):
            return (TYPE_STRING, True)
        if (type_left == type_right == TYPE_INT):
            return (TYPE_INT, True)
        else:
            return (TYPE_FLOAT, True)
    return (TYPE_OBJECT, isinstance(x, ast.AST))