{"id":15377744,"url":"https://github.com/cifkao/nopdb","last_synced_at":"2025-04-14T16:10:43.965Z","repository":{"id":44845790,"uuid":"339834164","full_name":"cifkao/nopdb","owner":"cifkao","description":"NoPdb: Non-interactive Python Debugger","archived":false,"fork":false,"pushed_at":"2022-07-12T08:56:57.000Z","size":4419,"stargazers_count":83,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-28T04:51:12.444Z","etag":null,"topics":["debugger","debugging-tool","debugging-tools","developer-tools","function-hooks","intercept-calls","machine-learning","pdb","programmatic","python","tracing"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cifkao.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-17T19:31:24.000Z","updated_at":"2024-12-03T21:48:39.000Z","dependencies_parsed_at":"2022-09-02T22:11:57.940Z","dependency_job_id":null,"html_url":"https://github.com/cifkao/nopdb","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cifkao%2Fnopdb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cifkao%2Fnopdb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cifkao%2Fnopdb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cifkao%2Fnopdb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cifkao","download_url":"https://codeload.github.com/cifkao/nopdb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248835704,"owners_count":21169277,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["debugger","debugging-tool","debugging-tools","developer-tools","function-hooks","intercept-calls","machine-learning","pdb","programmatic","python","tracing"],"created_at":"2024-10-01T14:13:40.157Z","updated_at":"2025-04-14T16:10:43.929Z","avatar_url":"https://github.com/cifkao.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"NoPdb: Non-interactive Python Debugger\n======================================\n|pypi-package| |docs-status| |test-status| |lint-status|\n\n* **Installation:** :code:`pip install nopdb`\n* **Docs:** https://nopdb.readthedocs.io/\n\nNoPdb is a **programmatic** (non-interactive) **debugger** for Python. This means it gives you access to\n**debugger-like superpowers** directly from your code. With NoPdb, you can:\n\n* **capture function calls**, including arguments, local variables, return values and stack traces\n* **set \"breakpoints\"** that trigger user-defined actions when hit, namely:\n\n  * **evaluate expressions** to retrieve their values later\n  * **execute arbitrary code**, including modifying local variables\n  * **enter an interactive debugger** like `pdb`\n\nNoPdb is also a convenient tool for inspecting **machine learning model internals**. For example,\n`this notebook \u003chttps://colab.research.google.com/github/cifkao/nopdb/blob/main/docs/pytorch_tutorial.ipynb\u003e`_, `this post on Towards Data Science \u003chttps://towardsdatascience.com/dissecting-ml-models-with-nopdb-6ff4651fb131\u003e`_ and `this notebook \u003chttps://mybinder.org/v2/gh/cifkao/scipy2022-nopdb/main?labpath=nopdb_poster.ipynb\u003e`_ (SciPy 2022 virtual poster)\nshow how to use it to visualize Transformer attention in PyTorch.\n\nNoPdb should run at least under CPython and PyPy. Most features should work under any implementation\nas long as it has :code:`sys.settrace()`.\n\n**Note:** This project is in its early development stage. Contributions and improvement ideas are welcome.\n\nCapturing function calls\n------------------------\n\nThe functions :code:`capture_call()` and :code:`capture_calls()` allow\ncapturing useful information about calls to a given function.\nThey are typically used as context managers, e.g.:\n\n.. code-block:: python\n\n    with nopdb.capture_calls(fn) as calls:\n        some_code_that_calls_fn()\n\n        print(calls)  # see details about how fn() was called\n\nThe information we can retrieve includes the function's arguments, return value, local variables and stack trace. For example:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e with nopdb.capture_call(f) as call:\n    ...     g(1)\n    \u003e\u003e\u003e call\n    CallCapture(name='f', args=OrderedDict(x=1, y=1), return_value=4)\n    \u003e\u003e\u003e call.print_stack()\n      File \"\u003cstdin\u003e\", line 2, in \u003cmodule\u003e\n      File \"\u003cstdin\u003e\", line 2, in g\n      File \"\u003cstdin\u003e\", line 1, in f\n    \u003e\u003e\u003e call.args['x']\n    1\n    \u003e\u003e\u003e call.return_value\n    4\n    \u003e\u003e\u003e call.locals\n    {'y': 1, 'x': 1, 'z': 2}\n\nSetting breakpoints\n-------------------\n\nLike conventional debuggers, NoPdb can set breakpoints. However, because NoPdb is a\n*non-interactive* debugger, its breakpoints do not actually stop the execution of the\nprogram. Instead, they allow executing actions scheduled in advance, such as\nevaluating expressions.\n\nTo set a breakpoint, call the :code:`breakpoint()` function. A breakpoint object\nis returned, allowing to schedule actions using its methods such as\n:code:`eval()` and :code:`exec()`. For example:\n\n.. code-block:: python\n\n   # Break at line 3 of the file or notebook cell where f is defined\n   with nopdb.breakpoint(function=f, line=3) as bp:\n       x = bp.eval(\"x\")             # Schedule an expression\n       type_y = bp.eval(\"type(y)\")  # Another one\n       bp.exec(\"print(y)\")          # Schedule a print statement\n\n       some_code_that_calls_f()\n\n   print(x, type_y)  # Retrieve the captured values\n\nThere are other ways to specify the breakpoint location. For example:\n\n.. code-block:: python\n\n   # Break at any line with the given source code in the given file\n   with nopdb.breakpoint(file=\"pathlib.py\", line=\"return obj\") as bp:\n       ...\n\n   # Break as soon as any function with the given name is called\n   with nopdb.breakpoint(function=\"myfunc\") as bp:\n       ...\n\nNot only can we capture values, we can also modify them!\n\n.. code-block:: python\n\n    \u003e\u003e\u003e with nopdb.breakpoint(function=f, line=3) as bp:\n    ...     # Get the value of x, then increment it, then get the new value\n    ...     x_before = bp.eval('x')\n    ...     bp.exec('x += 1')\n    ...     x_after = bp.eval('x')\n    ...\n    ...     some_code_that_calls_f()\n    \u003e\u003e\u003e x_before\n    [2]\n    \u003e\u003e\u003e x_after\n    [3]\n\nPlanned features\n----------------\nFunctionalities that do not exist, but could be added in the future:\n\n* :code:`Breakpoint.callback()` for calling a given callback function, passing information about the current frame as an argument.\n* :code:`Breakpoint.jump()` for jumping to a different line in the same function.\n\nLimitations\n-----------\n\n* Like Pdb, NoPdb only works with pure-Python functions. Calls to built-ins and C extensions cannot be captured. This also applies to ML frameworks that compile models into static graphs; for NoPdb to work, this feature needs to be disabled, e.g. with :code:`tf.config.run_functions_eagerly(True)` in TensorFlow and with the :code:`jax.disable_jit()` context manager in JAX.\n* Local variable assignment in :code:`Breakpoint.exec()` is only supported under CPython and PyPy.\n\n.. |pypi-package| image:: https://badge.fury.io/py/nopdb.svg?\n   :target: https://pypi.org/project/nopdb/\n   :alt: PyPI Package\n.. |docs-status| image:: https://readthedocs.org/projects/nopdb/badge/?version=latest\n   :target: https://nopdb.readthedocs.io/en/latest/?badge=latest\n   :alt: Documentation Status\n.. |test-status| image:: https://github.com/cifkao/nopdb/actions/workflows/test.yml/badge.svg\n   :target: https://github.com/cifkao/nopdb/actions/workflows/test.yml\n   :alt: Lint Status\n.. |lint-status| image:: https://github.com/cifkao/nopdb/actions/workflows/lint.yml/badge.svg\n   :target: https://github.com/cifkao/nopdb/actions/workflows/lint.yml\n   :alt: Lint Status\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcifkao%2Fnopdb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcifkao%2Fnopdb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcifkao%2Fnopdb/lists"}