summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--py/repl.c78
-rw-r--r--tests/cmdline/repl_autocomplete.py3
-rw-r--r--tests/cmdline/repl_autocomplete.py.exp3
-rw-r--r--tests/unix/extra_coverage.py.exp10
4 files changed, 39 insertions, 55 deletions
diff --git a/py/repl.c b/py/repl.c
index 7e8922e19..61ae2c1fe 100644
--- a/py/repl.c
+++ b/py/repl.c
@@ -27,6 +27,7 @@
#include <string.h>
#include "py/obj.h"
#include "py/runtime.h"
+#include "py/builtin.h"
#include "py/repl.h"
#if MICROPY_HELPER_REPL
@@ -136,8 +137,11 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print
}
}
- // begin search in locals dict
- mp_obj_dict_t *dict = mp_locals_get();
+ size_t nqstr = QSTR_TOTAL();
+
+ // begin search in outer global dict which is accessed from __main__
+ mp_obj_t obj = MP_OBJ_FROM_PTR(&mp_module___main__);
+ mp_obj_t dest[2];
for (;;) {
// get next word in string to complete
@@ -148,43 +152,20 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print
size_t s_len = str - s_start;
if (str < top) {
- // a complete word, lookup in current dict
-
- mp_obj_t obj = MP_OBJ_NULL;
- for (size_t i = 0; i < dict->map.alloc; i++) {
- if (MP_MAP_SLOT_IS_FILLED(&dict->map, i)) {
- size_t d_len;
- const char *d_str = mp_obj_str_get_data(dict->map.table[i].key, &d_len);
- if (s_len == d_len && strncmp(s_start, d_str, d_len) == 0) {
- obj = dict->map.table[i].value;
- break;
- }
- }
+ // a complete word, lookup in current object
+ qstr q = qstr_find_strn(s_start, s_len);
+ if (q == MP_QSTR_NULL) {
+ // lookup will fail
+ return 0;
}
+ mp_load_method_maybe(obj, q, dest);
+ obj = dest[0]; // attribute, method, or MP_OBJ_NULL if nothing found
if (obj == MP_OBJ_NULL) {
// lookup failed
return 0;
}
- // found an object of this name; try to get its dict
- if (MP_OBJ_IS_TYPE(obj, &mp_type_module)) {
- dict = mp_obj_module_get_globals(obj);
- } else {
- mp_obj_type_t *type;
- if (MP_OBJ_IS_TYPE(obj, &mp_type_type)) {
- type = MP_OBJ_TO_PTR(obj);
- } else {
- type = mp_obj_get_type(obj);
- }
- if (type->locals_dict != NULL && type->locals_dict->base.type == &mp_type_dict) {
- dict = type->locals_dict;
- } else {
- // obj has no dict
- return 0;
- }
- }
-
// skip '.' to move to next word
++str;
@@ -192,14 +173,15 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print
// end of string, do completion on this partial name
// look for matches
- int n_found = 0;
const char *match_str = NULL;
size_t match_len = 0;
- for (size_t i = 0; i < dict->map.alloc; i++) {
- if (MP_MAP_SLOT_IS_FILLED(&dict->map, i)) {
- size_t d_len;
- const char *d_str = mp_obj_str_get_data(dict->map.table[i].key, &d_len);
- if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) {
+ qstr q_first = 0, q_last;
+ for (qstr q = 1; q < nqstr; ++q) {
+ size_t d_len;
+ const char *d_str = (const char*)qstr_data(q, &d_len);
+ if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) {
+ mp_load_method_maybe(obj, q, dest);
+ if (dest[0] != MP_OBJ_NULL) {
if (match_str == NULL) {
match_str = d_str;
match_len = d_len;
@@ -213,13 +195,16 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print
}
}
}
- ++n_found;
+ if (q_first == 0) {
+ q_first = q;
+ }
+ q_last = q;
}
}
}
// nothing found
- if (n_found == 0) {
+ if (q_first == 0) {
// If there're no better alternatives, and if it's first word
// in the line, try to complete "import".
if (s_start == org_str) {
@@ -234,7 +219,7 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print
}
// 1 match found, or multiple matches with a common prefix
- if (n_found == 1 || match_len > s_len) {
+ if (q_first == q_last || match_len > s_len) {
*compl_str = match_str + s_len;
return match_len - s_len;
}
@@ -245,11 +230,12 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print
#define MAX_LINE_LEN (4 * WORD_SLOT_LEN)
int line_len = MAX_LINE_LEN; // force a newline for first word
- for (size_t i = 0; i < dict->map.alloc; i++) {
- if (MP_MAP_SLOT_IS_FILLED(&dict->map, i)) {
- size_t d_len;
- const char *d_str = mp_obj_str_get_data(dict->map.table[i].key, &d_len);
- if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) {
+ for (qstr q = q_first; q <= q_last; ++q) {
+ size_t d_len;
+ const char *d_str = (const char*)qstr_data(q, &d_len);
+ if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) {
+ mp_load_method_maybe(obj, q, dest);
+ if (dest[0] != MP_OBJ_NULL) {
int gap = (line_len + WORD_SLOT_LEN - 1) / WORD_SLOT_LEN * WORD_SLOT_LEN - line_len;
if (gap < 2) {
gap += WORD_SLOT_LEN;
diff --git a/tests/cmdline/repl_autocomplete.py b/tests/cmdline/repl_autocomplete.py
index a848cab0f..27cad428f 100644
--- a/tests/cmdline/repl_autocomplete.py
+++ b/tests/cmdline/repl_autocomplete.py
@@ -6,5 +6,4 @@ x = '123'
1, x.isdi ()
i = str
i.lowe ('ABC')
-j = None
-j. 
+None. 
diff --git a/tests/cmdline/repl_autocomplete.py.exp b/tests/cmdline/repl_autocomplete.py.exp
index dfb998ff6..75002985e 100644
--- a/tests/cmdline/repl_autocomplete.py.exp
+++ b/tests/cmdline/repl_autocomplete.py.exp
@@ -10,6 +10,5 @@ Use \.\+
>>> i = str
>>> i.lower('ABC')
'abc'
->>> j = None
->>> j.
+>>> None.
>>>
diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp
index 26fd2e332..8a2c6aea9 100644
--- a/tests/unix/extra_coverage.py.exp
+++ b/tests/unix/extra_coverage.py.exp
@@ -24,11 +24,11 @@ RuntimeError:
# repl
ame__
-__name__ path argv version
-version_info implementation platform byteorder
-maxsize exit stdin stdout
-stderr modules exc_info getsizeof
-print_exception
+__class__ __name__ argv byteorder
+exc_info exit getsizeof implementation
+maxsize modules path platform
+print_exception stderr stdin
+stdout version version_info
ementation
# attrtuple
(start=1, stop=2, step=3)