Description
Feature or enhancement
The Python CLI should automatically dedent the argument given to "-c".
I raised this issue on the Python-Ideas mailing list and it got some positive feedback, so I'm moving forward with it here and in a proof-of-concept PR.
Pitch
I have what I think is a fairly low impact quality of life improvement to suggest for the python CLI.
When I'm not working in Python I tend to be working in bash. But often I want to break out and do something quick in Python. I find the python -c
CLI very useful for this. For one liners it's perfect. E.g.
NEW_VAR=$(python -c "import pathlib; print(pathlib.Path('$MYVAR').parent.parent)")
And even if I want to do something multi-line it's pretty easy
NEW_VAR=$(python -c "
import pathlib
for _ in range(10):
print('this is a demo, bear with me')
")
But the problem is when I'm writing bash inside a function or some other nested code, I would like to have nice indentation in my bash file, but if I write something like this:
mybashfunc(){
python -c "
import pathlib
for _ in range(10):
print('this is a demo, bear with me')
"
}
I get IndentationError: unexpected indent
.
This means I have to write the function ugly like this:
mybashfunc(){
python -c "
import pathlib
for _ in range(10):
print('this is a demo, bear with me')
"
}
Or use a helper function like this:
codeblock()
{
__doc__='
copy-pastable implementation
Prevents indentation errors in bash
'
echo "$1" | python -c "import sys; from textwrap import dedent; print(dedent(sys.stdin.read()).strip('\n'))"
}
mybashfunc(){
python -c $(codeblock "
import pathlib
for _ in range(10):
print('this is a demo, bear with me')
")
}
Or more recently I found that this is a low-impact workaround:
mybashfunc(){
python -c "if 1:
import pathlib
for _ in range(10):
print('this is a demo, bear with me')
"
}
But as a certain Python dev may say: "There must be a better way."
Would there be any downside to the Python CLI automatically dedenting the input string given to -c? I can't think of any case off the top of my head where it would make a previously valid program invalid. Unless I'm missing something this would strictly make previously invalid strings valid.
Thoughts?
Previous discussion
On the mailing list there were these responses:
Lucas Wiman said:
Very strong +1 to this. That would be useful and it doesn't seem like there's a downside. I often make bash functions that pipe files or database queries to Python for post-processing. I also sometimes resort to Ruby because it's easy to write one-liners in Ruby and annoying to write one-liners in python/bash.
I suppose there's some ambiguity in the contents of multi-line """strings""". Should indentation be stripped at all in that case? E.g.
python -c "
'''
some text
''''
"But it seems simpler and easier to understand/document if you pre-process the input like using an algorithm like this:
- If the first nonempty line has indentation, and all subsequent lines either start with the same indentation characters or are empty, then remove that prefix from those lines.
I think that handles cases where editors strip trailing spaces or the first line is blank. So e.g.:
python -c "
some_code_here()
"
Then python receives something like "\n some_code_here\n"python -c "
some_code here()if some_some_other_code(): still_more_code()
"
Then python receives something like "\n some_code_here\n\n if ..."This wouldn't handle cases where indentation is mixed and there is a first line, e.g.:
python -c "first_thing()
if second_thing():
third_thing()
"
That seems simple enough to avoid, and raising a syntax error is reasonable in that case.Best wishes,
Lucas
There was also positive feedback from @cameron-simpson and @barry-scott suggested a PR with an implementation might move this forward. I have a proof-of-concept PR and this is the corresponding issue for it.