# executing
[![Build Status](https://github.com/alexmojaki/executing/workflows/Tests/badge.svg?branch=master)](https://github.com/alexmojaki/executing/actions) [![Coverage Status](https://coveralls.io/repos/github/alexmojaki/executing/badge.svg?branch=master)](https://coveralls.io/github/alexmojaki/executing?branch=master) [![Supports Python versions 3.5+, including PyPy](https://img.shields.io/pypi/pyversions/executing.svg)](https://pypi.python.org/pypi/executing)
This mini-package lets you get information about what a frame is currently doing, particularly the AST node being executed.
* [Usage](#usage)
* [Getting the AST node](#getting-the-ast-node)
* [Getting the source code of the node](#getting-the-source-code-of-the-node)
* [Getting the `__qualname__` of the current function](#getting-the-__qualname__-of-the-current-function)
* [The Source class](#the-source-class)
* [Installation](#installation)
* [How does it work?](#how-does-it-work)
* [Is it reliable?](#is-it-reliable)
* [Which nodes can it identify?](#which-nodes-can-it-identify)
* [Libraries that use this](#libraries-that-use-this)
## Usage
### Getting the AST node
```python
import executing
node = executing.Source.executing(frame).node
```
Then `node` will be an AST node (from the `ast` standard library module) or None if the node couldn't be identified (which may happen often and should always be checked).
`node` will always be the same instance for multiple calls with frames at the same point of execution.
If you have a traceback object, pass it directly to `Source.executing()` rather than the `tb_frame` attribute to get the correct node.
### Getting the source code of the node
For this you will need to separately install the [`asttokens`](https://github.com/gristlabs/asttokens) library, then obtain an `ASTTokens` object:
```python
executing.Source.executing(frame).source.asttokens()
```
or:
```python
executing.Source.for_frame(frame).asttokens()
```
or use one of the convenience methods:
```python
executing.Source.executing(frame).text()
executing.Source.executing(frame).text_range()
```
### Getting the `__qualname__` of the current function
```python
executing.Source.executing(frame).code_qualname()
```
or:
```python
executing.Source.for_frame(frame).code_qualname(frame.f_code)
```
### The `Source` class
Everything goes through the `Source` class. Only one instance of the class is created for each filename. Subclassing it to add more attributes on creation or methods is recommended. The classmethods such as `executing` will respect this. See the source code and docstrings for more detail.
## Installation
pip install executing
If you don't like that you can just copy the file `executing.py`, there are no dependencies (but of course you won't get updates).
## How does it work?
Suppose the frame is executing this line:
```python
self.foo(bar.x)
```
and in particular it's currently obtaining the attribute `self.foo`. Looking at the bytecode, specifically `frame.f_code.co_code[frame.f_lasti]`, we can tell that it's loading an attribute, but it's not obvious which one. We can narrow down the statement being executed using `frame.f_lineno` and find the two `ast.Attribute` nodes representing `self.foo` and `bar.x`. How do we find out which one it is, without recreating the entire compiler in Python?
The trick is to modify the AST slightly for each candidate expression and observe the changes in the bytecode instructions. We change the AST to this:
```python
(self.foo ** 'longuniqueconstant')(bar.x)
```
and compile it, and the bytecode will be almost the same but there will be two new instructions:
LOAD_CONST 'longuniqueconstant'
BINARY_POWER
and just before that will be a `LOAD_ATTR` instruction corresponding to `self.foo`. Seeing that it's in the same position as the original instruction lets us know we've found our match.
## Is it reliable?
Yes - if it identifies a node, you can trust that it's identified the correct one. The tests are very thorough - in addition to unit tests which check various situations directly, there are property tests against a large number of files (see the filenames printed in [this build](https://travis-ci.org/alexmojaki/executing/jobs/557970457)) with real code. Specifically, for each file, the tests:
1. Identify as many nodes as possible from all the bytecode instructions in the file, and assert that they are all distinct
2. Find all the nodes that should be identifiable, and assert that they were indeed identified somewhere
In other words, it shows that there is a one-to-one mapping between the nodes and the instructions that can be handled. This leaves very little room for a bug to creep in.
Furthermore, `executing` checks that the instructions compiled from the modified AST exactly match the original code save for a few small known exceptions. This accounts for all the quirks and optimisations in the interpreter.
## Which nodes can it identify?
Currently it works in almost all cases for the following `ast` nodes:
- `Call`, e.g. `self.foo(bar)`
- `Attribute`, e.g. `point.x`
- `Subscript`, e.g. `lst[1]`
- `BinOp`, e.g. `x + y` (doesn't include `and` and `or`)
- `UnaryOp`, e.g. `-n` (includes `not` but only works sometimes)
- `Compare` e.g. `a < b` (not for chains such as `0 < p < 1`)
The plan is to extend to more operations in the future.
## Projects that use this
### My Projects
- **[`stack_data`](https://github.com/alexmojaki/stack_data)**: Extracts data from stack frames and tracebacks, particularly to display more useful tracebacks than the default. Also uses another related library of mine: **[`pure_eval`](https://github.com/alexmojaki/pure_eval)**.
- **[`futurecoder`](https://futurecoder.io/)**: Highlights the executing node in tracebacks using `executing` via `stack_data`, and provides debugging with `snoop`.
- **[`snoop`](https://github.com/alexmojaki/snoop)**: A feature-rich and convenient debugging library. Uses `executing` to show the operation which caused an exception and to allow the `pp` function to display the source of its arguments.
- **[`heartrate`](https://github.com/alexmojaki/heartrate)**: A simple real time visualisation of the execution of a Python program. Uses `executing` to highlight currently executing operations, particularly in each frame of the stack trace.
- **[`sorcery`](https://github.com/alexmojaki/sorcery)**: Dark magic delights in Python. Uses `executing` to let special callables called spells know where they're being called from.
### Projects I've contributed to
- **[`IPython`](https://github.com/ipython/ipython/pull/12150)**: Highlights the executing node in tracebacks using `executing` via [`stack_data`](https://github.com/alexmojaki/stack_data).
- **[`icecream`](https://github.com/gruns/icecream)**: ���� Sweet and creamy print debugging. Uses `executing` to identify where `ic` is called and print its arguments.
- **[`friendly_traceback`](https://github.com/friendly-traceback/friendly-traceback)**: Uses `stack_data` and `executing` to pinpoint the cause of errors and provide helpful explanations.
- **[`python-devtools`](https://github.com/samuelcolvin/python-devtools)**: Uses `executing` for print debugging similar to `icecream`.
- **[`sentry_sdk`](https://github.com/getsentry/sentry-python)**: Add the integration `sentry_sdk.integrations.executingExecutingIntegration()` to show the function `__qualname__` in each frame in sentry events.
- **[`varname`](https://github.com/pwwang/python-varname)**: Dark magics about variable names in python. Uses `executing` to find where its various magical functions like `varname` and `nameof` are called from.
没有合适的资源?快使用搜索试试~ 我知道了~
executing-2.0.0.tar.gz
0 下载量 109 浏览量
2024-06-20
23:52:34
上传
评论
收藏 817KB GZ 举报
温馨提示
Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
资源推荐
资源详情
资源评论
收起资源包目录
executing-2.0.0.tar.gz (353个子文件)
setup.cfg 1KB
.gitignore 1KB
MANIFEST.in 20B
tox.ini 615B
datetime-py-3.12.json 477KB
datetime-py-3.11.json 475KB
bird-py-3.12.json 276KB
bird-py-3.11.json 271KB
datetime-py-3.10.json 241KB
datetime-py-3.8.json 239KB
datetime-py-3.9.json 239KB
tracer-py-3.12.json 138KB
tracer-py-3.11.json 137KB
bird-pypy-2.7.json 130KB
bird-py-2.7.json 130KB
tests-py-3.12.json 126KB
bird-py-3.10.json 126KB
bird-py-3.9.json 126KB
bird-pypy-3.6.json 125KB
bird-pypy-3.5.json 125KB
bird-py-3.6.json 125KB
bird-py-3.5.json 125KB
bird-py-3.7.json 125KB
bird-py-3.8.json 125KB
_parser-py-3.12.json 115KB
_parser-py-3.11.json 114KB
tests-py-3.11.json 112KB
executing-py-3.12.json 97KB
executing-py-3.11.json 94KB
tracer2-py-3.12.json 77KB
tracer2-py-3.11.json 76KB
_parser-py-3.10.json 71KB
_parser-py-3.9.json 70KB
_parser-py-3.8.json 70KB
db-py-3.12.json 67KB
db-py-3.11.json 66KB
tests-pypy-2.7.json 62KB
tests-py-2.7.json 61KB
tracer-py-2.7.json 60KB
tracer-pypy-2.7.json 60KB
tests-pypy-3.6.json 59KB
tests-pypy-3.5.json 59KB
tests-py-3.9.json 59KB
tests-py-3.10.json 59KB
tests-py-3.7.json 59KB
tests-py-3.8.json 59KB
tests-py-3.6.json 59KB
tests-py-3.5.json 59KB
server-py-3.12.json 59KB
tracer-py-3.10.json 58KB
tracer-py-3.6.json 58KB
tracer-py-3.5.json 58KB
tracer-pypy-3.6.json 57KB
tracer-pypy-3.5.json 57KB
tracer-py-3.7.json 57KB
tracer-py-3.8.json 57KB
tracer-py-3.9.json 57KB
server-py-3.11.json 57KB
executing-pypy-2.7.json 47KB
executing-py-2.7.json 47KB
executing-py-3.10.json 47KB
executing-py-3.9.json 46KB
executing-pypy-3.6.json 46KB
executing-pypy-3.5.json 46KB
executing-py-3.6.json 46KB
executing-py-3.5.json 46KB
executing-py-3.7.json 46KB
executing-py-3.8.json 46KB
server-pypy-2.7.json 44KB
server-py-2.7.json 44KB
server-pypy-3.6.json 43KB
server-pypy-3.5.json 43KB
server-py-3.6.json 43KB
server-py-3.7.json 43KB
server-py-3.8.json 43KB
server-py-3.10.json 43KB
server-py-3.9.json 43KB
server-py-3.5.json 43KB
tracer2-py-2.7.json 39KB
tracer2-pypy-2.7.json 39KB
tracer2-py-3.5.json 38KB
tracer2-py-3.6.json 38KB
tracer2-pypy-3.5.json 38KB
tracer2-pypy-3.6.json 38KB
tracer2-py-3.8.json 38KB
tracer2-py-3.7.json 38KB
tracer2-py-3.10.json 38KB
tracer2-py-3.9.json 38KB
utils-py-3.12.json 29KB
utils-py-3.11.json 28KB
configuration-py-3.12.json 27KB
configuration-py-3.11.json 27KB
db-py-2.7.json 27KB
db-pypy-2.7.json 27KB
db-py-3.10.json 26KB
db-py-3.9.json 25KB
db-py-3.6.json 25KB
db-py-3.5.json 25KB
db-pypy-3.5.json 25KB
db-pypy-3.6.json 25KB
共 353 条
- 1
- 2
- 3
- 4
资源评论
程序员Chino的日记
- 粉丝: 3670
- 资源: 5万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功