mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 22:14:27 +08:00
Make sure that typeddict py__getitem__ works
This commit is contained in:
@@ -389,7 +389,13 @@ class TypedDict(LazyValueWrapper):
|
||||
return ValueName(self, self.tree_node.name)
|
||||
|
||||
def py__simple_getitem__(self, index):
|
||||
return ValueSet({self.inference_state.builtins_module})
|
||||
if isinstance(index, str):
|
||||
return ValueSet.from_sets(
|
||||
name.infer()
|
||||
for filter in self._definition_class.get_filters(is_instance=True)
|
||||
for name in filter.get(index)
|
||||
)
|
||||
return NO_VALUES
|
||||
|
||||
def get_key_values(self):
|
||||
from jedi.inference.compiled import create_simple_object
|
||||
|
||||
@@ -547,10 +547,10 @@ class InstanceClassFilter(AbstractFilter):
|
||||
self._class_filter = class_filter
|
||||
|
||||
def get(self, name):
|
||||
return self._convert(self._class_filter.get(name, from_instance=True))
|
||||
return self._convert(self._class_filter.get(name))
|
||||
|
||||
def values(self):
|
||||
return self._convert(self._class_filter.values(from_instance=True))
|
||||
return self._convert(self._class_filter.values())
|
||||
|
||||
def _convert(self, names):
|
||||
return [
|
||||
@@ -586,7 +586,7 @@ class SelfAttributeFilter(ClassFilter):
|
||||
if trailer.type == 'trailer' \
|
||||
and len(trailer.parent.children) == 2 \
|
||||
and trailer.children[0] == '.':
|
||||
if name.is_definition() and self._access_possible(name, from_instance=True):
|
||||
if name.is_definition() and self._access_possible(name):
|
||||
# TODO filter non-self assignments instead of this bad
|
||||
# filter.
|
||||
if self._is_in_right_scope(trailer.parent.children[0], name):
|
||||
|
||||
@@ -104,12 +104,12 @@ class ClassFilter(ParserTreeFilter):
|
||||
node = get_cached_parent_scope(self._used_names, node)
|
||||
return False
|
||||
|
||||
def _access_possible(self, name, from_instance=False):
|
||||
def _access_possible(self, name):
|
||||
# Filter for ClassVar variables
|
||||
# TODO this is not properly done, yet. It just checks for the string
|
||||
# ClassVar in the annotation, which can be quite imprecise. If we
|
||||
# wanted to do this correct, we would have to infer the ClassVar.
|
||||
if not from_instance:
|
||||
if not self._is_instance:
|
||||
expr_stmt = name.get_definition()
|
||||
if expr_stmt is not None and expr_stmt.type == 'expr_stmt':
|
||||
annassign = expr_stmt.children[1]
|
||||
@@ -122,9 +122,9 @@ class ClassFilter(ParserTreeFilter):
|
||||
return not name.value.startswith('__') or name.value.endswith('__') \
|
||||
or self._equals_origin_scope()
|
||||
|
||||
def _filter(self, names, from_instance=False):
|
||||
def _filter(self, names):
|
||||
names = super(ClassFilter, self)._filter(names)
|
||||
return [name for name in names if self._access_possible(name, from_instance)]
|
||||
return [name for name in names if self._access_possible(name)]
|
||||
|
||||
|
||||
class ClassMixin(object):
|
||||
@@ -270,6 +270,7 @@ class ClassValue(use_metaclass(CachedMetaClass, ClassMixin, FunctionAndClassBase
|
||||
self.inference_state.builtins_module.py__getattribute__('object')
|
||||
)]
|
||||
|
||||
@inference_state_method_cache(default=False)
|
||||
def is_typeddict(self):
|
||||
# TODO Do a proper mro resolution. Currently we are just listing
|
||||
# classes. However, it's a complicated algorithm.
|
||||
|
||||
@@ -508,7 +508,7 @@ dynamic_annotation('')
|
||||
|
||||
class Foo(typing.TypedDict):
|
||||
foo: str
|
||||
bar: List[int]
|
||||
bar: typing.List[float]
|
||||
foo
|
||||
#! ['foo: str']
|
||||
foo
|
||||
@@ -519,7 +519,7 @@ class Foo(typing.TypedDict):
|
||||
d: Foo
|
||||
#? str()
|
||||
d['foo']
|
||||
#? str()
|
||||
#? float()
|
||||
d['bar'][0]
|
||||
#?
|
||||
d['baz']
|
||||
|
||||
Reference in New Issue
Block a user