Skip to content

Drop Python 2.7, 3.5 support, add 3.6-3.9 for fluent.syntax #161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/fluent.syntax.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [2.7, 3.5, 3.6, 3.7, 3.8, pypy2, pypy3]
python-version: [3.6, 3.7, 3.8, 3.9, pypy3]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
Expand All @@ -35,7 +35,6 @@ jobs:
run: |
python -m pip install wheel
python -m pip install --upgrade pip
python -m pip install six
- name: Test
working-directory: ./fluent.syntax
run: |
Expand All @@ -47,7 +46,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.7
python-version: 3.9
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
5 changes: 5 additions & 0 deletions fluent.syntax/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## fluent.syntax 0.19 (TBD)

- Drop support for Python 2.7 and 3.5
- Add support for Python 3.6 through 3.9

## fluent.syntax 0.18.1 (September 15, 2020)

- Fix serialization of multiline patterns starting with special characters. (#156)
Expand Down
57 changes: 27 additions & 30 deletions fluent.syntax/fluent/syntax/ast.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# coding=utf-8
from __future__ import unicode_literals
import re
import sys
import json
import six


def to_json(value, fn=None):
Expand Down Expand Up @@ -44,7 +41,7 @@ def scalars_equal(node1, node2, ignored_fields):
return node1 == node2


class BaseNode(object):
class BaseNode:
"""Base class for all Fluent AST nodes.

All productions described in the ASDL subclass BaseNode, including Span and
Expand Down Expand Up @@ -125,7 +122,7 @@ class SyntaxNode(BaseNode):
"""Base class for AST nodes which can have Spans."""

def __init__(self, span=None, **kwargs):
super(SyntaxNode, self).__init__(**kwargs)
super().__init__(**kwargs)
self.span = span

def add_span(self, start, end):
Expand All @@ -134,7 +131,7 @@ def add_span(self, start, end):

class Resource(SyntaxNode):
def __init__(self, body=None, **kwargs):
super(Resource, self).__init__(**kwargs)
super().__init__(**kwargs)
self.body = body or []


Expand All @@ -145,7 +142,7 @@ class Entry(SyntaxNode):
class Message(Entry):
def __init__(self, id, value=None, attributes=None,
comment=None, **kwargs):
super(Message, self).__init__(**kwargs)
super().__init__(**kwargs)
self.id = id
self.value = value
self.attributes = attributes or []
Expand All @@ -155,7 +152,7 @@ def __init__(self, id, value=None, attributes=None,
class Term(Entry):
def __init__(self, id, value, attributes=None,
comment=None, **kwargs):
super(Term, self).__init__(**kwargs)
super().__init__(**kwargs)
self.id = id
self.value = value
self.attributes = attributes or []
Expand All @@ -164,7 +161,7 @@ def __init__(self, id, value, attributes=None,

class Pattern(SyntaxNode):
def __init__(self, elements, **kwargs):
super(Pattern, self).__init__(**kwargs)
super().__init__(**kwargs)
self.elements = elements


Expand All @@ -174,13 +171,13 @@ class PatternElement(SyntaxNode):

class TextElement(PatternElement):
def __init__(self, value, **kwargs):
super(TextElement, self).__init__(**kwargs)
super().__init__(**kwargs)
self.value = value


class Placeable(PatternElement):
def __init__(self, expression, **kwargs):
super(Placeable, self).__init__(**kwargs)
super().__init__(**kwargs)
self.expression = expression


Expand All @@ -191,7 +188,7 @@ class Expression(SyntaxNode):
class Literal(Expression):
"""An abstract base class for literals."""
def __init__(self, value, **kwargs):
super(Literal, self).__init__(**kwargs)
super().__init__(**kwargs)
self.value = value

def parse(self):
Expand All @@ -206,7 +203,7 @@ def from_escape_sequence(matchobj):
return c
codepoint = int(codepoint4 or codepoint6, 16)
if codepoint <= 0xD7FF or 0xE000 <= codepoint:
return six.unichr(codepoint)
return chr(codepoint)
# Escape sequences reresenting surrogate code points are
# well-formed but invalid in Fluent. Replace them with U+FFFD
# REPLACEMENT CHARACTER.
Expand Down Expand Up @@ -235,98 +232,98 @@ def parse(self):

class MessageReference(Expression):
def __init__(self, id, attribute=None, **kwargs):
super(MessageReference, self).__init__(**kwargs)
super().__init__(**kwargs)
self.id = id
self.attribute = attribute


class TermReference(Expression):
def __init__(self, id, attribute=None, arguments=None, **kwargs):
super(TermReference, self).__init__(**kwargs)
super().__init__(**kwargs)
self.id = id
self.attribute = attribute
self.arguments = arguments


class VariableReference(Expression):
def __init__(self, id, **kwargs):
super(VariableReference, self).__init__(**kwargs)
super().__init__(**kwargs)
self.id = id


class FunctionReference(Expression):
def __init__(self, id, arguments, **kwargs):
super(FunctionReference, self).__init__(**kwargs)
super().__init__(**kwargs)
self.id = id
self.arguments = arguments


class SelectExpression(Expression):
def __init__(self, selector, variants, **kwargs):
super(SelectExpression, self).__init__(**kwargs)
super().__init__(**kwargs)
self.selector = selector
self.variants = variants


class CallArguments(SyntaxNode):
def __init__(self, positional=None, named=None, **kwargs):
super(CallArguments, self).__init__(**kwargs)
super().__init__(**kwargs)
self.positional = [] if positional is None else positional
self.named = [] if named is None else named


class Attribute(SyntaxNode):
def __init__(self, id, value, **kwargs):
super(Attribute, self).__init__(**kwargs)
super().__init__(**kwargs)
self.id = id
self.value = value


class Variant(SyntaxNode):
def __init__(self, key, value, default=False, **kwargs):
super(Variant, self).__init__(**kwargs)
super().__init__(**kwargs)
self.key = key
self.value = value
self.default = default


class NamedArgument(SyntaxNode):
def __init__(self, name, value, **kwargs):
super(NamedArgument, self).__init__(**kwargs)
super().__init__(**kwargs)
self.name = name
self.value = value


class Identifier(SyntaxNode):
def __init__(self, name, **kwargs):
super(Identifier, self).__init__(**kwargs)
super().__init__(**kwargs)
self.name = name


class BaseComment(Entry):
def __init__(self, content=None, **kwargs):
super(BaseComment, self).__init__(**kwargs)
super().__init__(**kwargs)
self.content = content


class Comment(BaseComment):
def __init__(self, content=None, **kwargs):
super(Comment, self).__init__(content, **kwargs)
super().__init__(content, **kwargs)


class GroupComment(BaseComment):
def __init__(self, content=None, **kwargs):
super(GroupComment, self).__init__(content, **kwargs)
super().__init__(content, **kwargs)


class ResourceComment(BaseComment):
def __init__(self, content=None, **kwargs):
super(ResourceComment, self).__init__(content, **kwargs)
super().__init__(content, **kwargs)


class Junk(SyntaxNode):
def __init__(self, content=None, annotations=None, **kwargs):
super(Junk, self).__init__(**kwargs)
super().__init__(**kwargs)
self.content = content
self.annotations = annotations or []

Expand All @@ -336,14 +333,14 @@ def add_annotation(self, annot):

class Span(BaseNode):
def __init__(self, start, end, **kwargs):
super(Span, self).__init__(**kwargs)
super().__init__(**kwargs)
self.start = start
self.end = end


class Annotation(SyntaxNode):
def __init__(self, code, arguments=None, message=None, **kwargs):
super(Annotation, self).__init__(**kwargs)
super().__init__(**kwargs)
self.code = code
self.arguments = arguments or []
self.message = message
3 changes: 0 additions & 3 deletions fluent.syntax/fluent/syntax/errors.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
from __future__ import unicode_literals


class ParseError(Exception):
def __init__(self, code, *args):
self.code = code
Expand Down
9 changes: 4 additions & 5 deletions fluent.syntax/fluent/syntax/parser.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from __future__ import unicode_literals
import re
from . import ast
from .stream import EOF, EOL, FluentParserStream
Expand All @@ -25,7 +24,7 @@ def decorated(self, ps, *args, **kwargs):
return decorated


class FluentParser(object):
class FluentParser:
"""This class is used to parse Fluent source content.

``with_spans`` enables source information in the form of
Expand Down Expand Up @@ -469,7 +468,7 @@ def get_escape_sequence(self, ps):

if next == '\\' or next == '"':
ps.next()
return '\\{}'.format(next)
return f'\\{next}'

if next == 'u':
return self.get_unicode_escape_sequence(ps, next, 4)
Expand All @@ -485,10 +484,10 @@ def get_unicode_escape_sequence(self, ps, u, digits):
for _ in range(digits):
ch = ps.take_hex_digit()
if not ch:
raise ParseError('E0026', '\\{}{}{}'.format(u, sequence, ps.current_char))
raise ParseError('E0026', f'\\{u}{sequence}{ps.current_char}')
sequence += ch

return '\\{}{}'.format(u, sequence)
return f'\\{u}{sequence}'

@with_span
def get_placeable(self, ps):
Expand Down
Loading