From b1533c43669c037d04c87d1756355cdc8edd5e0a Mon Sep 17 00:00:00 2001
From: Damien George <damien.p.george@gmail.com>
Date: Mon, 6 Jun 2016 17:28:32 +0100
Subject: [PATCH] py/parse: Treat constants that start with underscore as
 private.

Assignments of the form "_id = const(value)" are treated as private
(following a similar CPython convention) and code is no longer emitted
for the assignment to a global variable.

See issue #2111.
---
 py/parse.c                     | 11 +++++++++++
 tests/micropython/const.py     | 12 ++++++++++++
 tests/micropython/const.py.exp |  3 +++
 3 files changed, 26 insertions(+)

diff --git a/py/parse.c b/py/parse.c
index 7da484c49..1ec995cd8 100644
--- a/py/parse.c
+++ b/py/parse.c
@@ -461,6 +461,8 @@ STATIC const mp_rom_map_elem_t mp_constants_table[] = {
 STATIC MP_DEFINE_CONST_MAP(mp_constants_map, mp_constants_table);
 #endif
 
+STATIC void push_result_rule(parser_t *parser, size_t src_line, const rule_t *rule, size_t num_args);
+
 #if MICROPY_COMP_CONST_FOLDING
 STATIC bool fold_constants(parser_t *parser, const rule_t *rule, size_t num_args) {
     // this code does folding of arbitrary integer expressions, eg 1 + 2 * 3 + 4
@@ -587,6 +589,15 @@ STATIC bool fold_constants(parser_t *parser, const rule_t *rule, size_t num_args
                 assert(elem->value == MP_OBJ_NULL);
                 elem->value = MP_OBJ_NEW_SMALL_INT(value);
 
+                // If the constant starts with an underscore then treat it as a private
+                // variable and don't emit any code to store the value to the id.
+                if (qstr_str(id)[0] == '_') {
+                    pop_result(parser); // pop const(value)
+                    pop_result(parser); // pop id
+                    push_result_rule(parser, 0, rules[RULE_pass_stmt], 0); // replace with "pass"
+                    return true;
+                }
+
                 // replace const(value) with value
                 pop_result(parser);
                 push_result_node(parser, pn_value);
diff --git a/tests/micropython/const.py b/tests/micropython/const.py
index 457365c50..09717fd14 100644
--- a/tests/micropython/const.py
+++ b/tests/micropython/const.py
@@ -9,3 +9,15 @@ def f():
     print(X, Y + 1)
 
 f()
+
+_X = const(12)
+_Y = const(_X + 34)
+
+print(_X, _Y)
+
+class A:
+    Z = const(1)
+    _Z = const(2)
+    print(Z, _Z)
+
+print(hasattr(A, 'Z'), hasattr(A, '_Z'))
diff --git a/tests/micropython/const.py.exp b/tests/micropython/const.py.exp
index c447aaf8c..ece6a5cb2 100644
--- a/tests/micropython/const.py.exp
+++ b/tests/micropython/const.py.exp
@@ -1,2 +1,5 @@
 123 580
 123 580
+12 46
+1 2
+True False
-- 
GitLab