Base utilities for EO4EU
This package serves as a common base of utilities used in other eo4eu-[...]-utils packages. You may find it generally useful.
General
- The
if_nonefunction helps with the writing of optional parameters. For example:
def validate(input: str, accepted: list[str]|None = None):
accepted = if_none(accepted, ["yes", "definitely", "absolutely"])
if input not in accepted:
raise ValueError(f"Input \"{input}\" not in {accepted}")
Typing
The eo4eu_base_utils.typing submodule provides some of the types found in the standard library typing module. The difference is, for versions below 3.10, this module will pull them from typing_extensions instead.
Unify
The eo4eu_base_utils.unify submodule provides functions for working with dictionaries. Namely:
overlaycombines two dictionaries recursively, preserving nested keys if possible. In the case of conflicts,overlaywill prefer the second dictionary provided. Example:
from pprint import pprint
from eo4eu_base_utils.unify import overlay
h0 = {
"name": "bobby.png",
"dataset": "hamster images",
"date": None,
"metadata": {
"size": "3TB",
"color": "brown",
},
}
h1 = {
"path": "/usr/hamsters/bobby.png",
"date": "2025-14-01",
"metadata": {
"color": "brown and white, actually",
"type": "chubby",
},
}
pprint(overlay(h0, h1))
Output:
{'dataset': 'hamster images',
'date': '2025-14-01',
'metadata': {'color': 'brown and white, actually',
'size': '3TB',
'type': 'chubby'},
'name': 'bobby.png',
'path': '/usr/hamsters/bobby.png'}
unifyis similar tooverlay, but raises aeo4eu_base_utils.unify.UnifyErrorin the case of conflicts. This function has a more general notion of values being "compatible"; one or both of the dictionaries might have types as values, thus serving as more of a schema. An example:
from pprint import pprint
from eo4eu_base_utils.unify import overlay
schema = {
"service": "elasticsearch",
"auth": {
"username": str,
"password": str,
},
"port": int,
}
good_data = {
"service": "elasticsearch",
"mood": "good",
"auth": {
"username": "buddy",
"password": "pasword",
},
"port": 6868,
}
also_good_data = { # doesn't matter if keys are missing
"auth": {
"username": "buddy",
},
}
bad_data = {
"auth": {
"username": 007, # not a string
},
}
pprint(unify(schema, good_data))
pprint(unify(schema, also_good_data))
pprint(unify(schema, bad_data)) # this will raise an error
unify is commutative, therefore unify(d0, d1) == unify(d1, d0).
Result
The Result type is a hacky attempt to get something like rust's Result type, and have errors as values instead of exceptions. It has several constructors:
def parse_num(num_str: str) -> Result[float]:
try:
return Result.ok(float(num_str))
except Exception as e:
return Result.err(str(e))
The above function may also be written as:
def parse_num(num_str: str) -> Result[float]:
return Result.wrap(float, num_str)
The Result type allows you to do a few neat things. For example, instead of this pattern:
config = None
try:
config = read_from_file(config_file)
except Exception as e:
logger.error(f"Failed to read config: {e}")
You can do this:
config = read_from_file(config_file) # returns Result
if config.is_err():
logger.error(f"Failed to read config: {config.fmt_err()}")
There is also result.is_ok() which is the opposite of result.is_err(). Also, things like:
some_num = (Result.wrap(get_user_input)
.default("7")
.map_ok(lambda num_str: float(num_str))
.map_ok(lambda num: num if num > 0 else 0)
.unwrap()) # this raises an exception if the result is an error
Which would normally be written as:
def get_some_num():
user_input = "7"
try:
user_input = get_user_input()
except Exception:
pass
num = float(user_input)
if num < 0:
num = 0
return num
Possibly a bad example, but anyway...
Metadata
Release files for eo4eu-base-utils 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| eo4eu_base_utils-0.6.0.tar.gz | 11.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| eo4eu_base_utils-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.3 kB
Release files / eo4eu_base_utils-0.6.0.tar.gz
| Download URL | eo4eu_base_utils-0.6.0.tar.gz |
|---|---|
| Size | 11.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e425e792b68b9c4cef51fc4ac2940e772f5ae749c793e019122b6387097d52dd
|
|
BLAKE2b-256 checksum How to use checksums |
a283987c1193fa47f31beae2fca6c9b8ca3640ea49c8d7836eeec6e45cfdd4d9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / eo4eu_base_utils-0.6.0-py3-none-any.whl
| Download URL | eo4eu_base_utils-0.6.0-py3-none-any.whl |
|---|---|
| Size | 10.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5aba7485f0b60bad94cf289059aabebe69869fd148bfdf30dc4e38207d624eaa
|
|
BLAKE2b-256 checksum How to use checksums |
291f487ccad37ec87a7a471076fe4c7d3be20f3edbc2f7b148e52fed203feb5f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|