Subject: Re: bug#60142: 28.1; python.el Incorrect region when python-shell-send-region from indented code

From: kobarity <[email-masked]>
Date: Sat, 31 Dec 2022 00:33:13 +0900

Hi,

Pierre Mercatoris wrote:
> Excuse my ignorance, but how would I need to go about to apply those changes
> to test them?

The patch in my previous mail is a diff to master branch of Emacs.  I
attached a patch to python.el of Emacs 28.1.  It can be applied as
follows:

% patch python.el python.el.28.1.patch

After starting Emacs, I recommend to do 'M-x load-file' and specify
the patched python.el to avoid loading the old python.elc.

> Furthermore, I am not sure the main issue I raised has been diluted. Basically
> I was wondering why a region, which does not include any indentation (as it is
> a fragment of a line), is sent to the repl results in indentation error if the
> life the fragment comes from was indented. In the case Kobarty described
> above, he is mentioning sending the whole line to the repl, in which case it
> can be debated how to deal with indentation. However, my issue is that
> equivalent regions sent to the repl without any indentation within them
> results in different behaviours depending on where those regions (fragments of
> line) come from.

My explanation was probably misleading.  I'm not saying that the whole
line should be sent to the REPL.  My point was that if the content
sent to the REPL is one statement, there is no need to add `if True:`.
Please note that a "statement" in python.el is a logical unit based on
Python syntax and differs from physical lines.  A statement can be
part of a physical line, and it can also spans multiple physical
lines.

As Augusto pointed out, current Emacs python.el adds `if True:` if the
lines of the region was originally indented.  For example, let's
consider the following code.

#+begin_src python
def func():
    a = 1
    b = 2
#+end_src

If we set the region to "a = 1" and call `python-shell-send-region',
the following code will be sent to the REPL.

#+begin_src python
if True:
    a = 1
#+end_src

Even if the region is set to only "a", the following code will be
sent.

#+begin_src python
if True:
    a
#+end_src

Adding `if True:` is reasonable if the indented region spans multiple
lines.  For example, if the region is "a = 1\n    b = 2", the
following code will be sent.

#+begin_src python
if True:
    a = 1
    b = 2
#+end_src

If the region "a = 1\n    b = 2" or "    a = 1\n    b = 2" is sent as
is, an indentation error will occur.

I think current `python-shell-send-region' focuses on sending a region
of multiple lines and does not take into account sending part of a
line.

As I mentioned above, my patch is intended to improve this behavior.
If the region is "a = 1", or even "    a = 1", the following code will
be sent because this is a single statement.

#+begin_src python
a = 1
#+end_src

I think this behavior is what you expected.

Please note that the above explanation is a bit simplified.  The
actual contents `python-shell-send-region' sends includes a coding
cookie and empty lines.  Please see docstring of
`python-shell-buffer-substring' for more details.

I hope this clarifies things.

Regards,