Skip to content

Commit 614eded

Browse files
committed
getenv: Make os.getenv() show a better error
.. when an associated value is not a quoted string. This includes some cases where it would previously return an integer, a CPython incompatibility. However, it's an incompatible behavior change with circuitpython since previously a number would be returned. Closes: #9113 Signed-off-by: Jeff Epler <[email protected]>
1 parent db9aa78 commit 614eded

File tree

5 files changed

+66
-27
lines changed

5 files changed

+66
-27
lines changed

locale/circuitpython.pot

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,10 @@ msgstr ""
960960
msgid "Expected a kind of %q"
961961
msgstr ""
962962

963+
#: shared-module/os/getenv.c
964+
msgid "Expected quoted string"
965+
msgstr ""
966+
963967
#: ports/espressif/common-hal/_bleio/Adapter.c
964968
#: ports/nordic/common-hal/_bleio/Adapter.c
965969
msgid "Extended advertisements with scan response not supported."

shared-bindings/os/__init__.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
void common_hal_os_chdir(const char *path);
1616
mp_obj_t common_hal_os_getcwd(void);
1717
mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_);
18-
mp_obj_t common_hal_os_getenv_path(const char *path, const char *key, mp_obj_t default_);
1918

2019
mp_obj_t common_hal_os_listdir(const char *path);
2120
void common_hal_os_mkdir(const char *path);

shared-module/os/getenv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ os_getenv_err_t common_hal_os_getenv_str(const char *key, char *value, size_t va
365365
return result;
366366
}
367367

368-
mp_obj_t common_hal_os_getenv_path(const char *path, const char *key, mp_obj_t default_) {
368+
static mp_obj_t common_hal_os_getenv_path(const char *path, const char *key, mp_obj_t default_) {
369369
vstr_t buf;
370370
bool quoted;
371371

@@ -379,7 +379,7 @@ mp_obj_t common_hal_os_getenv_path(const char *path, const char *key, mp_obj_t d
379379
if (quoted) {
380380
return mp_obj_new_str_from_vstr(&buf);
381381
} else {
382-
return mp_parse_num_integer(buf.buf, buf.len, 0, NULL);
382+
mp_raise_ValueError(MP_ERROR_TEXT("Expected quoted string"));
383383
}
384384
}
385385

tests/circuitpython/getenv.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,17 @@ def ioctl(self, op, arg):
3838
content_good = b"""
3939
# comment
4040
key0 = "hello world"
41-
key1 = 7
4241
key2= "\\n"
4342
key3 ="\\u00c1x"
4443
key4 = "\\U000000c1x"
4544
key5 = "\\f\\"\\\\"
4645
key6 = "\\t\\r\\b"
4746
key7 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
4847
key8 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
49-
key9 = "hello comment" # comment
50-
key10 = 0x7f # comment
51-
key11 = 0
48+
key1 = "hello comment" # comment
49+
ikey0 = 7
50+
ikey1 = 0x7f # comment
51+
ikey2 = 0
5252
[section]
5353
subvalue = "hi"
5454
"""
@@ -58,35 +58,55 @@ def ioctl(self, op, arg):
5858
b'key = """\n',
5959
b"key =\n",
6060
b'key="',
61+
b'key="\0',
6162
b"key = strings must be quoted\n",
63+
b"key=7",
64+
# These all return None even though some of them look a bit like they might define key...
65+
b"",
66+
b"key",
67+
b"key ",
68+
b"key\0",
69+
b'key\0="x"',
70+
b"\n",
6271
]
6372

6473

65-
def run_test(key, content):
74+
def run_test(key, content, getter=os.getenv):
6675
with open("/settings.toml", "wb") as f:
6776
f.write(content)
6877

6978
try:
70-
v = os.getenv(key)
79+
v = getter(key)
7180
print(key, repr(v))
7281
except Exception as e:
7382
print(key, str(e))
7483

7584

85+
print("*** Tests that should succeed ***")
7686
run_test("key", b"")
7787

78-
for i in range(13):
88+
for i in range(10):
7989
run_test(f"key{i}", content_good)
90+
for i in range(4):
91+
run_test(f"ikey{i}", content_good, getenv_int)
8092

93+
# Run the test again but on CRLF content
8194
content_good = content_good.replace(b"\n", b"\r\n")
82-
for i in range(13):
95+
for i in range(10):
8396
run_test(f"key{i}", content_good)
97+
for i in range(4):
98+
run_test(f"ikey{i}", content_good, getenv_int)
8499

85-
run_test(f"K", b"K = 7\r\n")
86-
print(getenv_int("K"))
100+
print()
101+
print("*** Integer tests that should succeed***")
102+
run_test(f"K", b"K = 7\r\n", getenv_int)
87103

88104
# Test value without trailing newline
89-
run_test(f"noeol", b"noeol=3")
105+
run_test(f"noeol", b"noeol=3", getenv_int)
90106

107+
print("Tests that should fail")
91108
for content in content_bad:
92109
run_test("key", content)
110+
111+
# (note that getenv_int displays additional info on output)
112+
run_test(f"K", b'K = "7"\r\n', getenv_int)

tests/circuitpython/getenv.py.exp

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,51 @@
1+
*** Tests that should succeed ***
12
key None
23
key0 'hello world'
3-
key1 7
4+
key1 'hello comment'
45
key2 '\n'
56
key3 'Áx'
67
key4 'Áx'
78
key5 '\x0c"\\'
89
key6 '\t\r\x08'
910
key7 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
1011
key8 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
11-
key9 'hello comment'
12-
key10 127
13-
key11 0
14-
key12 None
12+
key9 None
13+
ikey0 7
14+
ikey1 127
15+
ikey2 0
16+
ikey3 None
1517
key0 'hello world'
16-
key1 7
18+
key1 'hello comment'
1719
key2 '\n'
1820
key3 'Áx'
1921
key4 'Áx'
2022
key5 '\x0c"\\'
2123
key6 '\t\r\x08'
2224
key7 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
2325
key8 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
24-
key9 'hello comment'
25-
key10 127
26-
key11 0
27-
key12 None
26+
key9 None
27+
ikey0 7
28+
ikey1 127
29+
ikey2 0
30+
ikey3 None
31+
32+
*** Integer tests that should succeed***
2833
K 7
29-
7
3034
noeol 3
35+
Tests that should fail
3136
key Invalid byte '\n'
3237
key Invalid byte '"'
33-
key invalid syntax for integer with base 10: ''
38+
key Expected quoted string
3439
key Invalid byte 'EOF'
35-
key invalid syntax for integer with base 10: 'strings must be quoted'
40+
key Invalid byte 'EOF'
41+
key Expected quoted string
42+
key Expected quoted string
43+
key None
44+
key None
45+
key None
46+
key None
47+
key None
48+
key None
49+
An error occurred while retrieving 'K':
50+
Invalid byte '"'
51+
K None

0 commit comments

Comments
 (0)