spyder-ide / spyder

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

[Feature Request]: AutoFormat using Blue or Ruff #21357

Open PhilipYip1988 opened 12 months ago

PhilipYip1988 commented 12 months ago

Ruff Format with Spyder

Install

Spyder 6.0.0b1 is installed with the ruff formatter (autopep8 and isort) are dependencies:

conda create -n spyder-env -c conda-forge python=3.11
conda activate spyder-env
conda install -c conda-forge/label/spyder_dev -c conda-forge/label/spyder_kernels_rc -c conda-forge spyder=6.0.0b1
conda install -c conda-forge python spyder cython seaborn scikit-learn pyarrow sympy openpyxl xlrd xlsxwriter lxml sqlalchemy tabulate pyqt ruff ghostscript

Ruff Configuration File

The formal representation in Python prefers single quotations:

22

A file is created with the following code, which modifies the quote style from double (following blacks default) to single (consistent to Pythons formal representation):

[format]
# 5. Use single quotes for non-triple-quoted strings.
quote-style = "single"

For other options see Configuring Ruff:

1

This is saved in the project directory as .ruff.toml

2

Test Code

The following code is added to a new file:

import numpy as np

x=np.array([1,2, 3, 4,5])
import pandas as pd

df=pd.DataFrame({"x":x,'y':2*y})
import sys

var=sys.argv

This code:

3

This file is saved as untitled1.py:

4

Current Working Directory

In order for this to work, the current working directory used by ipython needs to match the location of the files:

5

6

IPython Magics

PowerShell or bash commands can be used in the ipython console. For example:

!where python

7

This gives the order of Python environments checked when searching for a command.

Format File with AutoPEP8

AutoPEP8 is already integrated into Spyder. Format file or select AutoPEP8 can be used:

8

This changes the code to:

import sys
import pandas as pd
import numpy as np

x = np.array([1, 2, 3, 4, 5])

df=pd.DataFrame({"x": x, 'y': 2 * y})

var=sys.argv

9

The imports are grouped by standard modules and third-party libraries but these are not sorted alphabetically.

The quotation styles are still inconsistent.

Note that the file that has not been modified is not saved and must be saved before using another formatter.

Sort Imports with ISort

Spyder does not have integration with isort, the PowerShell or bash command:

!isort untitled1.py

can be used:

11

Now the imports are sorted in the two groups (standard and third-party) with a space between the groups and all imports alphabetically sorted. The code is updated to:

12

import sys

import numpy as np
import pandas as pd

x = np.array([1, 2, 3, 4, 5])

df=pd.DataFrame({"x": x, 'y': 2 * y})

var=sys.argv

Note that there is a relatively large delay when it comes to Spyder refreshing the file and usually it is faster to close and reopen the file.

Format File with Ruff

Spyder does not have integration with Ruff, the PowerShell or bash command can be used:

!ruff format untitled1.py

This updates the code to:

import sys

import numpy as np
import pandas as pd

x = np.array([1, 2, 3, 4, 5])

df=pd.DataFrame({'x': x, 'y': 2 * y})

var=sys.argv

15

Now single quotations are used, matching the expected formal string representation:

Spyder Configuration

An IDE like Spyder would probably be best served having a .ruff.toml file in its configuration folder: ~\.spyder-py3-dev. Therefore a button added in the menu would use the specified configuration file which would ideally be modified within Preferences:

16

Therefore a button would use the command --config flag for example:

!ruff format untitled1.py --config ~\.spyder-py3-dev\.ruff.toml

19

Currently the Ruff formatter doesn't perform import sorting and isort seems to only work well once a file has initially been formatted with autopep8. Since Ruff is undergoing rapid development and Ruff is designed to replace the fragmented tools autopep8, isort and black, it is therefore likely this option will be added to the format section of the .ruff.toml file in a future version.

ccordoba12 commented 12 months ago

Hey @PhilipYip1988, thanks for reporting. Unfortunately, this is not so simple because it'd require creating a python-lsp-server plugin for Blue and then connecting it to Spyder.

Since we don't have time for this, the initiative would need to come from our community.

PhilipYip1988 commented 9 months ago

Just adding some more information as integration with Rust Fast Formatter (Ruff) is probably going to be much more useful than integration with Blue and it seems to be growing in popularity.

autopep8 is integrated in Spyder but can be run in the IPython console using PowerShell:

!C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe C:\Users\AppsLab\miniconda3\envs\spyder\Scripts\autopep8.exe C:\Users\AppsLab\Desktop\test\script.py -i

1

import sort (isort) is not integrated in Spyder but can be ran in the IPython console using PowerShell with a similar command:

!C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe C:\Users\AppsLab\miniconda3\envs\spyder\Scripts\isort.exe C:\Users\AppsLab\Desktop\test\script.py

2

Ruff is not integrated into Spyder but can also be ran using a similar command. Ruff has an optional configuration file a ruff.toml that can be used to change some of the preferences for example swapping out double quotes for single quotes:

!C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe C:\Users\AppsLab\miniconda3\envs\spyder\Scripts\ruff.exe format C:\Users\AppsLab\Desktop\test\script.py

3

More details about the ruff.toml file are available on the Ruff website. As part of the wish list, if this is to be integrated into Spyder it might be useful to have a menu for these options.

Closing and reopening the script file in Spyder:

4

ccordoba12 commented 8 months ago

We'll try to add support for Ruff next year.

gamesbook commented 3 months ago

As we hit the half-way mark in 2024, is there any feedback/follow-up on Ruff integration?

PhilipYip1988 commented 3 months ago

As we hit the half-way mark in 2024, is there any feedback/follow-up on Ruff integration?

It's not in Spyder 6.0.0b1, however I updated the comment at the top of the post to give a bit more details when it comes to using the Ruff format with Spyder 6.0.0b1.

PhilipYip1988 commented 3 days ago

Ruff Integration Suggestions

I had a more detailed look at using Ruff with Spyder outlining how integration could work:

Install Ruff in environment (as a dependency):

Example standalone:

C:\Users\phili\AppData\local\spyder-6\envs\spyder-runtime\Scripts\ruff.exe

Example conda environment:

C:\Users\phili\anaconda3\envs\spyder-env\Scripts\ruff.exe

Create ruff.toml file in Spyder config folder:

C:\Users\phili\.spyder-py3\config\ruff.toml

Create %ruff magic

Example standalone:

%alias ruff C:\Users\phili\AppData\local\spyder-6\envs\spyder-runtime\Scripts\ruff.exe

Example conda:

%alias ruff C:\Users\phili\anaconda3\envs\spyder-env\Scripts\ruff.exe

image

Source Menu -> Ruff Check (Fix)

image

Under the hood should run:

%ruff check "C:\Users\phili\OneDrive\Documents\project\script.py" --fix  --config "C:\Users\phili\.spyder-py3\config\ruff.toml"

where the file is the currently selected script file. The user is made aware of changes in the IPython console and non-fixable errors are highlighted:

image image

In this case the non-fixable errors can be addressed with AutoPEP8:

image

Once this is run and the file saved:

image

The Ruff Check can be redone:

image

Source Menu -> Ruff Check (Fix + Import Sort)

image

Under the hood should run:

%ruff check "C:\Users\phili\OneDrive\Documents\project\script.py" --extend-select I --fix --config "C:\Users\phili\.spyder-py3\config\ruff.toml"

where the file is the currently selected script file.

image

Source Menu -> Ruff Format

image

Under the hood should run:

%ruff format "C:\Users\phili\OneDrive\Documents\project\script.py" --config "C:\Users\phili\.spyder-py3\config\ruff.toml"

where the file is the currently selected script file.

image

Tools -> Preferences -> Completion and Linting -> Code Style and Formatting

The following Ruff options should be added:

image

The quote style will probably be the most commonly changed option, so would be useful to have a dropdown list which updates this option:

image

The button to update the ruff.toml file, would open up the ruff.toml in a dialog box:

image

This would be similar to the VSCode extension that gives the ISort (Ruff)

VSCode Extension

Note that the VSCode Ruff extension gives more or less similar options:

image

Although having the check display the non-fixable errors in the IPython Console as the examples above is perhaps more useful.