spyder-ide / spyder

Official repository for Spyder - The Scientific Python Development Environment
https://www.spyder-ide.org
MIT License
8.3k stars 1.61k forks source link

Tab character (`\t`) not being properly shown with `print` function on the IPython Console #20495

Open AkkiDinosaur opened 1 year ago

AkkiDinosaur commented 1 year ago

Description

What steps will reproduce the problem?

print("Please provide your address.") street = input("Street: ") suburb = input("Suburb: ") state = input("State: ") postcode = input("Postcode: ")

print() print(street + " " + suburb + "\n" + state + "\t" + postcode)

this code outputs and ignores \t, printing a regular space instead.

Versions

Dependencies

# Mandatory:
atomicwrites >=1.2.0                 :  1.4.1 (OK)
chardet >=2.0.0                      :  5.1.0 (OK)
cloudpickle >=0.5.0                  :  2.2.0 (OK)
cookiecutter >=1.6.0                 :  2.1.1 (OK)
diff_match_patch >=20181111          :  20200713 (OK)
intervaltree                         :  None (OK)
IPython >=7.31.1;<9.0.0              :  8.8.0 (OK)
jedi >=0.17.2;<0.19.0                :  0.18.2 (OK)
jellyfish >=0.7                      :  0.9.0 (OK)
jsonschema >=3.2.0                   :  4.17.3 (OK)
keyring >=17.0.0                     :  23.13.1 (OK)
nbconvert >=4.0                      :  7.2.8 (OK)
numpydoc >=0.6.0                     :  1.5.0 (OK)
paramiko >=2.4.0                     :  2.12.0 (OK)
parso >=0.7.0;<0.9.0                 :  0.8.3 (OK)
pexpect >=4.4.0                      :  4.8.0 (OK)
pickleshare >=0.4                    :  0.7.5 (OK)
psutil >=5.3                         :  5.9.4 (OK)
pygments >=2.0                       :  2.14.0 (OK)
pylint >=2.5.0;<3.0                  :  2.15.10 (OK)
pylint_venv >=2.1.1                  :  2.3.0 (OK)
pyls_spyder >=0.4.0                  :  0.4.0 (OK)
pylsp >=1.7.1;<1.8.0                 :  1.7.1 (OK)
pylsp_black >=1.2.0                  :  1.2.1 (OK)
qdarkstyle >=3.0.2;<3.1.0            :  3.0.3 (OK)
qstylizer >=0.2.2                    :  0.2.2 (OK)
qtawesome >=1.2.1                    :  1.2.2 (OK)
qtconsole >=5.4.0;<5.5.0             :  5.4.0 (OK)
qtpy >=2.1.0                         :  2.3.0 (OK)
rtree >=0.9.7                        :  1.0.1 (OK)
setuptools >=49.6.0                  :  66.0.0 (OK)
sphinx >=0.6.6                       :  6.1.3 (OK)
spyder_kernels >=2.4.2;<2.5.0        :  2.4.2 (OK)
textdistance >=4.2.0                 :  4.5.0 (OK)
three_merge >=0.1.1                  :  0.1.1 (OK)
watchdog                             :  2.2.1 (OK)
zmq >=22.1.0                         :  24.0.1 (OK)

# Optional:
cython >=0.21                        :  0.29.33 (OK)
matplotlib >=3.0.0                   :  3.6.3 (OK)
numpy >=1.7                          :  1.24.1 (OK)
pandas >=1.1.1                       :  1.5.2 (OK)
scipy >=0.17.0                       :  1.10.0 (OK)
sympy >=0.7.3                        :  1.11.1 (OK)

# Spyder plugins:
spyder_terminal.terminalplugin 1.2.2 :  1.2.2 (OK)
ccordoba12 commented 1 year ago

Hey @AkkiDinosaur, thanks for reporting. Unfortunately, I can't reproduce this problem on Linux, as can be seen in the screenshot below:

imagen

@dalthviz, could you check if you get this problem on Windows?

dalthviz commented 1 year ago

@ccordoba12 I was able to reproduce this. Seems like if you have a number character before the tab character the print function uses a space instead of a tab?:

imagen

Also, I was able to reproduce this on QtConsole but not on IPython:

QtConsole

imagen

IPython

imagen

Could it be that your state and postcode variables contain numeric characters @AkkiDinosaur ?

ccordoba12 commented 1 year ago

Ok, thanks @dalthviz for the check.

@AkkiDinosaur, we'll try to solve this problem in the second half of the year. But please don't hold your breath because we have a ton of other things to do and this is not critical.

bessman commented 1 year ago

Isn't this exactly how \t is supposed to work? Tab isn't "spacebar but bigger". Citing wikipedia:

The tab key is used to advance the cursor to the next tab stop.

This behavior is also consistent between a regular python repl:

Python 3.9.16 (main, Dec  7 2022, 01:11:51) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print("a\ta")
a   a
>>> print("aa\ta")
aa  a
>>> print("aaa\ta")
aaa a
>>> 

IPython:

Python 3.9.16 (main, Dec  7 2022, 01:11:51) 
Type 'copyright', 'credits' or 'license' for more information
IPython 8.7.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: print("a\ta")
a   a

In [2]: print("aa\ta")
aa  a

In [3]: print("aaa\ta")
aaa a

And qtconsole:

Jupyter QtConsole 5.4.0
Python 3.9.16 (main, Dec  7 2022, 01:11:51) 
Type 'copyright', 'credits' or 'license' for more information
IPython 8.7.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: print("a\ta")
a   a

In [2]: print("aa\ta")
aa  a

In [3]: print("aaa\ta")
aaa a
ccordoba12 commented 1 year ago

But in the example @dalthviz posted above:

print('123\t456')

there are clearly different results between Qtconsole (which is embedded in Spyder) and terminal IPython. So, is that not a bug?

bessman commented 1 year ago

Well, it looks like the tab width in Qtconsole is 4 while it is 8 in IPython. Not sure I would consider that a bug.

The changelog for Qtconsole 4.4.0 mentions changing the default tab width to 4. Though, I can't find a way to set it to something else, for either Qtconsole or IPython.

dalthviz commented 3 weeks ago

Just in case, gave this a check again and seems to me that @bessman is right! So checking something like:

def print_test():
    print("a\ta")
    print("1\t1")
    print("aa\ta")
    print("11\t1")
    print("aaa\ta")
    print("111\t1")
    print("aaaa\ta")
    print("1111\t1")

You get over QtConsole and IPython the following:

image

And indeed the only variation there is that QtConsole takes 4 spaces for the tab and IPython takes 8. Also, is true that seems like the is no way to configure this behavior (at least I don't see any config available for that over the docs: https://qtconsole.readthedocs.io/en/stable/config_options.html). The value seems like is defined here: https://github.com/jupyter/qtconsole/blob/a72387f01dea2076346ecb38857de5266414dbe6/qtconsole/console_widget.py#L298

Maybe making that _tab_width a traitlet variable to allow its config via the CLI could be worthy?

ccordoba12 commented 3 weeks ago

Maybe making that _tab_width a traitlet variable to allow its config via the CLI could be worthy?

I don't think that would be enough to solve this problem because people would need to know that that setting exists and adjust it to make things work as in a system terminal.

Since the _tab_width change from 8 to 4 was done in PR https://github.com/jupyter/qtconsole/pull/250 to add indent/dedent of code when working in a prompt, I think we should have two _tab_widths: one for editing code and one for outputs.

So, @dalthviz please review that could be done in Qtconsole's code. My guess is that _tab_width = 4 is only used in the ConsoleWidget._indent method, and if that's the case, we can use that value there and restore self._tab_width = 8 for outputs.