#!/usr/bin/env python
# Copyright (c) 2001-2004, MetaSlash Inc. All rights reserved.
# Portions Copyright (c) 2005, Google, Inc. All rights reserved.
"""
Setup a lot of info about Python builtin types, functions, methods, etc.
"""
import types
import sys
from pychecker import utils
from pychecker import Stack
from pychecker import Warning
BOOL = types.IntType
# name (type, args: min, max, kwArgs?
GLOBAL_FUNC_INFO = { '__import__': (types.ModuleType, 1, 4),
'abs': (Stack.TYPE_UNKNOWN, 1, 1),
'apply': (Stack.TYPE_UNKNOWN, 2, 3),
'buffer': (types.BufferType, 1, 3),
'callable': (BOOL, 1, 1),
'chr': (types.StringType, 1, 1),
'cmp': (types.IntType, 2, 2),
'coerce': ([ types.NoneType, types.TupleType ], 2, 2),
'compile': (types.CodeType, 3, 3),
'complex': (types.ComplexType, 1, 2, ['real', 'imag']),
'delattr': (types.NoneType, 2, 2),
'dir': (types.ListType, 0, 1),
'divmod': (types.TupleType, 2, 2),
'eval': (Stack.TYPE_UNKNOWN, 1, 3),
'execfile': (types.NoneType, 1, 3),
'filter': (types.ListType, 2, 2),
'float': (types.FloatType, 1, 1),
'getattr': (Stack.TYPE_UNKNOWN, 2, 3),
'globals': (types.DictType, 0, 0),
'hasattr': (BOOL, 2, 2),
'hash': (types.IntType, 1, 1),
'hex': (types.StringType, 1, 1),
'id': (types.IntType, 1, 1),
'input': (Stack.TYPE_UNKNOWN, 0, 1),
'int': (types.IntType, 1, 2, ['x']),
'intern': (types.StringType, 1, 1),
'isinstance': (BOOL, 2, 2),
'issubclass': (BOOL, 2, 2),
'len': (types.IntType, 1, 1),
'list': (types.ListType, 1, 1, ['sequence']),
'locals': (types.DictType, 0, 0),
'long': (types.LongType, 1, 2, ['x']),
'map': (types.ListType, 2, None),
'max': (Stack.TYPE_UNKNOWN, 1, None),
'min': (Stack.TYPE_UNKNOWN, 1, None),
'oct': (types.StringType, 1, 1),
'open': (types.FileType, 1, 3, ['name', 'mode', 'buffering']),
'ord': (types.IntType, 1, 1),
'pow': (Stack.TYPE_UNKNOWN, 2, 3),
'range': (types.ListType, 1, 3),
'raw_input': (types.StringType, 0, 1),
'reduce': (Stack.TYPE_UNKNOWN, 2, 3),
'reload': (types.ModuleType, 1, 1),
'repr': (types.StringType, 1, 1),
'round': (types.FloatType, 1, 2),
'setattr': (types.NoneType, 3, 3),
'slice': (types.SliceType, 1, 3),
'str': (types.StringType, 1, 1),
'tuple': (types.TupleType, 1, 1),
'type': (types.TypeType, 1, 1),
'vars': (types.DictType, 0, 1),
'xrange': (types.ListType, 1, 3),
}
if hasattr(types, 'UnicodeType') :
GLOBAL_FUNC_INFO['unichr'] = (types.UnicodeType, 1, 1)
GLOBAL_FUNC_INFO['unicode'] = (types.UnicodeType, 1, 3, ['string', 'encoding', 'errors'])
if utils.pythonVersion() >= utils.PYTHON_2_2 :
GLOBAL_FUNC_INFO['compile'] = (types.CodeType, 3, 5)
GLOBAL_FUNC_INFO['dict'] = (types.DictType, 0, 1, ['items'])
GLOBAL_FUNC_INFO['file'] = GLOBAL_FUNC_INFO['open']
GLOBAL_FUNC_INFO['float'] = (types.FloatType, 0, 1, ['x'])
GLOBAL_FUNC_INFO['int'] = (types.IntType, 0, 2, ['x'])
GLOBAL_FUNC_INFO['list'] = (types.ListType, 0, 1, ['sequence'])
GLOBAL_FUNC_INFO['long'] = (types.LongType, 0, 2, ['x'])
GLOBAL_FUNC_INFO['str'] = (types.StringType, 0, 1, ['object'])
# FIXME: type doesn't take 2 args, only 1 or 3
GLOBAL_FUNC_INFO['type'] = (types.TypeType, 1, 3, ['name', 'bases', 'dict'])
GLOBAL_FUNC_INFO['tuple'] = (types.TupleType, 0, 1, ['sequence'])
GLOBAL_FUNC_INFO['classmethod'] = (types.MethodType, 1, 1)
GLOBAL_FUNC_INFO['iter'] = (Stack.TYPE_UNKNOWN, 1, 2)
GLOBAL_FUNC_INFO['property'] = (Stack.TYPE_UNKNOWN, 0, 4, ['fget', 'fset', 'fdel', 'doc'])
GLOBAL_FUNC_INFO['super'] = (Stack.TYPE_UNKNOWN, 1, 2)
GLOBAL_FUNC_INFO['staticmethod'] = (types.MethodType, 1, 1)
GLOBAL_FUNC_INFO['unicode'] = (types.UnicodeType, 0, 3, ['string', 'encoding', 'errors'])
GLOBAL_FUNC_INFO['bool'] = (BOOL, 1, 1, ['x'])
if utils.pythonVersion() >= utils.PYTHON_2_3:
GLOBAL_FUNC_INFO['dict'] = (types.DictType, 0, 1, [])
if utils.pythonVersion() >= utils.PYTHON_2_5:
GLOBAL_FUNC_INFO['max'] = (Stack.TYPE_UNKNOWN, 1, None, ['key'])
GLOBAL_FUNC_INFO['min'] = (Stack.TYPE_UNKNOWN, 1, None, ['key'])
def tryAddGlobal(name, *args):
if globals().has_key(name):
GLOBAL_FUNC_INFO[name] = args
zipMinArgs = 1
if utils.pythonVersion() >= utils.PYTHON_2_4:
zipMinArgs = 0
tryAddGlobal('zip', types.ListType, zipMinArgs, None)
tryAddGlobal('enumerate', types.TupleType, 1, 1, ['sequence'])
# sum() could also return float/long
tryAddGlobal('sum', types.IntType, 1, 2, ['start'])
# sorted() and reversed() always return an iterator (FIXME: support iterator)
tryAddGlobal('sorted', Stack.TYPE_UNKNOWN, 1, 1)
tryAddGlobal('reversed', Stack.TYPE_UNKNOWN, 1, 1)
tryAddGlobal('all', BOOL, 1, 1)
tryAddGlobal('any', BOOL, 1, 1)
_STRING_METHODS = { 'capitalize': (types.StringType, 0, 0),
'center': (types.StringType, 1, 1),
'count': (types.IntType, 1, 1),
'encode': (types.StringType, 0, 2),
'endswith': (BOOL, 1, 3),
'expandtabs': (types.StringType, 0, 1),
'find': (types.IntType, 1, 3),
'index': (types.IntType, 1, 3),
'isalnum': (BOOL, 0, 0),
'isalpha': (BOOL, 0, 0),
'isdigit': (BOOL, 0, 0),
'islower': (BOOL, 0, 0),
'isspace': (BOOL, 0, 0),
'istitle': (BOOL, 0, 0),
'isupper': (BOOL, 0, 0),
'join': (types.StringType, 1, 1),
'ljust': (types.StringType, 1, 1),
'lower': (types.StringType, 0, 0),
'lstrip': (types.StringType, 0, 0),
'replace': (types.StringType, 2, 3),
'rfind': (types.IntType, 1, 3),
'rindex': (types.IntType, 1, 3),
'rjust': (types.StringType, 1, 1),
'rstrip': (types.StringType, 0, 0),
'split': (types.ListType, 0, 2),
'splitlines': (types.ListType, 0, 1),
'startswith': (BOOL, 1, 3),
'strip': (types.StringType, 0, 0),
'swapcase': (types.StringType, 0, 0),
'title': (types.StringType, 0, 0),
'translate': (types.StringType, 1, 2),
'upper': (types.StringType, 0, 0),
}
if utils.pythonVersion() >= utils.PYTHON_2_2 :
_STRING_METHODS['decode'] = (types.UnicodeType, 0, 2)
_STRING_METHODS['zfill'] = (types.StringType, 1, 1)
if utils.pythonVersion() >= utils.PYTHON_2_4:
_STRING_METHODS['rsplit'] = (types.StringType, 0, 2)
_STRING_METHODS['center'] = (types.StringType, 1, 2),
_STRING_METHODS['ljust'] = (types.StringType, 1, 2),
_STRING_METHODS['rjust'] = (types.StringType, 1, 2),
BUILTIN_METHODS = { types.DictType :
{ 'clear': (types.NoneType, 0, 0),
'copy': (types.DictType, 0, 0),
'get': (Stack.TYPE_UNKNOWN, 1, 2),
'has_key': (BOOL, 1, 1),
'items': (types.ListType, 0, 0),
'keys': (types.ListType, 0, 0),
'popitem': (types.TupleType, 0, 0),
'setdefault': (Stack.TYPE_UNKNOWN, 1, 2),
'update': (types.NoneType, 1, 1),
'values': (types.ListType, 0, 0),
},
types.ListType :
{ 'append': (types.NoneType, 1, 1),
'count': (types.IntType, 1, 1),
'extend': (types.NoneType, 1, 1),
'index': (types.IntType, 1, 1),
'insert': (types.NoneType, 2, 2),
'pop': (Stack.TYPE_UNKNOWN, 0, 1),
'remove': (types.NoneType, 1, 1),
'reverse': (types.NoneType, 0, 0),
'sort': (types.NoneType, 0, 1),
},
types.FileType :
{ 'close': (types.NoneType, 0, 0),
'fileno': (types.IntType, 0, 0),
'flush': (types.NoneType, 0, 0),
'isatty': (BOOL, 0, 0),
'read': (types.StringType, 0, 1),
'readinto': (types.NoneType, 1, 1),
'readline': (types.StringType, 0, 1),
'readlines': (types.ListType, 0, 1),
'seek': (types.NoneType, 1, 2),
'tell': (types.IntType, 0, 0),
'truncate': (types.NoneType, 0, 1),
'write': (types.NoneType, 1, 1),
'writelines': (types.NoneType, 1, 1),
'xreadlines': (types.ListType, 0, 0),
},
}
if utils.pythonVersion() >= utils.PYTHON_2_4:
GLOBAL_FUNC_INFO['set'] = (Stack.TYPE_UNKNOWN, 0, 1)
GLOBAL_FUNC_INFO['frozenset'] = (Stack.TYPE_UNKNOWN, 0, 1)
kwargs = ['cmp', 'key', 'reverse']
BUILTIN_METHODS[types.ListType]['sort'] = (types.NoneType, 0, 3, kwargs)
BUILTIN_METHODS[types.DictType]['update'] = (types.NoneType, 1, 1, [])
if hasattr({}, 'pop'):
BUILTIN_METHODS[types.DictType]['pop'] = (Stack.TYPE_UNKNOWN, 1, 2)
if utils.pythonVersion() >= utils.PYTHON_2_5:
_STRING_METHODS['partition'] = (types.TupleType, 1, 1)
_STRING_METHODS['rpartition'] = (types.TupleType, 1, 1)
if utils.pythonVersion() >= utils.PYTHON_2_6:
GLOBAL_FUNC_INFO['bin'] = (types.StringType, 1, 1)
GLOBAL_FUNC_INFO['bytesarray'] = (bytearray, 0, 1)
GLOBAL_FUNC_INFO['bytes'] = (bytes, 0, 1)
GLOBAL_FUNC_INFO['format'] = (types.StringType, 1, 2)
GLOBAL_FUNC_INFO['next'] = (Stack.TYPE_UNKNOWN, 1, 2)
GLOBAL_FUNC_INFO['print'] = (types.NoneType, 0, None,
['sep', 'end', 'file'])
def _setupBuiltinMethods() :
if utils.pythonVersion() >= utils.PYTHON_2_2 :
PY22_DICT_METHODS = { 'iteritems': (types.ListType, 0, 0),
'iterkeys': (types.ListType, 0, 0),
'itervalues': (types.ListType, 0, 0),
}
BUILTIN_METHODS[types.DictType].update(PY22_DICT_METHODS)
try :
BUILTIN_METHODS[types.ComplexType] = \
{ 'conjugate': (types.ComplexType, 0, 0), }
except AttributeError :
pass
if len(dir('')) > 0 :
BUILTIN_METHODS[types.StringType] = _STRING_METHODS
try :
BUILTIN_METHODS[types.UnicodeType] = _STRING_METHODS
except AttributeError :
pass
_setupBuiltinMethods()
MUTABLE_TYPES = (types.ListType, types.DictType, types.InstanceType,)
# identifiers which will become a keyword in a future version
FUTURE_KEYWORDS = { 'yield': '2.2', 'with': '2.5', 'as': '2.5' }
METHODLESS_OBJECTS = { types.NoneType : None, types.IntType : None,
types.LongType : None, types.FloatType : None,
types.BufferType : None, types.TupleType : None,
types.EllipsisType : None,
}
def _setupBuiltinAttrs() :
item = Stack.Item(None, None)
BUILTIN_ATTRS[types.MethodType] = dir(item.__init__)
del item
if utils.pythonVersion() >= utils.PYTHON_2_2 :
# FIXME: I'm sure more types need to be added here
BUILTIN_ATTRS[types.StringType] = dir(''.__class__)
BUILTIN_ATTRS[types.ListType] = dir([].__class__)
BUILTIN_ATTRS[types.DictType] = dir({}.__class__)
try :
import warnings
_MSG = "xrange object's 'start', 'stop' and 'step' attributes are deprecated"
warnings.filterwarnings('ignore', _MSG)
del warnings, _MSG
except (ImportError, AssertionError):
pass
BUILTIN_ATTRS[types.XRangeType] = dir(xrange(0))
try: BUILTIN_ATTRS[types.ComplexType] = dir(complex(0, 1))
except: pass
try: BUILTIN_ATTRS[types.UnicodeType] = dir(unicode(''))
except: pass
try: BUILTIN_ATTRS[types.CodeType] = dir(_setupBuiltinAttrs.func_code)
except: pass
try: BUILTIN_ATTRS[types.FileType] = dir(sys.__stdin__)
except: pass
try:
raise TypeError
except TypeError :
try:
tb = sys.exc_info()[2]
BUILTIN_ATTRS[types.TracebackType] = dir(tb)
BUILTIN_ATTRS[types.FrameType] = dir(tb.tb_frame)
except:
pass
tb = None
BUILTIN_ATTRS = { types.StringType : dir(''),
types.TypeType : dir(type(type)),
types.ListType : dir([]),
types.DictType : dir({}),
types.FunctionType : dir(_setupBuiltinAttrs),
types.BuiltinFunctionType : dir(len),
types.BuiltinMethodType : dir([].append),
types.ClassType : dir(Stack.Item),
types.UnboundMethodType : dir(Stack.Item.__init__),
types.LambdaType : dir(lambda: None),
types.SliceType : dir(slice(0)),
}
# have to setup the rest this way to support different versions of Python
_setupBuiltinAttrs()
PENDING_DEPRECATED_MODULES = { 'string': None, 'types': None,
}
DEPRECATED_MODULES = { 'FCNTL': 'fcntl', 'gopherlib': None,
'macfs': 'Carbon.File or Carbon.Folder',
'posixfile': 'fcntl', 'pre': None, 'regsub': 're',
'statcache': 'os.stat()',
'stringold': None, 'tzparse': None,
'TERMIOS': 'termios', 'whrandom':'random',
'xmllib': 'xml.sax',
# C Modules
'mpz': None, 'pcre': None, 'pypcre': None,
'rgbimg': None, 'strop': None, 'xreadlines': 'file',
}
DEPRECATED_ATTRS = { 'array.read': None, 'array.write': None,
'operator.isCallable': None,
'operator.sequenceIncludes': None,
'pty.master_open': None, 'pty.slave_open': None,
'random.stdgamma': 'random.gammavariate',
'rfc822.AddrlistClass': 'rfc822.AddressList',
'string.atof': None, 'string.atoi': None,
'string.atol': None, 'string.zfill': None,
'sys.exc_traceback': None, 'sys.exit_thread': None,
'tempfile.mktemp': None, 'tempfile.template': None,
}
# FIXME: can't check these right now, maybe later
DEPRECATED_METHODS = {
'email.Message.get_type': 'email.Message.get_content_type',
'email.Message.get_subtype': 'email.Message.get_content_subtype',
'email.Message.get_main_type': 'email.Message.get_content_maintype',
'htmllib.HTMLParser.do_nextid': None,
'pstats.Stats.ignore': None,
'random.Random.cunifvariate': None,
'random.Random.stdgamma': 'Random.gammavariate',
}
_OS_AND_POSIX_FUNCS = { 'tempnam': None, 'tmpnam': None }
SECURITY_FUNCS = { 'os' : _OS_AND_POSIX_FUNCS, 'posix': _OS_AND_POSIX_FUNCS }
SPECIAL_METHODS = {
'__call__': None, # any number > 1
'__cmp__': 2,
'__coerce__': 2,
'__contains__': 2,
'__del__': 1,
'__hash__': 1,
'__iter__': 1,
'__len__': 1,
'__new__': None, # new-style class constructor
'__nonzero__': 1,
'__hex__': 1,
'__oct__': 1,
'__repr__': 1,
'__str__': 1,
'__invert__': 1, '__neg__': 1, '__pos__': 1, '__abs__': 1,
'__complex__': 1, '__int__': 1, '__long__': 1, '__float__': 1,
'__eq__': 2, '__ne__': 2,
'__ge__': 2, '__gt__': 2,
'__le__': 2, '__lt__': 2,
'__getattribute__': 2, # only in new-style classes
'__get__': 3, '__set__': 3, '__delete__': 2,
'__getattr__': 2, '__setattr__': 3, '__delattr__': 2,
'__getitem__': 2, '__setitem__': 3, '__delitem__': 2,
'__getslice__': 3, '__setslice__': 4, '__delslice__': 3,
# getslice is deprecated
'__add__': 2, '__radd__': 2, '__iadd__': 2,
'__sub__': 2, '__rsub__': 2, '__isub__': 2,
'__mul__': 2, '__rmul__': 2, '__imul__': 2,
'__div__': 2, '__rdiv__': 2, '__idiv__': 2,
# __pow__: 2 or 3 __ipow__: 2 or 3
'__pow__': 3, '__rpow__': 2, '__ipow__': 3,
'__truediv__': 2, '__rtruediv__': 2, '__itruediv__': 2,
'__floordiv__': 2, '__rfloordiv__': 2, '__ifloordiv__': 2,
'__mod__': 2, '__rmod__': 2, '__imod__': 2,
'__divmod__': 2, '__rdivmod__': 2, # no inplace op for divmod()
'__lshift__': 2, '__rlshift__': 2, '__ilshift__': 2,
'__rshift__': 2, '__rrshift__': 2, '__irshift__': 2,
'__and__': 2, '__rand__': 2, '__iand__': 2,
'__xor__': 2, '__rxor__': 2, '__ixor__': 2,
'__or__': 2, '__ror__': 2, '__ior__': 2,
# these are related to pickling
'__getstate__': 1, '__setstate__': 2,
'__copy__': 1, '__deepcopy__': 2,
'__getinitargs__': 1, '__getnewargs__': 1,
'__reduce__': 1, '__reduce_ex__': 2,
}
NEW_STYLE_CLASS_METHODS = ['__getattribute__', '__set__', '__get__', '__delete__']
|