py: Rename MP_QSTR_NULL to MP_QSTRnull to avoid intern collisions.
Fixes #5140.
diff --git a/ports/stm32/pin.c b/ports/stm32/pin.c
index a8068d8..d032d99 100644
--- a/ports/stm32/pin.c
+++ b/ports/stm32/pin.c
@@ -214,14 +214,14 @@
mp_print_str(print, qstr_str(mode_qst));
// pull mode
- qstr pull_qst = MP_QSTR_NULL;
+ qstr pull_qst = MP_QSTRnull;
uint32_t pull = pin_get_pull(self);
if (pull == GPIO_PULLUP) {
pull_qst = MP_QSTR_PULL_UP;
} else if (pull == GPIO_PULLDOWN) {
pull_qst = MP_QSTR_PULL_DOWN;
}
- if (pull_qst != MP_QSTR_NULL) {
+ if (pull_qst != MP_QSTRnull) {
mp_printf(print, ", pull=Pin.%q", pull_qst);
}
diff --git a/ports/unix/coverage-frzmpy/frzqstr.py b/ports/unix/coverage-frzmpy/frzqstr.py
new file mode 100644
index 0000000..051f2a9
--- /dev/null
+++ b/ports/unix/coverage-frzmpy/frzqstr.py
@@ -0,0 +1,3 @@
+# Checks for regression on MP_QSTR_NULL
+def returns_NULL():
+ return "NULL"
diff --git a/py/compile.c b/py/compile.c
index a8ec0bf..90d1bfd 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -1205,7 +1205,7 @@
// do the import
qstr dummy_q;
do_import_name(comp, pn_import_source, &dummy_q);
- EMIT_ARG(import, MP_QSTR_NULL, MP_EMIT_IMPORT_STAR);
+ EMIT_ARG(import, MP_QSTRnull, MP_EMIT_IMPORT_STAR);
} else {
EMIT_ARG(load_const_small_int, import_level);
@@ -2823,7 +2823,7 @@
return;
}
- qstr param_name = MP_QSTR_NULL;
+ qstr param_name = MP_QSTRnull;
uint param_flag = ID_FLAG_IS_PARAM;
mp_parse_node_struct_t *pns = NULL;
if (MP_PARSE_NODE_IS_ID(pn)) {
@@ -2882,7 +2882,7 @@
}
}
- if (param_name != MP_QSTR_NULL) {
+ if (param_name != MP_QSTRnull) {
id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, ID_INFO_KIND_UNDECIDED);
if (id_info->kind != ID_INFO_KIND_UNDECIDED) {
compile_syntax_error(comp, pn, "argument name reused");
diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py
index 163b7fc..7799be0 100644
--- a/py/makeqstrdata.py
+++ b/py/makeqstrdata.py
@@ -339,7 +339,7 @@
print('')
# add NULL qstr with no hash or data
- print('QDEF(MP_QSTR_NULL, (const byte*)"%s%s" "")' % ('\\x00' * cfg_bytes_hash, '\\x00' * cfg_bytes_len))
+ print('QDEF(MP_QSTRnull, (const byte*)"%s%s" "")' % ('\\x00' * cfg_bytes_hash, '\\x00' * cfg_bytes_len))
# go through each qstr and print it out
for order, ident, qstr in sorted(qstrs.values(), key=lambda x: x[0]):
diff --git a/py/moduerrno.c b/py/moduerrno.c
index de66c94..0e0a3f0 100644
--- a/py/moduerrno.c
+++ b/py/moduerrno.c
@@ -104,7 +104,7 @@
// We have the errorcode dict so can do a lookup using the hash map
mp_map_elem_t *elem = mp_map_lookup((mp_map_t*)&errorcode_dict.map, errno_val, MP_MAP_LOOKUP);
if (elem == NULL) {
- return MP_QSTR_NULL;
+ return MP_QSTRnull;
} else {
return MP_OBJ_QSTR_VALUE(elem->value);
}
@@ -115,7 +115,7 @@
return MP_OBJ_QSTR_VALUE(mp_module_uerrno_globals_table[i].key);
}
}
- return MP_QSTR_NULL;
+ return MP_QSTRnull;
#endif
}
diff --git a/py/obj.c b/py/obj.c
index 1797ee5..4588d89 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -93,7 +93,7 @@
#endif
// the block name can be NULL if it's unknown
qstr block = values[i + 2];
- if (block == MP_QSTR_NULL) {
+ if (block == MP_QSTRnull) {
mp_print_str(print, "\n");
} else {
mp_printf(print, ", in %q\n", block);
diff --git a/py/objexcept.c b/py/objexcept.c
index 7e3fdcc..dadbe98 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -121,7 +121,7 @@
// try to provide a nice OSError error message
if (o->base.type == &mp_type_OSError && mp_obj_is_small_int(o->args->items[0])) {
qstr qst = mp_errno_to_str(o->args->items[0]);
- if (qst != MP_QSTR_NULL) {
+ if (qst != MP_QSTRnull) {
mp_printf(print, "[Errno " INT_FMT "] %q", MP_OBJ_SMALL_INT_VALUE(o->args->items[0]), qst);
return;
}
diff --git a/py/objstr.c b/py/objstr.c
index 1047ea9..8824363 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -169,7 +169,7 @@
// Check if a qstr with this data already exists
qstr q = qstr_find_strn((const char*)str_data, str_len);
- if (q != MP_QSTR_NULL) {
+ if (q != MP_QSTRnull) {
return MP_OBJ_NEW_QSTR(q);
}
@@ -2042,7 +2042,7 @@
// if not a bytes object, look if a qstr with this data already exists
if (type == &mp_type_str) {
qstr q = qstr_find_strn(vstr->buf, vstr->len);
- if (q != MP_QSTR_NULL) {
+ if (q != MP_QSTRnull) {
vstr_clear(vstr);
vstr->alloc = 0;
return MP_OBJ_NEW_QSTR(q);
@@ -2067,7 +2067,7 @@
mp_obj_t mp_obj_new_str(const char* data, size_t len) {
qstr q = qstr_find_strn(data, len);
- if (q != MP_QSTR_NULL) {
+ if (q != MP_QSTRnull) {
// qstr with this data already exists
return MP_OBJ_NEW_QSTR(q);
} else {
diff --git a/py/objtype.c b/py/objtype.c
index 318c7b9..236c79e 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -460,7 +460,7 @@
}
// Binary-op enum values not listed here will have the default value of 0 in the
-// table, corresponding to MP_QSTR_NULL, and are therefore unsupported (a lookup will
+// table, corresponding to MP_QSTRnull, and are therefore unsupported (a lookup will
// fail). They can be added at the expense of code size for the qstr.
// Qstrs for special methods are guaranteed to have a small value, so we use byte
// type to represent them.
diff --git a/py/parse.c b/py/parse.c
index 254dbc7..82b5413 100644
--- a/py/parse.c
+++ b/py/parse.c
@@ -502,7 +502,7 @@
} else if (lex->tok_kind == MP_TOKEN_STRING || lex->tok_kind == MP_TOKEN_BYTES) {
// Don't automatically intern all strings/bytes. doc strings (which are usually large)
// will be discarded by the compiler, and so we shouldn't intern them.
- qstr qst = MP_QSTR_NULL;
+ qstr qst = MP_QSTRnull;
if (lex->vstr.len <= MICROPY_ALLOC_PARSE_INTERN_STRING_LEN) {
// intern short strings
qst = qstr_from_strn(lex->vstr.buf, lex->vstr.len);
@@ -510,7 +510,7 @@
// check if this string is already interned
qst = qstr_find_strn(lex->vstr.buf, lex->vstr.len);
}
- if (qst != MP_QSTR_NULL) {
+ if (qst != MP_QSTRnull) {
// qstr exists, make a leaf node
pn = mp_parse_node_new_leaf(lex->tok_kind == MP_TOKEN_STRING ? MP_PARSE_NODE_STRING : MP_PARSE_NODE_BYTES, qst);
} else {
@@ -705,7 +705,7 @@
mp_obj_t exc = mp_obj_new_exception_msg(&mp_type_SyntaxError,
"constant must be an integer");
mp_obj_exception_add_traceback(exc, parser->lexer->source_name,
- ((mp_parse_node_struct_t*)pn1)->source_line, MP_QSTR_NULL);
+ ((mp_parse_node_struct_t*)pn1)->source_line, MP_QSTRnull);
nlr_raise(exc);
}
@@ -1138,7 +1138,7 @@
}
// add traceback to give info about file name and location
// we don't have a 'block' name, so just pass the NULL qstr to indicate this
- mp_obj_exception_add_traceback(exc, lex->source_name, lex->tok_line, MP_QSTR_NULL);
+ mp_obj_exception_add_traceback(exc, lex->source_name, lex->tok_line, MP_QSTRnull);
nlr_raise(exc);
}
diff --git a/py/parsenum.c b/py/parsenum.c
index ae9b834..2b01b72 100644
--- a/py/parsenum.c
+++ b/py/parsenum.c
@@ -41,7 +41,7 @@
// exception's type from ValueError to SyntaxError and add traceback info
if (lex != NULL) {
((mp_obj_base_t*)MP_OBJ_TO_PTR(exc))->type = &mp_type_SyntaxError;
- mp_obj_exception_add_traceback(exc, lex->source_name, lex->tok_line, MP_QSTR_NULL);
+ mp_obj_exception_add_traceback(exc, lex->source_name, lex->tok_line, MP_QSTRnull);
}
nlr_raise(exc);
}
diff --git a/py/qstr.h b/py/qstr.h
index f4375ee..8153ef2 100644
--- a/py/qstr.h
+++ b/py/qstr.h
@@ -35,7 +35,7 @@
// Note: it would be possible to define MP_QSTR_xxx as qstr_from_str_static("xxx")
// for qstrs that are referenced this way, but you don't want to have them in ROM.
-// first entry in enum will be MP_QSTR_NULL=0, which indicates invalid/no qstr
+// first entry in enum will be MP_QSTRnull=0, which indicates invalid/no qstr
enum {
#ifndef NO_QSTR
#define QDEF(id, str) id,
@@ -61,7 +61,7 @@
void qstr_init(void);
mp_uint_t qstr_compute_hash(const byte *data, size_t len);
-qstr qstr_find_strn(const char *str, size_t str_len); // returns MP_QSTR_NULL if not found
+qstr qstr_find_strn(const char *str, size_t str_len); // returns MP_QSTRnull if not found
qstr qstr_from_str(const char *str);
qstr qstr_from_strn(const char *str, size_t len);
diff --git a/py/repl.c b/py/repl.c
index da0fefb..9389b34 100644
--- a/py/repl.c
+++ b/py/repl.c
@@ -159,7 +159,7 @@
if (str < top) {
// a complete word, lookup in current object
qstr q = qstr_find_strn(s_start, s_len);
- if (q == MP_QSTR_NULL) {
+ if (q == MP_QSTRnull) {
// lookup will fail
return 0;
}
diff --git a/tests/unix/extra_coverage.py b/tests/unix/extra_coverage.py
index cb68bae..09bb48f 100644
--- a/tests/unix/extra_coverage.py
+++ b/tests/unix/extra_coverage.py
@@ -74,3 +74,7 @@
import uio
buf = uio.resource_stream('frzstr_pkg2', 'mod.py')
print(buf.read(21))
+
+# test for MP_QSTR_NULL regression
+from frzqstr import returns_NULL
+print(returns_NULL())
diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp
index 07fde6c..54c5b63 100644
--- a/tests/unix/extra_coverage.py.exp
+++ b/tests/unix/extra_coverage.py.exp
@@ -107,3 +107,4 @@
1
ZeroDivisionError
b'# test frozen package'
+NULL
diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py
index 557ee98..c6f90e4 100755
--- a/tools/mpy-tool.py
+++ b/tools/mpy-tool.py
@@ -70,7 +70,7 @@
self.qstr_id = 'MP_QSTR_' + self.qstr_esc
# Initialise global list of qstrs with static qstrs
-global_qstrs = [None] # MP_QSTR_NULL should never be referenced
+global_qstrs = [None] # MP_QSTRnull should never be referenced
for n in qstrutil.static_qstr_list:
global_qstrs.append(QStrType(n))