-
Notifications
You must be signed in to change notification settings - Fork 7.1k
list of shennanigans (syntax footguns, unhelpful defaults, missing basic functionality, silently data dropping behavior) #164
Copy link
Copy link
Closed
Description
# SHENNANIGAN do not use xml.dom.minidom, it breaks space and newlines:
# https://bugs.python.org/issue5752
# use instead ElementTree
# SHENNANIGAN os.kill() does not call registered cleanup function `atexit.register(exit_cleanup)`
# by deamonzed threads. Must store pids of child processes and clean them explicitly or
# signal main thread via
def signalMainThread(self) -> None:
pass
# before Python 3.10: _thread.interrupt_main()
# since Python 3.10: _thread.interrupt_main(signum=signal.SIGKILL)
# SHENNANIGAN
# readline() with timeout io file api is broken, see https://github.com/python/cpython/issues/51571
# Workaround
# * 1. Read from Kernel structure and append chunk-wise to buffer from socket until stop event.
# * 2. After each read, try line = readline() from the buffer and remove the line on success.
# * 3. On failure of reading line, continue with 1.
# * 4. Teardown should also use readSocket to read all Kernel memory, if a stop was signaled.
# Note: utf-8 decoding must also be done and select or an equivalent should be used to check,
# if data for reading exists.
# SHENNANIGAN Dictionary is missing this common method
def is_subdict(small: dict, big: dict) -> bool:
"""
Test, if 'small' is subdict of 'big'
Example: big = {'pl' : 'key1': {'key2': 'value2'}}
Then small = {'pl' : 'key1': {'key2': 'value2'}, 'otherkey'..} matches,
but small = {'pl' : 'key1': {'key2': 'value2', 'otherkey'..}}
or small = {'pl' : 'key1': {'key2': {'value2', 'otherkey'..}}} not.
"""
# since python3.9:
# return big | small == big
# also:
# return {**big, **small} == big
return dict(big, **small) == big
# SHENNANIGAN Dictionary is missing this common method
def has_fieldsvals(small: dict, big: dict) -> bool:
"""
Test, if 'small' has all values of of 'big'
Example: big = {'pl' : 'key1': {'key2': 'value2'}}
Then small = {'pl' : 'key1': {'key2': 'value2'}, 'otherkey'..} matches,
small = {'pl' : 'key1': {'key2': 'value2', 'otherkey'..}} matches,
and small = {'pl' : 'key1': {'key2': {'value2', 'otherkey'..}}} matches.
"""
for key, value in small.items():
if key in big:
if isinstance(small[key], dict):
if not has_fieldsvals(small[key], big[key]):
return False
elif value != big[key]:
return False
else:
return False
return True
# SHENNANIGAN Dictionary is missing this common method
def merge_dicts(alpha: dict = {}, beta: dict = {}) -> dict:
"""
Recursive merge dicts. Not multi-threading safe.
"""
return _merge_dicts_aux(alpha, beta, copy.copy(alpha))
def _merge_dicts_aux(alpha: dict = {}, beta: dict = {}, result: dict = {}, path: Optional[List[str]] = None) -> dict:
if path is None:
path = []
for key in beta:
if key not in alpha:
result[key] = beta[key]
else:
if isinstance(alpha[key], dict) and isinstance(beta[key], dict):
# key value is dict in A and B => merge the dicts
_merge_dicts_aux(alpha[key], beta[key], result[key], path + [str(key)])
elif alpha[key] == beta[key]:
# key value is same in A and B => ignore
pass
else:
# key value differs in A and B => raise error
err: str = f"Conflict at {'.'.join(path + [str(key)])}"
raise Exception(err)
return result
### SHENNANIGAN tuples and dicts are annoying to differentiate
# dictionary
dict1 = {
"m1": "cp",
"m2": "cp"
}
# tuple
tup1 = {
"m1": "cp",
"m2": "cp"
},
# at least getting the intention correct, but python is still unhelpful with errror message
dict2 = dict({
"m1": "cp",
"m2": "cp"
})
# tuple
tup2 = tuple({
"m1": "cp",
"m2": "cp"
}),
Steal it from github.com/matu3ba/dotfiles/templates/common.py, if you want.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels