Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: allow libcst_transform to work piecewise instead of all-or-nothing #18

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

devdanzin
Copy link

This PR is meant to help explore a solution for #12. To simplify testing, it restricts running of passes to only replace_bodies_with_ellipsis in initial_cut. It attempts to make libcst_transform work with partial replacements instead of in a all-or-nothing fashion.

The code it's able to reduce is some variation of:

import asyncio
import _lsprof

if True:
    a = 1
    b = 2
    c = 3

if True:
    a = 11
    b = 12
    c = 13

if True:
    obj = _lsprof.Profiler()
    obj.enable()
    obj._pystart_callback(lambda: 0, 0)
    obj = None  
    loop = asyncio.get_event_loop()

if True:
    a = 21
    b = 22
    c = 23

if True:
    a = 31
    b = 32
    c = 33

if True:
    a = 41
    b = 42
    c = 43

if True:
    a = 51
    b = 52
    c = 53

if True:
    a = 61
    b = 62
    c = 63

if True:
    a = 71
    b = 72
    c = 73

It can be run against the following Python version which, on Linux, aborts with the code above:

Python 3.12.8+ (tags/v3.12.8-22-gb0615a8a9aa:b0615a8a9aa, Mar  6 2025, 21:52:08) [GCC 11.4.0]

For that, a interestingness test looks like:

#!/bin/bash
/home/danzin/projects/cpython/python ./short_source_lsprof.py
if ! test "$?" = "134"; then
    exit 1
else
    exit 0
fi

But it might be easier to just substitute the is_interesting function for the equivalent of lambda x: b"Profiler" in x.

The code as-is is known to be broken, since it's not able to generate each substitution and record a reduction from it. But it shows the idea might work if implemented correctly, something along the lines of:

  • Count the nodes in the test case;
  • Transform the module replacing a single/some nodes and check interestingness;
  • Each successful (i.e., interesting) replacement should update the test case, leading to incremental reductions;
  • Repeat.

As-is, the code is able to reduce the example above to:

import asyncio
import _lsprof

if True:
    a = 1
    b = 2
    c = 3

if True:
    a = 11
    b = 12
    c = 13

if True:
    obj = _lsprof.Profiler()
    obj.enable()
    obj._pystart_callback(lambda: 0, 0)
    obj = None  
    loop = asyncio.get_event_loop()

if True:
    ...

if True:
    ...

if True:
    ...

if True:
    ...

if True:
    ...

if True:
    ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant