Prevent changing indentation from tabs to spaces
Question:
I have VSCode installed and python 3.6.8
I use tabs for my indentation. But when ever I save the file, all the tabs are being converted to spaces.
This might be because of the formatter I use, i.e. Black. How do I prevent the formatter from doing that(Do all your formatting except inter-changing indents with spaces)?
Thank you
Answers:
Assuming you don’t have VS Code set up to insert space into tabs, then Black will very likely replace them with spaces as that’s the norm in the Python community and Black takes a very opinionated view on how to format Python code. You could try another formatter like yapf or autopep8 to see if they will leave physical tabs in.
But do note that the vast majority of the Python community uses spaces, so you are potentially facing an uphill battle.
Not only ‘black’ but also ‘autopep8’ and ‘yapf’ will convert the tabs to spaces. And looks like both ‘black’, ‘autopep8’ and ‘yapf’ haven’t provided args to change the format behavior of indent. And I agree with Brett Cannon, you’d better adapt to space indent.
If you really want a try of that, you can find the black.py in site-packages folder and at the lines of 1540 in black.py change the ‘ ‘(four spaces) to ‘ ‘(a tab, copy a tab, and you can choose any spaces of the tab contains). Then you can get what you want. But, I really don’t recommend it.
Both autopep8
and black
are very strict.
They don’t just recommend spaces over tabs, but force the usage of space indentation.
If you really want to use tabs, you should use yapf
, with style use_tabs=True
.
Until maintainers/contributors add a setting to be able to indent Python with tabs, I found a workaround to this issue by using multi-command extension.
Steps to fix the issue:
-
Install extension.
-
Find your settings.json
and keybindings.json
. From here:
Depending on your platform, the user settings file is located here:
- Windows %APPDATA%CodeUsersettings.json
- macOS $HOME/Library/Application Support/Code/User/settings.json
- Linux $HOME/.config/Code/User/settings.json
-
Add this to settings.json
:
"multiCommand.commands": [
{
"command": "multiCommand.properlyFormatAnyDocument",
"sequence": [
"editor.action.formatDocument",
"editor.action.indentationToTabs"
]
}
]
- Add this to
keybindings.json
:
{
"key": "shift+alt+f",
"command": "extension.multiCommand.execute",
"args": {
"command": "multiCommand.properlyFormatAnyDocument"
},
"when": "editorTextFocus"
}
- Save all files and it works.
Technically, yapf has use_tabs
setting, but I was never able to get it to work.
So one of the comments was that yapf is not so easy to get working. Under Debian, install
apt-get install yapf3
Now go to your source directory and run
yapf3 --style "google" --style-help > .style.yapf
Edit the .style.yapf so that you put
use_tabs=True
instead of False.
Now run
yapf3 -i dirty.py
and it really use tabs for indentation. Spaces are still used for visual formatting and tabs only for real indentation, I am sending a visual example how my code is formatted.
Pass in the argument --ignore=W191
to autopep8
, and it would ignore the Indentation warning of indentation contains tabs.
For VSCode, use the settings-entry python.formatting.autopep8Args
.
vscode-settings-entry-gui
I have VSCode installed and python 3.6.8
I use tabs for my indentation. But when ever I save the file, all the tabs are being converted to spaces.
This might be because of the formatter I use, i.e. Black. How do I prevent the formatter from doing that(Do all your formatting except inter-changing indents with spaces)?
Thank you
Assuming you don’t have VS Code set up to insert space into tabs, then Black will very likely replace them with spaces as that’s the norm in the Python community and Black takes a very opinionated view on how to format Python code. You could try another formatter like yapf or autopep8 to see if they will leave physical tabs in.
But do note that the vast majority of the Python community uses spaces, so you are potentially facing an uphill battle.
Not only ‘black’ but also ‘autopep8’ and ‘yapf’ will convert the tabs to spaces. And looks like both ‘black’, ‘autopep8’ and ‘yapf’ haven’t provided args to change the format behavior of indent. And I agree with Brett Cannon, you’d better adapt to space indent.
If you really want a try of that, you can find the black.py in site-packages folder and at the lines of 1540 in black.py change the ‘ ‘(four spaces) to ‘ ‘(a tab, copy a tab, and you can choose any spaces of the tab contains). Then you can get what you want. But, I really don’t recommend it.
Both autopep8
and black
are very strict.
They don’t just recommend spaces over tabs, but force the usage of space indentation.
If you really want to use tabs, you should use yapf
, with style use_tabs=True
.
Until maintainers/contributors add a setting to be able to indent Python with tabs, I found a workaround to this issue by using multi-command extension.
Steps to fix the issue:
-
Install extension.
-
Find your
settings.json
andkeybindings.json
. From here:Depending on your platform, the user settings file is located here:
- Windows %APPDATA%CodeUsersettings.json - macOS $HOME/Library/Application Support/Code/User/settings.json - Linux $HOME/.config/Code/User/settings.json
-
Add this to
settings.json
:
"multiCommand.commands": [
{
"command": "multiCommand.properlyFormatAnyDocument",
"sequence": [
"editor.action.formatDocument",
"editor.action.indentationToTabs"
]
}
]
- Add this to
keybindings.json
:
{
"key": "shift+alt+f",
"command": "extension.multiCommand.execute",
"args": {
"command": "multiCommand.properlyFormatAnyDocument"
},
"when": "editorTextFocus"
}
- Save all files and it works.
Technically, yapf has use_tabs
setting, but I was never able to get it to work.
So one of the comments was that yapf is not so easy to get working. Under Debian, install
apt-get install yapf3
Now go to your source directory and run
yapf3 --style "google" --style-help > .style.yapf
Edit the .style.yapf so that you put
use_tabs=True
instead of False.
Now run
yapf3 -i dirty.py
and it really use tabs for indentation. Spaces are still used for visual formatting and tabs only for real indentation, I am sending a visual example how my code is formatted.
Pass in the argument --ignore=W191
to autopep8
, and it would ignore the Indentation warning of indentation contains tabs.
For VSCode, use the settings-entry python.formatting.autopep8Args
.
vscode-settings-entry-gui