changeset 86:a7b1db623f41

Implement NameConstant correctly.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Wed, 22 Jun 2016 22:55:55 +0100
parents 09f5e0d7bcf3
children 624393ed3b0b
files src/ast_convert.rs src/ast_dump.rs src/python_ast.rs tests/test_parse_files/test_name_constant.py
diffstat 4 files changed, 32 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/ast_convert.rs
+++ b/src/ast_convert.rs
@@ -1,6 +1,6 @@
-use python_ast::{Module, stmt, expr, expr_context, cmpop, boolop, operator, unaryop, arguments, arg, alias, comprehension, keyword, withitem, excepthandler, slice};
+use python_ast::{Module, stmt, expr, expr_context, cmpop, boolop, operator, unaryop, arguments, arg, alias, comprehension, keyword, withitem, excepthandler, slice, name_constant};
 
-use cpython::{Python, PyObject};
+use cpython::{Python, PyObject, PyBool, PyResult};
 use cpython::ObjectProtocol; //for call method
 
 fn get_str(py: Python, object: PyObject) -> String {
@@ -369,8 +369,19 @@ fn parse_expr(py: Python, ast: PyObject)
         expr::Name(id, get_ctx(py, ast))
     } else if is_instance(&ast, &name_constant_type) {
         let value = ast.getattr(py, "value").unwrap();
-        let value = get_str(py, value);
-        expr::NameConstant(value)
+        let boolean: PyResult<PyBool> = value.extract(py);
+        let constant = match boolean {
+            Ok(boolean) => if boolean.is_true() {
+                name_constant::True
+            } else {
+                name_constant::False
+            },
+            Err(_) => {
+                assert!(value == py.None());
+                name_constant::None_
+            }
+        };
+        expr::NameConstant(constant)
     } else if is_instance(&ast, &num_type) {
         let n = ast.getattr(py, "n").unwrap();
         let n = get_str(py, n);
--- a/src/ast_dump.rs
+++ b/src/ast_dump.rs
@@ -1,4 +1,4 @@
-use python_ast::{Module, stmt, expr, boolop, operator, unaryop, cmpop, arguments, arg, keyword, comprehension, withitem, excepthandler, slice};
+use python_ast::{Module, stmt, expr, boolop, operator, unaryop, cmpop, arguments, arg, keyword, comprehension, withitem, excepthandler, slice, name_constant};
 
 use std::iter;
 
@@ -196,7 +196,11 @@ impl to_string_able for expr {
             }),
             expr::Num(n) => format!("{}", n),
             expr::Str(s) => format!("\"{}\"", s),
-            expr::NameConstant(name) => format!("{}", name),
+            expr::NameConstant(constant) => match constant {
+                name_constant::True => String::from("True"),
+                name_constant::False => String::from("False"),
+                name_constant::None_ => String::from("None")
+            },
             expr::Attribute(value, attr, _) => format!("{}.{}", value.to_string(), attr),
             expr::Name(name, _) => format!("{}", name),
             expr::List(elts, _) => format!("[{}]", vec_to_strings_vec(elts).join(", ")),
--- a/src/python_ast.rs
+++ b/src/python_ast.rs
@@ -103,7 +103,7 @@ pub enum expr {
     Num(String),
     Str(String),
     //Bytes(String),
-    NameConstant(String),
+    NameConstant(name_constant),
     Ellipsis,
 
     // the following expression can appear in assignment context
@@ -126,6 +126,13 @@ pub enum expr_context {
 }
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub enum name_constant {
+    True,
+    False,
+    None_
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub enum slice {
     Slice(Option<expr>, Option<expr>, Option<expr>),
     ExtSlice(Vec<slice>),
new file mode 100644
--- /dev/null
+++ b/tests/test_parse_files/test_name_constant.py
@@ -0,0 +1,3 @@
+True
+False
+None