function annotations are now safely ignored by the evaluation. the parser just stores them in the right objects.

This commit is contained in:
David Halter
2012-09-02 12:39:11 +02:00
parent acd6488891
commit 1afdb69314
4 changed files with 51 additions and 9 deletions

View File

@@ -46,11 +46,12 @@ Jedi supports many of the widely used Python features:
`__get__`, `__getitem__`, `__init__` `__get__`, `__getitem__`, `__init__`
- support for list.append, set.add, list.extend, etc. - support for list.append, set.add, list.extend, etc.
- (nested) list comprehensions / ternary expressions - (nested) list comprehensions / ternary expressions
- function annotations (py3k feature, are ignored right now, but being parsed.
I don't know what to do with them.)
However, it does not yet support (and probably will in future versions, because However, it does not yet support (and probably will in future versions, because
they are on my todo list): they are on my todo list):
- function annotations (py3k feature)
- class decorators (py3k feature) - class decorators (py3k feature)
- getattr() / __getattr__ / __getattribute__ - getattr() / __getattr__ / __getattribute__
- sys.path modifications - sys.path modifications

View File

@@ -13,7 +13,6 @@ TODO evaluate asserts/isinstance (type safety)
python 3 stuff: python 3 stuff:
TODO class decorators TODO class decorators
TODO annotations ? how ? type evaluation and return?
TODO nonlocal statement, needed or can be ignored? TODO nonlocal statement, needed or can be ignored?
TODO __ instance attributes should not be visible outside of the class. TODO __ instance attributes should not be visible outside of the class.

View File

@@ -336,8 +336,8 @@ class Function(Scope):
:param docstr: The docstring for the current Scope. :param docstr: The docstring for the current Scope.
:type docstr: str :type docstr: str
""" """
def __init__(self, name, params, start_pos, docstr=''): def __init__(self, name, params, start_pos, annotation):
Scope.__init__(self, start_pos, docstr) Scope.__init__(self, start_pos)
self.name = name self.name = name
name.parent = weakref.ref(self) name.parent = weakref.ref(self)
self.params = params self.params = params
@@ -348,6 +348,10 @@ class Function(Scope):
self.is_generator = False self.is_generator = False
self.listeners = set() # not used here, but in evaluation. self.listeners = set() # not used here, but in evaluation.
if annotation is not None:
annotation.parent = weakref.ref(self)
self.annotation = annotation
def get_code(self, first_indent=False, indention=" "): def get_code(self, first_indent=False, indention=" "):
str = "\n".join('@' + stmt.get_code() for stmt in self.decorators) str = "\n".join('@' + stmt.get_code() for stmt in self.decorators)
params = ','.join([stmt.code for stmt in self.params]) params = ','.join([stmt.code for stmt in self.params])
@@ -790,6 +794,11 @@ class Param(Statement):
# it is the position in the call (first argument, second...) # it is the position in the call (first argument, second...)
self.position_nr = None self.position_nr = None
self.is_generated = False self.is_generated = False
self.annotation_stmt = None
def add_annotation(self, annotation_stmt):
annotation_stmt.parent = weakref.ref(self)
self.annotation_stmt = annotation_stmt
def get_name(self): def get_name(self):
""" get the name of the param """ """ get the name of the param """
@@ -1162,12 +1171,18 @@ class PyFuzzyParser(object):
names = [] names = []
tok = None tok = None
pos = 0 pos = 0
breaks = [',', ':']
while tok not in [')', ':']: while tok not in [')', ':']:
stmt, tok = self._parse_statement(added_breaks=',', param, tok = self._parse_statement(added_breaks=breaks,
stmt_class=Param) stmt_class=Param)
if stmt: if param and tok == ':':
stmt.position_nr = pos # parse annotations
names.append(stmt) annotation, tok = self._parse_statement(added_breaks=breaks)
param.add_annotation(annotation)
if param:
param.position_nr = pos
names.append(param)
pos += 1 pos += 1
return names return names
@@ -1193,10 +1208,20 @@ class PyFuzzyParser(object):
params = self._parseparen() params = self._parseparen()
token_type, colon = self.next() token_type, colon = self.next()
annotation = None
if colon in ['-', '->']:
# parse annotations
if colon == '-':
# The Python 2 tokenizer doesn't understand this
token_type, colon = self.next()
if colon != '>':
return None
annotation, colon = self._parse_statement(added_breaks=[':'])
if colon != ':': if colon != ':':
return None return None
return Function(fname, params, first_pos) return Function(fname, params, first_pos, annotation)
def _parseclass(self): def _parseclass(self):
""" """

View File

@@ -320,3 +320,20 @@ nested_def2('', b=1, c=1.0)[1]
nested_def2('', c=1.0, b=1)[1] nested_def2('', c=1.0, b=1)[1]
#? [] #? []
nested_def2('')[1] nested_def2('')[1]
# -----------------
# function annotations (should be ignored at the moment)
# -----------------
def annot(a:3, *args:3):
return a, args[0]
#? str()
annot('', 1.0)[0]
#? float()
annot('', 1.0)[1]
def annot_ret(a:3) -> 3:
return a
#? str()
annot_ret('')