From 7e138eca3b6b3adef59c9b065aa0cd06043f3126 Mon Sep 17 00:00:00 2001 From: Windel Bouwman Date: Sun, 7 Jul 2019 12:04:43 +0200 Subject: [PATCH] Improve f-string syntax. Fixes #1099 --- parser/src/python.lalrpop | 2 +- tests/snippets/fstrings.py | 6 ++++++ vm/src/obj/objbool.rs | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/parser/src/python.lalrpop b/parser/src/python.lalrpop index 60a81e0203..4d92aac28a 100644 --- a/parser/src/python.lalrpop +++ b/parser/src/python.lalrpop @@ -19,7 +19,7 @@ grammar; pub Top: ast::Top = { StartProgram => ast::Top::Program(p), StartStatement => ast::Top::Statement(s), - StartExpression => ast::Top::Expression(e), + StartExpression => ast::Top::Expression(e), }; Program: ast::Program = { diff --git a/tests/snippets/fstrings.py b/tests/snippets/fstrings.py index c76967acb8..445911c687 100644 --- a/tests/snippets/fstrings.py +++ b/tests/snippets/fstrings.py @@ -39,3 +39,9 @@ def __str__(self): assert f'{v}' == 'foo' assert f'{v!r}' == 'bar' assert f'{v!s}' == 'baz' + +# advanced expressions: + +assert f'{True or True}' == 'True' +assert f'{1 == 1}' == 'True' +assert f'{"0" if True else "1"}' == '0' diff --git a/vm/src/obj/objbool.rs b/vm/src/obj/objbool.rs index f294434b30..1892eafcb7 100644 --- a/vm/src/obj/objbool.rs +++ b/vm/src/obj/objbool.rs @@ -5,6 +5,7 @@ use crate::pyobject::{IntoPyObject, PyContext, PyObjectRef, PyResult, TryFromObj use crate::vm::VirtualMachine; use super::objint::PyInt; +use super::objstr::PyStringRef; use super::objtype; impl IntoPyObject for bool { @@ -47,6 +48,7 @@ The class bool is a subclass of the class int, and cannot be subclassed."; extend_class!(context, bool_type, { "__new__" => context.new_rustfunc(bool_new), "__repr__" => context.new_rustfunc(bool_repr), + "__format__" => context.new_rustfunc(bool_format), "__or__" => context.new_rustfunc(bool_or), "__ror__" => context.new_rustfunc(bool_ror), "__and__" => context.new_rustfunc(bool_and), @@ -82,6 +84,18 @@ fn bool_repr(vm: &VirtualMachine, args: PyFuncArgs) -> Result PyResult { + if format_spec.value.is_empty() { + vm.to_str(&obj) + } else { + Err(vm.new_type_error("unsupported format string passed to bool.__format__".to_string())) + } +} + fn do_bool_or(vm: &VirtualMachine, lhs: &PyObjectRef, rhs: &PyObjectRef) -> PyResult { if objtype::isinstance(lhs, &vm.ctx.bool_type()) && objtype::isinstance(rhs, &vm.ctx.bool_type())