I can't think of a case where the check for "\n" would result in a false negative. It likely makes sense to do that to keep python startup as lightweight as possible.

I've made a PR that implements a proof-of-concept: https://github.com/python/cpython/pull/103998

It's currently done via the Python C-API, but in terms of keeping things lightweight, I might need some help on how to effectively use the wide c-string API to implement this.


On Mon, Apr 10, 2023 at 4:46 AM Barry <barry@barrys-emacs.org> wrote:


On 10 Apr 2023, at 02:18, Jonathan Crall <erotemic@gmail.com> wrote:


There's no question that there are lots of ways you can work around the issue (I think the `if 1:` method is the easiest and most portable, but it still is boilerplate which can be confusing if you don't know why it's there). The question is: would enough people benefit from this to add the feature to CPython?

A PR that has an implementation might push this forward.
I wonder if in the C code of -c treating a string that starts with \n could trigger the dedent?

Barry




On Sun, Apr 9, 2023 at 4:09 PM Barry Scott <barry@barrys-emacs.org> wrote:


On 04/04/2023 15:18, Jonathan Crall wrote:
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?

You can solve this with a small module. I named mine run_dedent

mkdir -p run_dedent
echo pass >run_dedent/__init__.py
cat <<EOF >run_dedent/__main__.py
import sys
import textwrap
cmd = textwrap.dedent(sys.argv[1])
exec(cmd)
EOF

    python3 -m run_dedent "
        import sys
        print(sys.version_info)
        "

Barry



--
-Dr. Jon Crall (him)

_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-leave@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/6SYN2MQIP5DTF6INZ4SP2YKLF6P4VJOW/
Code of Conduct: http://python.org/psf/codeofconduct/


--
-Dr. Jon Crall (him)


--
-Dr. Jon Crall (him)