Metadata-Version: 2.4
Name: lucidlog
Version: 0.1.4
Summary: Source-aware exception diagnostics with conservative explanations
Author-email: Malhar Pangarkar <malharpangarkar19@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/Malhar1912/LucidLog
Project-URL: Repository, https://github.com/Malhar1912/LucidLog
Project-URL: Issues, https://github.com/Malhar1912/LucidLog/issues
Project-URL: Changelog, https://github.com/Malhar1912/LucidLog/blob/main/docs/CHANGELOG.md
Keywords: debugging,exceptions,diagnostics,tracebacks
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"

# LucidLog

![CI](https://github.com/Malhar1912/LucidLog/actions/workflows/ci.yml/badge.svg)
![PyPI](https://img.shields.io/pypi/v/lucidlog.svg)
![Python](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue)

LucidLog is a lightweight, source-aware exception diagnostic library for Python.

It keeps the original exception behavior intact, adds a clearer reading of the relevant traceback frame, and provides deterministic built-in explanations without requiring a remote service.

## Quick start

```python
import lucidlog

lucidlog.install()

try:
    value = {}["missing"]
except Exception:
    lucidlog.exception("Lookup failed")
```

## Complete example

Run the bundled demo for a full tour of the library's features:

```bash
python examples/complete_demo.py
```

The demo covers chained exceptions, redaction, render output, custom rules, logging payloads, and the threading/asyncio integrations.

## Responsibility metadata (Git-aware)

When the code is running inside a Git repository, LucidLog can attach attribution metadata for the exact source line that raised the exception. The diagnostic records the author name, author email, commit ID, short summary, and date for that line when available.

```python
try:
    raise RuntimeError("something broke")
except RuntimeError as exc:
    diagnostic = lucidlog.diagnose(exc)
    frame = diagnostic.primary_frame
    if frame and frame.responsibility:
        print(frame.responsibility.author)
        print(frame.responsibility.commit_id)
        print(frame.responsibility.summary)
```

## Public API

- `lucidlog.install()`
- `lucidlog.uninstall()`
- `lucidlog.exception(message, *, stream=None, full=False, config=None)`
- `lucidlog.diagnose(exc, *, config=None)`
- `lucidlog.log_exception(logger, message, *, full=False, config=None)`
- `lucidlog.render_diagnostic(diagnostic, *, full=False, stream=None, color=None)`

## Configuration and output

Pass a frozen `lucidlog.Config` to `install`, `diagnose`, `exception`, or `log_exception` to configure capture and output:

```python
import lucidlog
from lucidlog import Config

lucidlog.install(
    config=Config(
        color=True,
        include_full_traceback=True,
        max_chain_depth=6,
        redact_patterns=(r"(?i)customer-id=[A-Z0-9]+",),
    )
)
```

Colors are disabled for non-interactive streams by default and honor `NO_COLOR` and `TERM=dumb`. `color=True` forces ANSI output; `color=False` disables it. Exception colors distinguish common diagnostic families, while the severity badge uses a separate palette (`critical`, `error`, `warning`, or `info`). The JSON representation contains the plain text values, never ANSI codes.

Cause/context chains and exception groups are represented as bounded nested data and included in the compact output. Limits (`max_chain_depth`, `max_group_exceptions`, `max_frames`, `max_message_length`, `max_traceback_chars`, `max_source_file_bytes`, and `max_diagnosis_evidence`) constrain diagnostic capture. `Diagnostic.to_dict()` and `to_json()` include a schema version, severity, fingerprint-like ID, cause relationships, and truncation indicator. Setting `include_local_variables=True` or `allow_network=True` is rejected; those capabilities are deliberately not part of the core.

The optional runtime integrations are explicit:

```python
from lucidlog.integrations.threading import install_threading_hook
from lucidlog.integrations.asyncio import install_asyncio_exception_handler

install_threading_hook()
install_asyncio_exception_handler()
```

Each has a corresponding `uninstall_*` function. Asyncio leaves an already-installed handler in place unless `chain_previous=True`; thread and main hooks restore prior handlers when removed. Worker-thread and event-loop hooks do not cover child processes.

## Privacy notes

LucidLog never reads local variables or makes network requests. It redacts common credential-shaped strings and user-configured patterns from messages, source context, causes, and traceback text before those values enter the diagnostic model. Absolute paths under the home directory are shortened by default; `root_path` can shorten project paths. Redaction is best-effort: exception messages and source code are arbitrary application data, so review output before storing or forwarding it and supply additional patterns for your environment. `Config` validates regex syntax and output limits up front.

Logging integration writes one structured log record with a `lucidlog` dictionary in `LogRecord` extra fields. It deliberately omits `exc_info` to avoid bypassing redaction with a raw traceback. The original exception is not modified, and `log_exception` requires an active exception handler.

## Tests

Run the unit and integration tests with:

```bash
python -m pytest
```

The suite covers chained and grouped exceptions, cycle/size limits, redaction, terminal colors, hook restoration, threading, asyncio, structured logging, and uncaught-process exit behavior.

## Project structure

```text
LucidLog/
├── .github/workflows/   # CI and release automation
├── docs/                # project documentation and changelog
├── examples/            # end-to-end examples and demonstrations
├── scripts/             # local release and publishing helpers
├── src/lucidlog/        # library package source
├── tests/               # unit and integration tests
├── .gitignore
├── .pypirc.example      # local PyPI credentials template (do not commit secrets)
├── README.md
├── pyproject.toml
├── pytest.ini
└── LICENSE              # if you choose to add one in the future
```

## Release workflow

Use the local helper script to build, validate, and publish the package:

```bash
python scripts/publish_release.py --repository pypi
```

For a dry validation run without uploading:

```bash
python scripts/publish_release.py --repository pypi --no-upload
```

Store real PyPI credentials in your user-level `.pypirc` file outside the repo, never in Git.

## Notes

- The core package is standard-library only.
- It does not capture local variables by default.
- It keeps the original traceback available and does not replace the application's original exception flow.
