2021-02-23 01:53:10 +00:00
|
|
|
from collections import namedtuple
|
2024-06-11 03:24:27 +00:00
|
|
|
from collections.abc import Iterable, Mapping, MutableMapping
|
2021-02-23 01:53:10 +00:00
|
|
|
|
2020-08-21 13:09:34 +00:00
|
|
|
|
|
|
|
def clean_none_dict_values(obj):
|
|
|
|
"""
|
|
|
|
Recursively remove keys with a value of None
|
|
|
|
"""
|
2024-06-11 04:46:20 +00:00
|
|
|
if not isinstance(obj, Iterable) or isinstance(obj, str):
|
2020-08-21 13:09:34 +00:00
|
|
|
return obj
|
|
|
|
|
|
|
|
queue = [obj]
|
|
|
|
|
|
|
|
while queue:
|
|
|
|
item = queue.pop()
|
|
|
|
|
2024-06-11 03:24:27 +00:00
|
|
|
if isinstance(item, Mapping):
|
|
|
|
mutable = isinstance(item, MutableMapping)
|
2020-08-21 13:09:34 +00:00
|
|
|
remove = []
|
|
|
|
|
|
|
|
for key, value in item.items():
|
|
|
|
if value is None and mutable:
|
|
|
|
remove.append(key)
|
|
|
|
|
2024-06-11 04:46:20 +00:00
|
|
|
elif isinstance(value, str):
|
2020-08-21 13:09:34 +00:00
|
|
|
continue
|
|
|
|
|
2024-06-11 03:24:27 +00:00
|
|
|
elif isinstance(value, Iterable):
|
2020-08-21 13:09:34 +00:00
|
|
|
queue.append(value)
|
|
|
|
|
|
|
|
if mutable:
|
|
|
|
# Remove keys with None value
|
|
|
|
for key in remove:
|
|
|
|
item.pop(key)
|
|
|
|
|
2024-06-11 03:24:27 +00:00
|
|
|
elif isinstance(item, Iterable):
|
2020-08-21 13:09:34 +00:00
|
|
|
for value in item:
|
2024-06-11 04:46:20 +00:00
|
|
|
if value is None or isinstance(value, str):
|
2020-08-21 13:09:34 +00:00
|
|
|
continue
|
2024-06-11 03:24:27 +00:00
|
|
|
elif isinstance(value, Iterable):
|
2020-08-21 13:09:34 +00:00
|
|
|
queue.append(value)
|
|
|
|
|
|
|
|
return obj
|
2021-02-23 01:42:26 +00:00
|
|
|
|
|
|
|
|
|
|
|
def sqlite_namedtuple_factory(cursor, row):
|
|
|
|
"""
|
|
|
|
Usage:
|
|
|
|
con.row_factory = namedtuple_factory
|
|
|
|
|
|
|
|
http://peter-hoffmann.com/2010/python-sqlite-namedtuple-factory.html
|
|
|
|
"""
|
|
|
|
fields = [col[0] for col in cursor.description]
|
|
|
|
Row = namedtuple("Row", fields)
|
|
|
|
return Row(*row)
|