From 016a4b7504b7ddc52796d609c580eef0b375c66c Mon Sep 17 00:00:00 2001 From: Edouard Coussoux Date: Tue, 6 May 2025 11:28:30 +0200 Subject: [PATCH 01/10] feat: Introducing Ruff config, removing .flake8, updating pre-commit-config --- .flake8 | 7 ------- .github/labeler.yml | 2 +- .pre-commit-config.yaml | 25 +++---------------------- ruff.toml | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 30 deletions(-) delete mode 100644 .flake8 create mode 100644 ruff.toml diff --git a/.flake8 b/.flake8 deleted file mode 100644 index e8a884b02..000000000 --- a/.flake8 +++ /dev/null @@ -1,7 +0,0 @@ -[flake8] -exclude = build, doc/source/conf.py -select = W191, W291, W293, W391, E115, E117, E122, E124, E125, E225, E231, E301, E303, E501, F401, F403 -count = True -max-complexity = 10 -max-line-length = 100 -statistics = True \ No newline at end of file diff --git a/.github/labeler.yml b/.github/labeler.yml index cb9b5d3e5..b528780fd 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -3,7 +3,7 @@ documentation: - any-glob-to-any-file: ['doc/source/**/*'] maintenance: - changed-files: - - any-glob-to-any-file: ['.github/**/*', '.flake8', 'pyproject.toml', 'docker/**/*'] + - any-glob-to-any-file: ['.github/**/*', 'ruff.toml', 'pyproject.toml', 'docker/**/*'] dependencies: - changed-files: - any-glob-to-any-file: ['requirements/*'] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3043a17e4..5ceea5c4d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,14 +1,10 @@ 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.8 hooks: - - id: black - args: [ - "doc/source/conf.py", - "examples" - ] + - id: ruff - repo: https://github.com/adamchainz/blacken-docs rev: 1.19.1 @@ -16,21 +12,6 @@ repos: - id: blacken-docs additional_dependencies: [black==24.8.0] -- repo: https://github.com/pycqa/isort - rev: 6.0.1 - hooks: - - id: isort - args: [ - "--profile", "black", - "--force-sort-within-sections", - "--line-length", "100", - ] - -- repo: https://github.com/PyCQA/flake8 - rev: 7.2.0 - hooks: - - id: flake8 - - repo: https://github.com/codespell-project/codespell rev: v2.4.1 hooks: diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 000000000..b20ebdc9f --- /dev/null +++ b/ruff.toml @@ -0,0 +1,35 @@ +exclude = [ + "build", + "doc/source/conf.py", +] + +line-length = 100 + +[format] +quote-style = "double" +indent-style = "space" +docstring-code-format = true + +[lint] +select = [ + "E", # pycodestyle, see https://docs.astral.sh/ruff/rules/#pycodestyle-e-w + "I", # isort, see https://docs.astral.sh/ruff/rules/#isort-i +] +ignore = [ + "D", # pydocstyle, see https://docs.astral.sh/ruff/rules/#pydocstyle-d + "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 + "W", # pycodestyle, see https://docs.astral.sh/ruff/rules/#pycodestyle-e-w +] + +[lint.pydocstyle] +convention = "numpy" + +[lint.isort] +combine-as-imports = true +force-sort-within-sections = true + +[lint.mccabe] +max-complexity = 10 \ No newline at end of file From 2f984e9b75962f42f7dfd32ed9f8cd808358517c Mon Sep 17 00:00:00 2001 From: Edouard Coussoux Date: Tue, 6 May 2025 12:16:49 +0200 Subject: [PATCH 02/10] feat: Adding ruff-format hook to pre-commit, updating fixed files --- .pre-commit-config.yaml | 1 + doc/source/doc-style/code/sample_func.py | 2 +- doc/source/how-to/code/pyansys_logging.py | 20 +++++-------------- .../how-to/code/test_pyansys_logging.py | 14 +++---------- 4 files changed, 10 insertions(+), 27 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5ceea5c4d..bae664488 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,6 +5,7 @@ repos: rev: v0.11.8 hooks: - id: ruff + - id: ruff-format - repo: https://github.com/adamchainz/blacken-docs rev: 1.19.1 diff --git a/doc/source/doc-style/code/sample_func.py b/doc/source/doc-style/code/sample_func.py index 69ef2c056..1e05684d5 100644 --- a/doc/source/doc-style/code/sample_func.py +++ b/doc/source/doc-style/code/sample_func.py @@ -25,7 +25,7 @@ def func(arg1, arg2): Examples -------- - >>> func(1, 'foo') + >>> func(1, "foo") True """ diff --git a/doc/source/how-to/code/pyansys_logging.py b/doc/source/how-to/code/pyansys_logging.py index fffd38fb3..3704e0937 100644 --- a/doc/source/how-to/code/pyansys_logging.py +++ b/doc/source/how-to/code/pyansys_logging.py @@ -10,9 +10,7 @@ # Formatting -STDOUT_MSG_FORMAT = ( - "%(levelname)s - %(instance_name)s - %(module)s - %(funcName)s - %(message)s" -) +STDOUT_MSG_FORMAT = "%(levelname)s - %(instance_name)s - %(module)s - %(funcName)s - %(message)s" FILE_MSG_FORMAT = STDOUT_MSG_FORMAT DEFAULT_STDOUT_HEADER = """ @@ -194,9 +192,7 @@ def __init__( ): """Initialize Logger class.""" - self.logger = logging.getLogger( - "pyproject_global" - ) # Creating default main logger. + self.logger = logging.getLogger("pyproject_global") # Creating default main logger. self.logger.addFilter(InstanceFilter()) self.logger.setLevel(level) self.logger.propagate = True @@ -234,9 +230,7 @@ def log_to_file(self, filename=FILE_NAME, level=LOG_LEVEL): Level of logging. E.x. 'DEBUG'. By default LOG_LEVEL """ - self = add_file_handler( - self, filename=filename, level=level, write_headers=True - ) + self = add_file_handler(self, filename=filename, level=level, write_headers=True) def log_to_stdout(self, level=LOG_LEVEL): """Add standard output handler to the logger. @@ -333,9 +327,7 @@ def _add_product_instance_logger(self, name, product_instance, level): self._make_child_logger("NO_NAMED_YET", level), product_instance ) else: - raise TypeError( - f"``name`` parameter must be a string or None, not f{type(name)}" - ) + raise TypeError(f"``name`` parameter must be a string or None, not f{type(name)}") return instance_logger @@ -391,9 +383,7 @@ def handle_exception(exc_type, exc_value, exc_traceback): if issubclass(exc_type, KeyboardInterrupt): sys.__excepthook__(exc_type, exc_value, exc_traceback) return - logger.critical( - "Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback) - ) + logger.critical("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)) sys.excepthook = handle_exception diff --git a/doc/source/how-to/code/test_pyansys_logging.py b/doc/source/how-to/code/test_pyansys_logging.py index ece1a4c06..701d2e30d 100644 --- a/doc/source/how-to/code/test_pyansys_logging.py +++ b/doc/source/how-to/code/test_pyansys_logging.py @@ -16,10 +16,7 @@ def test_default_logger(): test_logger = pyansys_logging.Logger() test_logger.info("Test stdout") - assert ( - "INFO - - test_pyansys_logging - test_default_logger - Test stdout" - in capture.content - ) + assert "INFO - - test_pyansys_logging - test_default_logger - Test stdout" in capture.content # File handlers are not activated. assert os.path.exists(os.path.exists(os.path.join(os.getcwd(), "PyProject.log"))) @@ -99,9 +96,7 @@ def test_file_handlers(tmpdir): with open(file_logger, "r") as f: content = f.readlines() - assert os.path.exists( - file_logger - ) # The file handler is not the default PyProject.Log + assert os.path.exists(file_logger) # The file handler is not the default PyProject.Log assert len(content) == 6 assert "NEW SESSION" in content[2] assert ( @@ -109,10 +104,7 @@ def test_file_handlers(tmpdir): in content[3] ) assert "LEVEL - INSTANCE NAME - MODULE - FUNCTION - MESSAGE" in content[4] - assert ( - "INFO - - test_pyansys_logging - test_file_handlers - Test Misc File" - in content[5] - ) + assert "INFO - - test_pyansys_logging - test_file_handlers - Test Misc File" in content[5] # Delete the logger and its file handler. test_logger_ref = weakref.ref(test_logger) From 90484729518c4ed2a0396d6d58183bdf6f2f9d96 Mon Sep 17 00:00:00 2001 From: Edouard Coussoux Date: Tue, 6 May 2025 14:22:29 +0200 Subject: [PATCH 03/10] feat: Adding linting rules to Ruff config, updating fixed file --- doc/source/how-to/code/pyansys_logging.py | 26 +++++++++++------------ ruff.toml | 12 ++++++----- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/doc/source/how-to/code/pyansys_logging.py b/doc/source/how-to/code/pyansys_logging.py index 3704e0937..9c2dfc82f 100644 --- a/doc/source/how-to/code/pyansys_logging.py +++ b/doc/source/how-to/code/pyansys_logging.py @@ -95,11 +95,11 @@ def log_to_stdout(self, level=LOG_LEVEL): self.logger = add_stdout_handler(self.logger, level=level) self.std_out_handler = self.logger.std_out_handler - def setLevel(self, level="DEBUG"): + def setlevel(self, level="DEBUG"): """Change the log level of the object and the attached handlers.""" - self.logger.setLevel(level) + self.logger.setlevel(level) for each_handler in self.logger.handlers: - each_handler.setLevel(level) + each_handler.setlevel(level) self.level = level @@ -194,7 +194,7 @@ def __init__( self.logger = logging.getLogger("pyproject_global") # Creating default main logger. self.logger.addFilter(InstanceFilter()) - self.logger.setLevel(level) + self.logger.setlevel(level) self.logger.propagate = True self.level = self.logger.level # TODO: TO REMOVE @@ -243,11 +243,11 @@ def log_to_stdout(self, level=LOG_LEVEL): self = add_stdout_handler(self, level=level) - def setLevel(self, level="DEBUG"): + def setlevel(self, level="DEBUG"): """Change the log level of the object and the attached handlers.""" - self.logger.setLevel(level) + self.logger.setlevel(level) for each_handler in self.logger.handlers: - each_handler.setLevel(level) + each_handler.setlevel(level) self._level = level def _make_child_logger(self, suffix, level): @@ -276,17 +276,17 @@ def _make_child_logger(self, suffix, level): # loglevel if the specified log level is lower # than the one of the global. if each_handler.level > string_to_loglevel[level.upper()]: - new_handler.setLevel(level) + new_handler.setlevel(level) logger.addHandler(new_handler) if level: if isinstance(level, str): level = string_to_loglevel[level.upper()] - logger.setLevel(level) + logger.setlevel(level) else: - logger.setLevel(self.logger.level) + logger.setlevel(self.logger.level) logger.propagate = True return logger @@ -395,7 +395,7 @@ def __del__(self): for handler in self.logger.handlers: handler.close() self.logger.removeHandler(handler) - except Exception as e: + except Exception: try: if self.logger is not None: self.logger.error("The logger was not deleted properly.") @@ -426,7 +426,7 @@ def add_file_handler(logger, filename=FILE_NAME, level=LOG_LEVEL, write_headers= """ file_handler = logging.FileHandler(filename) - file_handler.setLevel(level) + file_handler.setlevel(level) file_handler.setFormatter(logging.Formatter(FILE_MSG_FORMAT)) if isinstance(logger, Logger): @@ -463,7 +463,7 @@ def add_stdout_handler(logger, level=LOG_LEVEL, write_headers=False): """ std_out_handler = logging.StreamHandler(sys.stdout) - std_out_handler.setLevel(level) + std_out_handler.setlevel(level) std_out_handler.setFormatter(PyProjectFormatter(STDOUT_MSG_FORMAT)) if isinstance(logger, Logger): diff --git a/ruff.toml b/ruff.toml index b20ebdc9f..e97f766db 100644 --- a/ruff.toml +++ b/ruff.toml @@ -13,16 +13,18 @@ docstring-code-format = true [lint] select = [ "E", # pycodestyle, see https://docs.astral.sh/ruff/rules/#pycodestyle-e-w - "I", # isort, see https://docs.astral.sh/ruff/rules/#isort-i -] -ignore = [ - "D", # pydocstyle, see https://docs.astral.sh/ruff/rules/#pydocstyle-d "F", # pyflakes, see https://docs.astral.sh/ruff/rules/#pyflakes-f + "I", # isort, see https://docs.astral.sh/ruff/rules/#isort-i "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 "W", # pycodestyle, see https://docs.astral.sh/ruff/rules/#pycodestyle-e-w ] +ignore = [ + "D", # pydocstyle, see https://docs.astral.sh/ruff/rules/#pydocstyle-d + "PTH", # flake8-use-pathlib, https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth + "TD002", # Missing author in TODOs comment + "TD003", # Missing issue link in TODOs comment +] [lint.pydocstyle] convention = "numpy" From d40cb5f2bc999920f79bff6770b66f6c037ae442 Mon Sep 17 00:00:00 2001 From: Edouard Coussoux Date: Tue, 6 May 2025 15:41:39 +0200 Subject: [PATCH 04/10] feat: Extending Ruff linting rules list, updating fixed files --- doc/source/how-to/code/pyansys_logging.py | 8 +------- doc/source/how-to/code/test_pyansys_logging.py | 17 +++++++++-------- examples/pyvista_example.py | 3 +-- ruff.toml | 8 ++++++-- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/doc/source/how-to/code/pyansys_logging.py b/doc/source/how-to/code/pyansys_logging.py index 9c2dfc82f..db8707957 100644 --- a/doc/source/how-to/code/pyansys_logging.py +++ b/doc/source/how-to/code/pyansys_logging.py @@ -75,7 +75,6 @@ def log_to_file(self, filename=FILE_NAME, level=LOG_LEVEL): Level of logging, for example ``'DEBUG'``. By default ``logging.DEBUG``. """ - self.logger = add_file_handler( self.logger, filename=filename, level=level, write_headers=True ) @@ -191,7 +190,6 @@ def __init__( cleanup=True, ): """Initialize Logger class.""" - self.logger = logging.getLogger("pyproject_global") # Creating default main logger. self.logger.addFilter(InstanceFilter()) self.logger.setlevel(level) @@ -229,7 +227,6 @@ def log_to_file(self, filename=FILE_NAME, level=LOG_LEVEL): level : str, optional Level of logging. E.x. 'DEBUG'. By default LOG_LEVEL """ - self = add_file_handler(self, filename=filename, level=level, write_headers=True) def log_to_stdout(self, level=LOG_LEVEL): @@ -240,7 +237,6 @@ def log_to_stdout(self, level=LOG_LEVEL): level : str, optional Level of logging record. By default LOG_LEVEL """ - self = add_stdout_handler(self, level=level) def setlevel(self, level="DEBUG"): @@ -377,7 +373,7 @@ def __getitem__(self, key): raise KeyError(f"There are no instances with name {key}") def add_handling_uncaught_expections(self, logger): - """This just redirects the output of an exception to the logger.""" + """Just redirects the output of an exception to the logger.""" def handle_exception(exc_type, exc_value, exc_traceback): if issubclass(exc_type, KeyboardInterrupt): @@ -424,7 +420,6 @@ def add_file_handler(logger, filename=FILE_NAME, level=LOG_LEVEL, write_headers= logger Return the logger or Logger object. """ - file_handler = logging.FileHandler(filename) file_handler.setlevel(level) file_handler.setFormatter(logging.Formatter(FILE_MSG_FORMAT)) @@ -461,7 +456,6 @@ def add_stdout_handler(logger, level=LOG_LEVEL, write_headers=False): logger The logger or Logger object. """ - std_out_handler = logging.StreamHandler(sys.stdout) std_out_handler.setlevel(level) std_out_handler.setFormatter(PyProjectFormatter(STDOUT_MSG_FORMAT)) diff --git a/doc/source/how-to/code/test_pyansys_logging.py b/doc/source/how-to/code/test_pyansys_logging.py index 701d2e30d..0a19949eb 100644 --- a/doc/source/how-to/code/test_pyansys_logging.py +++ b/doc/source/how-to/code/test_pyansys_logging.py @@ -1,6 +1,6 @@ import io import logging -import os +from pathlib import Path import sys import weakref @@ -9,8 +9,9 @@ def test_default_logger(): """Create a logger with default options. - Only stdout logger must be used.""" + Only stdout logger must be used. + """ capture = CaptureStdOut() with capture: test_logger = pyansys_logging.Logger() @@ -18,13 +19,14 @@ def test_default_logger(): assert "INFO - - test_pyansys_logging - test_default_logger - Test stdout" in capture.content # File handlers are not activated. - assert os.path.exists(os.path.exists(os.path.join(os.getcwd(), "PyProject.log"))) + assert Path.exists(Path.exists(Path(Path.cwd() / "PyProject.log"))) def test_level_stdout(): """Create a logger with default options. - Only stdout logger must be used.""" + Only stdout logger must be used. + """ capture = CaptureStdOut() with capture: test_logger = pyansys_logging.Logger(level=logging.INFO) @@ -82,21 +84,20 @@ def test_level_stdout(): ) # File handlers are not activated. - assert os.path.exists(os.path.exists(os.path.join(os.getcwd(), "PyProject.log"))) + assert Path.exists(Path.exists(Path(Path.cwd() / "PyProject.log"))) def test_file_handlers(tmpdir): """Activate a file handler different from `PyProject.log`.""" - file_logger = tmpdir.mkdir("sub").join("test_logger.txt") test_logger = pyansys_logging.Logger(to_file=True, filename=file_logger) test_logger.info("Test Misc File") - with open(file_logger, "r") as f: + with Path.open(file_logger, "r") as f: content = f.readlines() - assert os.path.exists(file_logger) # The file handler is not the default PyProject.Log + assert Path.exists(file_logger) # The file handler is not the default PyProject.Log assert len(content) == 6 assert "NEW SESSION" in content[2] assert ( diff --git a/examples/pyvista_example.py b/examples/pyvista_example.py index 75345a197..37a70d66e 100644 --- a/examples/pyvista_example.py +++ b/examples/pyvista_example.py @@ -21,9 +21,8 @@ # SOFTWARE. """ -.. _adding_a_new_gallery_example: +Adding a new gallery example. -Adding a new gallery example ============================ This example shows how to add a new example to the PyAnsys `Sphinx-Gallery diff --git a/ruff.toml b/ruff.toml index e97f766db..c578d5b98 100644 --- a/ruff.toml +++ b/ruff.toml @@ -12,16 +12,20 @@ docstring-code-format = true [lint] select = [ + "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 "I", # isort, see https://docs.astral.sh/ruff/rules/#isort-i "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 "W", # pycodestyle, see https://docs.astral.sh/ruff/rules/#pycodestyle-e-w ] ignore = [ - "D", # pydocstyle, see https://docs.astral.sh/ruff/rules/#pydocstyle-d - "PTH", # flake8-use-pathlib, https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth + "D100", # Missing docstring in public module + "D101", # Missing docstring in public class + "D102", # Missing docstring in public method + "D105", # Missing docstring in magic method "TD002", # Missing author in TODOs comment "TD003", # Missing issue link in TODOs comment ] From 4d3ee777f5bb8c7be0f445209c4ca74964d2ee08 Mon Sep 17 00:00:00 2001 From: Edouard Coussoux Date: Wed, 7 May 2025 10:10:29 +0200 Subject: [PATCH 05/10] feat: Reverting change breaking doc build, updating ignored linting rules --- examples/pyvista_example.py | 3 ++- ruff.toml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/pyvista_example.py b/examples/pyvista_example.py index 37a70d66e..75345a197 100644 --- a/examples/pyvista_example.py +++ b/examples/pyvista_example.py @@ -21,8 +21,9 @@ # SOFTWARE. """ -Adding a new gallery example. +.. _adding_a_new_gallery_example: +Adding a new gallery example ============================ This example shows how to add a new example to the PyAnsys `Sphinx-Gallery diff --git a/ruff.toml b/ruff.toml index c578d5b98..171de69df 100644 --- a/ruff.toml +++ b/ruff.toml @@ -26,6 +26,7 @@ ignore = [ "D101", # Missing docstring in public class "D102", # Missing docstring in public method "D105", # Missing docstring in magic method + "D400", # First line should end with a period "TD002", # Missing author in TODOs comment "TD003", # Missing issue link in TODOs comment ] From f201f0dded22ff586a9ca0e914f5f76a4fc045e8 Mon Sep 17 00:00:00 2001 From: Edouard Coussoux Date: Mon, 12 May 2025 11:10:00 +0200 Subject: [PATCH 06/10] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Morais <146729917+SMoraisAnsys@users.noreply.github.com> --- doc/source/how-to/code/pyansys_logging.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/source/how-to/code/pyansys_logging.py b/doc/source/how-to/code/pyansys_logging.py index db8707957..2b7ba7029 100644 --- a/doc/source/how-to/code/pyansys_logging.py +++ b/doc/source/how-to/code/pyansys_logging.py @@ -94,11 +94,11 @@ def log_to_stdout(self, level=LOG_LEVEL): self.logger = add_stdout_handler(self.logger, level=level) self.std_out_handler = self.logger.std_out_handler - def setlevel(self, level="DEBUG"): + def setLevel(self, level="DEBUG"): """Change the log level of the object and the attached handlers.""" - self.logger.setlevel(level) + self.logger.setLevel(level) for each_handler in self.logger.handlers: - each_handler.setlevel(level) + each_handler.setLevel(level) self.level = level @@ -192,7 +192,7 @@ def __init__( """Initialize Logger class.""" self.logger = logging.getLogger("pyproject_global") # Creating default main logger. self.logger.addFilter(InstanceFilter()) - self.logger.setlevel(level) + self.logger.setLevel(level) self.logger.propagate = True self.level = self.logger.level # TODO: TO REMOVE @@ -373,7 +373,7 @@ def __getitem__(self, key): raise KeyError(f"There are no instances with name {key}") def add_handling_uncaught_expections(self, logger): - """Just redirects the output of an exception to the logger.""" + """Redirect the output of an exception to the logger.""" def handle_exception(exc_type, exc_value, exc_traceback): if issubclass(exc_type, KeyboardInterrupt): From 7c944dc8ecf1885ae95d6a728fed13b41f08d0ec Mon Sep 17 00:00:00 2001 From: Edouard Coussoux Date: Mon, 12 May 2025 11:23:00 +0200 Subject: [PATCH 07/10] feat: Updating pyansys_logging and ruff config based on review comments --- doc/source/how-to/code/pyansys_logging.py | 16 ++++++++-------- ruff.toml | 9 ++++++--- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/doc/source/how-to/code/pyansys_logging.py b/doc/source/how-to/code/pyansys_logging.py index 2b7ba7029..5abe3ec3a 100644 --- a/doc/source/how-to/code/pyansys_logging.py +++ b/doc/source/how-to/code/pyansys_logging.py @@ -239,11 +239,11 @@ def log_to_stdout(self, level=LOG_LEVEL): """ self = add_stdout_handler(self, level=level) - def setlevel(self, level="DEBUG"): + def setLevel(self, level="DEBUG"): """Change the log level of the object and the attached handlers.""" - self.logger.setlevel(level) + self.logger.setLevel(level) for each_handler in self.logger.handlers: - each_handler.setlevel(level) + each_handler.setLevel(level) self._level = level def _make_child_logger(self, suffix, level): @@ -272,17 +272,17 @@ def _make_child_logger(self, suffix, level): # loglevel if the specified log level is lower # than the one of the global. if each_handler.level > string_to_loglevel[level.upper()]: - new_handler.setlevel(level) + new_handler.setLevel(level) logger.addHandler(new_handler) if level: if isinstance(level, str): level = string_to_loglevel[level.upper()] - logger.setlevel(level) + logger.setLevel(level) else: - logger.setlevel(self.logger.level) + logger.setLevel(self.logger.level) logger.propagate = True return logger @@ -421,7 +421,7 @@ def add_file_handler(logger, filename=FILE_NAME, level=LOG_LEVEL, write_headers= Return the logger or Logger object. """ file_handler = logging.FileHandler(filename) - file_handler.setlevel(level) + file_handler.setLevel(level) file_handler.setFormatter(logging.Formatter(FILE_MSG_FORMAT)) if isinstance(logger, Logger): @@ -457,7 +457,7 @@ def add_stdout_handler(logger, level=LOG_LEVEL, write_headers=False): The logger or Logger object. """ std_out_handler = logging.StreamHandler(sys.stdout) - std_out_handler.setlevel(level) + std_out_handler.setLevel(level) std_out_handler.setFormatter(PyProjectFormatter(STDOUT_MSG_FORMAT)) if isinstance(logger, Logger): diff --git a/ruff.toml b/ruff.toml index 171de69df..f903c6f27 100644 --- a/ruff.toml +++ b/ruff.toml @@ -12,12 +12,12 @@ docstring-code-format = true [lint] select = [ - "D", # pydocstyle, see https://docs.astral.sh/ruff/rules/#pydocstyle-d + "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 "I", # isort, see https://docs.astral.sh/ruff/rules/#isort-i "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 + "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 "W", # pycodestyle, see https://docs.astral.sh/ruff/rules/#pycodestyle-e-w ] @@ -39,4 +39,7 @@ combine-as-imports = true force-sort-within-sections = true [lint.mccabe] -max-complexity = 10 \ No newline at end of file +max-complexity = 10 + +[lint.pep8-naming] +ignore-names = ["setLevel"] \ No newline at end of file From 7dc1f5f42a09800d4040807512a80f4b25735226 Mon Sep 17 00:00:00 2001 From: Edouard Coussoux Date: Wed, 14 May 2025 12:07:20 +0200 Subject: [PATCH 08/10] Update doc/source/how-to/code/test_pyansys_logging.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Morais <146729917+SMoraisAnsys@users.noreply.github.com> --- doc/source/how-to/code/test_pyansys_logging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/how-to/code/test_pyansys_logging.py b/doc/source/how-to/code/test_pyansys_logging.py index 0a19949eb..73363629a 100644 --- a/doc/source/how-to/code/test_pyansys_logging.py +++ b/doc/source/how-to/code/test_pyansys_logging.py @@ -84,7 +84,7 @@ def test_level_stdout(): ) # File handlers are not activated. - assert Path.exists(Path.exists(Path(Path.cwd() / "PyProject.log"))) + assert (Path.cwd() / "PyProject.log").exists() def test_file_handlers(tmpdir): From 349077a25e58b5aba470da64e2e85a9deb19ab81 Mon Sep 17 00:00:00 2001 From: Edouard Coussoux Date: Wed, 14 May 2025 18:14:52 +0200 Subject: [PATCH 09/10] feat: Removing ignored rules from ruff config and updating files accordingly --- doc/source/doc-style/code/sample_func.py | 2 +- doc/source/how-to/code/pyansys_logging.py | 9 ++++++++- doc/source/how-to/code/test_pyansys_logging.py | 4 ++++ examples/pyvista_example.py | 1 + ruff.toml | 10 +--------- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/doc/source/doc-style/code/sample_func.py b/doc/source/doc-style/code/sample_func.py index 1e05684d5..0d42b25cd 100644 --- a/doc/source/doc-style/code/sample_func.py +++ b/doc/source/doc-style/code/sample_func.py @@ -1,4 +1,4 @@ -def func(arg1, arg2): +def func(arg1, arg2): # noqa: D100 """Summary line . Extended description of the function. The extended description, diff --git a/doc/source/how-to/code/pyansys_logging.py b/doc/source/how-to/code/pyansys_logging.py index 5abe3ec3a..aa30e9690 100644 --- a/doc/source/how-to/code/pyansys_logging.py +++ b/doc/source/how-to/code/pyansys_logging.py @@ -1,3 +1,5 @@ +"""Module for PyAnsys logging.""" + from copy import copy from datetime import datetime import logging @@ -57,6 +59,7 @@ def __init__(self, logger, extra=None): self.std_out_handler = logger.std_out_handler def process(self, msg, kwargs): + """Get instance_name for logging.""" kwargs["extra"] = {} # These are the extra parameters sent to log # here self.extra is the argument pass to the log records. @@ -103,6 +106,8 @@ def setLevel(self, level="DEBUG"): class PyAnsysPercentStyle(logging.PercentStyle): + """Log message formatting.""" + def __init__(self, fmt, *, defaults=None): self._fmt = fmt or self.default_format self._defaults = defaults @@ -151,6 +156,7 @@ class InstanceFilter(logging.Filter): """Ensures that instance_name record always exists.""" def filter(self, record): + """If record had no attribute instance_name, create it and populate with empty string.""" if not hasattr(record, "instance_name"): record.instance_name = "" return True @@ -194,7 +200,7 @@ def __init__( self.logger.addFilter(InstanceFilter()) self.logger.setLevel(level) self.logger.propagate = True - self.level = self.logger.level # TODO: TO REMOVE + self.level = self.logger.level # noqa: TD002, TD003 # TODO: TO REMOVE # Writing logging methods. self.debug = self.logger.debug @@ -367,6 +373,7 @@ def add_instance_logger(self, name, product_instance, level=None): return self._instances[new_name] def __getitem__(self, key): + """Define custom KeyError message.""" if key in self._instances.keys(): return self._instances[key] else: diff --git a/doc/source/how-to/code/test_pyansys_logging.py b/doc/source/how-to/code/test_pyansys_logging.py index 73363629a..04115a1fb 100644 --- a/doc/source/how-to/code/test_pyansys_logging.py +++ b/doc/source/how-to/code/test_pyansys_logging.py @@ -1,3 +1,5 @@ +"""Test for PyAnsys logging.""" + import io import logging from pathlib import Path @@ -120,9 +122,11 @@ def __init__(self): self._stream = io.StringIO() def __enter__(self): + """Runtime context is entered.""" sys.stdout = self._stream def __exit__(self, type, value, traceback): + """Runtime context is exited.""" sys.stdout = sys.__stdout__ @property diff --git a/examples/pyvista_example.py b/examples/pyvista_example.py index 75345a197..3e976632f 100644 --- a/examples/pyvista_example.py +++ b/examples/pyvista_example.py @@ -20,6 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +# ruff: noqa: D400 """ .. _adding_a_new_gallery_example: diff --git a/ruff.toml b/ruff.toml index f903c6f27..39e0c33a5 100644 --- a/ruff.toml +++ b/ruff.toml @@ -21,15 +21,7 @@ select = [ "TD", # flake8-todos, https://docs.astral.sh/ruff/rules/#flake8-todos-td "W", # pycodestyle, see https://docs.astral.sh/ruff/rules/#pycodestyle-e-w ] -ignore = [ - "D100", # Missing docstring in public module - "D101", # Missing docstring in public class - "D102", # Missing docstring in public method - "D105", # Missing docstring in magic method - "D400", # First line should end with a period - "TD002", # Missing author in TODOs comment - "TD003", # Missing issue link in TODOs comment -] +ignore = [] [lint.pydocstyle] convention = "numpy" From b159c4966c10935db3997a5172e93d87dbabebf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Morais?= <146729917+SMoraisAnsys@users.noreply.github.com> Date: Thu, 15 May 2025 08:19:48 +0200 Subject: [PATCH 10/10] Update doc/source/how-to/code/test_pyansys_logging.py --- doc/source/how-to/code/test_pyansys_logging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/how-to/code/test_pyansys_logging.py b/doc/source/how-to/code/test_pyansys_logging.py index 04115a1fb..9bdfbd5aa 100644 --- a/doc/source/how-to/code/test_pyansys_logging.py +++ b/doc/source/how-to/code/test_pyansys_logging.py @@ -21,7 +21,7 @@ def test_default_logger(): assert "INFO - - test_pyansys_logging - test_default_logger - Test stdout" in capture.content # File handlers are not activated. - assert Path.exists(Path.exists(Path(Path.cwd() / "PyProject.log"))) + assert (Path.cwd() / "PyProject.log").exists() def test_level_stdout():