152 lines
5.3 KiB
Diff
152 lines
5.3 KiB
Diff
From 86b98a11559da7d1b21dc9b4c6b10511b9095bc4 Mon Sep 17 00:00:00 2001
|
|
From: Simon Cross <hodgestar@gmail.com>
|
|
Date: Sun, 16 Feb 2014 18:46:15 +0000
|
|
Subject: [PATCH 05/16] Add support for Python 3.4 AST (support for
|
|
NameConstants and changes to existing to arguments node attributes).
|
|
|
|
---
|
|
genshi/template/astutil.py | 31 ++++++++++++++++++++++++++++---
|
|
genshi/template/eval.py | 34 +++++++++++++++++++---------------
|
|
2 files changed, 47 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/genshi/template/astutil.py b/genshi/template/astutil.py
|
|
index a4c21c8..a3946b4 100644
|
|
--- a/genshi/template/astutil.py
|
|
+++ b/genshi/template/astutil.py
|
|
@@ -21,7 +21,7 @@ else:
|
|
def parse(source, mode):
|
|
return compile(source, '', mode, _ast.PyCF_ONLY_AST)
|
|
|
|
-from genshi.compat import IS_PYTHON2
|
|
+from genshi.compat import IS_PYTHON2, isstring
|
|
|
|
__docformat__ = 'restructuredtext en'
|
|
|
|
@@ -103,8 +103,13 @@ class ASTCodeGenerator(object):
|
|
self._new_line()
|
|
return self.visit(node.body)
|
|
|
|
+ # Python < 3.4
|
|
# arguments = (expr* args, identifier? vararg,
|
|
# identifier? kwarg, expr* defaults)
|
|
+ #
|
|
+ # Python >= 3.4
|
|
+ # arguments = (arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults,
|
|
+ # arg? kwarg, expr* defaults)
|
|
def visit_arguments(self, node):
|
|
first = True
|
|
no_default_count = len(node.args) - len(node.defaults)
|
|
@@ -122,13 +127,21 @@ class ASTCodeGenerator(object):
|
|
self._write(', ')
|
|
else:
|
|
first = False
|
|
- self._write('*' + node.vararg)
|
|
+ self._write('*')
|
|
+ if isstring(node.vararg):
|
|
+ self._write(node.vararg)
|
|
+ else:
|
|
+ self.visit(node.vararg)
|
|
if getattr(node, 'kwarg', None):
|
|
if not first:
|
|
self._write(', ')
|
|
else:
|
|
first = False
|
|
- self._write('**' + node.kwarg)
|
|
+ self._write('**')
|
|
+ if isstring(node.kwarg):
|
|
+ self._write(node.kwarg)
|
|
+ else:
|
|
+ self.visit(node.kwarg)
|
|
|
|
if not IS_PYTHON2:
|
|
# In Python 3 arguments get a special node
|
|
@@ -724,6 +737,17 @@ class ASTCodeGenerator(object):
|
|
def visit_Name(self, node):
|
|
self._write(node.id)
|
|
|
|
+ # NameConstant(singleton value)
|
|
+ def visit_NameConstant(self, node):
|
|
+ if node.value is None:
|
|
+ self._write('None')
|
|
+ elif node.value is True:
|
|
+ self._write('True')
|
|
+ elif node.value is False:
|
|
+ self._write('False')
|
|
+ else:
|
|
+ raise Exception("Unknown NameConstant %r" % (node.value,))
|
|
+
|
|
# List(expr* elts, expr_context ctx)
|
|
def visit_List(self, node):
|
|
self._write('[')
|
|
@@ -829,6 +853,7 @@ class ASTTransformer(object):
|
|
visit_Attribute = _clone
|
|
visit_Subscript = _clone
|
|
visit_Name = _clone
|
|
+ visit_NameConstant = _clone
|
|
visit_List = _clone
|
|
visit_Tuple = _clone
|
|
|
|
diff --git a/genshi/template/eval.py b/genshi/template/eval.py
|
|
index 89aec49..de4bc86 100644
|
|
--- a/genshi/template/eval.py
|
|
+++ b/genshi/template/eval.py
|
|
@@ -24,7 +24,8 @@ from genshi.template.astutil import ASTTransformer, ASTCodeGenerator, \
|
|
from genshi.template.base import TemplateRuntimeError
|
|
from genshi.util import flatten
|
|
|
|
-from genshi.compat import get_code_params, build_code_chunk, IS_PYTHON2
|
|
+from genshi.compat import get_code_params, build_code_chunk, isstring, \
|
|
+ IS_PYTHON2
|
|
|
|
__all__ = ['Code', 'Expression', 'Suite', 'LenientLookup', 'StrictLookup',
|
|
'Undefined', 'UndefinedError']
|
|
@@ -495,28 +496,31 @@ class TemplateASTTransformer(ASTTransformer):
|
|
def __init__(self):
|
|
self.locals = [CONSTANTS]
|
|
|
|
+ def _process(self, names, node):
|
|
+ if not IS_PYTHON2 and isinstance(node, _ast.arg):
|
|
+ names.add(node.arg)
|
|
+ elif isstring(node):
|
|
+ names.add(node)
|
|
+ elif isinstance(node, _ast.Name):
|
|
+ names.add(node.id)
|
|
+ elif isinstance(node, _ast.alias):
|
|
+ names.add(node.asname or node.name)
|
|
+ elif isinstance(node, _ast.Tuple):
|
|
+ for elt in node.elts:
|
|
+ self._process(names, elt)
|
|
+
|
|
def _extract_names(self, node):
|
|
names = set()
|
|
- def _process(node):
|
|
- if not IS_PYTHON2 and isinstance(node, _ast.arg):
|
|
- names.add(node.arg)
|
|
- if isinstance(node, _ast.Name):
|
|
- names.add(node.id)
|
|
- elif isinstance(node, _ast.alias):
|
|
- names.add(node.asname or node.name)
|
|
- elif isinstance(node, _ast.Tuple):
|
|
- for elt in node.elts:
|
|
- _process(elt)
|
|
if hasattr(node, 'args'):
|
|
for arg in node.args:
|
|
- _process(arg)
|
|
+ self._process(names, arg)
|
|
if hasattr(node, 'vararg'):
|
|
- names.add(node.vararg)
|
|
+ self._process(names, node.vararg)
|
|
if hasattr(node, 'kwarg'):
|
|
- names.add(node.kwarg)
|
|
+ self._process(names, node.kwarg)
|
|
elif hasattr(node, 'names'):
|
|
for elt in node.names:
|
|
- _process(elt)
|
|
+ self._process(names, elt)
|
|
return names
|
|
|
|
def visit_Str(self, node):
|
|
--
|
|
2.12.0
|
|
|