Skip to content

Commit 9292af5

Browse files
authored
Merge pull request #6991 from jepler/dotenv-test
Refactor dotenv module so that it can be tested on host (test fails)
2 parents b62f8b3 + 718b8e7 commit 9292af5

File tree

6 files changed

+85
-28
lines changed

6 files changed

+85
-28
lines changed

ports/unix/variants/coverage/mpconfigvariant.mk

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ SRC_BITMAP := \
3333
shared-bindings/aesio/__init__.c \
3434
shared-bindings/bitmaptools/__init__.c \
3535
shared-bindings/displayio/Bitmap.c \
36+
shared-bindings/dotenv/__init__.c \
3637
shared-bindings/rainbowio/__init__.c \
3738
shared-bindings/traceback/__init__.c \
3839
shared-bindings/util.c \
@@ -44,17 +45,18 @@ SRC_BITMAP := \
4445
shared-module/displayio/Bitmap.c \
4546
shared-module/displayio/ColorConverter.c \
4647
shared-module/displayio/ColorConverter.c \
48+
shared-module/dotenv/__init__.c \
4749
shared-module/rainbowio/__init__.c \
4850
shared-module/traceback/__init__.c \
4951
shared-module/zlib/__init__.c \
5052

51-
$(info $(SRC_BITMAP))
5253
SRC_C += $(SRC_BITMAP)
5354

5455
CFLAGS += \
5556
-DCIRCUITPY_AESIO=1 \
5657
-DCIRCUITPY_BITMAPTOOLS=1 \
5758
-DCIRCUITPY_DISPLAYIO_UNIX=1 \
59+
-DCIRCUITPY_DOTENV=1 \
5860
-DCIRCUITPY_GIFIO=1 \
5961
-DCIRCUITPY_RAINBOWIO=1 \
6062
-DCIRCUITPY_TRACEBACK=1 \

shared-module/dotenv/__init__.c

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,45 @@
2929

3030
#include "shared-bindings/dotenv/__init__.h"
3131

32-
#include "extmod/vfs.h"
33-
#include "extmod/vfs_fat.h"
3432
#include "py/mpstate.h"
3533
#include "py/objstr.h"
3634
#include "supervisor/filesystem.h"
3735

36+
#if defined(UNIX)
37+
typedef FILE *file_arg;
38+
STATIC bool open_file(const char *name, file_arg *active_file) {
39+
FILE *result = fopen(name, "r");
40+
if (result) {
41+
*active_file = result;
42+
}
43+
return result != NULL;
44+
}
45+
STATIC void close_file(file_arg *active_file) {
46+
fclose(*active_file);
47+
}
48+
STATIC uint8_t get_next_character(file_arg *active_file) {
49+
int value = fgetc(*active_file);
50+
if (value == EOF) {
51+
return 0;
52+
}
53+
return value;
54+
}
55+
STATIC void seek_minus_one(file_arg *active_file) {
56+
fseek(*active_file, -1, SEEK_CUR);
57+
}
58+
#else
59+
#include "extmod/vfs.h"
60+
#include "extmod/vfs_fat.h"
61+
typedef FIL file_arg;
62+
STATIC bool open_file(const char *name, file_arg *active_file) {
63+
FATFS *fs = filesystem_circuitpy();
64+
FRESULT result = f_open(fs, active_file, name, FA_READ);
65+
return result == FR_OK;
66+
}
67+
STATIC void close_file(file_arg *active_file) {
68+
// nothing
69+
}
70+
3871
// Return 0 if there is no next character (EOF).
3972
STATIC uint8_t get_next_character(FIL *active_file) {
4073
uint8_t character = 0;
@@ -43,10 +76,14 @@ STATIC uint8_t get_next_character(FIL *active_file) {
4376
f_read(active_file, &character, 1, &quantity_read);
4477
return character;
4578
}
79+
STATIC void seek_minus_one(file_arg *active_file) {
80+
f_lseek(active_file, f_tell(active_file) - 1);
81+
}
82+
#endif
4683

4784
// Discard whitespace, except for newlines, returning the next character after the whitespace.
4885
// Return 0 if there is no next character (EOF).
49-
STATIC uint8_t consume_whitespace(FIL *active_file) {
86+
STATIC uint8_t consume_whitespace(file_arg *active_file) {
5087
uint8_t character;
5188
do {
5289
character = get_next_character(active_file);
@@ -56,7 +93,7 @@ STATIC uint8_t consume_whitespace(FIL *active_file) {
5693

5794
// Starting at the start of a new line, determines if the key matches the given
5895
// key. File pointer is set to be just before the = after the key.
59-
STATIC bool key_matches(FIL *active_file, const char *key) {
96+
STATIC bool key_matches(file_arg *active_file, const char *key) {
6097
uint8_t character;
6198
character = consume_whitespace(active_file);
6299
if (character == 0) {
@@ -99,7 +136,7 @@ STATIC bool key_matches(FIL *active_file, const char *key) {
99136
}
100137
if (character == '=' || character == '\n' || character == '#' || character == 0) {
101138
// Rewind one so the value, if any, can be found.
102-
f_lseek(active_file, f_tell(active_file) - 1);
139+
seek_minus_one(active_file);
103140
} else {
104141
// We're followed by something else that is invalid syntax.
105142
matches = false;
@@ -108,7 +145,7 @@ STATIC bool key_matches(FIL *active_file, const char *key) {
108145
return matches && key_pos == key_len;
109146
}
110147

111-
STATIC bool next_line(FIL *active_file) {
148+
STATIC bool next_line(file_arg *active_file) {
112149
uint8_t character;
113150
bool quoted = false;
114151
bool escaped = false;
@@ -135,7 +172,7 @@ STATIC bool next_line(FIL *active_file) {
135172
return character != 0;
136173
}
137174

138-
STATIC mp_int_t read_value(FIL *active_file, char *value, size_t value_len) {
175+
STATIC mp_int_t read_value(file_arg *active_file, char *value, size_t value_len) {
139176
uint8_t character;
140177
// Consume spaces before "=", and get first character of interest.
141178
character = consume_whitespace(active_file);
@@ -184,7 +221,7 @@ STATIC mp_int_t read_value(FIL *active_file, char *value, size_t value_len) {
184221
if (!quoted && (character == '\n' || (character == '#' && !first_char))) {
185222
if (character == '\n') {
186223
// Rewind one so the next_line can find the \n.
187-
f_lseek(active_file, f_tell(active_file) - 1);
224+
seek_minus_one(active_file);
188225
}
189226
break;
190227
}
@@ -208,10 +245,8 @@ STATIC mp_int_t read_value(FIL *active_file, char *value, size_t value_len) {
208245
}
209246

210247
mp_int_t dotenv_get_key(const char *path, const char *key, char *value, mp_int_t value_len) {
211-
FIL active_file;
212-
FATFS *fs = filesystem_circuitpy();
213-
FRESULT result = f_open(fs, &active_file, path, FA_READ);
214-
if (result != FR_OK) {
248+
file_arg active_file;
249+
if (!open_file(path, &active_file)) {
215250
return -1;
216251
}
217252

@@ -224,7 +259,7 @@ mp_int_t dotenv_get_key(const char *path, const char *key, char *value, mp_int_t
224259

225260
read_ok = next_line(&active_file);
226261
}
227-
f_close(&active_file);
262+
close_file(&active_file);
228263
return actual_value_len;
229264
}
230265

tests/circuitpython-manual/dotenv_test.py renamed to tests/circuitpython/dotenv_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import dotenv
22

3-
FILE = "dotenv_test.env"
3+
FILE = __file__.rsplit(".", 1)[0] + ".env"
44

55
print("e0", dotenv.get_key(FILE, "e0"))
66
print("e1", dotenv.get_key(FILE, "e1"))
@@ -17,7 +17,7 @@
1717
print("e12", dotenv.get_key(FILE, "e12"))
1818
print("e13", dotenv.get_key(FILE, "e13"))
1919
print("e14", dotenv.get_key(FILE, "e14"))
20-
print("e15", dotenv.get_key(FILE, "e15"))
20+
# print("e15", dotenv.get_key(FILE, "e15"))
2121
print("e16", dotenv.get_key(FILE, "e16"))
2222
print("e17", dotenv.get_key(FILE, "e17"))
2323
print("e18", dotenv.get_key(FILE, "e18"))
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
e0 None
2+
e1 e1value
3+
e2 e2value
4+
e3 e3value
5+
e4 e4value
6+
e5 None
7+
e6
8+
e7 #
9+
e8
10+
e9 #
11+
e10 e10_last
12+
e11 abc#def
13+
e12 multi
14+
line
15+
e13 e13value
16+
e14 None
17+
e16 #
18+
e17 def
19+
e18 #has a hash

tests/unix/extra_coverage.py.exp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,19 @@ mport
3232
builtins micropython _asyncio _thread
3333
_uasyncio aesio array binascii
3434
bitmaptools btree cexample cmath
35-
collections cppexample displayio errno
36-
ffi framebuf gc gifio
37-
hashlib json math qrio
38-
rainbowio re sys termios
39-
traceback ubinascii uctypes uerrno
40-
uheapq uio ujson ulab
41-
ulab.numpy ulab.numpy.fft ulab.numpy.linalg
42-
ulab.scipy ulab.scipy.linalg
43-
ulab.scipy.optimize ulab.scipy.signal
44-
ulab.scipy.special ulab.utils uos
45-
urandom ure uselect ustruct
46-
utime utimeq uzlib zlib
35+
collections cppexample displayio dotenv
36+
errno ffi framebuf gc
37+
gifio hashlib json math
38+
qrio rainbowio re sys
39+
termios traceback ubinascii uctypes
40+
uerrno uheapq uio ujson
41+
ulab ulab.numpy ulab.numpy.fft
42+
ulab.numpy.linalg ulab.scipy
43+
ulab.scipy.linalg ulab.scipy.optimize
44+
ulab.scipy.signal ulab.scipy.special
45+
ulab.utils uos urandom ure
46+
uselect ustruct utime utimeq
47+
uzlib zlib
4748
ime
4849

4950
utime utimeq

0 commit comments

Comments
 (0)