
# zdbg
# Copyright (c) Stacy Prowell (sprowell@gmail.com)
# All rights reserved.
# This software is licensed under the MIT License. See LICENSE for details.

"""
zdbg: A lightweight (zero cost) debugging helper.

Public API:
    DEBUG: set[str]
    debug(msg: Any) -> None
    error(msg: Any) -> None
    configure(options: Iterable[str] | None, ...) -> None

    
Overview
========
This module provides two functions: `error` and `debug`. The error function
writes an error message in all cases, while the debug function writes a
debugging message only when debugging is enabled, and is explicitly a no-op
otherwise. This is configured at import time by reading the `DEBUG`
environment variable (or another; see Environment Variable, below), which
should be a comma-separated list of options.

The following options are supported.

    debug .......... Enable debug output. (1 is a synonym.)
    context ........ Include file:line for each debug message.
    nocolor ........ Disable ANSI colors.
    timestamp ...... Include an ISO-like timestamp.
    noflush_debug .. Do not flush debug output after each message.
    noflush_error .. Do not flush error output after each message.

By default, color is used when the corresponding output stream is a TTY. Any
other options can be passed, and these are available at runtime by checking
the `DEBUG` set.

When color is enabled, error messages are written in bold and tagged in red,
and debug messages are tagged in green. By default, error messages are
written to standard error, and debug messages are written to standard output.
This can be changed by passing different output streams to the `configure()`
function.

By default the output streams are flushed after every message. If you do not
want that, you can disable it with the `noflush_debug` and `noflush_error`
options.


General Usage
=============
To use this module, import it.

    import zdbg

To write an error message, use `zdbg.error("message")`. Likewise, to write a
debug message use `zdbg.debug("message")`. The debug message will only be
written if debugging is enabled, but if the message construction is costly,
you should check if debugging is enabled first, as follows.

    if 'debug' in zdbg.DEBUG:
        zdbg.debug(expensive_function())

This avoids the cost of calling `expensive_function()` when debugging is
not enabled. If the debug message is a static string, this will not matter.


Runtime Configuration
=====================
You can use the `configure()` function to change the debugging configuration
at runtime. For example, to enable debugging with context information, you
can do the following.

    import zdbg

    zdbg.configure(["debug", "context"])
    zdbg.debug("This will be printed with context")

    
Runtime Checks
==============
You can use the `DEBUG` set to check for other options at runtime. For example,
if you have a special debugging option called `fred`, you can check for it as
follows.

    if 'fred' in zdbg.DEBUG:
        zdbg.debug("Fred debugging is enabled.")

From the command line you might invoke the program (with this option) as follows.

    DEBUG=debug,fred python3 myprogram.py

    
Configuration
=============
To configure debugging at runtime, call the `configure()` function with
a list of options (as above). To re-parse from the environment variable, pass
`None` to the function. Note that the configuration is global, so this will
impact all uses of the `debug` and `error` functions.


Command Line Usage
==================
You can set the `DEBUG` environment variable from the command line in BASH and
ZSH as follows.

    export DEBUG="debug,context,timestamp"

To set it for just the next command, include the setting in front of the
command as follows.

    DEBUG=debug,context,timestamp python3 myprogram.py

    
Environment Variable
====================
If you don't want to use `DEBUG` as the environment variable, you can
configure from a different one using `configure()`. For example, to use
`ZDBG_DEBUG` instead of `DEBUG`, you can do the following at the start of your
program.

    import zdbg
    zdbg.configure(None, envvar="ZDBG_DEBUG")

"""

from .core import DEBUG, configure, debug, error

__all__ = ["DEBUG", "configure", "debug", "error"]

# Optional: package metadata
__version__ = "1.0.0"
__author__ = "Stacy Prowell"
__license__ = "MIT"
