From 1311c455281f74c64038d5bed6bef9718ce2f606 Mon Sep 17 00:00:00 2001 From: Philipp Hossner Date: Tue, 29 Oct 2019 21:13:54 +0100 Subject: [PATCH] Add support for Python 3.8 --- .travis.yml | 5 +--- astmonkey/tests/test_visitors.py | 17 ++++++++++- astmonkey/visitors.py | 48 +++++++++++++++++++++++++++++++- setup.py | 2 ++ tox.ini | 2 +- 5 files changed, 67 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index dd98e64..fef849d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,12 @@ language: python matrix: include: - - python: 2.6 - python: 2.7 - - python: 3.3 - python: 3.4 - python: 3.5 - python: 3.6 - python: 3.7 - dist: xenial - sudo: true + - python: 3.8 install: # python 2.6 and 3.3 compatibility - if [[ $TRAVIS_PYTHON_VERSION == 2.6 ]]; then pip install pycparser==2.14 cryptography==2.1.4; fi diff --git a/astmonkey/tests/test_visitors.py b/astmonkey/tests/test_visitors.py index 12ddec8..67db84e 100644 --- a/astmonkey/tests/test_visitors.py +++ b/astmonkey/tests/test_visitors.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import sys + import pytest try: @@ -34,7 +36,10 @@ def test_node_label(self, visitor): visitor.visit(node) dot_node = visitor.graph.get_node(str(node.body[0].value))[0] - assert dot_node.get_label() == 'ast.Num(n=1)' + if sys.version_info >= (3, 8): + assert dot_node.get_label() == 'ast.Constant(value=1, kind=None)' + else: + assert dot_node.get_label() == 'ast.Num(n=1)' def test_edge_label(self, visitor): node = transformers.ParentChildNodeTransformer().visit(ast.parse('x = 1')) @@ -350,6 +355,16 @@ class TestSourceGeneratorNodeVisitor(object): "f'{x!a}'", ] + if utils.check_version(from_inclusive=(3, 8)): + roundtrip_testdata += [ + # assignment expressions + 'if n := len(a) > 10:' + EOL + INDENT + PASS, + # positional-only parameters + 'def f(a, /, b, *, c):' + EOL + INDENT + PASS, + # positional-only parameters with defaults + 'def f(a=1, /, b=2, *, c=3):' + EOL + INDENT + PASS, + ] + # add additional tests for semantic testing semantic_testdata = list(roundtrip_testdata) diff --git a/astmonkey/visitors.py b/astmonkey/visitors.py index 6afb444..14b1ee1 100644 --- a/astmonkey/visitors.py +++ b/astmonkey/visitors.py @@ -1013,6 +1013,51 @@ def visit_FormattedValue(self, node): self.write('!%c' % (node.conversion,)) +class SourceGeneratorNodeVisitorPython38(SourceGeneratorNodeVisitorPython36): + __python_version__ = (3, 8) + + def visit_Constant(self, node): + if type(node.value) == str: + self.write(repr(node.s)) + elif node.value == Ellipsis: + self.write('...') + else: + self.write(str(node.value)) + + def visit_NamedExpr(self, node): + self.visit(node.target) + self.write(' := ') + self.visit(node.value) + + def signature(self, node, add_space=False): + write_comma = CommaWriter(self.write, add_space_at_beginning=add_space) + + + defaults = list(node.defaults) + + if node.posonlyargs: + padding = [None] * (len(node.posonlyargs) - len(node.defaults)) + for arg, default in zip(node.posonlyargs, padding + defaults[:len(node.posonlyargs)]): + self.signature_arg(arg, default, write_comma) + self.write(', /') + defaults = defaults[len(node.posonlyargs):] + + padding = [None] * (len(node.args) - len(node.defaults)) + for arg, default in zip(node.args, padding + defaults): + self.signature_arg(arg, default, write_comma) + + self.signature_spec_arg(node, 'vararg', write_comma, prefix='*') + self.signature_kwonlyargs(node, write_comma) + self.signature_spec_arg(node, 'kwarg', write_comma, prefix='**') + + @classmethod + def _get_actual_lineno(cls, node): + if isinstance(node, ast.FunctionDef) and node.decorator_list: + return node.decorator_list[0].lineno + else: + return SourceGeneratorNodeVisitorPython36._get_actual_lineno(node) + + SourceGeneratorNodeVisitor = utils.get_by_python_version([ SourceGeneratorNodeVisitorPython26, SourceGeneratorNodeVisitorPython27, @@ -1022,5 +1067,6 @@ def visit_FormattedValue(self, node): SourceGeneratorNodeVisitorPython33, SourceGeneratorNodeVisitorPython34, SourceGeneratorNodeVisitorPython35, - SourceGeneratorNodeVisitorPython36 + SourceGeneratorNodeVisitorPython36, + SourceGeneratorNodeVisitorPython38 ]) diff --git a/setup.py b/setup.py index 027806a..f945a54 100644 --- a/setup.py +++ b/setup.py @@ -24,6 +24,8 @@ 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', 'License :: OSI Approved :: Apache Software License' ] ) diff --git a/tox.ini b/tox.ini index 0f8fd51..bfcfe42 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] envlist = coverage-erase - test-py{26,27,33,34,35,36,37} + test-py{27,34,35,36,37,38} coverage-report [testenv] deps=