Skip to content

Commit

Permalink
Updated for fluent.syntax 0.14+ / Fluent spec 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
spookylukey committed May 3, 2019
1 parent 3cc4ecd commit 3475416
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 137 deletions.
10 changes: 5 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@ python:
- "nightly"
env:
global:
- FLUENT_RUNTIME_DEFAULT_DEPS="fluent.syntax==0.13.0 attrs==19.1.0 babel==2.6.0 pytz==2018.9 six==1.12.0"
- FLUENT_RUNTIME_DEFAULT_DEPS="fluent.syntax==0.15 attrs==19.1.0 babel==2.6.0 pytz==2018.9 six==1.12.0"
- FLUENT_SYNTAX_DEFAULT_DEPS="six"
matrix:
- PACKAGE=fluent.syntax
- PACKAGE=fluent.runtime
matrix:
include:
- name: "fluent.runtime w/ fluent.syntax==0.10"
- name: "fluent.runtime w/ fluent.syntax==0.14"
python: "3.6"
env: PACKAGE=fluent.runtime TEST_DEPS="fluent.syntax==0.10.0 attrs==19.1.0 babel==2.6.0 pytz==2018.9 six==1.12.0"
env: PACKAGE=fluent.runtime TEST_DEPS="fluent.syntax==0.14 attrs==19.1.0 babel==2.6.0 pytz==2018.9 six==1.12.0"
- name: "fluent.runtime with latest everything"
python: "3.6"
# These are copy-pasted from setup.py
env: PACKAGE=fluent.runtime TEST_DEPS="fluent.syntax>=0.10,<=0.13 attrs babel pytz six"
env: PACKAGE=fluent.runtime TEST_DEPS="fluent.syntax>=0.14,<=0.16 attrs babel pytz six"
allow_failures:
- python: "3.6"
env: PACKAGE=fluent.runtime TEST_DEPS="fluent.syntax>=0.10,<=0.13 attrs babel pytz six"
env: PACKAGE=fluent.runtime TEST_DEPS="fluent.syntax>=0.14,<=0.16 attrs babel pytz six"

install:
- if [ "$PACKAGE" = "fluent.runtime" ]; then TEST_DEPS=${TEST_DEPS:-$FLUENT_RUNTIME_DEFAULT_DEPS}; else TEST_DEPS=${TEST_DEPS:-$FLUENT_SYNTAX_DEFAULT_DEPS}; fi
Expand Down
75 changes: 17 additions & 58 deletions fluent.runtime/fluent/runtime/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def __call__(self, env):

class StringLiteral(FTL.StringLiteral, Literal):
def __call__(self, env):
return self.value
return self.parse()['value']


class NumberLiteral(FTL.NumberLiteral, BaseResolver):
Expand All @@ -180,7 +180,14 @@ def __call__(self, env):

class TermReference(FTL.TermReference, BaseResolver):
def __call__(self, env):
with env.modified_for_term_reference():
if self.arguments:
if self.arguments.positional:
env.errors.append(FluentFormatError("Ignored positional arguments passed to term '{0}'"
.format(reference_to_id(self))))
kwargs = {kwarg.name.name: kwarg.value(env) for kwarg in self.arguments.named}
else:
kwargs = None
with env.modified_for_term_reference(args=kwargs):
return lookup_reference(self, env)(env)


Expand All @@ -200,9 +207,9 @@ def lookup_reference(ref, env):
except LookupError:
env.errors.append(unknown_reference_error_obj(ref_id))

if isinstance(ref, AttributeExpression):
if ref.attribute:
# Fallback
parent_id = reference_to_id(ref.ref)
parent_id = reference_to_id(ref, ignore_attributes=True)
try:
return env.context.lookup(parent_id)
except LookupError:
Expand Down Expand Up @@ -231,40 +238,10 @@ def __call__(self, env):
return FluentNone(name)


class AttributeExpression(FTL.AttributeExpression, BaseResolver):
def __call__(self, env):
return lookup_reference(self, env)(env)


class Attribute(FTL.Attribute, BaseResolver):
pass


class VariantList(FTL.VariantList, BaseResolver):
def __call__(self, env, key=None):
found = None
for variant in self.variants:
if variant.default:
default = variant
if key is None:
# We only want the default
break

compare_value = variant.key(env)
if match(key, compare_value, env):
found = variant
break

if found is None:
if (key is not None and not isinstance(key, FluentNone)):
env.errors.append(FluentReferenceError("Unknown variant: {0}"
.format(key)))
found = default
assert found, "Not having a default variant is a parse error"

return found.value(env)


class SelectExpression(FTL.SelectExpression, BaseResolver):
def __call__(self, env):
key = self.selector(env)
Expand Down Expand Up @@ -314,33 +291,15 @@ def __call__(self, env):
return self.name


class VariantExpression(FTL.VariantExpression, BaseResolver):
def __call__(self, env):
message = lookup_reference(self.ref, env)

# TODO What to do if message is not a VariantList?
# Need test at least.
assert isinstance(message, VariantList)

variant_name = self.key.name
return message(env, variant_name)
class CallArguments(FTL.CallArguments, BaseResolver):
pass


class CallExpression(FTL.CallExpression, BaseResolver):
class FunctionReference(FTL.FunctionReference, BaseResolver):
def __call__(self, env):
args = [arg(env) for arg in self.positional]
kwargs = {kwarg.name.name: kwarg.value(env) for kwarg in self.named}

if isinstance(self.callee, (TermReference, AttributeExpression)):
term = lookup_reference(self.callee, env)
if args:
env.errors.append(FluentFormatError("Ignored positional arguments passed to term '{0}'"
.format(reference_to_id(self.callee))))
with env.modified_for_term_reference(args=kwargs):
return term(env)

# builtin or custom function call
function_name = self.callee.id.name
args = [arg(env) for arg in self.arguments.positional]
kwargs = {kwarg.name.name: kwarg.value(env) for kwarg in self.arguments.named}
function_name = self.id.name
try:
function = env.context._functions[function_name]
except LookupError:
Expand Down
25 changes: 10 additions & 15 deletions fluent.runtime/fluent/runtime/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from datetime import date, datetime
from decimal import Decimal

from fluent.syntax.ast import AttributeExpression, Term, TermReference
from fluent.syntax.ast import Term, TermReference

from .types import FluentInt, FluentFloat, FluentDecimal, FluentDate, FluentDateTime
from .errors import FluentReferenceError
Expand Down Expand Up @@ -39,9 +39,9 @@ def native_to_fluent(val):
return val


def reference_to_id(ref):
def reference_to_id(ref, ignore_attributes=False):
"""
Returns a string reference for a MessageReference, TermReference or AttributeExpression
Returns a string reference for a MessageReference or TermReference
AST node.
e.g.
Expand All @@ -50,12 +50,14 @@ def reference_to_id(ref):
-term
-term.attr
"""
if isinstance(ref, AttributeExpression):
return _make_attr_id(reference_to_id(ref.ref),
ref.name.name)
if isinstance(ref, TermReference):
return TERM_SIGIL + ref.id.name
return ref.id.name
start = TERM_SIGIL + ref.id.name
else:
start = ref.id.name

if not ignore_attributes and ref.attribute:
return ''.join([start, ATTRIBUTE_SEPARATOR, ref.attribute.name])
return start


def unknown_reference_error_obj(ref_id):
Expand All @@ -64,10 +66,3 @@ def unknown_reference_error_obj(ref_id):
if ref_id.startswith(TERM_SIGIL):
return FluentReferenceError("Unknown term: {0}".format(ref_id))
return FluentReferenceError("Unknown message: {0}".format(ref_id))


def _make_attr_id(parent_ref_id, attr_name):
"""
Given a parent id and the attribute name, return the attribute id
"""
return ''.join([parent_ref_id, ATTRIBUTE_SEPARATOR, attr_name])
2 changes: 1 addition & 1 deletion fluent.runtime/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
packages=['fluent', 'fluent.runtime'],
# These should also be duplicated in tox.ini and ../.travis.yml
install_requires=[
'fluent.syntax>=0.10,<=0.13',
'fluent.syntax>=0.14,<=0.16',
'attrs',
'babel',
'pytz',
Expand Down
6 changes: 0 additions & 6 deletions fluent.runtime/tests/format/test_placeables.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ def setUp(self):
uses-message = { message }
uses-message-attr = { message.attr }
uses-term = { -term }
uses-term-variant = { -term2[variant2] }
bad-message-ref = Text { not-a-message }
bad-message-attr-ref = Text { message.not-an-attr }
Expand Down Expand Up @@ -57,11 +56,6 @@ def test_placeable_term(self):
self.assertEqual(val, 'Term')
self.assertEqual(len(errs), 0)

def test_placeable_term_variant(self):
val, errs = self.ctx.format('uses-term-variant', {})
self.assertEqual(val, 'Term Variant 2')
self.assertEqual(len(errs), 0)

def test_placeable_bad_message(self):
val, errs = self.ctx.format('bad-message-ref', {})
self.assertEqual(val, 'Text not-a-message')
Expand Down
9 changes: 8 additions & 1 deletion fluent.runtime/tests/format/test_primitives.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals

import unittest
Expand All @@ -10,7 +11,7 @@
class TestSimpleStringValue(unittest.TestCase):
def setUp(self):
self.ctx = FluentBundle(['en-US'], use_isolating=False)
self.ctx.add_messages(dedent_ftl("""
self.ctx.add_messages(dedent_ftl(r"""
foo = Foo
placeable-literal = { "Foo" } Bar
placeable-message = { foo } Bar
Expand All @@ -27,6 +28,7 @@ def setUp(self):
[BazAttribute] Member 3
*[other] Member 4
}
escapes = {" "}stuff{"\u0258}\"\\end"}
"""))

def test_can_be_used_as_a_value(self):
Expand Down Expand Up @@ -64,6 +66,11 @@ def test_can_be_a_value_of_an_attribute_used_as_a_selector(self):
self.assertEqual(val, 'Member 3')
self.assertEqual(len(errs), 0)

def test_escapes(self):
val, errs = self.ctx.format('escapes', {})
self.assertEqual(val, r' stuffɘ}"\end')
self.assertEqual(len(errs), 0)


class TestComplexStringValue(unittest.TestCase):
def setUp(self):
Expand Down
47 changes: 0 additions & 47 deletions fluent.runtime/tests/format/test_variants.py

This file was deleted.

8 changes: 4 additions & 4 deletions fluent.runtime/tox.ini
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# This config is for local testing. It should be duplicated into .travis.yml
[tox]
envlist = {py27,py35,py36,py37,pypy,pypy3}-syntax0.13, py36-syntax0.10, latest
envlist = {py27,py35,py36,py37,pypy,pypy3}-syntax0.15, py36-syntax0.14, latest
skipsdist=True

[testenv]
setenv =
PYTHONPATH = {toxinidir}
deps =
syntax0.10: fluent.syntax==0.10.0
syntax0.13: fluent.syntax==0.13.0
syntax0.15: fluent.syntax==0.15
syntax0.14: fluent.syntax==0.14
attrs==19.1.0
babel==2.6.0
pytz==2018.9
Expand All @@ -22,7 +22,7 @@ deps =
# It's tempting to use '.' here to get 'pip install .'
# Unfortunately it is super slow: https://github.com/pypa/pip/issues/2195
# Instead we copy-paste from setup.py
fluent.syntax>=0.10,<=0.13
fluent.syntax>=0.14,<=0.16
attrs
babel
pytz
Expand Down

0 comments on commit 3475416

Please sign in to comment.