Metadata-Version: 2.4
Name: tracefunc
Version: 0.0.2
Summary: AST-level execution tracing via sys.settrace
Home-page: https://github.com/AnswerDotAI/tracefunc
Author: Jeremy Howard
Author-email: github@jhoward.fastmail.fm
License: Apache Software License 2.0
Keywords: nbdev jupyter notebook python
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: License :: OSI Approved :: Apache Software License
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: provides-extra
Dynamic: requires-python
Dynamic: summary

# tracefunc


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

`tracefunc` takes a function and its arguments, executes it, and returns
a dictionary mapping each source code snippet to a tuple of
`(hit_count, variables_dict)`. This lets you see exactly how many times
each statement ran and what values the variables held at each execution.

## Install

``` sh
pip install tracefunc
```

Requires Python 3.11+ (uses PEP 657 source positions).

## How to use

``` python
from tracefunc import tracefunc
from pprint import pprint
```

### Simple function

Here’s a simple example tracing a loop:

``` python
def demo(n):
    total = 0
    for i in range(n): total += i
    return total
```

``` python
def show_res(x):
    for snippet, (hits, vars_map) in x.items():
        print('-', repr(snippet), hits)
        pprint(vars_map)
```

``` python
result = tracefunc(demo, 3)
show_res(result)
```

    - 'total = 0' 1
    {'total': [('int', '0')]}
    - 'for i in range(n):' 4
    {'i': [('int', '0'), ('int', '1'), ('int', '2'), ('int', '2')],
     'n': [('int', '3'), ('int', '3'), ('int', '3'), ('int', '3')],
     'range': [('type', "<class 'range'>"),
               ('type', "<class 'range'>"),
               ('type', "<class 'range'>"),
               ('type', "<class 'range'>")]}
    - 'total += i' 3
    {'i': [('int', '0'), ('int', '1'), ('int', '2')],
     'total': [('int', '0'), ('int', '1'), ('int', '3')]}
    - 'return total' 1
    {'total': [('int', '3')]}

### Multiple statements on one physical line

Semicolon-separated statements are tracked separately.

``` python
def one_liner(): x = 1; y = 2; return x + y

show_res(tracefunc(one_liner))
```

    - 'x = 1' 1
    {'x': [('int', '1')]}
    - 'y = 2' 1
    {'y': [('int', '2')]}
    - 'return x + y' 1
    {'x': [('int', '1')], 'y': [('int', '2')]}

### Nested function

Nested definitions appear as statements, and their bodies are traced
when called.

``` python
def outer(x):
    def inner(y):
        return x + y
    return inner(5)

show_res(tracefunc(outer, 10))
```

    - 'def inner(y):' 1
    {'inner': [('function', '<function outer.<locals>.inner>')]}
    - 'return x + y' 1
    {'x': [('int', '10')], 'y': [('int', '5')]}
    - 'return inner(5)' 1
    {'inner': [('function', '<function outer.<locals>.inner>')]}
