Skip to content

Store patched source in linecache #542

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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

iloveitaly
Copy link

This enables ipdb and friends to work properly if breakpoint() is added to the mutated function.

Curious what you think of this approach. I can clean it up if you like it!

I'm not nearly as familiar with py internals as you, so curious what I'm missing too.

Copy link
Owner

@adamchainz adamchainz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, certainly seems worthwhile. Do you think you could write a test and changelog note?

And can you provide a command and example file to test this before/after? You didn't really describe the issue. I’m guessing that ipdb fails to show the source of patched functions... is it the same with pdb?

@@ -216,9 +216,21 @@ def _compile(
code: str | ast.Module,
flags: int = 0,
) -> CodeType | ast.Module:

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

result: CodeType | ast.Module = compile(
code, "<patchy>", "exec", flags=feature_flags | flags, dont_inherit=True
)

import linecache
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hoist to module level

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally, this was just a quick and dirty PR to see if you were interested in the idea

@iloveitaly
Copy link
Author

Yes, ipdb fails to show source when debugging. Haven't checked with pdb, but I believe it uses the exact same mechanism (ipdb is an extension of pdb, so probably the same exact source code).

I'll tidy this up!

iloveitaly and others added 2 commits October 25, 2024 15:47
this enables ipdb and friends to work properly if `breakpoint()` is added to the mutated function
@adamchainz adamchainz changed the title feat: include new source in linecache Store patched source in linecache Oct 25, 2024
@adamchainz
Copy link
Owner

I tried to finish this off but found several scenarios that don't work with the current approach.

  1. Unpatching a function doesn't restore its original source.
  2. Patching two functions leaves the source for the last one in linecache, only. This is because the storage currently saves source for the whole <patchy> virtual module.

I don't have time to dig into these details right now, but maybe you'd be interested? No pressure!

@iloveitaly
Copy link
Author

Ah, the unpatching case is interesting. What if we stored the original source for the function in a variable on the function original_linecache that we can pull from if unpatched?

@adamchainz
Copy link
Owner

I think it's harder than that. linecache is per-file, not per function.

Also, patchy should not add attributes to functions, but instead use a WeakKeyDictionary, as is already done for the source.

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.

2 participants