Skip to content

Commit 398b7c2

Browse files
authored
Merge pull request #7321 from jepler/dotenv-becomes-toml
Dotenv becomes toml
2 parents 9d410f3 + 369507e commit 398b7c2

File tree

39 files changed

+708
-723
lines changed

39 files changed

+708
-723
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
!atmel-samd/asf/**/*.a
1010
*.elf
1111
*.bin
12+
!*.toml.bin
1213
*.map
1314
*.hex
1415
*.dis

devices/ble_hci/common-hal/_bleio/Adapter.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@
4949
#include "shared-bindings/_bleio/ScanEntry.h"
5050
#include "shared-bindings/time/__init__.h"
5151

52-
#if CIRCUITPY_DOTENV
53-
#include "shared-module/dotenv/__init__.h"
52+
#if CIRCUITPY_OS_GETENV
53+
#include "shared-bindings/os/__init__.h"
5454
#endif
5555

5656
#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
@@ -284,15 +284,15 @@ char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0
284284
STATIC void bleio_adapter_hci_init(bleio_adapter_obj_t *self) {
285285
mp_int_t name_len = 0;
286286

287-
#if CIRCUITPY_DOTENV
288-
char ble_name[32];
289-
name_len = dotenv_get_key("/.env", "CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name) - 1);
290-
if (name_len > 0) {
291-
self->name = mp_obj_new_str(ble_name, (size_t)name_len);
287+
#if CIRCUITPY_OS_GETENV
288+
mp_obj_t name = common_hal_os_getenv("CIRCUITPY_BLE_NAME", mp_const_none);
289+
if (name != mp_const_none) {
290+
mp_arg_validate_type_string(name, MP_QSTR_CIRCUITPY_BLE_NAME);
291+
self->name = name;
292292
}
293293
#endif
294294

295-
if (name_len <= 0) {
295+
if (!self->name) {
296296
name_len = sizeof(default_ble_name);
297297
bt_addr_t addr;
298298
hci_check_error(hci_read_bd_addr(&addr));

docs/environment.rst

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,49 @@ variables are commonly used to store "secrets" such as Wi-Fi passwords and API
66
keys. This method *does not* make them secure. It only separates them from the
77
code.
88

9-
CircuitPython supports these by mimicking the `dotenv <https://github.com/theskumar/python-dotenv>`_
10-
CPython library. Other languages such as Javascript, PHP and Ruby also have
11-
dotenv libraries.
9+
CircuitPython uses a file called ``settings.toml`` at the drive root (no
10+
folder) as the environment. User code can access the values from the file
11+
using `os.getenv()`. It is recommended to save any values used repeatedly in a
12+
variable because `os.getenv()` will parse the ``settings.toml`` file contents
13+
on every access.
1214

13-
These libraries store environment variables in a ``.env`` file. Here is a simple
14-
example:
15+
CircuitPython only supports a subset of the full toml specification, see below
16+
for more details. The subset is very "Python-like", which is a key reason we
17+
selected the format.
1518

16-
.. code-block:: bash
19+
Due to technical limitations it probably also accepts some files that are
20+
not valid TOML files; bugs of this nature are subject to change (i.e., be
21+
fixed) without the usual deprecation period for incompatible changes.
1722

18-
KEY1='value1'
19-
# Comment
20-
KEY2='value2
21-
is multiple lines'
23+
File format example:
2224

23-
CircuitPython uses the ``.env`` at the drive root (no folder) as the environment.
24-
User code can access the values from the file using `os.getenv()`. It is
25-
recommended to save any values used repeatedly in a variable because `os.getenv()`
26-
will parse the ``/.env`` on every access.
25+
.. code-block::
26+
27+
str_key="Hello world" # with trailing comment
28+
int_key = 7
29+
unicode_key="œuvre"
30+
unicode_key2="\\u0153uvre" # same as above
31+
unicode_key3="\\U00000153uvre" # same as above
32+
escape_codes="supported, including \\r\\n\\"\\\\"
33+
# comment
34+
[subtable]
35+
subvalue="cannot retrieve this using getenv"
36+
37+
38+
Details of the toml language subset
39+
-----------------------------------
40+
41+
* The content is required to be in UTF-8 encoding
42+
* The supported data types are string and integer
43+
* Only basic strings are supported, not triple-quoted strings
44+
* Only integers supported by strtol. (no 0o, no 0b, no underscores 1_000, 011
45+
is 9, not 11)
46+
* Only bare keys are supported
47+
* Duplicate keys are not diagnosed.
48+
* Comments are supported
49+
* Only values from the "root table" can be retrieved
50+
* due to technical limitations, the content of multi-line
51+
strings can erroneously be parsed as a value.
2752

2853
CircuitPython behavior
2954
----------------------

docs/workflows.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ connection, the central device can discover two default services. One for file t
4646
CircuitPython specifically that includes serial characteristics.
4747

4848
To change the default BLE advertising name without (or before) running user code, the desired name
49-
can be put in the `/.env` file. The key is `CIRCUITPY_BLE_NAME`. It's limited to approximately
49+
can be put in the `settings.toml` file. The key is `CIRCUITPY_BLE_NAME`. It's limited to approximately
5050
30 characters depending on the port's settings and will be truncated if longer.
5151

5252
### File Transfer API
@@ -69,21 +69,21 @@ Read-only characteristic that returns the UTF-8 encoded version string.
6969

7070
## Web
7171

72-
The web workflow is depends on adding Wi-Fi credentials into the `/.env` file. The keys are
72+
The web workflow is depends on adding Wi-Fi credentials into the `settings.toml` file. The keys are
7373
`CIRCUITPY_WIFI_SSID` and `CIRCUITPY_WIFI_PASSWORD`. Once these are defined, CircuitPython will
7474
automatically connect to the network and start the webserver used for the workflow. The webserver
7575
is on port 80 unless overridden by `CIRCUITPY_WEB_API_PORT`. It also enables MDNS.
7676

77-
Here is an example `/.env`:
77+
Here is an example `/settings.toml`:
7878

7979
```bash
8080
# To auto-connect to Wi-Fi
81-
CIRCUITPY_WIFI_SSID='scottswifi'
82-
CIRCUITPY_WIFI_PASSWORD='secretpassword'
81+
CIRCUITPY_WIFI_SSID="scottswifi"
82+
CIRCUITPY_WIFI_PASSWORD="secretpassword"
8383

8484
# To enable modifying files from the web. Change this too!
8585
# Leave the User field blank in the browser.
86-
CIRCUITPY_WEB_API_PASSWORD='passw0rd'
86+
CIRCUITPY_WEB_API_PASSWORD="passw0rd"
8787

8888
CIRCUITPY_WEB_API_PORT=80
8989
```
@@ -124,7 +124,7 @@ All file system related APIs are protected by HTTP basic authentication. It is *
124124
hopefully prevent some griefing in shared settings. The password is sent unencrypted so do not reuse
125125
a password with something important. The user field is left blank.
126126

127-
The password is taken from `/.env` with the key `CIRCUITPY_WEB_API_PASSWORD`. If this is unset, the
127+
The password is taken from `settings.toml` with the key `CIRCUITPY_WEB_API_PASSWORD`. If this is unset, the
128128
server will respond with `403 Forbidden`. When a password is set, but not provided in a request, it
129129
will respond `401 Unauthorized`.
130130

locale/circuitpython.pot

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,10 @@ msgstr ""
10021002
msgid "File exists"
10031003
msgstr ""
10041004

1005+
#: shared-module/os/getenv.c
1006+
msgid "File not found"
1007+
msgstr ""
1008+
10051009
#: ports/atmel-samd/common-hal/canio/Listener.c
10061010
#: ports/espressif/common-hal/canio/Listener.c
10071011
#: ports/stm/common-hal/canio/Listener.c
@@ -1058,6 +1062,8 @@ msgstr ""
10581062
#: shared-bindings/displayio/Display.c
10591063
#: shared-bindings/displayio/EPaperDisplay.c
10601064
#: shared-bindings/framebufferio/FramebufferDisplay.c
1065+
#: shared-module/displayio/Display.c
1066+
#: shared-module/framebufferio/FramebufferDisplay.c
10611067
msgid "Group already used"
10621068
msgstr ""
10631069

@@ -1184,6 +1190,7 @@ msgid "Internal define error"
11841190
msgstr ""
11851191

11861192
#: ports/espressif/common-hal/paralleldisplay/ParallelBus.c
1193+
#: shared-module/os/getenv.c
11871194
msgid "Internal error"
11881195
msgstr ""
11891196

@@ -1230,6 +1237,11 @@ msgstr ""
12301237
msgid "Invalid bits per value"
12311238
msgstr ""
12321239

1240+
#: shared-module/os/getenv.c
1241+
#, c-format
1242+
msgid "Invalid byte %.*s"
1243+
msgstr ""
1244+
12331245
#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c
12341246
#, c-format
12351247
msgid "Invalid data_pins[%d]"
@@ -1260,10 +1272,18 @@ msgstr ""
12601272
msgid "Invalid state"
12611273
msgstr ""
12621274

1275+
#: shared-module/os/getenv.c
1276+
msgid "Invalid unicode escape"
1277+
msgstr ""
1278+
12631279
#: shared-bindings/aesio/aes.c
12641280
msgid "Key must be 16, 24, or 32 bytes long"
12651281
msgstr ""
12661282

1283+
#: shared-module/os/getenv.c
1284+
msgid "Key not found"
1285+
msgstr ""
1286+
12671287
#: shared-module/is31fl3741/FrameBuffer.c
12681288
msgid "LED mappings must match display size"
12691289
msgstr ""
@@ -2262,7 +2282,7 @@ msgid "Unkown error code %d"
22622282
msgstr ""
22632283

22642284
#: shared-bindings/adafruit_pixelbuf/PixelBuf.c
2265-
#: shared-module/adafruit_pixelbuf/PixelMap.c
2285+
#: shared-module/_pixelmap/PixelMap.c
22662286
#, c-format
22672287
msgid "Unmatched number of items on RHS (expected %d, got %d)."
22682288
msgstr ""
@@ -3143,7 +3163,7 @@ msgstr ""
31433163
msgid "index is out of bounds"
31443164
msgstr ""
31453165

3146-
#: shared-bindings/adafruit_pixelbuf/PixelMap.c
3166+
#: shared-bindings/_pixelmap/PixelMap.c
31473167
msgid "index must be tuple or int"
31483168
msgstr ""
31493169

@@ -3522,7 +3542,7 @@ msgstr ""
35223542
msgid "negative shift count"
35233543
msgstr ""
35243544

3525-
#: shared-bindings/adafruit_pixelbuf/PixelMap.c
3545+
#: shared-bindings/_pixelmap/PixelMap.c
35263546
msgid "nested index must be int"
35273547
msgstr ""
35283548

ports/atmel-samd/mpconfigport.mk

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ ifeq ($(CHIP_FAMILY),samd21)
2424
CIRCUITPY_AESIO ?= 0
2525
CIRCUITPY_ATEXIT ?= 0
2626
CIRCUITPY_AUDIOMIXER ?= 0
27+
CIRCUITPY_AUDIOMP3 ?= 0
2728
CIRCUITPY_BINASCII ?= 0
2829
CIRCUITPY_BITBANGIO ?= 0
2930
CIRCUITPY_BITMAPTOOLS ?= 0
30-
CIRCUITPY_BUSDEVICE ?= 0
31-
CIRCUITPY_AUDIOMP3 ?= 0
3231
CIRCUITPY_BLEIO_HCI = 0
3332
CIRCUITPY_BUILTINS_POW3 ?= 0
33+
CIRCUITPY_BUSDEVICE ?= 0
3434
CIRCUITPY_COMPUTED_GOTO_SAVE_SPACE ?= 1
3535
CIRCUITPY_COUNTIO ?= 0
3636
# Not enough RAM for framebuffers
@@ -42,6 +42,7 @@ CIRCUITPY_I2CTARGET ?= 0
4242
CIRCUITPY_JSON ?= 0
4343
CIRCUITPY_KEYPAD ?= 0
4444
CIRCUITPY_MSGPACK ?= 0
45+
CIRCUITPY_OS_GETENV ?= 0
4546
CIRCUITPY_PIXELMAP ?= 0
4647
CIRCUITPY_RE ?= 0
4748
CIRCUITPY_SDCARDIO ?= 0

ports/cxd56/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
134134
$(addprefix common-hal/, $(SRC_COMMON_HAL))
135135

136136
SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
137-
$(addprefix shared-module/, $(SRC_SHARED_MODULE))
137+
$(addprefix shared-module/, $(SRC_SHARED_MODULE)) \
138+
$(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL))
138139

139140
SRC_S = supervisor/cpu.s
140141

ports/espressif/bindings/esp32_camera/Camera.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
//| """
6464
//| Configure and initialize a camera with the given properties
6565
//|
66-
//| This driver requires that the ``CIRCUITPY_RESERVED_PSRAM`` in ``/.env`` be large enough to hold the camera frambuffer(s). Generally, boards with built-in cameras will have a default setting that is large enough. If the constructor raises a MemoryError or an IDFError, this probably indicates the setting is too small and should be increased.
66+
//| This driver requires that the ``CIRCUITPY_RESERVED_PSRAM`` in ``settings.toml`` be large enough to hold the camera frambuffer(s). Generally, boards with built-in cameras will have a default setting that is large enough. If the constructor raises a MemoryError or an IDFError, this probably indicates the setting is too small and should be increased.
6767
//|
6868
//|
6969
//| .. important::

ports/espressif/bindings/espidf/__init__.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ STATIC mp_obj_t espidf_get_total_psram(void) {
132132
MP_DEFINE_CONST_FUN_OBJ_0(espidf_get_total_psram_obj, espidf_get_total_psram);
133133

134134
//| def get_reserved_psram() -> int:
135-
//| """Returns number of bytes of psram reserved for use by esp-idf, either a board-specific default value or the value defined in ``/.env``."""
135+
//| """Returns number of bytes of psram reserved for use by esp-idf, either a board-specific default value or the value defined in ``settings.toml``."""
136136
//|
137137
STATIC mp_obj_t espidf_get_reserved_psram(void) {
138138
return MP_OBJ_NEW_SMALL_INT(common_hal_espidf_get_reserved_psram());

ports/espressif/common-hal/_bleio/Adapter.c

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@
5959
#include "esp_bt.h"
6060
#include "esp_nimble_hci.h"
6161

62-
#if CIRCUITPY_DOTENV
63-
#include "shared-module/dotenv/__init__.h"
62+
#if CIRCUITPY_OS_GETENV
63+
#include "shared-module/os/__init__.h"
6464
#endif
6565

6666
bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
@@ -101,22 +101,16 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
101101
ble_hs_cfg.sync_cb = _on_sync;
102102
// ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
103103

104-
#if CIRCUITPY_DOTENV
105-
mp_int_t name_len = 0;
106-
char ble_name[32];
107-
name_len = dotenv_get_key("/.env", "CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name) - 1);
108-
if (name_len > 0) {
109-
if (name_len > MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH) {
110-
name_len = MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH;
111-
}
112-
ble_name[name_len] = '\0';
104+
#if CIRCUITPY_OS_GETENV
105+
char ble_name[1 + MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH];
106+
os_getenv_err_t result = common_hal_os_getenv_str("CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name));
107+
if (result == GETENV_OK) {
113108
ble_svc_gap_device_name_set(ble_name);
114-
} else {
109+
} else
110+
#endif
111+
{
115112
ble_svc_gap_device_name_set("CIRCUITPY");
116113
}
117-
#else
118-
ble_svc_gap_device_name_set("CIRCUITPY");
119-
#endif
120114

121115
// Clear all of the internal connection objects.
122116
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {

0 commit comments

Comments
 (0)