Buckets:
MisterAI/LocalAI_Demo_backends / cpu-diffusers.upgrade-tmp /venv /lib /python3.10 /site-packages /jedi /inference /context.py
| from abc import abstractmethod | |
| from contextlib import contextmanager | |
| from pathlib import Path | |
| from typing import Optional, Any | |
| from parso.python.tree import Name | |
| from jedi.inference.filters import ParserTreeFilter, MergedFilter, \ | |
| GlobalNameFilter | |
| from jedi.inference.names import AnonymousParamName, TreeNameDefinition | |
| from jedi.inference.base_value import NO_VALUES, ValueSet | |
| from jedi.parser_utils import get_parent_scope | |
| from jedi import debug | |
| from jedi import parser_utils | |
| class AbstractContext: | |
| # Must be defined: inference_state and tree_node and parent_context as an attribute/property | |
| tree_node: Any | |
| parent_context: Any | |
| def __init__(self, inference_state): | |
| self.inference_state = inference_state | |
| self.predefined_names = {} | |
| def get_filters(self, until_position=None, origin_scope=None): | |
| raise NotImplementedError | |
| def goto(self, name_or_str, position): | |
| from jedi.inference import finder | |
| filters = _get_global_filters_for_name( | |
| self, name_or_str if isinstance(name_or_str, Name) else None, position, | |
| ) | |
| names = finder.filter_name(filters, name_or_str) | |
| debug.dbg('context.goto %s in (%s): %s', name_or_str, self, names) | |
| return names | |
| def py__getattribute__(self, name_or_str, name_context=None, position=None, | |
| analysis_errors=True): | |
| """ | |
| :param position: Position of the last statement -> tuple of line, column | |
| """ | |
| if name_context is None: | |
| name_context = self | |
| names = self.goto(name_or_str, position) | |
| string_name = name_or_str.value if isinstance(name_or_str, Name) else name_or_str | |
| # This paragraph is currently needed for proper branch type inference | |
| # (static analysis). | |
| found_predefined_types = None | |
| if self.predefined_names and isinstance(name_or_str, Name): | |
| node = name_or_str | |
| while node is not None and not parser_utils.is_scope(node): | |
| node = node.parent | |
| if node.type in ("if_stmt", "for_stmt", "comp_for", 'sync_comp_for'): | |
| try: | |
| name_dict = self.predefined_names[node] | |
| types = name_dict[string_name] | |
| except KeyError: | |
| continue | |
| else: | |
| found_predefined_types = types | |
| break | |
| if found_predefined_types is not None and names: | |
| from jedi.inference import flow_analysis | |
| check = flow_analysis.reachability_check( | |
| context=self, | |
| value_scope=self.tree_node, | |
| node=name_or_str, | |
| ) | |
| if check is flow_analysis.UNREACHABLE: | |
| values = NO_VALUES | |
| else: | |
| values = found_predefined_types | |
| else: | |
| values = ValueSet.from_sets(name.infer() for name in names) | |
| if not names and not values and analysis_errors: | |
| if isinstance(name_or_str, Name): | |
| from jedi.inference import analysis | |
| message = ("NameError: name '%s' is not defined." % string_name) | |
| analysis.add(name_context, 'name-error', name_or_str, message) | |
| debug.dbg('context.names_to_types: %s -> %s', names, values) | |
| if values: | |
| return values | |
| return self._check_for_additional_knowledge(name_or_str, name_context, position) | |
| def _check_for_additional_knowledge(self, name_or_str, name_context, position): | |
| name_context = name_context or self | |
| # Add isinstance and other if/assert knowledge. | |
| if isinstance(name_or_str, Name) and not name_context.is_instance(): | |
| flow_scope = name_or_str | |
| base_nodes = [name_context.tree_node] | |
| if any(b.type in ('comp_for', 'sync_comp_for') for b in base_nodes): | |
| return NO_VALUES | |
| from jedi.inference.finder import check_flow_information | |
| while True: | |
| flow_scope = get_parent_scope(flow_scope, include_flows=True) | |
| n = check_flow_information(name_context, flow_scope, | |
| name_or_str, position) | |
| if n is not None: | |
| return n | |
| if flow_scope in base_nodes: | |
| break | |
| return NO_VALUES | |
| def get_root_context(self): | |
| parent_context = self.parent_context | |
| if parent_context is None: | |
| return self | |
| return parent_context.get_root_context() | |
| def is_module(self): | |
| return False | |
| def is_builtins_module(self): | |
| return False | |
| def is_class(self): | |
| return False | |
| def is_stub(self): | |
| return False | |
| def is_instance(self): | |
| return False | |
| def is_compiled(self): | |
| return False | |
| def is_bound_method(self): | |
| return False | |
| def py__name__(self): | |
| raise NotImplementedError | |
| def get_value(self): | |
| raise NotImplementedError | |
| def name(self): | |
| return None | |
| def get_qualified_names(self): | |
| return () | |
| def py__doc__(self): | |
| return '' | |
| def predefine_names(self, flow_scope, dct): | |
| predefined = self.predefined_names | |
| predefined[flow_scope] = dct | |
| try: | |
| yield | |
| finally: | |
| del predefined[flow_scope] | |
| class ValueContext(AbstractContext): | |
| """ | |
| Should be defined, otherwise the API returns empty types. | |
| """ | |
| def __init__(self, value): | |
| super().__init__(value.inference_state) | |
| self._value = value | |
| def tree_node(self): | |
| return self._value.tree_node | |
| def parent_context(self): | |
| return self._value.parent_context | |
| def is_module(self): | |
| return self._value.is_module() | |
| def is_builtins_module(self): | |
| return self._value == self.inference_state.builtins_module | |
| def is_class(self): | |
| return self._value.is_class() | |
| def is_stub(self): | |
| return self._value.is_stub() | |
| def is_instance(self): | |
| return self._value.is_instance() | |
| def is_compiled(self): | |
| return self._value.is_compiled() | |
| def is_bound_method(self): | |
| return self._value.is_bound_method() | |
| def py__name__(self): | |
| return self._value.py__name__() | |
| def name(self): | |
| return self._value.name | |
| def get_qualified_names(self): | |
| return self._value.get_qualified_names() | |
| def py__doc__(self): | |
| return self._value.py__doc__() | |
| def get_value(self): | |
| return self._value | |
| def __repr__(self): | |
| return '%s(%s)' % (self.__class__.__name__, self._value) | |
| class TreeContextMixin: | |
| tree_node: Any | |
| is_module: Any | |
| get_value: Any | |
| inference_state: Any | |
| is_class: Any | |
| parent_context: Any | |
| def infer_node(self, node): | |
| from jedi.inference.syntax_tree import infer_node | |
| return infer_node(self, node) | |
| def create_value(self, node): | |
| from jedi.inference import value | |
| if node == self.tree_node: | |
| assert self.is_module() | |
| return self.get_value() | |
| parent_context = self.create_context(node) | |
| if node.type in ('funcdef', 'lambdef'): | |
| func = value.FunctionValue.from_context(parent_context, node) | |
| if parent_context.is_class(): | |
| class_value = parent_context.parent_context.create_value(parent_context.tree_node) | |
| instance = value.AnonymousInstance( | |
| self.inference_state, parent_context.parent_context, class_value) | |
| func = value.BoundMethod( | |
| instance=instance, | |
| class_context=class_value.as_context(), | |
| function=func | |
| ) | |
| return func | |
| elif node.type == 'classdef': | |
| return value.ClassValue(self.inference_state, parent_context, node) | |
| else: | |
| raise NotImplementedError("Probably shouldn't happen: %s" % node) | |
| def create_context(self, node): | |
| def from_scope_node(scope_node, is_nested=True): | |
| if scope_node == self.tree_node: | |
| return self | |
| if scope_node.type in ('funcdef', 'lambdef', 'classdef'): | |
| return self.create_value(scope_node).as_context() | |
| elif scope_node.type in ('comp_for', 'sync_comp_for'): | |
| parent_context = from_scope_node(parent_scope(scope_node.parent)) | |
| if node.start_pos >= scope_node.children[-1].start_pos: | |
| return parent_context | |
| return CompForContext(parent_context, scope_node) | |
| raise Exception("There's a scope that was not managed: %s" % scope_node) | |
| def parent_scope(node): | |
| while True: | |
| node = node.parent | |
| if parser_utils.is_scope(node): | |
| return node | |
| elif node.type in ('argument', 'testlist_comp'): | |
| if node.children[1].type in ('comp_for', 'sync_comp_for'): | |
| return node.children[1] | |
| elif node.type == 'dictorsetmaker': | |
| for n in node.children[1:4]: | |
| # In dictionaries it can be pretty much anything. | |
| if n.type in ('comp_for', 'sync_comp_for'): | |
| return n | |
| scope_node = parent_scope(node) | |
| if scope_node.type in ('funcdef', 'classdef'): | |
| colon = scope_node.children[scope_node.children.index(':')] | |
| if node.start_pos < colon.start_pos: | |
| parent = node.parent | |
| if not (parent.type == 'param' and parent.name == node): | |
| scope_node = parent_scope(scope_node) | |
| return from_scope_node(scope_node, is_nested=True) | |
| def create_name(self, tree_name): | |
| definition = tree_name.get_definition() | |
| if definition and definition.type == 'param' and definition.name == tree_name: | |
| funcdef = definition.search_ancestor('funcdef', 'lambdef') | |
| func = self.create_value(funcdef) | |
| return AnonymousParamName(func, tree_name) | |
| else: | |
| context = self.create_context(tree_name) | |
| return TreeNameDefinition(context, tree_name) | |
| class FunctionContext(TreeContextMixin, ValueContext): | |
| def get_filters(self, until_position=None, origin_scope=None): | |
| yield ParserTreeFilter( | |
| parent_context=self, | |
| until_position=until_position, | |
| origin_scope=origin_scope | |
| ) | |
| class ModuleContext(TreeContextMixin, ValueContext): | |
| def py__file__(self) -> Optional[Path]: | |
| return self._value.py__file__() # type: ignore[no-any-return] | |
| def get_filters(self, until_position=None, origin_scope=None): | |
| filters = self._value.get_filters(origin_scope) | |
| # Skip the first filter and replace it. | |
| next(filters, None) | |
| yield MergedFilter( | |
| ParserTreeFilter( | |
| parent_context=self, | |
| until_position=until_position, | |
| origin_scope=origin_scope | |
| ), | |
| self.get_global_filter(), | |
| ) | |
| yield from filters | |
| def get_global_filter(self): | |
| return GlobalNameFilter(self) | |
| def string_names(self): | |
| return self._value.string_names | |
| def code_lines(self): | |
| return self._value.code_lines | |
| def get_value(self): | |
| """ | |
| This is the only function that converts a context back to a value. | |
| This is necessary for stub -> python conversion and vice versa. However | |
| this method shouldn't be moved to AbstractContext. | |
| """ | |
| return self._value | |
| class NamespaceContext(TreeContextMixin, ValueContext): | |
| def get_filters(self, until_position=None, origin_scope=None): | |
| return self._value.get_filters() | |
| def get_value(self): | |
| return self._value | |
| def string_names(self): | |
| return self._value.string_names | |
| def py__file__(self) -> Optional[Path]: | |
| return self._value.py__file__() # type: ignore[no-any-return] | |
| class ClassContext(TreeContextMixin, ValueContext): | |
| def get_filters(self, until_position=None, origin_scope=None): | |
| yield self.get_global_filter(until_position, origin_scope) | |
| def get_global_filter(self, until_position=None, origin_scope=None): | |
| return ParserTreeFilter( | |
| parent_context=self, | |
| until_position=until_position, | |
| origin_scope=origin_scope | |
| ) | |
| class CompForContext(TreeContextMixin, AbstractContext): | |
| def __init__(self, parent_context, comp_for): | |
| super().__init__(parent_context.inference_state) | |
| self.tree_node = comp_for | |
| self.parent_context = parent_context | |
| def get_filters(self, until_position=None, origin_scope=None): | |
| yield ParserTreeFilter(self) | |
| def get_value(self): | |
| return None | |
| def py__name__(self): | |
| return '<comprehension context>' | |
| def __repr__(self): | |
| return '%s(%s)' % (self.__class__.__name__, self.tree_node) | |
| class CompiledContext(ValueContext): | |
| def get_filters(self, until_position=None, origin_scope=None): | |
| return self._value.get_filters() | |
| class CompiledModuleContext(CompiledContext): | |
| code_lines = None | |
| def get_value(self): | |
| return self._value | |
| def string_names(self): | |
| return self._value.string_names | |
| def py__file__(self) -> Optional[Path]: | |
| return self._value.py__file__() # type: ignore[no-any-return] | |
| def _get_global_filters_for_name(context, name_or_none, position): | |
| # For functions and classes the defaults don't belong to the | |
| # function and get inferred in the value before the function. So | |
| # make sure to exclude the function/class name. | |
| if name_or_none is not None: | |
| ancestor = name_or_none.search_ancestor('funcdef', 'classdef', 'lambdef') | |
| lambdef = None | |
| if ancestor == 'lambdef': | |
| # For lambdas it's even more complicated since parts will | |
| # be inferred later. | |
| lambdef = ancestor | |
| ancestor = name_or_none.search_ancestor('funcdef', 'classdef') | |
| if ancestor is not None: | |
| colon = ancestor.children[-2] | |
| if position is not None and position < colon.start_pos: | |
| if lambdef is None or position < lambdef.children[-2].start_pos: | |
| position = ancestor.start_pos | |
| return get_global_filters(context, position, name_or_none) | |
| def get_global_filters(context, until_position, origin_scope): | |
| """ | |
| Returns all filters in order of priority for name resolution. | |
| For global name lookups. The filters will handle name resolution | |
| themselves, but here we gather possible filters downwards. | |
| >>> from jedi import Script | |
| >>> script = Script(''' | |
| ... x = ['a', 'b', 'c'] | |
| ... def func(): | |
| ... y = None | |
| ... ''') | |
| >>> module_node = script._module_node | |
| >>> scope = next(module_node.iter_funcdefs()) | |
| >>> scope | |
| <Function: func@3-5> | |
| >>> context = script._get_module_context().create_context(scope) | |
| >>> filters = list(get_global_filters(context, (4, 0), None)) | |
| First we get the names from the function scope. | |
| >>> print(filters[0]) # doctest: +ELLIPSIS | |
| MergedFilter(<ParserTreeFilter: ...>, <GlobalNameFilter: ...>) | |
| >>> sorted(str(n) for n in filters[0].values()) # doctest: +NORMALIZE_WHITESPACE | |
| ['<TreeNameDefinition: string_name=func start_pos=(3, 4)>', | |
| '<TreeNameDefinition: string_name=x start_pos=(2, 0)>'] | |
| >>> filters[0]._filters[0]._until_position | |
| (4, 0) | |
| >>> filters[0]._filters[1]._until_position | |
| Then it yields the names from one level "lower". In this example, this is | |
| the module scope (including globals). | |
| As a side note, you can see, that the position in the filter is None on the | |
| globals filter, because there the whole module is searched. | |
| >>> list(filters[1].values()) # package modules -> Also empty. | |
| [] | |
| >>> sorted(name.string_name for name in filters[2].values()) # Module attributes | |
| ['__doc__', '__name__', '__package__'] | |
| Finally, it yields the builtin filter, if `include_builtin` is | |
| true (default). | |
| >>> list(filters[3].values()) # doctest: +ELLIPSIS | |
| [...] | |
| """ | |
| base_context = context | |
| from jedi.inference.value.function import BaseFunctionExecutionContext | |
| while context is not None: | |
| # Names in methods cannot be resolved within the class. | |
| yield from context.get_filters( | |
| until_position=until_position, | |
| origin_scope=origin_scope | |
| ) | |
| if isinstance(context, (BaseFunctionExecutionContext, ModuleContext)): | |
| # The position should be reset if the current scope is a function. | |
| until_position = None | |
| context = context.parent_context | |
| b = next(base_context.inference_state.builtins_module.get_filters(), None) | |
| assert b is not None | |
| # Add builtins to the global scope. | |
| yield b | |
Xet Storage Details
- Size:
- 17.3 kB
- Xet hash:
- 7d1839bfdd102ee9694ec4dccec8d32fb9ea23c7ef54e461a6c9514cfc252b69
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.