-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revamp stdin_install & add env actions
There are now new methods on env to interact with environment variables: - getenv - setenv - unsetenv - getenvb - setenvb - unsetenvb The first three work with str input and output, presuming data is encoded with UTF-8. getenvb and friends instead use bytes as input and output for raw access to environment variables. Some time ago stdin_install was changed from working with str to be bytes instead, which is arguably more correct. However, a bug crept in so while the returned data was indeed bytes, the type signature said str. This has been fixed by revamping stdin_install. stdin_install now support working with strings in a convenient manner just like previously, but now handles chunking of data as well as reporting errors (which were previously unhandled) as well as providing a raw bytes interface. When stdin is attached to a terminal, it uses line buffering. The buffer is however limited in size so if the line is really long, it will be chopped into chunks. If a unicode characters happens to be split so we only get the first byte of a multi-byte character, then the decode would fail. The string StringDecoder actor will attempt to handle this and store the remaining bytes in a buffer to be decoded upon receipt of the next chunk. Just like with a raw interface to stdin, it attempts to be line buffered but there is no guarantee when the line exceeds the buffer size. We attempt to automatically detect the encoding of the terminal by reading the LANG environment variable. If this is not possible, we assume UTF-8 encoding. Since we do not currently support anything besides UTF-8, any other encoding will lead to an exception (which might go unhandled). Acton-by-Example has been updated with some examples around this.
- Loading branch information
Showing
7 changed files
with
211 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Environment | ||
|
||
The environment of an Acton application is the outside world. Any useful application typically needs to interact with the environment in some way, like reading arguments or taking input from stdin and printing output. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Reading stdin input | ||
|
||
Read input from stdin by installing a handler for stdin data. The returned data is `str` | ||
```python | ||
actor main(env): | ||
def interact(input): | ||
print("Got some input:", input) | ||
|
||
env.stdin_install(interact) | ||
``` | ||
|
||
|
||
It is possible to specify the encoding and an on_error() callback which is invoked if there are problem with decoding the data. When encoding is not specified (default `None`), an attempt is made to discover the encoding by reading the `LANG` environment variable. If no encoding is discovered, the default is to use `utf-8`. | ||
|
||
```python | ||
actor main(env): | ||
def interact(input): | ||
print("Got some input:", input) | ||
|
||
def on_stdin_error(err, data): | ||
print("Some error with decoding the input data:", err) | ||
print("Raw bytes data:", data) | ||
|
||
env.stdin_install(on_stdin=interact, encoding="utf-8", on_error=on_stdin_error) | ||
``` | ||
|
||
You can read the raw data in `bytes` form by installing a bytes handler instead: | ||
|
||
```python | ||
actor main(env): | ||
def interact(bytes_input): | ||
# Note how the input might contain parts (some bytes) of a multi-byte | ||
# Unicode character in which case decoding will fail | ||
print("Got some input:", bytes_input.decode()) | ||
|
||
env.stdin_install(on_stdin_bytes=interact) | ||
``` | ||
|
||
This allows reading binary data and more explicit control over how to decode the data. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Environment variables | ||
|
||
It is possible to read, set and unset environment variables. The standard functions `env.getenv`, `env.setenv` and `env.unsetenv` all assume `str` input and output, which is a convenience based on the assumption that all data is encoded using UTF-8. POSIX systems really use binary encoding for both environment names and variables. To access the environment as bytes and handle decoding explicitly, use `env.getenvb`, `env.setenvb` and `env.unsetenvb`. | ||
|
||
Source: | ||
```python | ||
actor main(env): | ||
env_user = env.getenv("USER") | ||
if env_user is not None: | ||
print("User:", env_user) | ||
env.setenv("FOO", "bar") | ||
env.unsetenv("LANG") | ||
foo_env = env.getenv("FOO") | ||
if foo_env is not None: | ||
print("FOO:", foo_env) | ||
env.exit(0) | ||
``` | ||
|
||
Output: | ||
```sh | ||
User: myuser | ||
FOO: bar | ||
``` |