Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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.

2 changes: 1 addition & 1 deletion .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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/*']
26 changes: 4 additions & 22 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,36 +1,18 @@
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
- id: ruff-format

- repo: https://github.com/adamchainz/blacken-docs
rev: 1.19.1
hooks:
- 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:
Expand Down
2 changes: 1 addition & 1 deletion doc/source/doc-style/code/sample_func.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def func(arg1, arg2):

Examples
--------
>>> func(1, 'foo')
>>> func(1, "foo")
True

"""
Expand Down
54 changes: 19 additions & 35 deletions doc/source/how-to/code/pyansys_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = """
Expand Down Expand Up @@ -77,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
)
Expand All @@ -97,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


Expand Down Expand Up @@ -193,12 +190,9 @@ def __init__(
cleanup=True,
):
"""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.setlevel(level)
self.logger.propagate = True
self.level = self.logger.level # TODO: TO REMOVE

Expand Down Expand Up @@ -233,10 +227,7 @@ 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
)
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.
Expand All @@ -246,14 +237,13 @@ 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"):
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):
Expand Down Expand Up @@ -282,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
Expand Down Expand Up @@ -333,9 +323,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

Expand Down Expand Up @@ -385,15 +373,13 @@ 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):
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

Expand All @@ -405,7 +391,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.")
Expand Down Expand Up @@ -434,9 +420,8 @@ 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.setlevel(level)
file_handler.setFormatter(logging.Formatter(FILE_MSG_FORMAT))

if isinstance(logger, Logger):
Expand Down Expand Up @@ -471,9 +456,8 @@ 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.setlevel(level)
std_out_handler.setFormatter(PyProjectFormatter(STDOUT_MSG_FORMAT))

if isinstance(logger, Logger):
Expand Down
29 changes: 11 additions & 18 deletions doc/source/how-to/code/test_pyansys_logging.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import io
import logging
import os
from pathlib import Path
import sys
import weakref

Expand All @@ -9,25 +9,24 @@

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()
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")))
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)
Expand Down Expand Up @@ -85,34 +84,28 @@ 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 (
"==============================================================================="
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)
Expand Down
42 changes: 42 additions & 0 deletions ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
exclude = [
"build",
"doc/source/conf.py",
]

line-length = 100

[format]
quote-style = "double"
indent-style = "space"
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 = [
"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
]

[lint.pydocstyle]
convention = "numpy"

[lint.isort]
combine-as-imports = true
force-sort-within-sections = true

[lint.mccabe]
max-complexity = 10