<commit_before># executing

[![Build Status](https://travis-ci.org/alexmojaki/executing.svg?branch=master)](https://travis-ci.org/alexmojaki/executing) [![Coverage Status](https://coveralls.io/repos/github/alexmojaki/executing/badge.svg?branch=master)](https://coveralls.io/github/alexmojaki/executing?branch=master) [![Supports Python versions 2.7 and 3.4+, 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

    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:

    executing.Source.executing(frame).source.asttokens()

or:

    executing.Source.for_frame(frame).asttokens()

or use one of the convenience methods:

    executing.Source.executing(frame).get_text()
    executing.Source.executing(frame).get_text_range()

### Getting the `__qualname__` of the current function

    executing.Source.executing(frame).code_qualname()

or:

    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:<commit_msg>Fix names of text and text_range in README<commit_after># executing

[![Build Status](https://travis-ci.org/alexmojaki/executing.svg?branch=master)](https://travis-ci.org/alexmojaki/executing) [![Coverage Status](https://coveralls.io/repos/github/alexmojaki/executing/badge.svg?branch=master)](https://coveralls.io/github/alexmojaki/executing?branch=master) [![Supports Python versions 2.7 and 3.4+, 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

    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:

    executing.Source.executing(frame).source.asttokens()

or:

    executing.Source.for_frame(frame).asttokens()

or use one of the convenience methods:

    executing.Source.executing(frame).text()
    executing.Source.executing(frame).text_range()

### Getting the `__qualname__` of the current function

    executing.Source.executing(frame).code_qualname()

or:

    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:
{'fraction_non_alphanumeric': 0.11159699142907119, 'fraction_numerical': 0.0013993353157250306, 'mean_word_length': 4.75251509054326, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 14, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1283142', 'n_tokens_mistral': 1763, 'n_tokens_neox': 1652, 'n_words': 570}