BFS-enhanced method lookup for Python classes
Project description
BFSMRO
⚠️ Note: This is a pet project for practicing advanced Python concepts like metaprogramming, context managers, and dynamic method resolution.
It is not intended for production use. Features like__slots__,property, and full descriptor support are not implemented.
BFS-enhanced method lookup for Python classes and instances.
This context manager allows a class or instance to access @classmethod, @staticmethod, and instance methods from its subclasses — even if they’re not in the MRO.
It uses Breadth-First Search (BFS) to find methods downward in the inheritance tree, while preserving normal MRO lookup (upward) as the first priority.
Ideal for dynamic plugin systems, framework extensions, and exploratory programming.
🔧 Features
- ✅ Works on classes and instances
- ✅ Supports
@classmethod,@staticmethod, and instance methods - ✅ Lookup order: MRO first (up), then BFS in subclasses (down)
- ✅ Opt-in
debugmode: logs lookup and enhances error messages - ✅ Thread-safe mode available
- ✅ Zero changes to existing classes
🚀 Usage
from bfs_mro import BFSMRO
class Wizard: pass
class WhiteWizard(Wizard):
@classmethod
def cast_light(cls):
return f"{cls.__name__} casts light"
def heal(self):
return f"A {self.__class__.__name__} heals"
# Enhance class to access subclass methods
with BFSMRO(Wizard) as Wizard:
print(Wizard.cast_light()) # → "Wizard casts light"
# Enhance instance
wizard = Wizard()
with BFSMRO(wizard) as wizard:
print(wizard.heal()) # -> "A Wizard heals"
⚠️ Name Shadowing in Functions
Due to Python’s scoping rules, you cannot use the same name in the with ... as target if it’s also used in the expression, when inside a function:
def bad():
with BFSMRO(Wizard) as Wizard: # ❌ UnboundLocalError
Wizard.cast_light()
✅ Workaround
Use a temporary name for the class or instance:
_Wizard = Wizard
def good():
with BFSMRO(_Wizard) as Wizard:
assert Wizard.cast_light() == "Wizard casts light"
This allows you to preserve the original name in the as clause while avoiding the scoping conflict.
📦 Installation
pip install bfs-mro
🛠 Development
# Clone and install in dev mode
git clone https://github.com/AlexShchW/bfs_mro.git
cd bfs_mro
pip install -e .[dev]
# Run tests
pytest
📄 License MIT — see LICENSE file.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bfs_mro-0.1.0.tar.gz.
File metadata
- Download URL: bfs_mro-0.1.0.tar.gz
- Upload date:
- Size: 5.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe6e17a005262d1a42be1df54c6e62956917a84d51cef23b1359906dcb001cb9
|
|
| MD5 |
344f4925283c5c6ef6705bd2026d3efd
|
|
| BLAKE2b-256 |
30023b5a1fb325797a46a04a11b288fb47924683882af300b93ef49771e7ec05
|
File details
Details for the file bfs_mro-0.1.0-py3-none-any.whl.
File metadata
- Download URL: bfs_mro-0.1.0-py3-none-any.whl
- Upload date:
- Size: 5.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
636424a0e06b2e9b0bb685ba8939d8b79d6c2a82eea78d30dcaad176e97e8162
|
|
| MD5 |
d7aa9be9cd464a9d5e1260ad10cc45d4
|
|
| BLAKE2b-256 |
f3595c478016b24c051552fba69c295b7944468eff691dc94c73e72287480303
|