Workbench replacing Tabs with Spaces in string literals

Expected behavior

I have a string literal (one line, or triple quoted block) with some actual tab characters in it. For example a copied and pasted block from an Excel spreadsheet. The tabs should be preserved such that mystring.split("\t") does the right thing. Splitting on all white space with split() won’t work if the Excel cells have strings with spaces, or there are blank cells.

Actual behavior

Workbench replaces each tab with four spaces before feeding the line to Python (always four, regardless of the “size” of the tab displayed in the editor which aligns to the next 4-character column)

Steps to reproduce the behavior

Try the following in and out of Mantid:

mystring= "hello	world" # a real tab
for i in mystring:
    print(ord(i))
print (repr(mystring))

Platforms affected

Workbench 4.2 (tested Windows so far)

As Mantid tries to “correct” a script by converting tabs to spaces, the easiest fix might be to change this, so that only tabs at the start and end of each line (not in the middle of a line as in your example) are converted to spaces.

Additionally it might be useful to be able to define the number of spaces it is converting to from tabs (Enable in Plot as in Workbench).

I’ve have created issues for both of these: Tabs to Spaces only at line ends · Issue #27509 · mantidproject/mantid · GitHub Configure Tabs option · Issue #27510 · mantidproject/mantid · GitHub

It’s quite easy to get in a mess in Workbench. For example editing an old script that uses tabs as indents, and inserting extra lines of code inside existing loops or if statements. Workbench will (sometimes) execute the code as it appears on screen, but if I then save the edited script it will do something different if run in MantidPlot or plain Python.

  • One level tab indent: Workbench inserts 4 spaces but it’s a syntax error
  • Two level tab indent: Workbench inserts 8 spaces, executes it as if at the 2nd level but if saved, Python considers it at the first level
  • Third level tab indent: Workbench inserts 12 spaces but it’s a syntax error
  • Fourth level tab indent: Workbench inserts 16 spaces, executes it as if at the 4th level but if saved, Python considers it at the 2nd level

I think we may need:

  • A menu option or external program to go through a script and do a careful job of re-indenting it with 4 spaces instead of tabs, taking care with lines which already had space indenting. There’s probably such a program out there already.
  • Perhaps an option on loading an old script that uses tabs, such that the tab key inserts tab characters instead of spaces (for quick modifications to an old script). This would apply to that file only and be turned off again if the above tab conversion operation was invoked.
  • Perhaps a warning on loading a script, saying that it has tabs, or a mix, before offering the above option.
  • Actual tab characters displayed on 8 character boundaries so the code looks the same to the user as it does to the Python interpreter
  • And no conversion at execution time.

Thanks for thoroughly investigating this, James. The conversion at execution time is a bug related to how we compute the progress arrow placement and can easily be fixed.

I’m slightly surprised by the editor behaviour as it’s actually the same library that provides the editor that we use in MantidPlot so we had naively assumed this would be taken care of. We’ll investigate how to make this more robust with mixing editors. Thanks.