mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 22:44:27 +08:00
Remove fakes, RIP
This commit is contained in:
@@ -364,7 +364,6 @@ class DirectObjectAccess(object):
|
|||||||
yield builtins
|
yield builtins
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
# TODO use sys.modules, __module__ can be faked.
|
|
||||||
yield sys.modules[imp_plz]
|
yield sys.modules[imp_plz]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# __module__ can be something arbitrary that doesn't exist.
|
# __module__ can be something arbitrary that doesn't exist.
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ from jedi.evaluate.lazy_context import LazyKnownContext
|
|||||||
from jedi.evaluate.compiled.access import _sentinel
|
from jedi.evaluate.compiled.access import _sentinel
|
||||||
from jedi.evaluate.cache import evaluator_function_cache
|
from jedi.evaluate.cache import evaluator_function_cache
|
||||||
from jedi.evaluate.helpers import reraise_getitem_errors, execute_evaluated
|
from jedi.evaluate.helpers import reraise_getitem_errors, execute_evaluated
|
||||||
from . import fake
|
|
||||||
|
|
||||||
|
|
||||||
class CheckAttribute(object):
|
class CheckAttribute(object):
|
||||||
@@ -47,11 +46,9 @@ class CheckAttribute(object):
|
|||||||
|
|
||||||
|
|
||||||
class CompiledObject(Context):
|
class CompiledObject(Context):
|
||||||
def __init__(self, evaluator, access_handle, parent_context=None, faked_class=None):
|
def __init__(self, evaluator, access_handle, parent_context=None):
|
||||||
super(CompiledObject, self).__init__(evaluator, parent_context)
|
super(CompiledObject, self).__init__(evaluator, parent_context)
|
||||||
self.access_handle = access_handle
|
self.access_handle = access_handle
|
||||||
# This attribute will not be set for most classes, except for fakes.
|
|
||||||
self.tree_node = faked_class
|
|
||||||
|
|
||||||
@CheckAttribute()
|
@CheckAttribute()
|
||||||
def py__call__(self, arguments):
|
def py__call__(self, arguments):
|
||||||
@@ -448,44 +445,30 @@ def _parse_function_doc(doc):
|
|||||||
|
|
||||||
|
|
||||||
def create_from_name(evaluator, compiled_object, name):
|
def create_from_name(evaluator, compiled_object, name):
|
||||||
faked = None
|
|
||||||
try:
|
|
||||||
faked = fake.get_faked_with_parent_context(compiled_object, name)
|
|
||||||
except fake.FakeDoesNotExist:
|
|
||||||
pass
|
|
||||||
|
|
||||||
access = compiled_object.access_handle.getattr(name, default=None)
|
access = compiled_object.access_handle.getattr(name, default=None)
|
||||||
parent_context = compiled_object
|
parent_context = compiled_object
|
||||||
if parent_context.is_class():
|
if parent_context.is_class():
|
||||||
parent_context = parent_context.parent_context
|
parent_context = parent_context.parent_context
|
||||||
return create_cached_compiled_object(
|
return create_cached_compiled_object(
|
||||||
evaluator, access, parent_context=parent_context, faked=faked
|
evaluator, access, parent_context=parent_context
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _normalize_create_args(func):
|
def _normalize_create_args(func):
|
||||||
"""The cache doesn't care about keyword vs. normal args."""
|
"""The cache doesn't care about keyword vs. normal args."""
|
||||||
def wrapper(evaluator, obj, parent_context=None, faked=None):
|
def wrapper(evaluator, obj, parent_context=None):
|
||||||
return func(evaluator, obj, parent_context, faked)
|
return func(evaluator, obj, parent_context)
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def create_from_access_path(evaluator, access_path):
|
def create_from_access_path(evaluator, access_path):
|
||||||
parent_context = None
|
parent_context = None
|
||||||
for name, access in access_path.accesses:
|
for name, access in access_path.accesses:
|
||||||
try:
|
parent_context = create_cached_compiled_object(evaluator, access, parent_context)
|
||||||
if parent_context is None:
|
|
||||||
faked = fake.get_faked_module(evaluator, access_path.accesses[0][0])
|
|
||||||
else:
|
|
||||||
faked = fake.get_faked_with_parent_context(parent_context, name)
|
|
||||||
except fake.FakeDoesNotExist:
|
|
||||||
faked = None
|
|
||||||
|
|
||||||
parent_context = create_cached_compiled_object(evaluator, access, parent_context, faked)
|
|
||||||
return parent_context
|
return parent_context
|
||||||
|
|
||||||
|
|
||||||
@_normalize_create_args
|
@_normalize_create_args
|
||||||
@evaluator_function_cache()
|
@evaluator_function_cache()
|
||||||
def create_cached_compiled_object(evaluator, access_handle, parent_context, faked):
|
def create_cached_compiled_object(evaluator, access_handle, parent_context):
|
||||||
return CompiledObject(evaluator, access_handle, parent_context, faked)
|
return CompiledObject(evaluator, access_handle, parent_context)
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
"""
|
|
||||||
Loads functions that are mixed in to the standard library. E.g. builtins are
|
|
||||||
written in C (binaries), but my autocompletion only understands Python code. By
|
|
||||||
mixing in Python code, the autocompletion should work much better for builtins.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
from itertools import chain
|
|
||||||
|
|
||||||
from jedi._compatibility import unicode
|
|
||||||
|
|
||||||
fake_modules = {}
|
|
||||||
|
|
||||||
|
|
||||||
def _get_path_dict():
|
|
||||||
path = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
base_path = os.path.join(path, 'fake')
|
|
||||||
dct = {}
|
|
||||||
for file_name in os.listdir(base_path):
|
|
||||||
if file_name.endswith('.pym'):
|
|
||||||
dct[file_name[:-4]] = os.path.join(base_path, file_name)
|
|
||||||
return dct
|
|
||||||
|
|
||||||
|
|
||||||
_path_dict = _get_path_dict()
|
|
||||||
|
|
||||||
|
|
||||||
class FakeDoesNotExist(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def _load_faked_module(evaluator, module_name):
|
|
||||||
try:
|
|
||||||
return fake_modules[module_name]
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
check_module_name = module_name
|
|
||||||
if module_name == '__builtin__' and evaluator.environment.version_info.major == 2:
|
|
||||||
check_module_name = 'builtins'
|
|
||||||
|
|
||||||
try:
|
|
||||||
path = _path_dict[check_module_name]
|
|
||||||
except KeyError:
|
|
||||||
fake_modules[module_name] = None
|
|
||||||
return
|
|
||||||
|
|
||||||
with open(path) as f:
|
|
||||||
source = f.read()
|
|
||||||
|
|
||||||
fake_modules[module_name] = m = evaluator.latest_grammar.parse(unicode(source))
|
|
||||||
|
|
||||||
if check_module_name != module_name:
|
|
||||||
# There are two implementations of `open` for either python 2/3.
|
|
||||||
# -> Rename the python2 version (`look at fake/builtins.pym`).
|
|
||||||
open_func = _search_scope(m, 'open')
|
|
||||||
open_func.children[1].value = 'open_python3'
|
|
||||||
open_func = _search_scope(m, 'open_python2')
|
|
||||||
open_func.children[1].value = 'open'
|
|
||||||
return m
|
|
||||||
|
|
||||||
|
|
||||||
def _search_scope(scope, obj_name):
|
|
||||||
for s in chain(scope.iter_classdefs(), scope.iter_funcdefs()):
|
|
||||||
if s.name.value == obj_name:
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
def get_faked_with_parent_context(parent_context, name):
|
|
||||||
if parent_context.tree_node is not None:
|
|
||||||
# Try to search in already clearly defined stuff.
|
|
||||||
found = _search_scope(parent_context.tree_node, name)
|
|
||||||
if found is not None:
|
|
||||||
return found
|
|
||||||
raise FakeDoesNotExist
|
|
||||||
|
|
||||||
|
|
||||||
def get_faked_module(evaluator, string_name):
|
|
||||||
module = _load_faked_module(evaluator, string_name)
|
|
||||||
if module is None:
|
|
||||||
raise FakeDoesNotExist
|
|
||||||
return module
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
class partial():
|
|
||||||
def __init__(self, func, *args, **keywords):
|
|
||||||
self.__func = func
|
|
||||||
self.__args = args
|
|
||||||
self.__keywords = keywords
|
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
|
||||||
# TODO should be **dict(self.__keywords, **kwargs)
|
|
||||||
return self.__func(*(self.__args + args), **self.__keywords)
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
def connect(database, timeout=None, isolation_level=None, detect_types=None, factory=None):
|
|
||||||
return Connection()
|
|
||||||
|
|
||||||
|
|
||||||
class Connection():
|
|
||||||
def cursor(self):
|
|
||||||
return Cursor()
|
|
||||||
|
|
||||||
|
|
||||||
class Cursor():
|
|
||||||
def cursor(self):
|
|
||||||
return Cursor()
|
|
||||||
|
|
||||||
def fetchone(self):
|
|
||||||
return Row()
|
|
||||||
|
|
||||||
def fetchmany(self, size=cursor.arraysize):
|
|
||||||
return [self.fetchone()]
|
|
||||||
|
|
||||||
def fetchall(self):
|
|
||||||
return [self.fetchone()]
|
|
||||||
|
|
||||||
|
|
||||||
class Row():
|
|
||||||
def keys(self):
|
|
||||||
return ['']
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
def compile():
|
|
||||||
class SRE_Match():
|
|
||||||
endpos = int()
|
|
||||||
lastgroup = int()
|
|
||||||
lastindex = int()
|
|
||||||
pos = int()
|
|
||||||
string = str()
|
|
||||||
regs = ((int(), int()),)
|
|
||||||
|
|
||||||
def __init__(self, pattern):
|
|
||||||
self.re = pattern
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
return int()
|
|
||||||
|
|
||||||
def end(self):
|
|
||||||
return int()
|
|
||||||
|
|
||||||
def span(self):
|
|
||||||
return int(), int()
|
|
||||||
|
|
||||||
def expand(self):
|
|
||||||
return str()
|
|
||||||
|
|
||||||
def group(self, nr):
|
|
||||||
return str()
|
|
||||||
|
|
||||||
def groupdict(self):
|
|
||||||
return {str(): str()}
|
|
||||||
|
|
||||||
def groups(self):
|
|
||||||
return (str(),)
|
|
||||||
|
|
||||||
class SRE_Pattern():
|
|
||||||
flags = int()
|
|
||||||
groupindex = {}
|
|
||||||
groups = int()
|
|
||||||
pattern = str()
|
|
||||||
|
|
||||||
def findall(self, string, pos=None, endpos=None):
|
|
||||||
"""
|
|
||||||
findall(string[, pos[, endpos]]) --> list.
|
|
||||||
Return a list of all non-overlapping matches of pattern in string.
|
|
||||||
"""
|
|
||||||
return [str()]
|
|
||||||
|
|
||||||
def finditer(self, string, pos=None, endpos=None):
|
|
||||||
"""
|
|
||||||
finditer(string[, pos[, endpos]]) --> iterator.
|
|
||||||
Return an iterator over all non-overlapping matches for the
|
|
||||||
RE pattern in string. For each match, the iterator returns a
|
|
||||||
match object.
|
|
||||||
"""
|
|
||||||
yield SRE_Match(self)
|
|
||||||
|
|
||||||
def match(self, string, pos=None, endpos=None):
|
|
||||||
"""
|
|
||||||
match(string[, pos[, endpos]]) --> match object or None.
|
|
||||||
Matches zero or more characters at the beginning of the string
|
|
||||||
pattern
|
|
||||||
"""
|
|
||||||
return SRE_Match(self)
|
|
||||||
|
|
||||||
def scanner(self, string, pos=None, endpos=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def search(self, string, pos=None, endpos=None):
|
|
||||||
"""
|
|
||||||
search(string[, pos[, endpos]]) --> match object or None.
|
|
||||||
Scan through string looking for a match, and return a corresponding
|
|
||||||
MatchObject instance. Return None if no position in the string matches.
|
|
||||||
"""
|
|
||||||
return SRE_Match(self)
|
|
||||||
|
|
||||||
def split(self, string, maxsplit=0]):
|
|
||||||
"""
|
|
||||||
split(string[, maxsplit = 0]) --> list.
|
|
||||||
Split string by the occurrences of pattern.
|
|
||||||
"""
|
|
||||||
return [str()]
|
|
||||||
|
|
||||||
def sub(self, repl, string, count=0):
|
|
||||||
"""
|
|
||||||
sub(repl, string[, count = 0]) --> newstring
|
|
||||||
Return the string obtained by replacing the leftmost non-overlapping
|
|
||||||
occurrences of pattern in string by the replacement repl.
|
|
||||||
"""
|
|
||||||
return str()
|
|
||||||
|
|
||||||
def subn(self, repl, string, count=0):
|
|
||||||
"""
|
|
||||||
subn(repl, string[, count = 0]) --> (newstring, number of subs)
|
|
||||||
Return the tuple (new_string, number_of_subs_made) found by replacing
|
|
||||||
the leftmost non-overlapping occurrences of pattern with the
|
|
||||||
replacement repl.
|
|
||||||
"""
|
|
||||||
return (str(), int())
|
|
||||||
|
|
||||||
return SRE_Pattern()
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
def proxy(object, callback=None):
|
|
||||||
return object
|
|
||||||
|
|
||||||
class ref():
|
|
||||||
def __init__(self, object, callback=None):
|
|
||||||
self.__object = object
|
|
||||||
|
|
||||||
def __call__(self):
|
|
||||||
return self.__object
|
|
||||||
@@ -1,262 +0,0 @@
|
|||||||
"""
|
|
||||||
Pure Python implementation of some builtins.
|
|
||||||
This code is not going to be executed anywhere.
|
|
||||||
These implementations are not always correct, but should work as good as
|
|
||||||
possible for the auto completion.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def next(iterator, default=None):
|
|
||||||
if random.choice([0, 1]):
|
|
||||||
if hasattr("next"):
|
|
||||||
return iterator.next()
|
|
||||||
else:
|
|
||||||
return iterator.__next__()
|
|
||||||
else:
|
|
||||||
if default is not None:
|
|
||||||
return default
|
|
||||||
|
|
||||||
|
|
||||||
def iter(collection, sentinel=None):
|
|
||||||
if sentinel:
|
|
||||||
yield collection()
|
|
||||||
else:
|
|
||||||
for c in collection:
|
|
||||||
yield c
|
|
||||||
|
|
||||||
|
|
||||||
def range(start, stop=None, step=1):
|
|
||||||
return [0]
|
|
||||||
|
|
||||||
|
|
||||||
class file():
|
|
||||||
def __iter__(self):
|
|
||||||
yield ''
|
|
||||||
|
|
||||||
def next(self):
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def readlines(self):
|
|
||||||
return ['']
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
|
|
||||||
class xrange():
|
|
||||||
# Attention: this function doesn't exist in Py3k (there it is range).
|
|
||||||
def __iter__(self):
|
|
||||||
yield 1
|
|
||||||
|
|
||||||
def count(self):
|
|
||||||
return 1
|
|
||||||
|
|
||||||
def index(self):
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
def open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True):
|
|
||||||
import io
|
|
||||||
return io.TextIOWrapper(file, mode, buffering, encoding, errors, newline, closefd)
|
|
||||||
|
|
||||||
|
|
||||||
def open_python2(name, mode=None, buffering=None):
|
|
||||||
return file(name, mode, buffering)
|
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------
|
|
||||||
# descriptors
|
|
||||||
#--------------------------------------------------------
|
|
||||||
class property():
|
|
||||||
def __init__(self, fget, fset=None, fdel=None, doc=None):
|
|
||||||
self.fget = fget
|
|
||||||
self.fset = fset
|
|
||||||
self.fdel = fdel
|
|
||||||
self.__doc__ = doc
|
|
||||||
|
|
||||||
def __get__(self, obj, cls):
|
|
||||||
return self.fget(obj)
|
|
||||||
|
|
||||||
def __set__(self, obj, value):
|
|
||||||
self.fset(obj, value)
|
|
||||||
|
|
||||||
def __delete__(self, obj):
|
|
||||||
self.fdel(obj)
|
|
||||||
|
|
||||||
def setter(self, func):
|
|
||||||
self.fset = func
|
|
||||||
return self
|
|
||||||
|
|
||||||
def getter(self, func):
|
|
||||||
self.fget = func
|
|
||||||
return self
|
|
||||||
|
|
||||||
def deleter(self, func):
|
|
||||||
self.fdel = func
|
|
||||||
return self
|
|
||||||
|
|
||||||
|
|
||||||
class staticmethod():
|
|
||||||
def __init__(self, func):
|
|
||||||
self.__func = func
|
|
||||||
|
|
||||||
def __get__(self, obj, cls):
|
|
||||||
return self.__func
|
|
||||||
|
|
||||||
|
|
||||||
class classmethod():
|
|
||||||
def __init__(self, func):
|
|
||||||
self.__func = func
|
|
||||||
|
|
||||||
def __get__(self, obj, cls):
|
|
||||||
def _method(*args, **kwargs):
|
|
||||||
return self.__func(cls, *args, **kwargs)
|
|
||||||
return _method
|
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------
|
|
||||||
# array stuff
|
|
||||||
#--------------------------------------------------------
|
|
||||||
class list():
|
|
||||||
def __init__(self, iterable=[]):
|
|
||||||
self.__iterable = []
|
|
||||||
for i in iterable:
|
|
||||||
self.__iterable += [i]
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
for i in self.__iterable:
|
|
||||||
yield i
|
|
||||||
|
|
||||||
def __getitem__(self, y):
|
|
||||||
return self.__iterable[y]
|
|
||||||
|
|
||||||
def pop(self):
|
|
||||||
return self.__iterable[int()]
|
|
||||||
|
|
||||||
|
|
||||||
class tuple():
|
|
||||||
def __init__(self, iterable=[]):
|
|
||||||
self.__iterable = []
|
|
||||||
for i in iterable:
|
|
||||||
self.__iterable += [i]
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
for i in self.__iterable:
|
|
||||||
yield i
|
|
||||||
|
|
||||||
def __getitem__(self, y):
|
|
||||||
return self.__iterable[y]
|
|
||||||
|
|
||||||
def index(self):
|
|
||||||
return 1
|
|
||||||
|
|
||||||
def count(self):
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
class set():
|
|
||||||
def __init__(self, iterable=[]):
|
|
||||||
self.__iterable = iterable
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
for i in self.__iterable:
|
|
||||||
yield i
|
|
||||||
|
|
||||||
def pop(self):
|
|
||||||
return list(self.__iterable)[-1]
|
|
||||||
|
|
||||||
def copy(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def difference(self, other):
|
|
||||||
return self - other
|
|
||||||
|
|
||||||
def intersection(self, other):
|
|
||||||
return self & other
|
|
||||||
|
|
||||||
def symmetric_difference(self, other):
|
|
||||||
return self ^ other
|
|
||||||
|
|
||||||
def union(self, other):
|
|
||||||
return self | other
|
|
||||||
|
|
||||||
|
|
||||||
class frozenset():
|
|
||||||
def __init__(self, iterable=[]):
|
|
||||||
self.__iterable = iterable
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
for i in self.__iterable:
|
|
||||||
yield i
|
|
||||||
|
|
||||||
def copy(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
|
|
||||||
class dict():
|
|
||||||
def __init__(self, **elements):
|
|
||||||
self.__elements = elements
|
|
||||||
|
|
||||||
def clear(self):
|
|
||||||
# has a strange docstr
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __getitem__(self, obj):
|
|
||||||
return self.__elements[obj]
|
|
||||||
|
|
||||||
def get(self, k, d=None):
|
|
||||||
# TODO implement
|
|
||||||
try:
|
|
||||||
return self.__elements[k]
|
|
||||||
pass
|
|
||||||
except KeyError:
|
|
||||||
return d
|
|
||||||
|
|
||||||
def values(self):
|
|
||||||
return self.__elements.values()
|
|
||||||
|
|
||||||
def setdefault(self, k, d):
|
|
||||||
# TODO maybe also return the content
|
|
||||||
return d
|
|
||||||
|
|
||||||
|
|
||||||
class enumerate():
|
|
||||||
def __init__(self, sequence, start=0):
|
|
||||||
self.__sequence = sequence
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
for i in self.__sequence:
|
|
||||||
yield 1, i
|
|
||||||
|
|
||||||
def __next__(self):
|
|
||||||
return next(self.__iter__())
|
|
||||||
|
|
||||||
def next(self):
|
|
||||||
return next(self.__iter__())
|
|
||||||
|
|
||||||
|
|
||||||
def sorted(iterable, cmp=None, key=None, reverse=False):
|
|
||||||
return iterable
|
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------
|
|
||||||
# basic types
|
|
||||||
#--------------------------------------------------------
|
|
||||||
class int():
|
|
||||||
def __init__(self, x, base=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class str():
|
|
||||||
def __init__(self, obj):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def strip(self):
|
|
||||||
return str()
|
|
||||||
|
|
||||||
def split(self):
|
|
||||||
return [str()]
|
|
||||||
|
|
||||||
class type():
|
|
||||||
def mro():
|
|
||||||
return [object]
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
class datetime():
|
|
||||||
@staticmethod
|
|
||||||
def now():
|
|
||||||
return datetime()
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
class TextIOWrapper():
|
|
||||||
def __next__(self):
|
|
||||||
return str()
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
yield str()
|
|
||||||
|
|
||||||
def readlines(self):
|
|
||||||
return ['']
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
return self
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# Just copied this code from Python 3.6.
|
|
||||||
|
|
||||||
class itemgetter:
|
|
||||||
"""
|
|
||||||
Return a callable object that fetches the given item(s) from its operand.
|
|
||||||
After f = itemgetter(2), the call f(r) returns r[2].
|
|
||||||
After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])
|
|
||||||
"""
|
|
||||||
__slots__ = ('_items', '_call')
|
|
||||||
|
|
||||||
def __init__(self, item, *items):
|
|
||||||
if not items:
|
|
||||||
self._items = (item,)
|
|
||||||
def func(obj):
|
|
||||||
return obj[item]
|
|
||||||
self._call = func
|
|
||||||
else:
|
|
||||||
self._items = items = (item,) + items
|
|
||||||
def func(obj):
|
|
||||||
return tuple(obj[i] for i in items)
|
|
||||||
self._call = func
|
|
||||||
|
|
||||||
def __call__(self, obj):
|
|
||||||
return self._call(obj)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return '%s.%s(%s)' % (self.__class__.__module__,
|
|
||||||
self.__class__.__name__,
|
|
||||||
', '.join(map(repr, self._items)))
|
|
||||||
|
|
||||||
def __reduce__(self):
|
|
||||||
return self.__class__, self._items
|
|
||||||
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
def getcwd():
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def getcwdu():
|
|
||||||
return ''
|
|
||||||
@@ -645,11 +645,6 @@ class _ArrayInstance(object):
|
|||||||
Used for the usage of set() and list().
|
Used for the usage of set() and list().
|
||||||
This is definitely a hack, but a good one :-)
|
This is definitely a hack, but a good one :-)
|
||||||
It makes it possible to use set/list conversions.
|
It makes it possible to use set/list conversions.
|
||||||
|
|
||||||
In contrast to Array, ListComprehension and all other iterable types, this
|
|
||||||
is something that is only used inside `evaluate/compiled/fake/builtins.py`
|
|
||||||
and therefore doesn't need filters, `py__bool__` and so on, because
|
|
||||||
we don't use these operations in `builtins.py`.
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, instance, var_args):
|
def __init__(self, instance, var_args):
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
|
|||||||
@@ -136,10 +136,6 @@ def builtins_property(objects, types, obj, arguments):
|
|||||||
|
|
||||||
@argument_clinic('iterator[, default], /', want_evaluator=True)
|
@argument_clinic('iterator[, default], /', want_evaluator=True)
|
||||||
def builtins_next(iterators, defaults, evaluator):
|
def builtins_next(iterators, defaults, evaluator):
|
||||||
"""
|
|
||||||
TODO this function is currently not used. It's a stab at implementing next
|
|
||||||
in a different way than fake objects. This would be a bit more flexible.
|
|
||||||
"""
|
|
||||||
if evaluator.environment.version_info.major == 2:
|
if evaluator.environment.version_info.major == 2:
|
||||||
name = 'next'
|
name = 'next'
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user