Skip to content

CHORE: Setting up ruff #6157

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
May 22, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions .flake8

This file was deleted.

25 changes: 5 additions & 20 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,12 @@ exclude: |

repos:

- repo: https://github.com/psf/black
rev: 25.1.0 # IF VERSION CHANGES --> MODIFY "blacken-docs" MANUALLY AS WELL!!
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.9
hooks:
- id: black
args:
- --line-length=120

- repo: https://github.com/pycqa/isort
rev: 6.0.1
hooks:
- id: isort
name: isort (python)
args: ['--force-single-line-imports', '--profile', 'black']

- repo: https://github.com/PyCQA/flake8
rev: 7.2.0
hooks:
- id: flake8
args:
- --max-line-length=120

- id: ruff
- id: ruff-format

- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
hooks:
Expand Down
1 change: 1 addition & 0 deletions doc/changelog.d/6157.maintenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Setting up ruff
3 changes: 2 additions & 1 deletion doc/print_errors.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Read errors output from a sphinx build and remove duplicate groups"""
import sys

import os
import pathlib
import sys

sys.tracebacklimit = 0
my_path = pathlib.Path(__file__).parent.resolve()
Expand Down
12 changes: 6 additions & 6 deletions doc/source/Resources/pyaedt_installer_from_aedt.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
VENV_DIR_PREFIX = ".pyaedt_env"

"""
It is possible create Python virtual environment in a specific directory by setting variable VENV_DIR.
It is possible create Python virtual environment in a specific directory by setting variable VENV_DIR.
For example,
VENV_DIR = "e:/pyaedt_env"
"""
Expand Down Expand Up @@ -93,10 +93,10 @@ def run_pyinstaller_from_c_python(oDesktop):
if is_student_version(oDesktop):
command.append("--student")
if is_linux:
command.extend([r'--edt_root={}'.format(edt_root), '--python_version="{}"'.format(python_version)])
command.extend([r"--edt_root={}".format(edt_root), '--python_version="{}"'.format(python_version)])

if wheelpyaedt:
command.extend([r'--wheel={}'.format(wheelpyaedt)])
command.extend([r"--wheel={}".format(wheelpyaedt)])

oDesktop.AddMessage("", "", 0, "Installing PyAEDT.")
return_code = subprocess.call(command) # nosec
Expand Down Expand Up @@ -193,13 +193,14 @@ def parse_arguments_for_pyaedt_installer(args=None):
parser.error("No arguments given!")
return args


def unzip_if_zip(path):
"""Unzip path if it is a ZIP file."""
import zipfile

# Extracted folder
unzipped_path = path
if path.suffix == '.zip':
if path.suffix == ".zip":
unzipped_path = path.parent / path.stem
if unzipped_path.exists():
shutil.rmtree(unzipped_path, ignore_errors=True)
Expand Down Expand Up @@ -266,7 +267,7 @@ def install_pyaedt():
if args.version <= "231":
command.append("pyaedt[all,dotnet]=='0.9.0'")
else:
command.append("pyaedt[all]")
command.append("pyaedt[all]")
subprocess.run(command, check=True) # nosec
else:
print("Installing PyAEDT using online sources")
Expand Down Expand Up @@ -333,7 +334,6 @@ def validate_disclaimer():


if __name__ == "__main__":

if is_iron_python:
if "GetIsNonGraphical" in oDesktop.__dir__() and oDesktop.GetIsNonGraphical():
print("When using IronPython, this script is expected to be run in graphical mode.")
Expand Down
24 changes: 17 additions & 7 deletions doc/source/Resources/toolkit_installer_from_aedt.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import os
import sys

import subprocessdotnet as subprocess # nosec

# This script installs PyAEDT tabs (PyAEDT Console, Jupyter, Run Script and Extension Manager)
Expand All @@ -47,14 +48,17 @@ def run_pyinstaller_from_c_python(oDesktop, pyaedt_interpreter):

# Create Toolkits in PersonalLib
import tempfile

python_script = os.path.join(tempfile.gettempdir(), "configure_pyaedt.py")
if os.path.isfile(python_script):
os.remove(python_script)
with open(python_script, "w") as f:
f.write("from ansys.aedt.core.extensions.installer.pyaedt_installer import add_pyaedt_to_aedt\n")
f.write(
'add_pyaedt_to_aedt(aedt_version="{}", personal_lib=r"{}")\n'.format(
oDesktop.GetVersion()[:6], oDesktop.GetPersonalLibDirectory()))
oDesktop.GetVersion()[:6], oDesktop.GetPersonalLibDirectory()
)
)

command = [pyaedt_interpreter, python_script]
oDesktop.AddMessage("", "", 0, "Configuring PyAEDT panels in automation tab.")
Expand All @@ -67,21 +71,27 @@ def run_pyinstaller_from_c_python(oDesktop, pyaedt_interpreter):
oDesktop.RefreshToolkitUI()
msg = "PyAEDT configuration complete."
if is_linux:
msg += " Please ensure Ansys Electronics Desktop is launched in gRPC mode (i.e. launch ansysedt with -grpcsrv" \
" argument) to take advantage of the new toolkits."
msg += (
" Please ensure Ansys Electronics Desktop is launched in gRPC mode (i.e. launch ansysedt with -grpcsrv"
" argument) to take advantage of the new toolkits."
)

if "GetIsNonGraphical" in oDesktop.__dir__() and not oDesktop.GetIsNonGraphical():
from System.Windows.Forms import MessageBox, MessageBoxButtons, MessageBoxIcon
from System.Windows.Forms import MessageBox
from System.Windows.Forms import MessageBoxButtons
from System.Windows.Forms import MessageBoxIcon

oDesktop.AddMessage("", "", 0, msg)
MessageBox.Show(msg, 'Info', MessageBoxButtons.OK, MessageBoxIcon.Information)
MessageBox.Show(msg, "Info", MessageBoxButtons.OK, MessageBoxIcon.Information)
oDesktop.AddMessage("", "", 0, "Create a project if the PyAEDT panel is not visible.")


if __name__ == "__main__":

python_interpreter = os.getenv(pyaedt_enviroment_variable)
if python_interpreter:
oDesktop.AddMessage("", "", 0, "Using Python environment defined with the environment variable PYAEDT_INTERPRETER.")
oDesktop.AddMessage(
"", "", 0, "Using Python environment defined with the environment variable PYAEDT_INTERPRETER."
)
if os.path.exists(python_interpreter):
oDesktop.AddMessage("", "", 2, "Python environment does not exist.")
sys.exit()
Expand Down
65 changes: 34 additions & 31 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,46 @@

# -- Project information -----------------------------------------------------
import datetime
from importlib import import_module
import os
import pathlib
from pprint import pformat
import shutil
import sys
import warnings

import numpy as np
from sphinx_gallery.sorting import FileNameSortKey
from ansys_sphinx_theme import (ansys_favicon,
get_version_match,
watermark,
ansys_logo_white,
ansys_logo_white_cropped, latex)
from importlib import import_module
from pprint import pformat
from docutils.parsers.rst import Directive
from ansys_sphinx_theme import ansys_favicon
from ansys_sphinx_theme import ansys_logo_white
from ansys_sphinx_theme import ansys_logo_white_cropped
from ansys_sphinx_theme import get_version_match
from ansys_sphinx_theme import latex
from ansys_sphinx_theme import watermark
from docutils import nodes
from docutils.parsers.rst import Directive
import numpy as np
from sphinx import addnodes
from sphinx.util import logging
import shutil

# <-----------------Override the sphinx pdf builder---------------->
# Some pages do not render properly as per the expected Sphinx LaTeX PDF signature.
# This issue can be resolved by migrating to the autoapi format.
# Additionally, when documenting images in formats other than the supported ones,
# Additionally, when documenting images in formats other than the supported ones,
# make sure to specify their types.
from sphinx.builders.latex import LaTeXBuilder
from sphinx.util import logging
from sphinx_gallery.sorting import FileNameSortKey

LaTeXBuilder.supported_image_types = ["image/png", "image/pdf", "image/svg+xml"]

from docutils.nodes import Element
from sphinx.writers.latex import CR
from sphinx.writers.latex import LaTeXTranslator
from docutils.nodes import Element


def visit_desc_content(self, node: Element) -> None:
self.body.append(CR + r'\pysigstopsignatures')
self.body.append(CR + r"\pysigstopsignatures")
self.in_desc_signature = False


LaTeXTranslator.visit_desc_content = visit_desc_content

# <----------------- End of sphinx pdf builder override---------------->
Expand All @@ -47,23 +52,22 @@ def visit_desc_content(self, node: Element) -> None:

# Sphinx event hooks


class PrettyPrintDirective(Directive):
"""Renders a constant using ``pprint.pformat`` and inserts it into the document."""

required_arguments = 1

def run(self):
module_path, member_name = self.arguments[0].rsplit('.', 1)
module_path, member_name = self.arguments[0].rsplit(".", 1)

member_data = getattr(import_module(module_path), member_name)
code = pformat(member_data, 2, width=68)

literal = nodes.literal_block(code, code)
literal['language'] = 'python'
literal["language"] = "python"

return [
addnodes.desc_name(text=member_name),
addnodes.desc_content('', literal)
]
return [addnodes.desc_name(text=member_name), addnodes.desc_content("", literal)]


def autodoc_skip_member(app, what, name, obj, skip, options):
Expand All @@ -87,6 +91,7 @@ def directory_size(directory_path):
res /= 1e6
return res


def remove_doctree(app, exception):
"""Remove the ``.doctree`` directory created during the documentation build."""

Expand All @@ -100,10 +105,11 @@ def remove_doctree(app, exception):
shutil.rmtree(app.doctreedir, ignore_errors=True)
logger.info(f"Doctree removed.")


def setup(app):
app.add_directive('pprint', PrettyPrintDirective)
app.connect('autodoc-skip-member', autodoc_skip_member)
app.connect('build-finished', remove_doctree, priority=600)
app.add_directive("pprint", PrettyPrintDirective)
app.connect("autodoc-skip-member", autodoc_skip_member)
app.connect("build-finished", remove_doctree, priority=600)


local_path = os.path.dirname(os.path.realpath(__file__))
Expand All @@ -112,7 +118,6 @@ def setup(app):
try:
from ansys.aedt.core import __version__
except ImportError:

sys.path.append(os.path.abspath(os.path.join(local_path)))
sys.path.append(os.path.join(root_path))
from ansys.aedt.core import __version__
Expand Down Expand Up @@ -181,8 +186,8 @@ def setup(app):
"GL09", # Deprecation warning should precede extended summary
"GL10", # reST directives {directives} must be followed by two colons
# Return
"RT04", # Return value description should start with a capital letter"
"RT05", # Return value description should finish with "."
"RT04", # Return value description should start with a capital letter"
"RT05", # Return value description should finish with "."
# Summary
"SS01", # No summary found
"SS02", # Summary does not start with a capital letter
Expand Down Expand Up @@ -319,7 +324,7 @@ def setup(app):
# These paths are either relative to html_static_path
# or fully qualified paths (eg. https://...)
html_css_files = [
'custom.css',
"custom.css",
]

# -- Options for LaTeX output ------------------------------------------------
Expand All @@ -338,6 +343,4 @@ def setup(app):
# If we are on a release, we have to ignore the "release" URLs, since it is not
# available until the release is published.
if switcher_version != "dev":
linkcheck_ignore.append(
f"https://github.com/ansys/pyaedt/releases/tag/v{__version__}"
) # noqa: E501
linkcheck_ignore.append(f"https://github.com/ansys/pyaedt/releases/tag/v{__version__}") # noqa: E501
43 changes: 36 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,44 @@ Discussions = "https://github.com/ansys/pyaedt/discussions"
Releases = "https://github.com/ansys/pyaedt/releases"
Changelog = "https://github.com/ansys/pyaedt/blob/main/doc/source/changelog.rst"

[tool.black]
[tool.ruff]
line-length = 120
exclude = [
"venv",
"__init__.py",
"doc/_build",
"doc/source/examples"
]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

[tool.ruff.lint]
select = [
"I", # isort, see https://docs.astral.sh/ruff/rules/#isort-i
"W", # pycodestyle, see https://docs.astral.sh/ruff/rules/#pycodestyle-e-w
]
ignore = [
"D", # pydocstyle, see https://docs.astral.sh/ruff/rules/#pydocstyle-d
"E", # pycodestyle, see https://docs.astral.sh/ruff/rules/#pycodestyle-e-w
"F", # pyflakes, see https://docs.astral.sh/ruff/rules/#pyflakes-f
"N", # pep8-naming, see https://docs.astral.sh/ruff/rules/#pep8-naming-n
"PTH", # flake8-use-pathlib, https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth
"TD", # flake8-todos, https://docs.astral.sh/ruff/rules/#flake8-todos-td
]

[tool.ruff.lint.pydocstyle]
# Use Numpy-style docstrings.
convention = "numpy"

[tool.ruff.lint.isort]
force-sort-within-sections = true
known-first-party = ["doc", "src/ansys/aedt/core", "tests"]
force-single-line = true

[tool.isort]
profile = "black"
force_sort_within_sections = true
line_length = 120
default_section = "THIRDPARTY"
src_paths = ["doc", "src/ansys/aedt/core", "tests"]
[tool.ruff.lint.mccabe]
max-complexity = 10

[tool.codespell]
ignore-words = "ignore_words.txt"
Expand Down
Loading
Loading