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__`
- support for list.append, set.add, list.extend, etc.
- (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
they are on my todo list):
- function annotations (py3k feature)
- class decorators (py3k feature)
- getattr() / __getattr__ / __getattribute__
- sys.path modifications

View File

@@ -13,7 +13,6 @@ TODO evaluate asserts/isinstance (type safety)
python 3 stuff:
TODO class decorators
TODO annotations ? how ? type evaluation and return?
TODO nonlocal statement, needed or can be ignored?
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.
:type docstr: str
"""
def __init__(self, name, params, start_pos, docstr=''):
Scope.__init__(self, start_pos, docstr)
def __init__(self, name, params, start_pos, annotation):
Scope.__init__(self, start_pos)
self.name = name
name.parent = weakref.ref(self)
self.params = params
@@ -348,6 +348,10 @@ class Function(Scope):
self.is_generator = False
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=" "):
str = "\n".join('@' + stmt.get_code() for stmt in self.decorators)
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...)
self.position_nr = None
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):
""" get the name of the param """
@@ -1162,12 +1171,18 @@ class PyFuzzyParser(object):
names = []
tok = None
pos = 0
breaks = [',', ':']
while tok not in [')', ':']:
stmt, tok = self._parse_statement(added_breaks=',',
param, tok = self._parse_statement(added_breaks=breaks,
stmt_class=Param)
if stmt:
stmt.position_nr = pos
names.append(stmt)
if param and tok == ':':
# parse annotations
annotation, tok = self._parse_statement(added_breaks=breaks)
param.add_annotation(annotation)
if param:
param.position_nr = pos
names.append(param)
pos += 1
return names
@@ -1193,10 +1208,20 @@ class PyFuzzyParser(object):
params = self._parseparen()
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 != ':':
return None
return Function(fname, params, first_pos)
return Function(fname, params, first_pos, annotation)
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('')[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('')