mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 05:54:25 +08:00
Remove fakes, RIP
This commit is contained in:
@@ -364,7 +364,6 @@ class DirectObjectAccess(object):
|
||||
yield builtins
|
||||
else:
|
||||
try:
|
||||
# TODO use sys.modules, __module__ can be faked.
|
||||
yield sys.modules[imp_plz]
|
||||
except KeyError:
|
||||
# __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.cache import evaluator_function_cache
|
||||
from jedi.evaluate.helpers import reraise_getitem_errors, execute_evaluated
|
||||
from . import fake
|
||||
|
||||
|
||||
class CheckAttribute(object):
|
||||
@@ -47,11 +46,9 @@ class CheckAttribute(object):
|
||||
|
||||
|
||||
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)
|
||||
self.access_handle = access_handle
|
||||
# This attribute will not be set for most classes, except for fakes.
|
||||
self.tree_node = faked_class
|
||||
|
||||
@CheckAttribute()
|
||||
def py__call__(self, arguments):
|
||||
@@ -448,44 +445,30 @@ def _parse_function_doc(doc):
|
||||
|
||||
|
||||
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)
|
||||
parent_context = compiled_object
|
||||
if parent_context.is_class():
|
||||
parent_context = parent_context.parent_context
|
||||
return create_cached_compiled_object(
|
||||
evaluator, access, parent_context=parent_context, faked=faked
|
||||
evaluator, access, parent_context=parent_context
|
||||
)
|
||||
|
||||
|
||||
def _normalize_create_args(func):
|
||||
"""The cache doesn't care about keyword vs. normal args."""
|
||||
def wrapper(evaluator, obj, parent_context=None, faked=None):
|
||||
return func(evaluator, obj, parent_context, faked)
|
||||
def wrapper(evaluator, obj, parent_context=None):
|
||||
return func(evaluator, obj, parent_context)
|
||||
return wrapper
|
||||
|
||||
|
||||
def create_from_access_path(evaluator, access_path):
|
||||
parent_context = None
|
||||
for name, access in access_path.accesses:
|
||||
try:
|
||||
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)
|
||||
parent_context = create_cached_compiled_object(evaluator, access, parent_context)
|
||||
return parent_context
|
||||
|
||||
|
||||
@_normalize_create_args
|
||||
@evaluator_function_cache()
|
||||
def create_cached_compiled_object(evaluator, access_handle, parent_context, faked):
|
||||
return CompiledObject(evaluator, access_handle, parent_context, faked)
|
||||
def create_cached_compiled_object(evaluator, access_handle, parent_context):
|
||||
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().
|
||||
This is definitely a hack, but a good one :-)
|
||||
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):
|
||||
self.instance = instance
|
||||
|
||||
@@ -136,10 +136,6 @@ def builtins_property(objects, types, obj, arguments):
|
||||
|
||||
@argument_clinic('iterator[, default], /', want_evaluator=True)
|
||||
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:
|
||||
name = 'next'
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user