Metadata-Version: 2.4
Name: pusher_debug
Version: 1.0.1
Summary: tools to assist with debug
Project-URL: repository, https://codeberg.org/Pusher2531/debug_tools.git
Project-URL: issues, https://codeberg.org/Pusher2531/debug_tools/issues
Author-email: Doug Sojourner <doug@sojournings.org>
License: GNU General Public License v3 (GPLv3)
License-File: LICENSE.md
Keywords: class modification,debug,debuging,decorator,monkeypatching,typed
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: <4.0,>=3.11.13
Requires-Dist: objwatch
Requires-Dist: packaging
Requires-Dist: project-version-finder
Requires-Dist: regex
Description-Content-Type: text/markdown

### `pusher_debug`
## `pusher_debug.tracing`
Tools to aid in adding print statements to trace program flow:
* `ObjWatch` from the objwatch library
* `DetailWrapper`, a "wrapper" to use with Objwatch that provides more details on function calls and returns, and can be subclassed easily to provide distinct id strings for different instances of selected classes.
* `fn_name`, `fn_entry`, and `fn_exit`, to provide manual logging of details of function you enter (caller, parameters, return value, annotations)

## `pusher_debug.monkeypatching`
Tools to aid in monkeypatching. Two decorators:
```python
@add_new_class(ExistingClass)
class MyClass: ...
```

will (in the module where `ExistingClass` is defined)
1. Create `orig_ExistingClass`, as a backup of `ExistingClass`  
2. Create `new_ExistingClass`, as a backup of `MyClass`  
3. Make `ExistingClass` be `new_ExistingClass` (fixing `__name__` and `__qualname__` between `new_ExistingClass` and `orig_ExistingClass` as well)  

Then `restore_class(ExistingClass)` will restore the original, and `restore_new_class(ExistingClass)` will put back the new version again.  

```python
@add_to_class(ExistingClass)
def fn():...
```

will (in `ExistingClass`) add a method `fn`. If `fn` already exists, the the original is backed up as `orig_fn`. `new_fn` is created and names are fixed as for `@add_new_class`.  

`@add_to_class` can be combined with one of `@classmethod`, `@staticmethod`, or `@property` (and if property, then `fn` in the local namespace will be the property, so you can then do  
```python
@add_to_class(ExistingClass)
@fn@setter
def fn():...
```

You should know that monkeypatching will wreack havoc with mypy, since it does stuff you shouldn't do. (It's for __debugging__ !)  

For examples, use help(...), and/or download the source package and look at the tests. Seeing all the # test: ignore[] stuff in the test program gives you an idea of how much mypy hates this.  

The library can be built with `hatchling build`, tested with `tests/test_tools.py -v`, and should pass `mypy` (including having annotations for objwatch).  
