Registry / serialization / banal
library1.1.2pypypi✓ verified 23d ago

Banal is a Python library providing a collection of 'micro-functions' focused on handling and buffering type uncertainties. It's designed as an outsourced utility module to simplify common tasks like checking if an object is list-like or ensuring an argument is a list. The current version is 1.0.6, released in February 2021, indicating a low release cadence and a mature, stable codebase.

pip install banal
INSTALL
IMPORT
SIG · BANAL
B
banal
serializationpythonv1.1.2
Install
1.5s avg
Import
15ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.1.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.016s · 17.8MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.5s · import 0.014s · 18MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

is_listish
from banal import is_listish
ensure_list
from banal import ensure_list
clean_dict
from banal import clean_dict
hash_data
from banal import hash_data

This quickstart demonstrates the `ensure_list` function for normalizing various inputs into lists and the `clean_dict` function for recursively removing `None` values from dictionaries. The library's functions are generally self-contained and directly imported.

import os from banal import ensure_list, clean_dict # Example 1: ensure_list - ensures an argument is a list print("--- ensure_list examples ---") print(f"Scalar to list: {ensure_list('hello')}") print(f"None to list: {ensure_list(None)}") print(f"Tuple to list: {ensure_list(('a', 'b'))}") print(f"Existing list: {ensure_list([1, 2, 3])}") # Example 2: clean_dict - removes None values from a dict, recursively print("\n--- clean_dict examples ---") data_with_nones = { "name": "Alice", "age": 30, "email": None, "address": { "street": "123 Main St", "city": "Anytown", "zip": None }, "preferences": [] } cleaned_data = clean_dict(data_with_nones) print(f"Original: {data_with_nones}") print(f"Cleaned: {cleaned_data}") # clean_dict typically keeps empty strings, zeros, False, empty lists/dicts data_with_falsey = { "key1": "value", "key2": "", "key3": None, "key4": 0, "key5": False, "key6": [], "key7": {}, "nested": { "sub_key1": "abc", "sub_key2": None } } cleaned_falsey = clean_dict(data_with_falsey) print(f"\nOriginal (falsey values): {data_with_falsey}") print(f"Cleaned (falsey values): {cleaned_falsey}")
Debug
Known issues
gotchaThe library's core philosophy is to 'buffer type uncertainties', meaning functions like `ensure_list` might aggressively convert inputs (e.g., a string) into a list (`['string']`) rather than raising a TypeError. Users accustomed to strict type checking might find this behavior surprising if not explicitly anticipated.
fix
Review the documentation for each function to understand its specific type-handling behavior and ensure it aligns with your application's requirements. Explicitly validate types before passing if strictness is required.
affects: All versions
deprecatedThe `banal` library has not seen a new release since February 2021 (v1.0.6). While stable, this suggests it is in maintenance mode rather than active development. It may not support the latest Python versions (e.g., Python 3.10+) optimally or leverage newer language features.
fix
Test thoroughly on newer Python versions. For new projects, consider if a more actively maintained utility library better suits long-term compatibility and feature needs. For existing projects, be aware of potential subtle incompatibilities with very recent Python versions.
affects: <=1.0.6 on Python 3.10+
gotchaSome older package distributions (e.g., Debian, BlackArch) of `banal` explicitly listed `python-six` as a dependency for Python 2/3 compatibility. While the GitHub README for recent versions now states it 'Cannot depend on anything but the standard library', users in mixed or older Python environments might implicitly pull in or expect `six`, which is generally not needed in modern Python 3-only projects.
fix
For new Python 3-only projects, verify that `six` is not being implicitly installed or relied upon if not explicitly needed. For older projects, be aware of this dependency if migrating between Python versions.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'banal'
The 'banal' library is not installed in your Python environment or there is a typo in the import statement.
fix
Install the library using pip: `pip install banal`
AttributeError: module 'banal' has no attribute 'is_list'
You are attempting to access a function or attribute that does not exist or is misspelled within the `banal` module. The correct function name is `is_listish`, not `is_list`.
fix
Correct the function name to one of the available functions, such as `banal.is_listish`.
TypeError: can only concatenate tuple (not "int") to tuple (resulting from using banal.ensure_list)
This error often occurs when `banal.ensure_list` is used with an iterable (like a tuple) and the subsequent code expects the elements of the original iterable to be individually accessible, but `ensure_list` wraps the entire iterable as a single element within a new list. For example, `banal.ensure_list((1, 2, 3))` returns `[(1, 2, 3)]`, not `[1, 2, 3]`.
fix
If you intend to flatten an iterable into a list of its individual elements, manually convert it. If you explicitly want to wrap any non-list into a single-element list, ensure your subsequent code handles the wrapped iterable correctly.
```python
import banal

# Scenario leading to TypeError (original intent: flatten tuple)
my_data = (1, 2, 3)
processed_data = banal.ensure_list(my_data) # Result: [(1, 2, 3)]
# Assuming you then iterate expecting individual integers:
# for item in processed_data: # item becomes (1, 2, 3)
#    result = item + 1 # This would raise TypeError

# Fix: If the goal is to flatten an iterable:
if not isinstance(my_data, list):
    my_data = list(my_data) # Converts (1, 2, 3) to

# Or, if `ensure_list` is desired but you need to process the inner iterable:
processed_data = banal.ensure_list(my_data)
if isinstance(processed_data, (tuple, list)): # Check if it wrapped an iterable
    final_data = list(processed_data) # Flatten it
else:
    final_data = processed_data

# Now final_data will be
for item in final_data:
    result = item + 1 # Works correctly
```
Upgrade
Version history
1.1.2latest on PyPI · released Apr 14, 2026
Audit
Dependencies
sixoptionalHistorically, some package distributions (e.g., Debian, BlackArch) listed 'six' as a dependency for Python 2/3 compatibility. While the GitHub README now states 'Cannot depend on anything but the standard library', older installations or specific environments might still encounter it.
Agent activity
27 hits · last 30 days
node
22
OpenAI (training)
1
Resources
banal — pip install banal · libregistry