Metadata-Version: 2.4
Name: debugignore
Version: 0.1.0
Summary: Runtime policy engine for Python — .gitignore-style workflow for disabling debug/dev behaviors.
Author: debugignore contributors
License: MIT
Project-URL: Homepage, https://github.com/Tharuneswar2/debugignore
Project-URL: Documentation, https://github.com/Tharuneswar2/debugignore#readme
Project-URL: Issues, https://github.com/Tharuneswar2/debugignore/issues
Project-URL: Repository, https://github.com/Tharuneswar2/debugignore
Keywords: debug,ignore,monkey-patch,runtime,policy,gitignore
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Debuggers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=4.0; extra == "dev"
Dynamic: license-file

<div align="center">
  <img src="docs/logo.png" alt="debugignore logo" height="150" />
  <h1>debugignore</h1>
  <p><b>Runtime policy engine for Python</b></p>

  <p>
    <a href="https://github.com/Tharuneswar2/debugignore/actions"><img src="https://img.shields.io/github/actions/workflow/status/Tharuneswar2/debugignore/python.yml?style=flat-square&logo=github" alt="Build Status"></a>
    <a href="https://pypi.org/project/debugignore/"><img src="https://img.shields.io/pypi/v/debugignore?style=flat-square&color=blue" alt="PyPI Version"></a>
    <a href="https://pypi.org/project/debugignore/"><img src="https://img.shields.io/pypi/pyversions/debugignore?style=flat-square" alt="Python Versions"></a>
    <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-green.svg?style=flat-square" alt="License: MIT"></a>
  </p>
</div>

---

**One import. Zero code changes. Full runtime control.**

`debugignore` brings a `.gitignore`-style workflow to Python runtime behaviors. It lets you dynamically disable prints, debug logs, network requests, or file writes directly from a configuration file, without modifying your source code.

---

## 📖 Table of Contents
- [The Problem Statement](#-the-problem-statement)
- [Why not just use standard logging?](#-why-not-just-use-standard-logging)
- [✨ Key Features](#-key-features)
- [🚀 Installation](#-installation)
- [⚡ Quick Start](#-quick-start)
- [🛠 Rule Syntax & Usage](#-rule-syntax--usage)
- [🏗 Architecture Overview](#-architecture-overview)
- [🗺 Roadmap](#-roadmap)
- [🤝 Contributing](#-contributing)
- [📄 License](#-license)

---

## 🎯 The Problem Statement

During development, we heavily rely on `print()`, `logging.debug()`, helper decorators, and mock network calls to iterate quickly. However, stripping these out before a production release is tedious, error-prone, and often results in noisy logs or accidental data leaks.

`debugignore` solves this by safely monkey-patching specified targets at runtime, turning them into safe `noop` operations based on a centralized `.debugignore` file.

### 🤔 Why not just use standard logging?
While Python's standard `logging` library is robust, it doesn't cover everything:
- You can't easily suppress third-party module network calls (like an accidental `requests.post()` in a test environment).
- Junior developers often leave `print()` statements behind.
- You might want to temporarily disable file writes (`open(..., "w")`) during dry-run executions without wrapping your entire I/O layer in conditionals.

`debugignore` acts as an **enforcer**, working seamlessly alongside your existing logging framework.

---

## ✨ Key Features
- **Zero Boilerplate:** Only requires `import debugignore`.
- **`.gitignore` Syntax:** Familiar wildcard and glob matching for rules.
- **Environment Aware:** Mode-scoped rules (e.g., `[production] print`).
- **Safe Patching:** Original callables are preserved and can be restored at any time.
- **Lazy Hooking:** Hooks into `sys.meta_path` to intercept modules imported *after* `debugignore`.
- **Pure Python:** No C-extensions, no third-party dependencies.

---

## 🚀 Installation

Install via pip:

```bash
pip install debugignore
```

For development and testing:
```bash
pip install debugignore[dev]
```

---

## ⚡ Quick Start

### 1. Create a `.debugignore` file
Place this in the root of your project:

```gitignore
# Suppress all built-in prints
print

# Block all outgoing HTTP posts via requests
requests.post

# Silence standard debug logging
logging.debug
```

### 2. Import it once
Import it as early as possible in your application lifecycle (e.g., in `main.py` or `__init__.py`).

```python
import debugignore
import requests
import logging

print("This will NOT appear.")

requests.post("https://api.example.com/webhook", json={"test": True}) # Blocked safely
logging.debug("This is silenced.")
```

---

## 🛠 Rule Syntax & Usage

| Pattern | Effect |
|---|---|
| `print` | Suppress `builtins.print` |
| `json.dumps` | Suppress a specific module attribute |
| `json.*` | Suppress all public callables in `json` |
| `debug_*` | Suppress any callable matching the glob |
| `requests.post` | Safely block `requests.post()` |
| `open` | Intercept file writes (reads still work) |
| `*.write` | Intercept file writes via any matched write method |
| `stdout` / `stderr` | Redirect streams to `/dev/null` equivalent |
| `app.py:120` | Suppress calls originating from a specific file:line (best-effort) |
| `[production] print` | Only suppress `print` when `DEBUGIGNORE_MODE=production` |

### Environment Variables
- `DEBUGIGNORE_MODE=production` — Activates rules tagged with `[production]`.
- `DEBUGIGNORE=1` — Forces engine activation even if the `.debugignore` file is missing.

### API Reference
If you prefer manual control over auto-activation:

```python
import debugignore

debugignore.enable()           # Activate manually
debugignore.disable()          # Restore all original functions
debugignore.reload()           # Re-read .debugignore and apply
```

You can also use the context manager for temporary suppression:
```python
with debugignore.disabled():
    print("This WILL print, even if blocked globally.")
```

---

## 🏗 Architecture Overview

`debugignore` is built on a non-destructive patching engine:
1. **Parser:** Reads `.debugignore` and constructs strongly-typed `Rule` instances.
2. **Patterns Engine:** Uses `fnmatch` to match rules against runtime targets.
3. **Patcher:** Applies monkey-patches. It heavily relies on `debugignore.utils.noop` to ensure return types don't crash standard operations.
4. **Hooks:** Installs a `sys.meta_path` finder to intercept and patch modules that are imported *after* `debugignore` is initialized.

---

## 🗺 Roadmap
Future plans for `debugignore` include:
- **Async Support:** Wrapping `async def` targets with awaitable noops.
- **CLI Analyzer:** `debugignore check` to dry-run rules against a codebase using AST analysis.
- **FastAPI / Django Plugins:** First-class middleware for web frameworks.
- **Policy Validation:** Strict mode to raise exceptions instead of silent suppression (useful in CI).

---

## 🤝 Contributing
Contributions are highly welcome! We use `pytest` for tests and `mypy` for static analysis.
Please read our [Contributing Guide](CONTRIBUTING.md) for full instructions on setting up your environment and submitting Pull Requests.

---

## 📄 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
