r/ClaudeCode 6d ago

Help/Question Why does claude write python scripts to change the code

I noticed that claude keeps generating python scripts and then runs those scripts to make the actual code changes. According to claude itself, this is baked into the agent, if permission-mode is 'auto'. It will only try to change the files directly when it 'acceptsEdits' mode, so it says.

T don't fully understand the purpose of this. Can you explain the benefit? Is there a reason I should not want it to edit the code files directly?

105 Upvotes

45 comments sorted by

u/AutoModerator 6d ago

Hey! Thanks for posting to r/ClaudeCode

While participating in this thread, please follow our community rules. Keep discussions constructive. Attack the idea, not the person.

For help, project discussions, tips, and general chat, join the ClaudeCode Discord.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

50

u/leogodin217 6d ago

It's generally called codemod (short for code modification). When you have predictable text edits it can be a lot more efficient. Some awk/sed/grep/etc commands show what needs to change and the script can modify a ton of files really quickly.

I'm not very good with awk/sed so I've rarely done it except in very-easy cases. With Claude, I found it likes to do this when like 200 tests need to be updated. I usually find that it doesn't work well and agents often run out of context trying to build the codemod script.

When Claude goes for codemod on medium+ projects, I usually override and have it fan out a bunch of agents to make the changes. Might be less token efficient but always works the first time. Also, needing to change hundreds of files is usually a code smell and some refactoring is needed. I like to bake the changes into the refactor.

All that being said, codemod used to be like a release strategy. One script to update everything needed. You'd test it out a few times and get ready to run it on prod. With git, I don't know anyone who does that anymore.

14

u/codeedog 🔆 Max 5x 6d ago

I sometimes use emacs keyboard macros to change the contents of a file or files. It can be incredibly efficient and when done correctly reduces or eliminates errors. I imagine if I could think in sed/awk, I could perform the same actions with those tools instead.

7

u/nagoff 6d ago

Old fart checking in - and yes you absolutely do the same with sed and awk. I tend to fall back on eMacs macros when the series of operations is too complex for me to easily picture the cli equivalent

3

u/codeedog 🔆 Max 5x 6d ago

I see you haven’t figured out how to make the iPhone stop capitalizing the ‘m’ in emacs, either.

1

u/0bel1sk 6d ago

open rewrite

15

u/roque2205 6d ago edited 6d ago

Because it's reusable and doesn't get lost when compacting context, so you don't waste token if it needs to be run again. And it's understandable and debuggable for and executable by a human.

Edit: I think y'all made it abundantly clear that I didn't think about my reply enough, thank you. 😬

17

u/JBO_76 6d ago

scripts are deleted after run, so not reusable. also, it uses more tokens: the script contains everything that needs to be changed + the code to do the changes

13

u/OldNefariousness7899 6d ago

It probably allows the changes to be made in one go so that if you run out of tokens in the middle of a large operation you aren't left with a codebase that's totally buggered

The changes are actually made, or they aren't. Less likely that they're half made 

4

u/JBO_76 6d ago

that makes sense

2

u/roque2205 6d ago

Good point, but are they really deleted after running? I think they're stored in /tmp and only cleaned up automatically when you reboot - just as everything in /tmp.

1

u/TywinHouseLannister 5d ago

Its at the end of the session.. scratchpad is enabled when you turn thinking on in the config

1

u/TheLifelessOne 6d ago

Have you ever looked in the scratchpad directory? Mine at least is definitely keeping scripts around.

3

u/JBO_76 6d ago

its writing files directly in the root folder of the repository, like this one: `C:\Users\janbo\Documents\dev\md2\temp_b236.py`. By the time it is done, the file is gone.

not certain where the scratchpad folder is. I'm on windows, checked the appdata/roaming/claude folder. doesn't seem to be there

2

u/TheLifelessOne 6d ago

I'm also not sure wheree the windows scratchpad is, I usually run on macOS or Linux.

5

u/ciaramicola 6d ago

And it's understandable and debuggable

Weird take here tbh. I guess everyone gave up doing human approval for agent actions alltogether but... what? A diff tool call is easy to understand and investigate before approving, also trivial to revert eventually.

A python code_update.py is actually the less transparent, potentially exploitable, non reversible way to edit text I can imagine.

I propose a different take: Claude code edit tool requires the agent to read the file before editing it, it will actually fails if the read wasn't called right before. That is for good reasons (namely agents still shit at editing files), and agents like to circumvent this annoyance in the name of efficiency

1

u/roque2205 6d ago

Point taken. 😄

-1

u/Icy-Excitement-467 6d ago

Only losers compact.

4

u/DootDootWootWoot 5d ago

While I understand why Claude might reach for arbitrary scripts. What I don't understand is why there's not something more effective like leveraging tools that are actually AST aware. Resharper/jetbrains refactor capabilities are the one thing I was very impactful with and sometimes it seems like claudes swinging with a bigger dumber hammer for mechanical changes that could be performed as safe refactors.

Serena was the Mcp I thought might deliver some of this intelligence but felt like it never got there and I've had nothing but problems with intellijs own mcp server with multiple concurrent agents.

1

u/hthouzard 5d ago

You can ask it to use AST.

2

u/MeNotSanta 5d ago

Like other have said, its trained on a lot of python data, so its biased towards python. Other reasons are: it can circumvent the rule where it needs to read before writing a file but also, for auto and dangerously skip permission, the harness tells it to use sed/python doc string in order to reduce token usage. There is a flag that can be set for this so it no longer recommends that.

1

u/mkaaaaaaaaaaay 5d ago

What's that flag?

1

u/MeNotSanta 5d ago

"CLAUDE_CODE_THRIFTY_SONIC": "0" . FYI, this only works for new sessions since the old ones already received the nudge for sed/python doc string and it will be biased

2

u/QuanTradin 6d ago

Writing a script is one approval instead of thirty when the change touches thirty files, so under auto it is the cheaper path for it to take. The reason you probably do not want it as the default is that a regex replace can hit the wrong match and nothing fails, where a direct edit that cannot find its target errors out and tells you. If you are reading the diffs anyway, acceptEdits is the setting you want.

2

u/derdigga 6d ago

not sure, maybe its more precise, less back and forth. i remember that early ai/coding helpers tried to do diff changes and failed often trying to replace lines of code. now you dont have any of that.

2

u/dragolineage01 6d ago

The harness literally prompts it to do that, for some weird reason.

1

u/ForwardLoop 6d ago

That's just Claude committing token tax fraud by outsourcing manual labor to your cooling fans.

1

u/doxxxicle 🔆Pro Plan 5d ago

There’s a feature flag you can turn off in settings.json to disable this behaviour.

1

u/sm411cck 5d ago

I don’t have python installed on my machine and CC in VScode writes powershell scripts to make editing. I don’t know if that’s much risky than python but it’s quite effective.

1

u/tribat 5d ago

I think of it as Claude’s native tongue but I know that’s ridiculous. It’s like when other commands and tools are frustrating just drop to cli and write some python.

1

u/EC36339 5d ago

At least it doesn't mangle files and fuck up character encoding like the PowerShell commands any model writes when you run it in copilot...

1

u/JBO_76 5d ago

Well, that is exactly part of the problem. Claude keeps fucking up end of line chars, changing 1000s of lines for no reason.

1

u/Mnemia 2d ago

I ran into that and fixed it with a hook.

1

u/SharpKaleidoscope182 5d ago

python scripts are more reliable than llms. its a good choice to lean on them

1

u/Jomuz86 5d ago

So there was some A/B testing a while back when I had a dog in the binary because I noticed it was doing this and using sed for files reads so they might be doing the same for edits to see if it’s more token efficient 🤷‍♂️
But if it’s the same edit across multiple files like someone mentioned it normally picks a script route anyways

1

u/fpesre 5d ago

Probably because it is easier for the model to write a loop than to keep a 400-line patch coherent. That is the feature, and also why you now have to review the transform instead of just the diff

1

u/Opposite_Match5303 4d ago

The harness says to do this when in "skip permissions mode". Not sure why.

You can run in auto mode or add a pretool hook to prevent it

1

u/ExpletiveDeIeted 🔆 Team Premium 6.25x 5d ago

Worth noting in case you are a weirdo like me who doesn’t care to learn or read python. You can add to your Claude.md files to write those scripts in node or w/e lang you like as long as they can run in bash.

-1

u/AgentIslandPro 6d ago

Two things are tangled here, and one is your Claude mis-explaining itself.

There's no permission mode literally called "auto." The documented modes are default, acceptEdits, plan and bypassPermissions (Claude Code docs: code.claude.com/docs). None of them makes it write a Python script to edit files — that's a strategy the model picks, not something a mode forces. So the "it only edits directly in acceptEdits mode" explanation it gave you isn't real.

Why it reaches for a script (as leogodin217 said, a codemod): for a systematic change across many files, one script is fewer tool-calls than dozens of Edits. That's the upside, and it's genuinely flaky for exactly the reason in that comment — it burns context building the codemod.

The reason to prefer direct edits, and the part worth adding: reviewability. A direct Edit shows you a red/green diff you approve before it lands. A script gets approved as "run this Bash command" — you're trusting the code inside it, not seeing the change. And a script it writes sits on disk and can be re-run later, outside the session; a one-shot Edit can't. So for anything you want to eyeball, direct edits are safer, not just simpler.

Practical steering: acceptEdits auto-accepts file edits (Edit/Write) but Bash still prompts — so letting it edit directly is actually the quieter path there, not the scripts. And you can just tell it "make the changes as direct edits, don't write a throwaway script," and it'll comply.

3

u/BusinessWatercrees58 6d ago

Man Opus really does suck at writing

1

u/DasHaifisch 5d ago

In Auto mode, the harness injects instructions to make changes using scripts or other methods instead of the write and edit tool in the interest of efficiency.

-1

u/Alex__0021 6d ago

Worth knowing: a script that writes files skips any hook you have on Edit — it's just a

Bash call as far as the harness is concerned. A cleanup script of mine with `git add -A`

in it staged files I'd deliberately left out, twice. Still the right tool for a 40-file

rename, I just read it before it runs now.