| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767 |
- """This module trys to support builtin types and functions."""
- import inspect
- import rope.base.evaluate
- from rope.base import pynames, pyobjects, arguments, utils, ast
- class BuiltinModule(pyobjects.AbstractModule):
- def __init__(self, name, pycore=None, initial={}):
- super(BuiltinModule, self).__init__()
- self.name = name
- self.pycore = pycore
- self.initial = initial
- parent = None
- def get_attributes(self):
- return self.attributes
- def get_doc(self):
- if self.module:
- return self.module.__doc__
- def get_name(self):
- return self.name.split('.')[-1]
- @property
- @utils.saveit
- def attributes(self):
- result = _object_attributes(self.module, self)
- result.update(self.initial)
- if self.pycore is not None:
- submodules = self.pycore._builtin_submodules(self.name)
- for name, module in submodules.iteritems():
- result[name] = rope.base.builtins.BuiltinName(module)
- return result
- @property
- @utils.saveit
- def module(self):
- try:
- result = __import__(self.name)
- for token in self.name.split('.')[1:]:
- result = getattr(result, token, None)
- return result
- except ImportError:
- return
- class _BuiltinElement(object):
- def __init__(self, builtin, parent=None):
- self.builtin = builtin
- self._parent = parent
- def get_doc(self):
- if self.builtin:
- return getattr(self.builtin, '__doc__', None)
- def get_name(self):
- if self.builtin:
- return getattr(self.builtin, '__name__', None)
- @property
- def parent(self):
- if self._parent is None:
- return builtins
- return self._parent
- class BuiltinClass(_BuiltinElement, pyobjects.AbstractClass):
- def __init__(self, builtin, attributes, parent=None):
- _BuiltinElement.__init__(self, builtin, parent)
- pyobjects.AbstractClass.__init__(self)
- self.initial = attributes
- @utils.saveit
- def get_attributes(self):
- result = _object_attributes(self.builtin, self)
- result.update(self.initial)
- return result
- class BuiltinFunction(_BuiltinElement, pyobjects.AbstractFunction):
- def __init__(self, returned=None, function=None, builtin=None,
- argnames=[], parent=None):
- _BuiltinElement.__init__(self, builtin, parent)
- pyobjects.AbstractFunction.__init__(self)
- self.argnames = argnames
- self.returned = returned
- self.function = function
- def get_returned_object(self, args):
- if self.function is not None:
- return self.function(_CallContext(self.argnames, args))
- else:
- return self.returned
- def get_param_names(self, special_args=True):
- return self.argnames
- class BuiltinUnknown(_BuiltinElement, pyobjects.PyObject):
- def __init__(self, builtin):
- super(BuiltinUnknown, self).__init__(pyobjects.get_unknown())
- self.builtin = builtin
- self.type = pyobjects.get_unknown()
- def get_name(self):
- return getattr(type(self.builtin), '__name__', None)
- @utils.saveit
- def get_attributes(self):
- return _object_attributes(self.builtin, self)
- def _object_attributes(obj, parent):
- attributes = {}
- for name in dir(obj):
- if name == 'None':
- continue
- try:
- child = getattr(obj, name)
- except AttributeError:
- # descriptors are allowed to raise AttributeError
- # even if they are in dir()
- continue
- pyobject = None
- if inspect.isclass(child):
- pyobject = BuiltinClass(child, {}, parent=parent)
- elif inspect.isroutine(child):
- pyobject = BuiltinFunction(builtin=child, parent=parent)
- else:
- pyobject = BuiltinUnknown(builtin=child)
- attributes[name] = BuiltinName(pyobject)
- return attributes
- def _create_builtin_type_getter(cls):
- def _get_builtin(*args):
- if not hasattr(cls, '_generated'):
- cls._generated = {}
- if args not in cls._generated:
- cls._generated[args] = cls(*args)
- return cls._generated[args]
- return _get_builtin
- def _create_builtin_getter(cls):
- type_getter = _create_builtin_type_getter(cls)
- def _get_builtin(*args):
- return pyobjects.PyObject(type_getter(*args))
- return _get_builtin
- class _CallContext(object):
- def __init__(self, argnames, args):
- self.argnames = argnames
- self.args = args
- def _get_scope_and_pyname(self, pyname):
- if pyname is not None and isinstance(pyname, pynames.AssignedName):
- pymodule, lineno = pyname.get_definition_location()
- if pymodule is None:
- return None, None
- if lineno is None:
- lineno = 1
- scope = pymodule.get_scope().get_inner_scope_for_line(lineno)
- name = None
- while name is None and scope is not None:
- for current in scope.get_names():
- if scope[current] is pyname:
- name = current
- break
- else:
- scope = scope.parent
- return scope, name
- return None, None
- def get_argument(self, name):
- if self.args:
- args = self.args.get_arguments(self.argnames)
- return args[self.argnames.index(name)]
- def get_pyname(self, name):
- if self.args:
- args = self.args.get_pynames(self.argnames)
- if name in self.argnames:
- return args[self.argnames.index(name)]
- def get_arguments(self, argnames):
- if self.args:
- return self.args.get_arguments(argnames)
- def get_pynames(self, argnames):
- if self.args:
- return self.args.get_pynames(argnames)
- def get_per_name(self):
- if self.args is None:
- return None
- pyname = self.args.get_instance_pyname()
- scope, name = self._get_scope_and_pyname(pyname)
- if name is not None:
- pymodule = pyname.get_definition_location()[0]
- return pymodule.pycore.object_info.get_per_name(scope, name)
- return None
- def save_per_name(self, value):
- if self.args is None:
- return None
- pyname = self.args.get_instance_pyname()
- scope, name = self._get_scope_and_pyname(pyname)
- if name is not None:
- pymodule = pyname.get_definition_location()[0]
- pymodule.pycore.object_info.save_per_name(scope, name, value)
- class _AttributeCollector(object):
- def __init__(self, type):
- self.attributes = {}
- self.type = type
- def __call__(self, name, returned=None, function=None,
- argnames=['self'], check_existence=True):
- try:
- builtin = getattr(self.type, name)
- except AttributeError:
- if check_existence:
- raise
- builtin=None
- self.attributes[name] = BuiltinName(
- BuiltinFunction(returned=returned, function=function,
- argnames=argnames, builtin=builtin))
- def __setitem__(self, name, value):
- self.attributes[name] = value
- class List(BuiltinClass):
- def __init__(self, holding=None):
- self.holding = holding
- collector = _AttributeCollector(list)
- collector('__iter__', function=self._iterator_get)
- collector('__new__', function=self._new_list)
- # Adding methods
- collector('append', function=self._list_add, argnames=['self', 'value'])
- collector('__setitem__', function=self._list_add,
- argnames=['self', 'index', 'value'])
- collector('insert', function=self._list_add,
- argnames=['self', 'index', 'value'])
- collector('extend', function=self._self_set,
- argnames=['self', 'iterable'])
- # Getting methods
- collector('__getitem__', function=self._list_get)
- collector('pop', function=self._list_get)
- collector('__getslice__', function=self._self_get)
- super(List, self).__init__(list, collector.attributes)
- def _new_list(self, args):
- return _create_builtin(args, get_list)
- def _list_add(self, context):
- if self.holding is not None:
- return
- holding = context.get_argument('value')
- if holding is not None and holding != pyobjects.get_unknown():
- context.save_per_name(holding)
- def _self_set(self, context):
- if self.holding is not None:
- return
- iterable = context.get_pyname('iterable')
- holding = _infer_sequence_for_pyname(iterable)
- if holding is not None and holding != pyobjects.get_unknown():
- context.save_per_name(holding)
- def _list_get(self, context):
- if self.holding is not None:
- return self.holding
- return context.get_per_name()
- def _iterator_get(self, context):
- return get_iterator(self._list_get(context))
- def _self_get(self, context):
- return get_list(self._list_get(context))
- get_list = _create_builtin_getter(List)
- get_list_type = _create_builtin_type_getter(List)
- class Dict(BuiltinClass):
- def __init__(self, keys=None, values=None):
- self.keys = keys
- self.values = values
- item = get_tuple(self.keys, self.values)
- collector = _AttributeCollector(dict)
- collector('__new__', function=self._new_dict)
- collector('__setitem__', function=self._dict_add)
- collector('popitem', function=self._item_get)
- collector('pop', function=self._value_get)
- collector('get', function=self._key_get)
- collector('keys', function=self._key_list)
- collector('values', function=self._value_list)
- collector('items', function=self._item_list)
- collector('copy', function=self._self_get)
- collector('__getitem__', function=self._value_get)
- collector('__iter__', function=self._key_iter)
- collector('update', function=self._self_set)
- super(Dict, self).__init__(dict, collector.attributes)
- def _new_dict(self, args):
- def do_create(holding=None):
- if holding is None:
- return get_dict()
- type = holding.get_type()
- if isinstance(type, Tuple) and len(type.get_holding_objects()) == 2:
- return get_dict(*type.get_holding_objects())
- return _create_builtin(args, do_create)
- def _dict_add(self, context):
- if self.keys is not None:
- return
- key, value = context.get_arguments(['self', 'key', 'value'])[1:]
- if key is not None and key != pyobjects.get_unknown():
- context.save_per_name(get_tuple(key, value))
- def _item_get(self, context):
- if self.keys is not None:
- return get_tuple(self.keys, self.values)
- item = context.get_per_name()
- if item is None or not isinstance(item.get_type(), Tuple):
- return get_tuple(self.keys, self.values)
- return item
- def _value_get(self, context):
- item = self._item_get(context).get_type()
- return item.get_holding_objects()[1]
- def _key_get(self, context):
- item = self._item_get(context).get_type()
- return item.get_holding_objects()[0]
- def _value_list(self, context):
- return get_list(self._value_get(context))
- def _key_list(self, context):
- return get_list(self._key_get(context))
- def _item_list(self, context):
- return get_list(self._item_get(context))
- def _value_iter(self, context):
- return get_iterator(self._value_get(context))
- def _key_iter(self, context):
- return get_iterator(self._key_get(context))
- def _item_iter(self, context):
- return get_iterator(self._item_get(context))
- def _self_get(self, context):
- item = self._item_get(context).get_type()
- key, value = item.get_holding_objects()[:2]
- return get_dict(key, value)
- def _self_set(self, context):
- if self.keys is not None:
- return
- new_dict = context.get_pynames(['self', 'd'])[1]
- if new_dict and isinstance(new_dict.get_object().get_type(), Dict):
- args = arguments.ObjectArguments([new_dict])
- items = new_dict.get_object()['popitem'].\
- get_object().get_returned_object(args)
- context.save_per_name(items)
- else:
- holding = _infer_sequence_for_pyname(new_dict)
- if holding is not None and isinstance(holding.get_type(), Tuple):
- context.save_per_name(holding)
- get_dict = _create_builtin_getter(Dict)
- get_dict_type = _create_builtin_type_getter(Dict)
- class Tuple(BuiltinClass):
- def __init__(self, *objects):
- self.objects = objects
- first = None
- if objects:
- first = objects[0]
- attributes = {
- '__getitem__': BuiltinName(BuiltinFunction(first)),
- '__getslice__': BuiltinName(BuiltinFunction(pyobjects.PyObject(self))),
- '__new__': BuiltinName(BuiltinFunction(function=self._new_tuple)),
- '__iter__': BuiltinName(BuiltinFunction(get_iterator(first)))}
- super(Tuple, self).__init__(tuple, attributes)
- def get_holding_objects(self):
- return self.objects
- def _new_tuple(self, args):
- return _create_builtin(args, get_tuple)
- get_tuple = _create_builtin_getter(Tuple)
- get_tuple_type = _create_builtin_type_getter(Tuple)
- class Set(BuiltinClass):
- def __init__(self, holding=None):
- self.holding = holding
- collector = _AttributeCollector(set)
- collector('__new__', function=self._new_set)
- self_methods = ['copy', 'difference', 'intersection',
- 'symmetric_difference', 'union']
- for method in self_methods:
- collector(method, function=self._self_get)
- collector('add', function=self._set_add)
- collector('update', function=self._self_set)
- collector('update', function=self._self_set)
- collector('symmetric_difference_update', function=self._self_set)
- collector('difference_update', function=self._self_set)
- collector('pop', function=self._set_get)
- collector('__iter__', function=self._iterator_get)
- super(Set, self).__init__(set, collector.attributes)
- def _new_set(self, args):
- return _create_builtin(args, get_set)
- def _set_add(self, context):
- if self.holding is not None:
- return
- holding = context.get_arguments(['self', 'value'])[1]
- if holding is not None and holding != pyobjects.get_unknown():
- context.save_per_name(holding)
- def _self_set(self, context):
- if self.holding is not None:
- return
- iterable = context.get_pyname('iterable')
- holding = _infer_sequence_for_pyname(iterable)
- if holding is not None and holding != pyobjects.get_unknown():
- context.save_per_name(holding)
- def _set_get(self, context):
- if self.holding is not None:
- return self.holding
- return context.get_per_name()
- def _iterator_get(self, context):
- return get_iterator(self._set_get(context))
- def _self_get(self, context):
- return get_list(self._set_get(context))
- get_set = _create_builtin_getter(Set)
- get_set_type = _create_builtin_type_getter(Set)
- class Str(BuiltinClass):
- def __init__(self):
- self_object = pyobjects.PyObject(self)
- collector = _AttributeCollector(str)
- collector('__iter__', get_iterator(self_object), check_existence=False)
- self_methods = ['__getitem__', '__getslice__', 'capitalize', 'center',
- 'decode', 'encode', 'expandtabs', 'join', 'ljust',
- 'lower', 'lstrip', 'replace', 'rjust', 'rstrip', 'strip',
- 'swapcase', 'title', 'translate', 'upper', 'zfill']
- for method in self_methods:
- collector(method, self_object)
- for method in ['rsplit', 'split', 'splitlines']:
- collector(method, get_list(self_object))
- super(Str, self).__init__(str, collector.attributes)
- def get_doc(self):
- return str.__doc__
- get_str = _create_builtin_getter(Str)
- get_str_type = _create_builtin_type_getter(Str)
- class BuiltinName(pynames.PyName):
- def __init__(self, pyobject):
- self.pyobject = pyobject
- def get_object(self):
- return self.pyobject
- def get_definition_location(self):
- return (None, None)
- class Iterator(pyobjects.AbstractClass):
- def __init__(self, holding=None):
- super(Iterator, self).__init__()
- self.holding = holding
- self.attributes = {
- 'next': BuiltinName(BuiltinFunction(self.holding)),
- '__iter__': BuiltinName(BuiltinFunction(self))}
- def get_attributes(self):
- return self.attributes
- def get_returned_object(self, args):
- return self.holding
- get_iterator = _create_builtin_getter(Iterator)
- class Generator(pyobjects.AbstractClass):
- def __init__(self, holding=None):
- super(Generator, self).__init__()
- self.holding = holding
- self.attributes = {
- 'next': BuiltinName(BuiltinFunction(self.holding)),
- '__iter__': BuiltinName(BuiltinFunction(get_iterator(self.holding))),
- 'close': BuiltinName(BuiltinFunction()),
- 'send': BuiltinName(BuiltinFunction()),
- 'throw': BuiltinName(BuiltinFunction())}
- def get_attributes(self):
- return self.attributes
- def get_returned_object(self, args):
- return self.holding
- get_generator = _create_builtin_getter(Generator)
- class File(BuiltinClass):
- def __init__(self):
- self_object = pyobjects.PyObject(self)
- str_object = get_str()
- str_list = get_list(get_str())
- attributes = {}
- def add(name, returned=None, function=None):
- builtin = getattr(file, name, None)
- attributes[name] = BuiltinName(
- BuiltinFunction(returned=returned, function=function,
- builtin=builtin))
- add('__iter__', get_iterator(str_object))
- for method in ['next', 'read', 'readline', 'readlines']:
- add(method, str_list)
- for method in ['close', 'flush', 'lineno', 'isatty', 'seek', 'tell',
- 'truncate', 'write', 'writelines']:
- add(method)
- super(File, self).__init__(file, attributes)
- get_file = _create_builtin_getter(File)
- get_file_type = _create_builtin_type_getter(File)
- class Property(BuiltinClass):
- def __init__(self, fget=None, fset=None, fdel=None, fdoc=None):
- self._fget = fget
- self._fdoc = fdoc
- attributes = {
- 'fget': BuiltinName(BuiltinFunction()),
- 'fset': BuiltinName(pynames.UnboundName()),
- 'fdel': BuiltinName(pynames.UnboundName()),
- '__new__': BuiltinName(BuiltinFunction(function=_property_function))}
- super(Property, self).__init__(property, attributes)
- def get_property_object(self, args):
- if isinstance(self._fget, pyobjects.AbstractFunction):
- return self._fget.get_returned_object(args)
- def _property_function(args):
- parameters = args.get_arguments(['fget', 'fset', 'fdel', 'fdoc'])
- return pyobjects.PyObject(Property(parameters[0]))
- class Lambda(pyobjects.AbstractFunction):
- def __init__(self, node, scope):
- super(Lambda, self).__init__()
- self.node = node
- self.arguments = node.args
- self.scope = scope
- def get_returned_object(self, args):
- result = rope.base.evaluate.eval_node(self.scope, self.node.body)
- if result is not None:
- return result.get_object()
- else:
- return pyobjects.get_unknown()
- def get_module(self):
- return self.parent.get_module()
- def get_scope(self):
- return self.scope
- def get_kind(self):
- return 'lambda'
- def get_ast(self):
- return self.node
- def get_attributes(self):
- return {}
- def get_name(self):
- return 'lambda'
- def get_param_names(self, special_args=True):
- result = [node.id for node in self.arguments.args
- if isinstance(node, ast.Name)]
- if self.arguments.vararg:
- result.append('*' + self.arguments.vararg)
- if self.arguments.kwarg:
- result.append('**' + self.arguments.kwarg)
- return result
- @property
- def parent(self):
- return self.scope.pyobject
- class BuiltinObject(BuiltinClass):
- def __init__(self):
- super(BuiltinObject, self).__init__(object, {})
- class BuiltinType(BuiltinClass):
- def __init__(self):
- super(BuiltinType, self).__init__(type, {})
- def _infer_sequence_for_pyname(pyname):
- if pyname is None:
- return None
- seq = pyname.get_object()
- args = arguments.ObjectArguments([pyname])
- if '__iter__' in seq:
- obj = seq['__iter__'].get_object()
- if not isinstance(obj, pyobjects.AbstractFunction):
- return None
- iter = obj.get_returned_object(args)
- if iter is not None and 'next' in iter:
- holding = iter['next'].get_object().\
- get_returned_object(args)
- return holding
- def _create_builtin(args, creator):
- passed = args.get_pynames(['sequence'])[0]
- if passed is None:
- holding = None
- else:
- holding = _infer_sequence_for_pyname(passed)
- if holding is not None:
- return creator(holding)
- else:
- return creator()
- def _range_function(args):
- return get_list()
- def _reversed_function(args):
- return _create_builtin(args, get_iterator)
- def _sorted_function(args):
- return _create_builtin(args, get_list)
- def _super_function(args):
- passed_class, passed_self = args.get_arguments(['type', 'self'])
- if passed_self is None:
- return passed_class
- else:
- #pyclass = passed_self.get_type()
- pyclass = passed_class
- if isinstance(pyclass, pyobjects.AbstractClass):
- supers = pyclass.get_superclasses()
- if supers:
- return pyobjects.PyObject(supers[0])
- return passed_self
- def _zip_function(args):
- args = args.get_pynames(['sequence'])
- objects = []
- for seq in args:
- if seq is None:
- holding = None
- else:
- holding = _infer_sequence_for_pyname(seq)
- objects.append(holding)
- tuple = get_tuple(*objects)
- return get_list(tuple)
- def _enumerate_function(args):
- passed = args.get_pynames(['sequence'])[0]
- if passed is None:
- holding = None
- else:
- holding = _infer_sequence_for_pyname(passed)
- tuple = get_tuple(None, holding)
- return get_iterator(tuple)
- def _iter_function(args):
- passed = args.get_pynames(['sequence'])[0]
- if passed is None:
- holding = None
- else:
- holding = _infer_sequence_for_pyname(passed)
- return get_iterator(holding)
- def _input_function(args):
- return get_str()
- _initial_builtins = {
- 'list': BuiltinName(get_list_type()),
- 'dict': BuiltinName(get_dict_type()),
- 'tuple': BuiltinName(get_tuple_type()),
- 'set': BuiltinName(get_set_type()),
- 'str': BuiltinName(get_str_type()),
- 'file': BuiltinName(get_file_type()),
- 'open': BuiltinName(get_file_type()),
- 'unicode': BuiltinName(get_str_type()),
- 'range': BuiltinName(BuiltinFunction(function=_range_function, builtin=range)),
- 'reversed': BuiltinName(BuiltinFunction(function=_reversed_function, builtin=reversed)),
- 'sorted': BuiltinName(BuiltinFunction(function=_sorted_function, builtin=sorted)),
- 'super': BuiltinName(BuiltinFunction(function=_super_function, builtin=super)),
- 'property': BuiltinName(BuiltinFunction(function=_property_function, builtin=property)),
- 'zip': BuiltinName(BuiltinFunction(function=_zip_function, builtin=zip)),
- 'enumerate': BuiltinName(BuiltinFunction(function=_enumerate_function, builtin=enumerate)),
- 'object': BuiltinName(BuiltinObject()),
- 'type': BuiltinName(BuiltinType()),
- 'iter': BuiltinName(BuiltinFunction(function=_iter_function, builtin=iter)),
- 'raw_input': BuiltinName(BuiltinFunction(function=_input_function, builtin=raw_input)),
- }
- builtins = BuiltinModule('__builtin__', initial=_initial_builtins)
|