[pypy-commit] pypy py3.6: Merged in alcarithemad/pypy/pep526 (pull request #595)

2018-03-01 Thread arigo
Author: Armin Rigo 
Branch: py3.6
Changeset: r93928:552eccd54e83
Date: 2018-03-01 10:06 +
http://bitbucket.org/pypy/pypy/changeset/552eccd54e83/

Log:Merged in alcarithemad/pypy/pep526 (pull request #595)

PEP 526: Type annotations for variables

Approved-by: Armin Rigo  Approved-by: Amaury
Forgeot d'Arc 

diff --git a/lib-python/3/opcode.py b/lib-python/3/opcode.py
--- a/lib-python/3/opcode.py
+++ b/lib-python/3/opcode.py
@@ -121,7 +121,7 @@
 
 def_op('RETURN_VALUE', 83)
 def_op('IMPORT_STAR', 84)
-
+def_op('SETUP_ANNOTATIONS', 85)
 def_op('YIELD_VALUE', 86)
 def_op('POP_BLOCK', 87)
 def_op('END_FINALLY', 88)
@@ -171,6 +171,7 @@
 haslocal.append(125)
 def_op('DELETE_FAST', 126)  # Local variable number
 haslocal.append(126)
+name_op('STORE_ANNOTATION', 127) # Index in name list
 
 def_op('RAISE_VARARGS', 130)# Number of raise arguments (1, 2, or 3)
 def_op('CALL_FUNCTION', 131)# #args + (#kwargs << 8)
diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py
--- a/pypy/interpreter/app_main.py
+++ b/pypy/interpreter/app_main.py
@@ -577,6 +577,7 @@
 mainmodule = type(sys)('__main__')
 mainmodule.__loader__ = sys.__loader__
 mainmodule.__builtins__ = os.__builtins__
+mainmodule.__annotations__ = {}
 sys.modules['__main__'] = mainmodule
 
 if not no_site:
diff --git a/pypy/interpreter/astcompiler/assemble.py 
b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -690,6 +690,9 @@
 ops.POP_JUMP_IF_FALSE: -1,
 ops.JUMP_IF_NOT_DEBUG: 0,
 
+ops.SETUP_ANNOTATIONS: 0,
+ops.STORE_ANNOTATION: -1,
+
 # TODO
 ops.BUILD_LIST_FROM_ARG: 1,
 
diff --git a/pypy/interpreter/astcompiler/ast.py 
b/pypy/interpreter/astcompiler/ast.py
--- a/pypy/interpreter/astcompiler/ast.py
+++ b/pypy/interpreter/astcompiler/ast.py
@@ -339,6 +339,8 @@
 return Assign.from_object(space, w_node)
 if space.isinstance_w(w_node, get(space).w_AugAssign):
 return AugAssign.from_object(space, w_node)
+if space.isinstance_w(w_node, get(space).w_AnnAssign):
+return AnnAssign.from_object(space, w_node)
 if space.isinstance_w(w_node, get(space).w_For):
 return For.from_object(space, w_node)
 if space.isinstance_w(w_node, get(space).w_AsyncFor):
@@ -816,6 +818,64 @@
 State.ast_type('AugAssign', 'stmt', ['target', 'op', 'value'])
 
 
+class AnnAssign(stmt):
+
+def __init__(self, target, annotation, value, simple, lineno, col_offset):
+self.target = target
+self.annotation = annotation
+self.value = value
+self.simple = simple
+stmt.__init__(self, lineno, col_offset)
+
+def walkabout(self, visitor):
+visitor.visit_AnnAssign(self)
+
+def mutate_over(self, visitor):
+self.target = self.target.mutate_over(visitor)
+self.annotation = self.annotation.mutate_over(visitor)
+if self.value:
+self.value = self.value.mutate_over(visitor)
+return visitor.visit_AnnAssign(self)
+
+def to_object(self, space):
+w_node = space.call_function(get(space).w_AnnAssign)
+w_target = self.target.to_object(space)  # expr
+space.setattr(w_node, space.newtext('target'), w_target)
+w_annotation = self.annotation.to_object(space)  # expr
+space.setattr(w_node, space.newtext('annotation'), w_annotation)
+w_value = self.value.to_object(space) if self.value is not None else 
space.w_None  # expr
+space.setattr(w_node, space.newtext('value'), w_value)
+w_simple = space.newint(self.simple)  # int
+space.setattr(w_node, space.newtext('simple'), w_simple)
+w_lineno = space.newint(self.lineno)  # int
+space.setattr(w_node, space.newtext('lineno'), w_lineno)
+w_col_offset = space.newint(self.col_offset)  # int
+space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
+return w_node
+
+@staticmethod
+def from_object(space, w_node):
+w_target = get_field(space, w_node, 'target', False)
+w_annotation = get_field(space, w_node, 'annotation', False)
+w_value = get_field(space, w_node, 'value', True)
+w_simple = get_field(space, w_node, 'simple', False)
+w_lineno = get_field(space, w_node, 'lineno', False)
+w_col_offset = get_field(space, w_node, 'col_offset', False)
+_target = expr.from_object(space, w_target)
+if _target is None:
+raise_required_value(space, w_node, 'target')
+_annotation = expr.from_object(space, w_annotation)
+if _annotation is None:
+raise_required_value(space, w_node, 'annotation')
+_value = expr.from_object(space, w_value)
+_simple = obj_to_int(space, w_simple)
+_lineno = obj_to_int(space, w_lineno)
+_col_offset = obj_to_int(space, w_col_offset)
+ 

[pypy-commit] pypy pep526: Update Python.asdl to 3.6.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93909:031ac5343b06
Date: 2018-02-12 23:28 -0800
http://bitbucket.org/pypy/pypy/changeset/031ac5343b06/

Log:Update Python.asdl to 3.6.

diff --git a/pypy/interpreter/astcompiler/tools/Python.asdl 
b/pypy/interpreter/astcompiler/tools/Python.asdl
--- a/pypy/interpreter/astcompiler/tools/Python.asdl
+++ b/pypy/interpreter/astcompiler/tools/Python.asdl
@@ -17,6 +17,7 @@
stmt* body, expr* decorator_list, expr? returns)
   | AsyncFunctionDef(identifier name, arguments args,
  stmt* body, expr* decorator_list, expr? returns)
+
   | ClassDef(identifier name,
  expr* bases,
  keyword* keywords,
@@ -27,6 +28,8 @@
   | Delete(expr* targets)
   | Assign(expr* targets, expr value)
   | AugAssign(expr target, operator op, expr value)
+  -- 'simple' indicates that we annotate simple name without parens
+  | AnnAssign(expr target, expr annotation, expr? value, int simple)
 
   -- use 'orelse' because else is a keyword in target languages
   | For(expr target, expr iter, stmt* body, stmt* orelse)
@@ -107,7 +110,7 @@
 
 cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn
 
-comprehension = (expr target, expr iter, expr* ifs)
+comprehension = (expr target, expr iter, expr* ifs, int is_async)
 
 excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)
 attributes (int lineno, int col_offset)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Make astbuilder produce AnnAssign nodes for variable annotations.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93914:61124ea0a2b7
Date: 2018-02-13 23:23 -0800
http://bitbucket.org/pypy/pypy/changeset/61124ea0a2b7/

Log:Make astbuilder produce AnnAssign nodes for variable annotations.

diff --git a/pypy/interpreter/astcompiler/astbuilder.py 
b/pypy/interpreter/astcompiler/astbuilder.py
--- a/pypy/interpreter/astcompiler/astbuilder.py
+++ b/pypy/interpreter/astcompiler/astbuilder.py
@@ -737,6 +737,7 @@
 raise AssertionError("unknown statment type")
 
 def handle_expr_stmt(self, stmt):
+from pypy.interpreter.pyparser.parser import AbstractNonterminal
 if stmt.num_children() == 1:
 expression = self.handle_testlist(stmt.get_child(0))
 return ast.Expr(expression, stmt.get_lineno(), stmt.get_column())
@@ -754,6 +755,44 @@
 operator = augassign_operator_map[op_str]
 return ast.AugAssign(target_expr, operator, value_expr,
  stmt.get_lineno(), stmt.get_column())
+elif stmt.get_child(1).type == syms.annassign:
+# Variable annotation (PEP 526), which may or may not include 
assignment.
+target = stmt.get_child(0)
+target_expr = self.handle_testlist(target)
+simple = 0
+# target is a name, nothing funky
+if isinstance(target_expr, ast.Name):
+# The PEP demands that `(x): T` be treated differently than 
`x: T`
+# however, the parser does not easily expose the wrapping 
parens, which are a no-op
+# they are elided by handle_testlist if they existed.
+# so here we walk down the parse tree until we hit a terminal, 
and check whether it's
+# a left paren
+simple_test = target.get_child(0)
+while isinstance(simple_test, AbstractNonterminal):
+simple_test = simple_test.get_child(0)
+if simple_test.type != tokens.LPAR:
+simple = 1
+# subscripts are allowed with nothing special
+elif isinstance(target_expr, ast.Subscript):
+pass
+# attributes are also fine here
+elif isinstance(target_expr, ast.Attribute):
+pass
+# tuples and lists get special error messages
+elif isinstance(target_expr, ast.Tuple):
+self.error("only single target (not tuple) can be annotated", 
target)
+elif isinstance(target_expr, ast.List):
+self.error("only single target (not list) can be annotated", 
target)
+# and everything else gets a generic error
+else:
+self.error("illegal target for annoation", target)
+self.set_context(target_expr, ast.Store)
+second = stmt.get_child(1)
+annotation = self.handle_expr(second.get_child(1))
+value_expr = None
+if second.num_children() == 4:
+value_expr = self.handle_testlist(second.get_child(-1))
+return ast.AnnAssign(target_expr, annotation, value_expr, simple, 
stmt.get_lineno(), stmt.get_column())
 else:
 # Normal assignment.
 targets = []
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Add test for parsing variable annotations.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93912:27758040aaa8
Date: 2018-02-13 23:21 -0800
http://bitbucket.org/pypy/pypy/changeset/27758040aaa8/

Log:Add test for parsing variable annotations.

diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py 
b/pypy/interpreter/astcompiler/test/test_astbuilder.py
--- a/pypy/interpreter/astcompiler/test/test_astbuilder.py
+++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py
@@ -614,6 +614,44 @@
 assert len(dec.args) == 2
 assert dec.keywords is None
 
+def test_annassign(self):
+simple = self.get_first_stmt('a: int')
+assert isinstance(simple, ast.AnnAssign)
+assert isinstance(simple.target, ast.Name)
+assert simple.target.ctx == ast.Store
+assert isinstance(simple.annotation, ast.Name)
+assert simple.value == None
+assert simple.simple == 1
+
+with_value = self.get_first_stmt('x: str = "test"')
+assert isinstance(with_value, ast.AnnAssign)
+assert isinstance(with_value.value, ast.Str)
+assert self.space.eq_w(with_value.value.s, self.space.wrap("test"))
+
+not_simple = self.get_first_stmt('(a): int')
+assert isinstance(not_simple, ast.AnnAssign)
+assert isinstance(not_simple.target, ast.Name)
+assert not_simple.target.ctx == ast.Store
+assert not_simple.simple == 0
+
+attrs = self.get_first_stmt('a.b.c: int')
+assert isinstance(attrs, ast.AnnAssign)
+assert isinstance(attrs.target, ast.Attribute)
+
+subscript = self.get_first_stmt('a[0:2]: int')
+assert isinstance(subscript, ast.AnnAssign)
+assert isinstance(subscript.target, ast.Subscript)
+
+exc_tuple = py.test.raises(SyntaxError, self.get_ast, 'a, b: 
int').value
+assert exc_tuple.msg == "only single target (not tuple) can be 
annotated"
+
+exc_list = py.test.raises(SyntaxError, self.get_ast, '[]: int').value
+assert exc_list.msg == "only single target (not list) can be annotated"
+
+exc_bad_target = py.test.raises(SyntaxError, self.get_ast, '{}: 
int').value
+assert exc_bad_target.msg == "illegal target for annoation"
+
+
 def test_augassign(self):
 aug_assigns = (
 ("+=", ast.Add),
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Update ast.py, generated from Python.asdl.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93913:8cf248660bb4
Date: 2018-02-13 23:22 -0800
http://bitbucket.org/pypy/pypy/changeset/8cf248660bb4/

Log:Update ast.py, generated from Python.asdl.

diff --git a/pypy/interpreter/astcompiler/ast.py 
b/pypy/interpreter/astcompiler/ast.py
--- a/pypy/interpreter/astcompiler/ast.py
+++ b/pypy/interpreter/astcompiler/ast.py
@@ -339,6 +339,8 @@
 return Assign.from_object(space, w_node)
 if space.isinstance_w(w_node, get(space).w_AugAssign):
 return AugAssign.from_object(space, w_node)
+if space.isinstance_w(w_node, get(space).w_AnnAssign):
+return AnnAssign.from_object(space, w_node)
 if space.isinstance_w(w_node, get(space).w_For):
 return For.from_object(space, w_node)
 if space.isinstance_w(w_node, get(space).w_AsyncFor):
@@ -816,6 +818,64 @@
 State.ast_type('AugAssign', 'stmt', ['target', 'op', 'value'])
 
 
+class AnnAssign(stmt):
+
+def __init__(self, target, annotation, value, simple, lineno, col_offset):
+self.target = target
+self.annotation = annotation
+self.value = value
+self.simple = simple
+stmt.__init__(self, lineno, col_offset)
+
+def walkabout(self, visitor):
+visitor.visit_AnnAssign(self)
+
+def mutate_over(self, visitor):
+self.target = self.target.mutate_over(visitor)
+self.annotation = self.annotation.mutate_over(visitor)
+if self.value:
+self.value = self.value.mutate_over(visitor)
+return visitor.visit_AnnAssign(self)
+
+def to_object(self, space):
+w_node = space.call_function(get(space).w_AnnAssign)
+w_target = self.target.to_object(space)  # expr
+space.setattr(w_node, space.newtext('target'), w_target)
+w_annotation = self.annotation.to_object(space)  # expr
+space.setattr(w_node, space.newtext('annotation'), w_annotation)
+w_value = self.value.to_object(space) if self.value is not None else 
space.w_None  # expr
+space.setattr(w_node, space.newtext('value'), w_value)
+w_simple = space.newint(self.simple)  # int
+space.setattr(w_node, space.newtext('simple'), w_simple)
+w_lineno = space.newint(self.lineno)  # int
+space.setattr(w_node, space.newtext('lineno'), w_lineno)
+w_col_offset = space.newint(self.col_offset)  # int
+space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
+return w_node
+
+@staticmethod
+def from_object(space, w_node):
+w_target = get_field(space, w_node, 'target', False)
+w_annotation = get_field(space, w_node, 'annotation', False)
+w_value = get_field(space, w_node, 'value', True)
+w_simple = get_field(space, w_node, 'simple', False)
+w_lineno = get_field(space, w_node, 'lineno', False)
+w_col_offset = get_field(space, w_node, 'col_offset', False)
+_target = expr.from_object(space, w_target)
+if _target is None:
+raise_required_value(space, w_node, 'target')
+_annotation = expr.from_object(space, w_annotation)
+if _annotation is None:
+raise_required_value(space, w_node, 'annotation')
+_value = expr.from_object(space, w_value)
+_simple = obj_to_int(space, w_simple)
+_lineno = obj_to_int(space, w_lineno)
+_col_offset = obj_to_int(space, w_col_offset)
+return AnnAssign(_target, _annotation, _value, _simple, _lineno, 
_col_offset)
+
+State.ast_type('AnnAssign', 'stmt', ['target', 'annotation', 'value', 
'simple'])
+
+
 class For(stmt):
 
 def __init__(self, target, iter, body, orelse, lineno, col_offset):
@@ -3673,10 +3733,11 @@
 
 class comprehension(AST):
 
-def __init__(self, target, iter, ifs):
+def __init__(self, target, iter, ifs, is_async):
 self.target = target
 self.iter = iter
 self.ifs = ifs
+self.is_async = is_async
 
 def mutate_over(self, visitor):
 self.target = self.target.mutate_over(visitor)
@@ -3702,6 +3763,8 @@
 ifs_w = [node.to_object(space) for node in self.ifs] # expr
 w_ifs = space.newlist(ifs_w)
 space.setattr(w_node, space.newtext('ifs'), w_ifs)
+w_is_async = space.newint(self.is_async)  # int
+space.setattr(w_node, space.newtext('is_async'), w_is_async)
 return w_node
 
 @staticmethod
@@ -3709,6 +3772,7 @@
 w_target = get_field(space, w_node, 'target', False)
 w_iter = get_field(space, w_node, 'iter', False)
 w_ifs = get_field(space, w_node, 'ifs', False)
+w_is_async = get_field(space, w_node, 'is_async', False)
 _target = expr.from_object(space, w_target)
 if _target is None:
 raise_required_value(space, w_node, 'target')
@@ -3717,9 +3781,10 @@
 raise_required_value(space, w_node, 'iter')
 ifs_w = space.unpackiterable(w_ifs)
 _ifs

[pypy-commit] pypy pep526: Add another symtable test to ensure proper scoping of non-Name targets.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93919:7a50e0c20060
Date: 2018-02-14 22:04 -0800
http://bitbucket.org/pypy/pypy/changeset/7a50e0c20060/

Log:Add another symtable test to ensure proper scoping of non-Name
targets.

diff --git a/pypy/interpreter/astcompiler/test/test_symtable.py 
b/pypy/interpreter/astcompiler/test/test_symtable.py
--- a/pypy/interpreter/astcompiler/test/test_symtable.py
+++ b/pypy/interpreter/astcompiler/test/test_symtable.py
@@ -513,6 +513,9 @@
 assert fscp.contains_annotated == False
 assert fscp.lookup("x") == symtable.SCOPE_LOCAL
 
+def test_nonsimple_annotation(self):
+fscp = self.func_scope("def f(): implicit_global[0]: int")
+assert fscp.lookup("implicit_global") == symtable.SCOPE_GLOBAL_IMPLICIT
 
 def test_issue13343(self):
 scp = self.mod_scope("lambda *, k1=x, k2: None")
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Add minimal update to comprehensions to produce valid AST nodes for new asdl.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93910:89c267ae1715
Date: 2018-02-12 23:29 -0800
http://bitbucket.org/pypy/pypy/changeset/89c267ae1715/

Log:Add minimal update to comprehensions to produce valid AST nodes for
new asdl.

diff --git a/pypy/interpreter/astcompiler/astbuilder.py 
b/pypy/interpreter/astcompiler/astbuilder.py
--- a/pypy/interpreter/astcompiler/astbuilder.py
+++ b/pypy/interpreter/astcompiler/astbuilder.py
@@ -1315,7 +1315,8 @@
 expr = self.handle_expr(comp_node.get_child(3))
 assert isinstance(expr, ast.expr)
 if for_node.num_children() == 1:
-comp = ast.comprehension(for_targets[0], expr, None)
+# FIXME: determine whether this is actually async
+comp = ast.comprehension(for_targets[0], expr, None, 0)
 else:
 # Modified in python2.7, see http://bugs.python.org/issue6704
 # Fixing unamed tuple location
@@ -1324,7 +1325,8 @@
 col = expr_node.col_offset
 line = expr_node.lineno
 target = ast.Tuple(for_targets, ast.Store, line, col)
-comp = ast.comprehension(target, expr, None)
+# FIXME: determine whether this is actually async
+comp = ast.comprehension(target, expr, None, 0)
 if comp_node.num_children() == 5:
 comp_node = comp_iter = comp_node.get_child(4)
 assert comp_iter.type == syms.comp_iter
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Update grammer to 3.6

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93908:8a37c2a3ef7c
Date: 2018-02-10 14:40 -0800
http://bitbucket.org/pypy/pypy/changeset/8a37c2a3ef7c/

Log:Update grammer to 3.6

diff --git a/pypy/interpreter/pyparser/data/Grammar3.6 
b/pypy/interpreter/pyparser/data/Grammar3.6
new file mode 100644
--- /dev/null
+++ b/pypy/interpreter/pyparser/data/Grammar3.6
@@ -0,0 +1,149 @@
+# Grammar for Python
+
+# NOTE WELL: You should also follow all the steps listed at
+# https://devguide.python.org/grammar/
+
+# Start symbols for the grammar:
+#   single_input is a single interactive statement;
+#   file_input is a module or sequence of commands read from an input file;
+#   eval_input is the input for the eval() functions.
+# NB: compound_stmt in single_input is followed by extra NEWLINE!
+single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
+file_input: (NEWLINE | stmt)* ENDMARKER
+eval_input: testlist NEWLINE* ENDMARKER
+
+decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+decorators: decorator+
+decorated: decorators (classdef | funcdef | async_funcdef)
+
+async_funcdef: ASYNC funcdef
+funcdef: 'def' NAME parameters ['->' test] ':' suite
+
+parameters: '(' [typedargslist] ')'
+typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [',' [
+'*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]]
+  | '**' tfpdef [',']]]
+  | '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]]
+  | '**' tfpdef [','])
+tfpdef: NAME [':' test]
+varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [
+'*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]]
+  | '**' vfpdef [',']]]
+  | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]]
+  | '**' vfpdef [',']
+)
+vfpdef: NAME
+
+stmt: simple_stmt | compound_stmt
+simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
+small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
+ import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
+expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) |
+ ('=' (yield_expr|testlist_star_expr))*)
+annassign: ':' test ['=' test]
+testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
+augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' |
+'<<=' | '>>=' | '**=' | '//=')
+# For normal and annotated assignments, additional restrictions enforced by 
the interpreter
+del_stmt: 'del' exprlist
+pass_stmt: 'pass'
+flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
+break_stmt: 'break'
+continue_stmt: 'continue'
+return_stmt: 'return' [testlist]
+yield_stmt: yield_expr
+raise_stmt: 'raise' [test ['from' test]]
+import_stmt: import_name | import_from
+import_name: 'import' dotted_as_names
+# note below: the ('.' | '...') is necessary because '...' is tokenized as 
ELLIPSIS
+import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
+  'import' ('*' | '(' import_as_names ')' | import_as_names))
+import_as_name: NAME ['as' NAME]
+dotted_as_name: dotted_name ['as' NAME]
+import_as_names: import_as_name (',' import_as_name)* [',']
+dotted_as_names: dotted_as_name (',' dotted_as_name)*
+dotted_name: NAME ('.' NAME)*
+global_stmt: 'global' NAME (',' NAME)*
+nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
+assert_stmt: 'assert' test [',' test]
+
+compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | 
funcdef | classdef | decorated | async_stmt
+async_stmt: ASYNC (funcdef | with_stmt | for_stmt)
+if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+while_stmt: 'while' test ':' suite ['else' ':' suite]
+for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
+try_stmt: ('try' ':' suite
+   ((except_clause ':' suite)+
+['else' ':' suite]
+['finally' ':' suite] |
+   'finally' ':' suite))
+with_stmt: 'with' with_item (',' with_item)*  ':' suite
+with_item: test ['as' expr]
+# NB compile.c makes sure that the default except clause is last
+except_clause: 'except' [test ['as' NAME]]
+suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
+
+test: or_test ['if' or_test 'else' test] | lambdef
+test_nocond: or_test | lambdef_nocond
+lambdef: 'lambda' [varargslist] ':' test
+lambdef_nocond: 'lambda' [varargslist] ':' test_nocond
+or_test: and_test ('or' and_test)*
+and_test: not_test ('and' not_test)*
+not_test: 'not' not_test | comparison
+comparison: expr (comp_op expr)*
+# <> isn't actually a valid comparison operator in Python. It's here for the
+# sake of a __future__ import described in PEP 401 (which really works :-)
+comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+star_expr: '*' expr
+expr: xor_expr ('|' xor_expr)*
+xor_expr: and_expr ('^' and_expr)*
+and_expr: shift_expr ('&' shift_expr)*
+shift_expr: arith_expr (('<<'|'>>') arith_expr)*
+arith_expr: term (('+'|'-') term)*
+term: factor (('*'|'@'|'/'|'%'|'//') 

[pypy-commit] pypy pep526: Set __annotations__ to an empty dict in __main__.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93926:103116c17ec7
Date: 2018-02-18 09:24 -0800
http://bitbucket.org/pypy/pypy/changeset/103116c17ec7/

Log:Set __annotations__ to an empty dict in __main__.

diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py
--- a/pypy/interpreter/app_main.py
+++ b/pypy/interpreter/app_main.py
@@ -577,6 +577,7 @@
 mainmodule = type(sys)('__main__')
 mainmodule.__loader__ = sys.__loader__
 mainmodule.__builtins__ = os.__builtins__
+mainmodule.__annotations__ = {}
 sys.modules['__main__'] = mainmodule
 
 if not no_site:
diff --git a/pypy/interpreter/main.py b/pypy/interpreter/main.py
--- a/pypy/interpreter/main.py
+++ b/pypy/interpreter/main.py
@@ -13,6 +13,8 @@
 raise
 mainmodule = module.Module(space, w_main)
 space.setitem(w_modules, w_main, mainmodule)
+w_annotations = space.newdict()
+space.setitem_str(mainmodule.w_dict, '__annotations__', w_annotations)
 return mainmodule
 
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Implement the variable annotation bytecodes.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93923:52cd5d8635c2
Date: 2018-02-14 22:13 -0800
http://bitbucket.org/pypy/pypy/changeset/52cd5d8635c2/

Log:Implement the variable annotation bytecodes.

diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -292,6 +292,10 @@
 self.DELETE_DEREF(oparg, next_instr)
 elif opcode == opcodedesc.DELETE_FAST.index:
 self.DELETE_FAST(oparg, next_instr)
+elif opcode == opcodedesc.SETUP_ANNOTATIONS.index:
+self.SETUP_ANNOTATIONS(oparg, next_instr)
+elif opcode == opcodedesc.STORE_ANNOTATION.index:
+self.STORE_ANNOTATION(oparg, next_instr)
 elif opcode == opcodedesc.DELETE_GLOBAL.index:
 self.DELETE_GLOBAL(oparg, next_instr)
 elif opcode == opcodedesc.DELETE_NAME.index:
@@ -947,6 +951,18 @@
 varname)
 self.locals_cells_stack_w[varindex] = None
 
+def SETUP_ANNOTATIONS(self, oparg, next_instr):
+w_locals = self.getorcreatedebug().w_locals
+if not self.space.finditem_str(w_locals, '__annotations__'):
+w_annotations = self.space.newdict()
+self.space.setitem_str(w_locals, '__annotations__', w_annotations)
+
+def STORE_ANNOTATION(self, varindex, next_instr):
+varname = self.getname_u(varindex)
+w_newvalue = self.popvalue()
+
self.space.setitem_str(self.getorcreatedebug().w_locals.getitem_str('__annotations__'),
 varname,
+   w_newvalue)
+
 def BUILD_TUPLE(self, itemcount, next_instr):
 items = self.popvalues(itemcount)
 w_tuple = self.space.newtuple(items)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Add AST validator for AnnAssign.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93915:9bfa5258df88
Date: 2018-02-13 23:24 -0800
http://bitbucket.org/pypy/pypy/changeset/9bfa5258df88/

Log:Add AST validator for AnnAssign.

diff --git a/pypy/interpreter/astcompiler/validate.py 
b/pypy/interpreter/astcompiler/validate.py
--- a/pypy/interpreter/astcompiler/validate.py
+++ b/pypy/interpreter/astcompiler/validate.py
@@ -212,6 +212,12 @@
 self._validate_exprs(node.targets, ast.Store)
 self._validate_expr(node.value)
 
+def visit_AnnAssign(self, node):
+self._validate_expr(node.target, ast.Store)
+self._validate_expr(node.annotation)
+if node.value:
+self._validate_expr(node.value)
+
 def visit_AugAssign(self, node):
 self._validate_expr(node.target, ast.Store)
 self._validate_expr(node.value)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Add new instructions to opcode.py.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93922:59ecffe9844c
Date: 2018-02-14 22:12 -0800
http://bitbucket.org/pypy/pypy/changeset/59ecffe9844c/

Log:Add new instructions to opcode.py.

diff --git a/lib-python/3/opcode.py b/lib-python/3/opcode.py
--- a/lib-python/3/opcode.py
+++ b/lib-python/3/opcode.py
@@ -121,7 +121,7 @@
 
 def_op('RETURN_VALUE', 83)
 def_op('IMPORT_STAR', 84)
-
+def_op('SETUP_ANNOTATIONS', 85)
 def_op('YIELD_VALUE', 86)
 def_op('POP_BLOCK', 87)
 def_op('END_FINALLY', 88)
@@ -171,6 +171,7 @@
 haslocal.append(125)
 def_op('DELETE_FAST', 126)  # Local variable number
 haslocal.append(126)
+name_op('STORE_ANNOTATION', 127) # Index in name list
 
 def_op('RAISE_VARARGS', 130)# Number of raise arguments (1, 2, or 3)
 def_op('CALL_FUNCTION', 131)# #args + (#kwargs << 8)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Stack effect values for new annotation opcodes.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93918:d6987b09241a
Date: 2018-02-14 07:14 -0800
http://bitbucket.org/pypy/pypy/changeset/d6987b09241a/

Log:Stack effect values for new annotation opcodes.

diff --git a/pypy/interpreter/astcompiler/assemble.py 
b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -690,6 +690,9 @@
 ops.POP_JUMP_IF_FALSE: -1,
 ops.JUMP_IF_NOT_DEBUG: 0,
 
+ops.SETUP_ANNOTATIONS: 0,
+ops.STORE_ANNOTATION: -1,
+
 # TODO
 ops.BUILD_LIST_FROM_ARG: 1,
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Add WIP test for variable annotation in symtable.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93911:2ddcba2e06c4
Date: 2018-02-13 23:21 -0800
http://bitbucket.org/pypy/pypy/changeset/2ddcba2e06c4/

Log:Add WIP test for variable annotation in symtable.

diff --git a/pypy/interpreter/astcompiler/test/test_symtable.py 
b/pypy/interpreter/astcompiler/test/test_symtable.py
--- a/pypy/interpreter/astcompiler/test/test_symtable.py
+++ b/pypy/interpreter/astcompiler/test/test_symtable.py
@@ -486,6 +486,34 @@
 scp = self.mod_scope("with x: pass")
 assert scp.lookup("_[1]") == symtable.SCOPE_LOCAL
 
+def test_annotation_global(self):
+src_global = ("def f():\n"
+  "x: int\n"
+  "global x\n")
+exc_global = py.test.raises(SyntaxError, self.func_scope, 
src_global).value
+assert exc_global.msg == "annotated name 'x' can't be global"
+assert exc_global.lineno == 3
+
+def test_annotation_nonlocal(self):
+src_nonlocal = ("def f():\n"
+"x: int\n"
+"nonlocal x\n")
+exc_nonlocal = py.test.raises(SyntaxError, self.func_scope, 
src_nonlocal).value
+assert exc_nonlocal.msg == "annotated name 'x' can't be nonlocal"
+assert exc_nonlocal.lineno == 3
+
+def test_annotation_assignment(self):
+scp = self.mod_scope("x: int = 1")
+assert scp.contains_annotated == True
+
+scp2 = self.mod_scope("x = 1")
+assert scp2.contains_annotated == False
+
+fscp = self.func_scope("def f(): x: int")
+assert fscp.contains_annotated == False
+assert fscp.lookup("x") == symtable.SCOPE_LOCAL
+
+
 def test_issue13343(self):
 scp = self.mod_scope("lambda *, k1=x, k2: None")
 assert scp.lookup("x") == symtable.SCOPE_GLOBAL_IMPLICIT
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Add test to ensure repeated calls to SETUP_ANNOTATIONS work.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93925:37e249a9c04b
Date: 2018-02-14 22:53 -0800
http://bitbucket.org/pypy/pypy/changeset/37e249a9c04b/

Log:Add test to ensure repeated calls to SETUP_ANNOTATIONS work.

diff --git a/pypy/interpreter/test/test_annotations.py 
b/pypy/interpreter/test/test_annotations.py
--- a/pypy/interpreter/test/test_annotations.py
+++ b/pypy/interpreter/test/test_annotations.py
@@ -69,6 +69,14 @@
 C()
 '''
 
+def test_repeated_setup(self):
+'''
+d = {}
+exec('a: int', d)
+exec('b: int', d)
+exec('assert __annotations__ == {"a": int, "b": int}', d)
+'''
+
 def test_function_no___annotations__(self):
 '''
 a: int
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Support code generation with variable annotations.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93924:2588a45dab22
Date: 2018-02-14 22:14 -0800
http://bitbucket.org/pypy/pypy/changeset/2588a45dab22/

Log:Support code generation with variable annotations.

diff --git a/pypy/interpreter/astcompiler/codegen.py 
b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -299,6 +299,12 @@
 else:
 return False
 
+def _maybe_setup_annotations(self):
+# if the scope contained an annotated variable assignemt,
+# this will emit the requisite SETUP_ANNOTATIONS
+if self.scope.contains_annotated and not isinstance(self, 
AbstractFunctionCodeGenerator):
+self.emit_op(ops.SETUP_ANNOTATIONS)
+
 def visit_Module(self, mod):
 if not self._handle_body(mod.body):
 self.first_lineno = self.lineno = 1
@@ -925,6 +931,66 @@
 self.visit_sequence(targets)
 return True
 
+def _annotation_evaluate(self, item):
+# PEP 526 requires that some things be evaluated, to avoid bugs
+# where a non-assigning variable annotation references invalid items
+# this is effectively a NOP, but will fail if e.g. item is an
+# Attribute and one of the chained names does not exist
+item.walkabout(self)
+self.emit_op(ops.POP_TOP)
+
+def _annotation_eval_slice(self, target):
+if isinstance(target, ast.Index):
+self._annotation_evaluate(target.value)
+elif isinstance(target, ast.Slice):
+for val in [target.lower, target.upper, target.step]:
+if val:
+self._annotation_evaluate(val)
+elif isinstance(target, ast.ExtSlice):
+for val in target.dims:
+if isinstance(val, ast.Index) or isinstance(val, ast.Slice):
+self._annotation_eval_slice(val)
+else:
+self.error("Invalid nested slice", val)
+else:
+self.error("Invalid slice?", target)
+
+def visit_AnnAssign(self, assign):
+self.update_position(assign.lineno, True)
+target = assign.target
+# if there's an assignment to be done, do it
+if assign.value:
+assign.value.walkabout(self)
+target.walkabout(self)
+# the PEP requires that certain parts of the target be evaluated at 
runtime
+# to avoid silent annotation-related errors
+if isinstance(target, ast.Name):
+# if it's just a simple name and we're not in a function, store
+# the annotation in __annotations__
+if assign.simple and not isinstance(self.scope, 
symtable.FunctionScope):
+assign.annotation.walkabout(self)
+name = target.id
+self.emit_op_arg(ops.STORE_ANNOTATION, 
self.add_name(self.names, name))
+elif isinstance(target, ast.Attribute):
+# the spec requires that `a.b: int` evaluates `a`
+# and in a non-function scope, also evaluates `int`
+# (N.B.: if the target is of the form `a.b.c`, `a.b` will be 
evaluated)
+if not assign.value:
+attr = target.value
+self._annotation_evaluate(attr)
+elif isinstance(target, ast.Subscript):
+# similar to the above, `a[0:5]: int` evaluates the name and the 
slice argument
+# and if not in a function, also evaluates the annotation
+sl = target.slice
+self._annotation_evaluate(target.value)
+self._annotation_eval_slice(sl)
+else:
+self.error("can't handle annotation with %s" % (target,), target)
+# if this is not in a function, evaluate the annotation
+if not (assign.simple or isinstance(self.scope, 
symtable.FunctionScope)):
+self._annotation_evaluate(assign.annotation)
+
+
 def visit_With(self, wih):
 self.update_position(wih.lineno, True)
 self.handle_withitem(wih, 0, is_async=False)
@@ -1527,6 +1593,7 @@
  symbols, compile_info, qualname=None)
 
 def _compile(self, tree):
+self._maybe_setup_annotations()
 tree.walkabout(self)
 
 def _get_code_flags(self):
@@ -1656,6 +1723,7 @@
 w_qualname = self.space.newtext(self.qualname)
 self.load_const(w_qualname)
 self.name_op("__qualname__", ast.Store)
+self._maybe_setup_annotations()
 # compile the body proper
 self._handle_body(cls.body)
 # return the (empty) __class__ cell
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Catch expected exception in test_annotations.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93921:c9cec4aab2cc
Date: 2018-02-14 22:09 -0800
http://bitbucket.org/pypy/pypy/changeset/c9cec4aab2cc/

Log:Catch expected exception in test_annotations.

diff --git a/pypy/interpreter/test/test_annotations.py 
b/pypy/interpreter/test/test_annotations.py
--- a/pypy/interpreter/test/test_annotations.py
+++ b/pypy/interpreter/test/test_annotations.py
@@ -59,8 +59,13 @@
 class C:
 def __init__(self):
 self.x: invalid_name = 1
-y[0]: also_invalid
 assert self.x == 1
+try:
+# this is invalid because `y` is undefined
+# it should raise a NameError
+y[0]: also_invalid
+except NameError:
+...
 C()
 '''
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Improve annotation tests.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93927:250a545b5734
Date: 2018-02-18 10:42 -0800
http://bitbucket.org/pypy/pypy/changeset/250a545b5734/

Log:Improve annotation tests.

diff --git a/pypy/interpreter/test/test_annotations.py 
b/pypy/interpreter/test/test_annotations.py
--- a/pypy/interpreter/test/test_annotations.py
+++ b/pypy/interpreter/test/test_annotations.py
@@ -1,13 +1,14 @@
-import py
-
 class AppTestAnnotations:
 
-def test_simple_annotation(self):
+def test_toplevel_annotation(self):
 # exec because this needs to be in "top level" scope
 # whereas the docstring-based tests are inside a function
 # (or don't care)
 exec("a: int; assert __annotations__['a'] == int")
 
+def test_toplevel_invalid(self):
+exec('try: a: invalid\nexcept NameError: pass\n')
+
 def test_non_simple_annotation(self):
 '''
 class C:
@@ -33,8 +34,8 @@
 
 def test_subscript_target(self):
 '''
-# this test exists to ensure that these type annotations
-# don't raise exceptions during compilation
+# ensure that these type annotations don't raise exceptions
+# during compilation
 class C:
 a = 1
 a[0]: int
@@ -48,10 +49,9 @@
 '''
 class C:
 a: int
-b: str = "s"
+b: str
 assert "__annotations__" in locals()
 assert C.__annotations__ == {"a": int, "b": str}
-assert C.b == "s"
 '''
 
 def test_unevaluated_name(self):
@@ -60,22 +60,27 @@
 def __init__(self):
 self.x: invalid_name = 1
 assert self.x == 1
-try:
-# this is invalid because `y` is undefined
-# it should raise a NameError
-y[0]: also_invalid
-except NameError:
-...
 C()
 '''
 
+def test_nonexistent_target(self):
+'''
+try:
+# this is invalid because `y` is undefined
+# it should raise a NameError
+y[0]: invalid
+except NameError:
+...
+'''
+
 def test_repeated_setup(self):
-'''
+# each exec will run another SETUP_ANNOTATIONS
+# we want to confirm that this doesn't blow away
+# the previous __annotations__
 d = {}
 exec('a: int', d)
 exec('b: int', d)
 exec('assert __annotations__ == {"a": int, "b": int}', d)
-'''
 
 def test_function_no___annotations__(self):
 '''
@@ -84,25 +89,25 @@
 '''
 
 def test_unboundlocal(self):
-# this test and the one below it are adapted from PEP 526
+# a simple variable annotation implies its target is a local
 '''
 a: int
 try:
 print(a)
 except UnboundLocalError:
-pass
-except:
-assert False
+return
+assert False
 '''
 
-def test_nameerror(self):
-# there's no annotation here, but it's present for contrast with
-# the test above
+def test_reassigned___annotations__(self):
 '''
-try:
-print(a)
-except NameError:
-pass
-except:
-raise
+class C:
+__annotations__ = None
+try:
+a: int
+raise
+except TypeError:
+pass
+except:
+assert False
 '''
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Handle AnnAssign in symtable building (WIP).

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93916:e3f0d3b1a562
Date: 2018-02-13 23:25 -0800
http://bitbucket.org/pypy/pypy/changeset/e3f0d3b1a562/

Log:Handle AnnAssign in symtable building (WIP).

diff --git a/pypy/interpreter/astcompiler/symtable.py 
b/pypy/interpreter/astcompiler/symtable.py
--- a/pypy/interpreter/astcompiler/symtable.py
+++ b/pypy/interpreter/astcompiler/symtable.py
@@ -12,6 +12,7 @@
 SYM_PARAM = 2 << 1
 SYM_NONLOCAL = 2 << 2
 SYM_USED = 2 << 3
+SYM_ANNOTATED = 2 << 4
 SYM_BOUND = (SYM_PARAM | SYM_ASSIGNED)
 
 # codegen.py actually deals with these:
@@ -44,6 +45,7 @@
 self.child_has_free = False
 self.nested = False
 self.doc_removable = False
+self.contains_annotated = False
 self._in_try_body_depth = 0
 
 def lookup(self, name):
@@ -139,7 +141,7 @@
 self.free_vars.append(name)
 free[name] = None
 self.has_free = True
-elif flags & SYM_BOUND:
+elif flags & (SYM_BOUND | SYM_ANNOTATED):
 self.symbols[name] = SCOPE_LOCAL
 local[name] = None
 try:
@@ -420,6 +422,18 @@
 self.scope.note_return(ret)
 ast.GenericASTVisitor.visit_Return(self, ret)
 
+def visit_AnnAssign(self, assign):
+# __annotations__ is not setup or used in functions.
+if not isinstance(self.scope, FunctionScope):
+self.scope.contains_annotated = True
+target = assign.target
+if isinstance(target, ast.Name):
+scope = SYM_ANNOTATED
+name = target.id
+if assign.value:
+scope |= SYM_USED
+self.note_symbol(name, scope)
+
 def visit_ClassDef(self, clsdef):
 self.note_symbol(clsdef.name, SYM_ASSIGNED)
 self.visit_sequence(clsdef.bases)
@@ -485,10 +499,13 @@
 msg = "name '%s' is nonlocal and global" % (name,)
 raise SyntaxError(msg, glob.lineno, glob.col_offset)
 
-if old_role & (SYM_USED | SYM_ASSIGNED):
+if old_role & (SYM_USED | SYM_ASSIGNED | SYM_ANNOTATED):
 if old_role & SYM_ASSIGNED:
 msg = "name '%s' is assigned to before global declaration"\
 % (name,)
+elif old_role & SYM_ANNOTATED:
+msg = "annotated name '%s' can't be global" \
+% (name,)
 else:
 msg = "name '%s' is used prior to global declaration" % \
 (name,)
@@ -498,6 +515,7 @@
 def visit_Nonlocal(self, nonl):
 for name in nonl.names:
 old_role = self.scope.lookup_role(name)
+print(name, old_role)
 msg = ""
 if old_role & SYM_GLOBAL:
 msg = "name '%s' is nonlocal and global" % (name,)
@@ -505,6 +523,9 @@
 msg = "name '%s' is parameter and nonlocal" % (name,)
 if isinstance(self.scope, ModuleScope):
 msg = "nonlocal declaration not allowed at module level"
+if old_role & SYM_ANNOTATED:
+msg = "annotated name '%s' can't be nonlocal" \
+% (name,)
 if msg is not "":
 raise SyntaxError(msg, nonl.lineno, nonl.col_offset)
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Add some app-level test for variable annotations.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93917:8d9b6685e41e
Date: 2018-02-13 23:27 -0800
http://bitbucket.org/pypy/pypy/changeset/8d9b6685e41e/

Log:Add some app-level test for variable annotations.

diff --git a/pypy/interpreter/test/test_annotations.py 
b/pypy/interpreter/test/test_annotations.py
new file mode 100644
--- /dev/null
+++ b/pypy/interpreter/test/test_annotations.py
@@ -0,0 +1,95 @@
+import py
+
+class AppTestAnnotations:
+
+def test_simple_annotation(self):
+# exec because this needs to be in "top level" scope
+# whereas the docstring-based tests are inside a function
+# (or don't care)
+exec("a: int; assert __annotations__['a'] == int")
+
+def test_non_simple_annotation(self):
+'''
+class C:
+(a): int
+assert "a" not in __annotations__
+'''
+
+def test_simple_with_target(self):
+'''
+class C:
+a: int = 1
+assert __annotations__["a"] == int
+assert a == 1
+'''
+
+def test_attribute_target(self):
+'''
+class C:
+a = 1
+a.x: int
+assert __annotations__ == {}
+'''
+
+def test_subscript_target(self):
+'''
+# this test exists to ensure that these type annotations
+# don't raise exceptions during compilation
+class C:
+a = 1
+a[0]: int
+a[1:2]: int
+a[1:2:2]: int
+a[1:2:2,...]: int
+assert __annotations__ == {}
+'''
+
+def test_class_annotation(self):
+'''
+class C:
+a: int
+b: str = "s"
+assert "__annotations__" in locals()
+assert C.__annotations__ == {"a": int, "b": str}
+assert C.b == "s"
+'''
+
+def test_unevaluated_name(self):
+'''
+class C:
+def __init__(self):
+self.x: invalid_name = 1
+y[0]: also_invalid
+assert self.x == 1
+C()
+'''
+
+def test_function_no___annotations__(self):
+'''
+a: int
+assert "__annotations__" not in locals()
+'''
+
+def test_unboundlocal(self):
+# this test and the one below it are adapted from PEP 526
+'''
+a: int
+try:
+print(a)
+except UnboundLocalError:
+pass
+except:
+assert False
+'''
+
+def test_nameerror(self):
+# there's no annotation here, but it's present for contrast with
+# the test above
+'''
+try:
+print(a)
+except NameError:
+pass
+except:
+raise
+'''
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy pep526: Make symtable handle non-Name targets properly in variable annotation.

2018-03-01 Thread alcarithemad
Author: Colin Valliant 
Branch: pep526
Changeset: r93920:509be3f27434
Date: 2018-02-14 22:08 -0800
http://bitbucket.org/pypy/pypy/changeset/509be3f27434/

Log:Make symtable handle non-Name targets properly in variable
annotation.

diff --git a/pypy/interpreter/astcompiler/symtable.py 
b/pypy/interpreter/astcompiler/symtable.py
--- a/pypy/interpreter/astcompiler/symtable.py
+++ b/pypy/interpreter/astcompiler/symtable.py
@@ -433,6 +433,8 @@
 if assign.value:
 scope |= SYM_USED
 self.note_symbol(name, scope)
+else:
+target.walkabout(self)
 
 def visit_ClassDef(self, clsdef):
 self.note_symbol(clsdef.name, SYM_ASSIGNED)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5: trivial test fixes for win

2018-03-01 Thread mattip
Author: Matti Picus 
Branch: py3.5
Changeset: r93930:934b5f719f0d
Date: 2018-03-01 05:36 -0500
http://bitbucket.org/pypy/pypy/changeset/934b5f719f0d/

Log:trivial test fixes for win

diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py
--- a/pypy/module/imp/test/test_app.py
+++ b/pypy/module/imp/test/test_app.py
@@ -82,7 +82,7 @@
 import imp
 for suffix, mode, type in imp.get_suffixes():
 if type == imp.PY_SOURCE:
-assert suffix == '.py'
+assert suffix in ('.py', '.pyw')
 assert mode == 'r'
 elif type == imp.PY_COMPILED:
 assert suffix == '.pyc'
diff --git a/pypy/module/posix/test/test_posix2.py 
b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -1478,6 +1478,8 @@
 def test_environ(self):
 import sys, os
 environ = os.environ
+if not environ:
+skip('environ not filled in for untranslated tests')
 for k, v in environ.items():
 assert type(k) is str
 assert type(v) is str
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5: generalize win Reg* calls for A and W variants, use and fix tests

2018-03-01 Thread mattip
Author: Matti Picus 
Branch: py3.5
Changeset: r93929:0684dbb33360
Date: 2018-03-01 05:35 -0500
http://bitbucket.org/pypy/pypy/changeset/0684dbb33360/

Log:generalize win Reg* calls for A and W variants, use and fix tests

diff --git a/pypy/module/_winreg/interp_winreg.py 
b/pypy/module/_winreg/interp_winreg.py
--- a/pypy/module/_winreg/interp_winreg.py
+++ b/pypy/module/_winreg/interp_winreg.py
@@ -175,7 +175,7 @@
 c_subkey = rffi.cast(rffi.CCHARP, wide_subkey)
 with rffi.scoped_unicode2wcharp(filename) as wide_filename:
 c_filename = rffi.cast(rffi.CCHARP, wide_filename)
-ret = rwinreg.RegLoadKey(hkey, c_subkey, c_filename)
+ret = rwinreg.RegLoadKeyW(hkey, c_subkey, c_filename)
 if ret != 0:
 raiseWindowsError(space, ret, 'RegLoadKey')
 
@@ -196,7 +196,7 @@
 hkey = hkey_w(w_hkey, space)
 with rffi.scoped_unicode2wcharp(filename) as wide_filename:
 c_filename = rffi.cast(rffi.CCHARP, wide_filename)
-ret = rwinreg.RegSaveKey(hkey, c_filename, None)
+ret = rwinreg.RegSaveKeyW(hkey, c_filename, None)
 if ret != 0:
 raiseWindowsError(space, ret, 'RegSaveKey')
 
@@ -226,7 +226,7 @@
 c_subkey = rffi.cast(rffi.CCHARP, subkey)
 with rffi.scoped_unicode2wcharp(value) as dataptr:
 c_dataptr = rffi.cast(rffi.CCHARP, dataptr)
-ret = rwinreg.RegSetValue(hkey, c_subkey, rwinreg.REG_SZ, 
+ret = rwinreg.RegSetValueW(hkey, c_subkey, rwinreg.REG_SZ,
 c_dataptr, len(value))
 if ret != 0:
 raiseWindowsError(space, ret, 'RegSetValue')
@@ -250,7 +250,7 @@
 with rffi.scoped_unicode2wcharp(subkey) as wide_subkey:
 c_subkey = rffi.cast(rffi.CCHARP, wide_subkey)
 with lltype.scoped_alloc(rwin32.PLONG.TO, 1) as bufsize_p:
-ret = rwinreg.RegQueryValue(hkey, c_subkey, None, bufsize_p)
+ret = rwinreg.RegQueryValueW(hkey, c_subkey, None, bufsize_p)
 bufSize = intmask(bufsize_p[0])
 if ret == rwinreg.ERROR_MORE_DATA:
 bufSize = 256
@@ -259,7 +259,7 @@
 
 while True:
 with lltype.scoped_alloc(rffi.CCHARP.TO, bufSize) as buf:
-ret = rwinreg.RegQueryValue(hkey, c_subkey, buf, bufsize_p)
+ret = rwinreg.RegQueryValueW(hkey, c_subkey, buf, 
bufsize_p)
 if ret == rwinreg.ERROR_MORE_DATA:
 print 'bufSize was %d, too small' % bufSize
 # Resize and retry
@@ -440,7 +440,7 @@
 try:
 with rffi.scoped_unicode2wcharp(value_name) as wide_vn:
 c_vn = rffi.cast(rffi.CCHARP, wide_vn)
-ret = rwinreg.RegSetValueEx(hkey, c_vn, 0, typ, buf, buflen)
+ret = rwinreg.RegSetValueExW(hkey, c_vn, 0, typ, buf, buflen)
 finally:
 lltype.free(buf, flavor='raw')
 if ret != 0:
@@ -460,7 +460,7 @@
 with rffi.scoped_unicode2wcharp(subkey) as wide_subkey:
 c_subkey = rffi.cast(rffi.CCHARP, wide_subkey)
 with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retDataSize:
-ret = rwinreg.RegQueryValueEx(hkey, c_subkey, null_dword, 
null_dword,
+ret = rwinreg.RegQueryValueExW(hkey, c_subkey, null_dword, 
null_dword,
   None, retDataSize)
 bufSize = intmask(retDataSize[0])
 if ret == rwinreg.ERROR_MORE_DATA:
@@ -472,7 +472,7 @@
 with lltype.scoped_alloc(rffi.CCHARP.TO, bufSize) as databuf:
 with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retType:
 
-ret = rwinreg.RegQueryValueEx(hkey, c_subkey, 
null_dword,
+ret = rwinreg.RegQueryValueExW(hkey, c_subkey, 
null_dword,
   retType, databuf, 
retDataSize)
 if ret == rwinreg.ERROR_MORE_DATA:
 # Resize and retry
@@ -505,7 +505,7 @@
 with rffi.scoped_unicode2wcharp(subkey) as wide_subkey:
 c_subkey = rffi.cast(rffi.CCHARP, wide_subkey)
 with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
-ret = rwinreg.RegCreateKey(hkey, c_subkey, rethkey)
+ret = rwinreg.RegCreateKeyW(hkey, c_subkey, rethkey)
 if ret != 0:
 raiseWindowsError(space, ret, 'CreateKey')
 return W_HKEY(space, rethkey[0])
@@ -527,7 +527,7 @@
 with rffi.scoped_unicode2wcharp(sub_key) as wide_sub_key:
 c_subkey = rffi.cast(rffi.CCHARP, wide_sub_key)
 with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
-ret = rwinreg.RegCreateKeyEx(hkey, c_subkey, reserved, None, 0,
+ret = rwinreg.RegCreateKeyExW(hkey, c_subkey, reserved, None, 0,
  access, None, rethkey,
  

[pypy-commit] pypy py3.6: CPython Issue #14711: os.stat_float_times() has been deprecated.

2018-03-01 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: py3.6
Changeset: r93933:1297ffb4dd1a
Date: 2018-02-26 01:57 +0100
http://bitbucket.org/pypy/pypy/changeset/1297ffb4dd1a/

Log:CPython Issue #14711: os.stat_float_times() has been deprecated.

diff --git a/pypy/module/posix/interp_posix.py 
b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -586,6 +586,8 @@
 future calls return ints.
 If newval is omitted, return the current setting.
 """
+space.warn(space.newtext("stat_float_times() is deprecated"),
+   space.w_DeprecationWarning)
 state = space.fromcache(StatState)
 
 if newval == -1:
diff --git a/pypy/module/posix/test/test_posix2.py 
b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -162,8 +162,12 @@
 def test_stat_float_times(self):
 path = self.path
 posix = self.posix
-current = posix.stat_float_times()
-assert current is True
+import warnings
+with warnings.catch_warnings(record=True) as l:
+warnings.simplefilter('always')
+current = posix.stat_float_times()
+assert current is True
+assert "stat_float_times" in repr(l[0].message)
 try:
 posix.stat_float_times(True)
 st = posix.stat(path)
@@ -180,6 +184,7 @@
 finally:
 posix.stat_float_times(current)
 
+
 def test_stat_result(self):
 st = self.posix.stat_result((0, 0, 0, 0, 0, 0, 0, 41, 42.1, 43))
 assert st.st_atime == 41
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.6: CPython Issue #26129: grp.getgrgid() sends a DeprecationWarning when passing non-integers

2018-03-01 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: py3.6
Changeset: r93932:0ebac2fc9fb1
Date: 2018-02-26 01:13 +0100
http://bitbucket.org/pypy/pypy/changeset/0ebac2fc9fb1/

Log:CPython Issue #26129: grp.getgrgid() sends a DeprecationWarning when
passing non-integers

diff --git a/lib_pypy/grp.py b/lib_pypy/grp.py
--- a/lib_pypy/grp.py
+++ b/lib_pypy/grp.py
@@ -33,7 +33,13 @@
 
 @builtinify
 def getgrgid(gid):
-res = lib.getgrgid(gid)
+try:
+res = lib.getgrgid(gid)
+except TypeError:
+gid = int(gid)
+res = lib.getgrgid(gid)
+import warnings
+warnings.warn("group id must be int", DeprecationWarning)
 if not res:
 # XXX maybe check error eventually
 raise KeyError(gid)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.6: hg merge py3.5

2018-03-01 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: py3.6
Changeset: r93931:eb5abc38e4b2
Date: 2018-02-25 23:09 +0100
http://bitbucket.org/pypy/pypy/changeset/eb5abc38e4b2/

Log:hg merge py3.5

diff too long, truncating to 2000 out of 5407 lines

diff --git a/extra_tests/test_pyrepl/__init__.py 
b/extra_tests/test_pyrepl/__init__.py
new file mode 100644
--- /dev/null
+++ b/extra_tests/test_pyrepl/__init__.py
@@ -0,0 +1,1 @@
+
diff --git a/extra_tests/test_pyrepl/infrastructure.py 
b/extra_tests/test_pyrepl/infrastructure.py
new file mode 100644
--- /dev/null
+++ b/extra_tests/test_pyrepl/infrastructure.py
@@ -0,0 +1,87 @@
+#   Copyright 2000-2004 Michael Hudson-Doyle 
+#
+#All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from __future__ import print_function
+from contextlib import contextmanager
+import os
+
+from pyrepl.reader import Reader
+from pyrepl.console import Console, Event
+
+
+class EqualsAnything(object):
+def __eq__(self, other):
+return True
+
+
+EA = EqualsAnything()
+
+
+class TestConsole(Console):
+height = 24
+width = 80
+encoding = 'utf-8'
+
+def __init__(self, events, verbose=False):
+self.events = events
+self.next_screen = None
+self.verbose = verbose
+
+def refresh(self, screen, xy):
+if self.next_screen is not None:
+assert screen == self.next_screen, "[ %s != %s after %r ]" % (
+screen, self.next_screen, self.last_event_name)
+
+def get_event(self, block=1):
+ev, sc = self.events.pop(0)
+self.next_screen = sc
+if not isinstance(ev, tuple):
+ev = (ev, None)
+self.last_event_name = ev[0]
+if self.verbose:
+print("event", ev)
+return Event(*ev)
+
+
+class BaseTestReader(Reader):
+
+def get_prompt(self, lineno, cursor_on_line):
+return ''
+
+def refresh(self):
+Reader.refresh(self)
+self.dirty = True
+
+
+def read_spec(test_spec, reader_class=BaseTestReader):
+# remember to finish your test_spec with 'accept' or similar!
+con = TestConsole(test_spec, verbose=True)
+reader = reader_class(con)
+reader.readline()
+
+
+@contextmanager
+def sane_term():
+"""Ensure a TERM that supports clear"""
+old_term, os.environ['TERM'] = os.environ.get('TERM'), 'xterm'
+yield
+if old_term is not None:
+os.environ['TERM'] = old_term
+else:
+del os.environ['TERM']
diff --git a/extra_tests/test_pyrepl/test_basic.py 
b/extra_tests/test_pyrepl/test_basic.py
new file mode 100644
--- /dev/null
+++ b/extra_tests/test_pyrepl/test_basic.py
@@ -0,0 +1,116 @@
+#   Copyright 2000-2004 Michael Hudson-Doyle 
+#
+#All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+import pytest
+from .infrastructure import read_spec
+
+
+def test_basic():
+read_spec([(('self-insert', 'a'), ['a']),
+   ( 'accept',['a'])])
+
+
+def test_repeat():
+read_spec([(('digit-arg', '3'),   ['']),
+   (('self-insert', 'a'), ['aaa']),
+   ( 'accept',['aaa'])])
+
+
+def test_kill_line():
+read_spec([(('self-insert', 'abc'), ['abc']),
+   ( 'left',None),
+   ( 'kill-line',   ['ab']),
+   ( 'accept',  ['ab'])])
+
+
+def test_unix_line_discard():
+read_spec([(('self-insert', 'abc'), ['abc']),
+   ( 'l

[pypy-commit] pypy py3.5: Cleanup duplication between setup_buffer_procs() and make_bf_getbuffer() by killing the former

2018-03-01 Thread rlamy
Author: Ronan Lamy 
Branch: py3.5
Changeset: r93934:235304efbb73
Date: 2018-03-01 21:10 +
http://bitbucket.org/pypy/pypy/changeset/235304efbb73/

Log:Cleanup duplication between setup_buffer_procs() and
make_bf_getbuffer() by killing the former

diff --git a/pypy/module/cpyext/buffer.py b/pypy/module/cpyext/buffer.py
--- a/pypy/module/cpyext/buffer.py
+++ b/pypy/module/cpyext/buffer.py
@@ -189,33 +189,6 @@
 decref(space, view.c_obj)
 return 0
 
-def fill_buffer(space, view, pybuf, py_obj):
-view.c_buf = cts.cast('void *', pybuf.get_raw_address())
-view.c_obj = py_obj
-if py_obj:
-incref(space, py_obj)
-view.c_len = pybuf.getlength()
-view.c_itemsize = pybuf.getitemsize()
-rffi.setintfield(view, 'c_readonly', int(pybuf.readonly))
-rffi.setintfield(view, 'c_ndim', pybuf.getndim())
-view.c_format = rffi.str2charp(pybuf.getformat())
-shape = pybuf.getshape()
-if not shape:
-view.c_shape = lltype.nullptr(Py_ssize_tP.TO)
-else:
-view.c_shape = cts.cast('Py_ssize_t*', view.c__shape)
-for i, n in enumerate(shape):
-view.c_shape[i] = n
-strides = pybuf.getstrides()
-if not strides:
-view.c_strides = lltype.nullptr(Py_ssize_tP.TO)
-else:
-view.c_strides = cts.cast('Py_ssize_t*', view.c__strides)
-for i, n in enumerate(strides):
-view.c_strides[i] = n
-view.c_suboffsets = lltype.nullptr(Py_ssize_tP.TO)
-view.c_internal = lltype.nullptr(rffi.VOIDP.TO)
-
 DEFAULT_FMT = rffi.str2charp("B")
 
 @cpython_api([lltype.Ptr(Py_buffer), PyObject, rffi.VOIDP, Py_ssize_t,
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -688,12 +688,46 @@
 return space.call_args(space.get(new_fn, w_self), args)
 return slot_tp_new
 
+@slot_function([PyObject, lltype.Ptr(Py_buffer), rffi.INT_real],
+rffi.INT_real, error=-1)
+def bytes_getbuffer(space, w_str, view, flags):
+from pypy.module.cpyext.bytesobject import PyBytes_AsString
+from pypy.module.cpyext.buffer import PyBuffer_FillInfo
+c_buf = rffi.cast(rffi.VOIDP, PyBytes_AsString(space, w_str))
+return PyBuffer_FillInfo(space, view, w_str, c_buf,
+ space.len_w(w_str), 1, flags)
+
+def slot_from_buffer_w(space, typedef):
+name = 'bf_getbuffer'
+@slot_function([PyObject, Py_bufferP, rffi.INT_real],
+rffi.INT_real, error=-1)
+@func_renamer("cpyext_%s_%s" % (name, typedef.name))
+def buff_w(space, w_self, c_view, flags):
+w_obj = w_self
+if c_view:
+#like PyObject_GetBuffer
+flags = widen(flags)
+buf = space.buffer_w(w_obj, flags)
+try:
+c_view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address())
+c_view.c_obj = make_ref(space, w_obj)
+except ValueError:
+s = buf.as_str()
+w_s = space.newbytes(s)
+c_view.c_obj = make_ref(space, w_s)
+c_view.c_buf = rffi.cast(rffi.VOIDP, rffi.str2charp(
+s, track_allocation=False))
+rffi.setintfield(c_view, 'c_readonly', 1)
+ret = fill_Py_buffer(space, buf, c_view)
+return ret
+return 0
+return buff_w
+
 @slot_factory('tp_as_buffer.c_bf_getbuffer')
 def make_bf_getbuffer(space, typedef, name, attr):
 w_type = space.gettypeobject(typedef)
-buff_fn = w_type.lookup('__buffer__')
-if buff_fn is not None:
-return slot_from___buffer__(space, typedef, buff_fn)
+if space.is_w(w_type, space.w_bytes):
+return bytes_getbuffer
 elif typedef.buffer:
 return slot_from_buffer_w(space, typedef)
 else:
@@ -739,59 +773,6 @@
 return slot_tp_descr_set
 
 
-def slot_from___buffer__(space, typedef, buff_fn):
-name = 'bf_getbuffer'
-@slot_function([PyObject, Py_bufferP, rffi.INT_real],
-rffi.INT_real, error=-1)
-@func_renamer("cpyext_%s_%s" % (name, typedef.name))
-def buff_w(space, w_self, c_view, flags):
-args = Arguments(space, [space.newint(flags)])
-w_obj = space.call_args(space.get(buff_fn, w_self), args)
-if c_view:
-#like PyObject_GetBuffer
-flags = widen(flags)
-buf = space.buffer_w(w_obj, flags)
-try:
-c_view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address())
-c_view.c_obj = make_ref(space, w_obj)
-except ValueError:
-s = buf.as_str()
-w_s = space.newbytes(s)
-c_view.c_obj = make_ref(space, w_s)
-c_view.c_buf = rffi.cast(rffi.VOIDP, rffi.str2charp(
-s, track_allocation=False))
-rffi.setintfield(c_view, 'c_readonly', 1)
-ret = fill_Py_bu

[pypy-commit] extradoc extradoc: utf8-ization

2018-03-01 Thread arigo
Author: Armin Rigo 
Branch: extradoc
Changeset: r5872:b41ddb578d82
Date: 2018-03-01 22:41 +0100
http://bitbucket.org/pypy/extradoc/changeset/b41ddb578d82/

Log:utf8-ization

diff --git a/sprintinfo/leysin-winter-2018/people.txt 
b/sprintinfo/leysin-winter-2018/people.txt
--- a/sprintinfo/leysin-winter-2018/people.txt
+++ b/sprintinfo/leysin-winter-2018/people.txt
@@ -20,7 +20,7 @@
 Antonio Cuni 18.3/23.3  Ermina, exact dates to be confirmed
 Alexander Schremmer  18.3/20.3  Ermina
 Ronan Lamy   17.3/23.3  Ermina
-Ren� Dudfield18.3/24.3  Ermina
+René Dudfield18.3/24.3  Ermina
  == ===
 
 **NOTE:** lodging is by default in Ermina.  Based on past years, there
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: port winreg changes from 0684dbb33360

2018-03-01 Thread mattip
Author: Matti Picus 
Branch: 
Changeset: r93935:645bfc512f05
Date: 2018-03-01 16:17 -0800
http://bitbucket.org/pypy/pypy/changeset/645bfc512f05/

Log:port winreg changes from 0684dbb33360

diff --git a/pypy/module/_winreg/interp_winreg.py 
b/pypy/module/_winreg/interp_winreg.py
--- a/pypy/module/_winreg/interp_winreg.py
+++ b/pypy/module/_winreg/interp_winreg.py
@@ -169,7 +169,7 @@
 
 The docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE tree"""
 hkey = hkey_w(w_hkey, space)
-ret = rwinreg.RegLoadKey(hkey, subkey, filename)
+ret = rwinreg.RegLoadKeyA(hkey, subkey, filename)
 if ret != 0:
 raiseWindowsError(space, ret, 'RegLoadKey')
 
@@ -188,7 +188,7 @@
 The caller of this method must possess the SeBackupPrivilege security 
privilege.
 This function passes NULL for security_attributes to the API."""
 hkey = hkey_w(w_hkey, space)
-ret = rwinreg.RegSaveKey(hkey, filename, None)
+ret = rwinreg.RegSaveKeyA(hkey, filename, None)
 if ret != 0:
 raiseWindowsError(space, ret, 'RegSaveKey')
 
@@ -219,7 +219,7 @@
 else:
 subkey = space.text_w(w_subkey)
 with rffi.scoped_str2charp(value) as dataptr:
-ret = rwinreg.RegSetValue(hkey, subkey, rwinreg.REG_SZ, dataptr, 
len(value))
+ret = rwinreg.RegSetValueA(hkey, subkey, rwinreg.REG_SZ, dataptr, 
len(value))
 if ret != 0:
 raiseWindowsError(space, ret, 'RegSetValue')
 
@@ -240,7 +240,7 @@
 else:
 subkey = space.text_w(w_subkey)
 with lltype.scoped_alloc(rwin32.PLONG.TO, 1) as bufsize_p:
-ret = rwinreg.RegQueryValue(hkey, subkey, None, bufsize_p)
+ret = rwinreg.RegQueryValueA(hkey, subkey, None, bufsize_p)
 bufSize = intmask(bufsize_p[0])
 if ret == rwinreg.ERROR_MORE_DATA:
 bufSize = 256
@@ -249,7 +249,7 @@
 
 while True:
 with lltype.scoped_alloc(rffi.CCHARP.TO, bufSize) as buf:
-ret = rwinreg.RegQueryValue(hkey, subkey, buf, bufsize_p)
+ret = rwinreg.RegQueryValueA(hkey, subkey, buf, bufsize_p)
 if ret == rwinreg.ERROR_MORE_DATA:
 # Resize and retry
 bufSize *= 2
@@ -423,7 +423,7 @@
 hkey = hkey_w(w_hkey, space)
 buf, buflen = convert_to_regdata(space, w_value, typ)
 try:
-ret = rwinreg.RegSetValueEx(hkey, value_name, 0, typ, buf, buflen)
+ret = rwinreg.RegSetValueExA(hkey, value_name, 0, typ, buf, buflen)
 finally:
 lltype.free(buf, flavor='raw')
 if ret != 0:
@@ -441,7 +441,7 @@
 subkey = space.text_w(w_subkey)
 null_dword = lltype.nullptr(rwin32.LPDWORD.TO)
 with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retDataSize:
-ret = rwinreg.RegQueryValueEx(hkey, subkey, null_dword, null_dword,
+ret = rwinreg.RegQueryValueExA(hkey, subkey, null_dword, null_dword,
   None, retDataSize)
 bufSize = intmask(retDataSize[0])
 if ret == rwinreg.ERROR_MORE_DATA:
@@ -453,7 +453,7 @@
 with lltype.scoped_alloc(rffi.CCHARP.TO, bufSize) as databuf:
 with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retType:
 
-ret = rwinreg.RegQueryValueEx(hkey, subkey, null_dword,
+ret = rwinreg.RegQueryValueExA(hkey, subkey, null_dword,
   retType, databuf, 
retDataSize)
 if ret == rwinreg.ERROR_MORE_DATA:
 # Resize and retry
@@ -484,7 +484,7 @@
 If the function fails, an exception is raised."""
 hkey = hkey_w(w_hkey, space)
 with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
-ret = rwinreg.RegCreateKey(hkey, subkey, rethkey)
+ret = rwinreg.RegCreateKeyA(hkey, subkey, rethkey)
 if ret != 0:
 raiseWindowsError(space, ret, 'CreateKey')
 return W_HKEY(space, rethkey[0])
@@ -504,7 +504,7 @@
 If the function fails, an exception is raised."""
 hkey = hkey_w(w_hkey, space)
 with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
-ret = rwinreg.RegCreateKeyEx(hkey, subkey, res, None, 0,
+ret = rwinreg.RegCreateKeyExA(hkey, subkey, res, None, 0,
  sam, None, rethkey,
  lltype.nullptr(rwin32.LPDWORD.TO))
 if ret != 0:
@@ -524,7 +524,7 @@
 If the method succeeds, the entire key, including all of its values,
 is removed.  If the method fails, an EnvironmentError exception is raised."""
 hkey = hkey_w(w_hkey, space)
-ret = rwinreg.RegDeleteKey(hkey, subkey)
+ret = rwinreg.RegDeleteKeyA(hkey, subkey)
 if ret != 0:
 raiseWindowsError(space, ret, 'RegDeleteKey')
 
@@ -535,7 +535,7 @@
 key is an already open key, or any one of the predefined HKEY_* constants.
 value is a string that identifies the value to remove."""
 hkey = hkey_w(w_hkey, space)
-ret = rwinreg.

[pypy-commit] pypy py3.5: cleanup

2018-03-01 Thread mattip
Author: Matti Picus 
Branch: py3.5
Changeset: r93937:8e1fc4f86361
Date: 2018-03-01 16:22 -0800
http://bitbucket.org/pypy/pypy/changeset/8e1fc4f86361/

Log:cleanup

diff --git a/rpython/rlib/rwinreg.py b/rpython/rlib/rwinreg.py
--- a/rpython/rlib/rwinreg.py
+++ b/rpython/rlib/rwinreg.py
@@ -47,7 +47,7 @@
 HKEY = rwin32.HANDLE
 PHKEY = rffi.CArrayPtr(HKEY)
 REGSAM = rwin32.DWORD
-suffix = 'W'
+
 def get_traits(suffix):
 RegSetValue = external(
 'RegSetValue' + suffix,
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5: merge default into py3.5

2018-03-01 Thread mattip
Author: Matti Picus 
Branch: py3.5
Changeset: r93936:bd80880bbcdc
Date: 2018-03-01 16:21 -0800
http://bitbucket.org/pypy/pypy/changeset/bd80880bbcdc/

Log:merge default into py3.5

___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit