Files
peace-makerandCopilot 79ca9a962c Add type hints to timeout, term.text, hashes, and more (#2723)
* Add typehints to timeout module

Co-authored-by: Copilot <[email protected]>

* Add typehints to device class

* Add typehints to PwnlibException

* Add general typehints for term.text module

Since the available module attributes are handled dynamically like `text.green()` or `text.green_on_white()` or `text.underline_red()`, it's not feasible to type out all possible combinations.

Just tell the type checker that all module attibutes have the same type and thus avoid the `error: Module has no attribute "bold_blue"  [attr-defined]` errors.

* Add typehints for config module

* Add typehints for hashes module

The guaranteed algorithms in hashlib are pretty stable and we can generate the list out proper type checking and auto complete.

Still add a check in CI that notifies us if there are changes in the future.

* Add atexception and atexit types

atexception.unregister was not documented correctly since the function expects an identifier returned by `atexception.register` instead of the handler function.

* Fix toplevel type hints in shellcraft.internal

* Fix toplevel type hints in term.key

---------

Co-authored-by: Copilot <[email protected]>
2026-05-07 14:37:29 +02:00

71 lines
2.1 KiB
Python

"""Allows per-user and per-host configuration of Pwntools settings.
The list of configurable options includes all of the logging symbols
and colors, as well as all of the default values on the global context
object.
The configuration file is read from ``~/.pwn.conf``, ``$XDG_CONFIG_HOME/pwn.conf``
(``$XDG_CONFIG_HOME`` defaults to ``~/.config``, per XDG Base Directory Specification),
and ``/etc/pwn.conf``.
The configuration file is only read in ``from pwn import *`` mode, and not
when used in library mode (``import pwnlib``). To read the configuration
file in library mode, invoke :func:`.config.initialize`.
The ``context`` section supports complex types, at least as far as is
supported by :func:`pwnlib.util.safeeval.expr`.
::
[log]
success.symbol=😎
error.symbol=☠
info.color=blue
[context]
adb_port=4141
randomize=1
timeout=60
terminal=['x-terminal-emulator', '-e']
[update]
interval=7
"""
import configparser
import os
from typing import Any, Callable
ConfigHandler = Callable[[dict[str, Any]], None]
registered_configs: dict[str, ConfigHandler] = {}
def register_config(section: str, function: ConfigHandler) -> None:
"""Registers a configuration section.
Arguments:
section(str): Named configuration section
function(callable): Function invoked with a dictionary of
``{option: value}`` for the entries in the section.
"""
registered_configs[section] = function
def initialize() -> None:
"""Read the configuration files."""
from pwnlib.log import getLogger
log = getLogger(__name__)
xdg_config_home = os.environ.get('XDG_CONFIG_HOME',
os.path.expanduser("~/.config"))
c = configparser.ConfigParser()
c.read(['/etc/pwn.conf',
os.path.join(xdg_config_home, 'pwn.conf'),
os.path.expanduser('~/.pwn.conf')])
for section in c.sections():
if section not in registered_configs:
log.warn("Unknown configuration section %r", section)
continue
settings = dict(c.items(section))
registered_configs[section](settings)