From b674a0f24e0c28622576d693955058446c639d1e Mon Sep 17 00:00:00 2001 From: Saeed Rasooli Date: Sat, 16 Mar 2024 03:59:16 +0330 Subject: [PATCH] update pyproject.toml, and ignore PLR0904 --- pyglossary/entry.py | 2 +- pyglossary/glossary_types.py | 4 +- pyglossary/glossary_v2.py | 2 +- pyglossary/io_utils.py | 4 +- pyglossary/plugin_prop.py | 77 +++++++-------- pyproject.toml | 186 ++++++++++++++++++----------------- 6 files changed, 138 insertions(+), 137 deletions(-) diff --git a/pyglossary/entry.py b/pyglossary/entry.py index bd1ca623a..e74585cc4 100644 --- a/pyglossary/entry.py +++ b/pyglossary/entry.py @@ -31,7 +31,7 @@ # aka Resource -class DataEntry(BaseEntry): +class DataEntry(BaseEntry): # noqa: PLR0904 __slots__ = [ "_byteProgress", "_data", diff --git a/pyglossary/glossary_types.py b/pyglossary/glossary_types.py index b8125f72e..9a83756f7 100644 --- a/pyglossary/glossary_types.py +++ b/pyglossary/glossary_types.py @@ -37,7 +37,7 @@ ) -class EntryType(typing.Protocol): +class EntryType(typing.Protocol): # noqa: PLR0904 def __init__(self) -> None: ... def isData(self) -> bool: ... @@ -132,7 +132,7 @@ def sort(self) -> None: ... def close(self) -> None: ... -class GlossaryType(typing.Protocol): +class GlossaryType(typing.Protocol): # noqa: PLR0904 """ an abstract type class for Glossary class in plugins. it only diff --git a/pyglossary/glossary_v2.py b/pyglossary/glossary_v2.py index b0eaefbc5..4114eab3c 100644 --- a/pyglossary/glossary_v2.py +++ b/pyglossary/glossary_v2.py @@ -111,7 +111,7 @@ class ConvertArgs: infoOverride: "dict[str, str] | None" = None -class GlossaryCommon(GlossaryInfo, GlossaryProgress, PluginManager): +class GlossaryCommon(GlossaryInfo, GlossaryProgress, PluginManager): # noqa: PLR0904 """ The signature of 'convert' method is different in glossary_v2.py diff --git a/pyglossary/io_utils.py b/pyglossary/io_utils.py index 3ba4a3dbc..a0d2494e7 100644 --- a/pyglossary/io_utils.py +++ b/pyglossary/io_utils.py @@ -7,7 +7,7 @@ __all__ = ["nullBinaryIO", "nullTextIO"] -class _NullBinaryIO(io.BufferedIOBase): +class _NullBinaryIO(io.BufferedIOBase): # noqa: PLR0904 def __enter__(self, *args): raise NotImplementedError @@ -79,7 +79,7 @@ def writelines(self, lines: "list[bytes]") -> None: # type: ignore raise NotImplementedError -class _NullTextIO(io.TextIOBase): +class _NullTextIO(io.TextIOBase): # noqa: PLR0904 def __enter__(self, *args): raise NotImplementedError diff --git a/pyglossary/plugin_prop.py b/pyglossary/plugin_prop.py index 9bc268999..0ce0fa55c 100644 --- a/pyglossary/plugin_prop.py +++ b/pyglossary/plugin_prop.py @@ -23,7 +23,6 @@ if TYPE_CHECKING: import pathlib - from collections.abc import Callable from typing import Any from .flags import StrWithDesc @@ -65,7 +64,7 @@ class PluginCheckError(Exception): pass -class PluginProp: +class PluginProp: # noqa: PLR0904 __slots__ = [ "_Reader", "_ReaderLoaded", @@ -305,7 +304,7 @@ def canWrite(self) -> bool: return self._canWrite @staticmethod - def getOptionAttrNamesFromClass(rwclass: "type") -> "list[str]": + def _getOptionAttrNamesFromClass(rwclass: "type") -> "list[str]": nameList = [] for cls in (*rwclass.__bases__, rwclass): @@ -321,13 +320,13 @@ def getOptionAttrNamesFromClass(rwclass: "type") -> "list[str]": return nameList - def getOptionsFromClass(self, rwclass: "type") -> "dict[str, Any]": + def _getOptionsFromClass(self, rwclass: "type") -> "dict[str, Any]": optionsProp = self.optionsProp options = odict() if rwclass is None: return options - for attrName in self.getOptionAttrNamesFromClass(rwclass): + for attrName in self._getOptionAttrNamesFromClass(rwclass): name = attrName[1:] default = getattr(rwclass, attrName) if name not in optionsProp: @@ -352,12 +351,12 @@ def getOptionsFromClass(self, rwclass: "type") -> "dict[str, Any]": def getReadOptions(self) -> "dict[str, Any]": if self._readOptions is None: - self._readOptions = self.getOptionsFromClass(self.readerClass) + self._readOptions = self._getOptionsFromClass(self.readerClass) return self._readOptions def getWriteOptions(self) -> "dict[str, Any]": if self._writeOptions is None: - self._writeOptions = self.getOptionsFromClass(self.writerClass) + self._writeOptions = self._getOptionsFromClass(self.writerClass) return self._writeOptions @property @@ -490,35 +489,35 @@ def checkWriterClass(self) -> bool: return True - def getReadExtraOptions(self) -> "list[str]": # noqa: F811 - cls = self.readerClass - if cls is None: - return [] - return self.__class__.getExtraOptionsFromFunc(cls.open, self.name) - - def getWriteExtraOptions(self) -> "list[str]": # noqa: F811 - cls = self.writerClass - if cls is None: - return [] - return self.__class__.getExtraOptionsFromFunc(cls.write, self.name) - - @classmethod - def getExtraOptionsFromFunc( - cls: "type", - func: "Callable", - format: str, - ) -> "list[str]": - import inspect - - extraOptNames = [] - for name, param in inspect.signature(func).parameters.items(): - if name == "self": - continue - if str(param.default) != "": - extraOptNames.append(name) - continue - if name not in {"filename", "dirname"}: - extraOptNames.append(name) - if extraOptNames: - log.warning(f"{format}: {extraOptNames = }") - return extraOptNames + # def _getReadExtraOptions(self) -> "list[str]": # noqa: F811 + # cls = self.readerClass + # if cls is None: + # return [] + # return self.__class__.getExtraOptionsFromFunc(cls.open, self.name) + + # def _getWriteExtraOptions(self) -> "list[str]": # noqa: F811 + # cls = self.writerClass + # if cls is None: + # return [] + # return self.__class__.getExtraOptionsFromFunc(cls.write, self.name) + + # @classmethod + # def getExtraOptionsFromFunc( + # cls: "type", + # func: "Callable", + # format: str, + # ) -> "list[str]": + # import inspect + + # extraOptNames = [] + # for name, param in inspect.signature(func).parameters.items(): + # if name == "self": + # continue + # if str(param.default) != "": + # extraOptNames.append(name) + # continue + # if name not in {"filename", "dirname"}: + # extraOptNames.append(name) + # if extraOptNames: + # log.warning(f"{format}: {extraOptNames = }") + # return extraOptNames diff --git a/pyproject.toml b/pyproject.toml index af0dceb86..fffb58877 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,12 +9,12 @@ lint.select = [ # "C90", # mccabe: C901: {name} is too complex ({complexity}) "I", # isort: unsorted-imports, missing-required-import # "N", # pep8-naming - "D", # pydocstyle - "B", # flake8-bugbear - "UP", # pyupgrade + "D", # pydocstyle + "B", # flake8-bugbear + "UP", # pyupgrade "YTT", # flake8-2020 # "ANN", # flake8-annotationsq, still gives errors for `self` - # ASYNC, # flake8-async + # "ASYNC", # flake8-async "TRIO", # flake8-trio # "S", # flake8-bandit "BLE", # flake8-blind-except @@ -23,96 +23,95 @@ lint.select = [ # "A", # flake8-builtins "COM", # flake8-commas # "CPY", # flake8-copyright --preview - "C4", # flake8-comprehensions - "DTZ", # flake8-datetimez - "T10", # flake8-debugger - "DJ", # flake8-django - # "EM", # flake8-errmsg, WTF? - "EXE", # flake8-executable - "FA", # flake8-future-annotations - "ISC", # flake8-implicit-str-concat - "ICN", # flake8-import-conventions - "G", # flake8-logging-format - "INP", # flake8-no-pep420 - "PIE", # flake8-pie - "T20", # flake8-print - "PYI", # flake8-pyi - "PT", # flake8-pytest-style - "Q", # flake8-quotes - "RSE", # flake8-raise - "RET", # flake8-return - "SLF", # flake8-self - "SLOT", # flake8-slots - "SIM", # flake8-simplify - "TID", # flake8-tidy-imports - "TCH", # flake8-type-checking - "INT", # flake8-gettext - "ARG", # flake8-unused-arguments + "C4", # flake8-comprehensions + "DTZ", # flake8-datetimez + "T10", # flake8-debugger + "DJ", # flake8-django + "EXE", # flake8-executable + "FA", # flake8-future-annotations + "ISC", # flake8-implicit-str-concat + "ICN", # flake8-import-conventions + "G", # flake8-logging-format + "INP", # flake8-no-pep420 + "PIE", # flake8-pie + "T20", # flake8-print + "PYI", # flake8-pyi + "PT", # flake8-pytest-style + "Q", # flake8-quotes + "RSE", # flake8-raise + "RET", # flake8-return + "SLF", # flake8-self + "SLOT", # flake8-slots + "SIM", # flake8-simplify + "TID", # flake8-tidy-imports + "TCH", # flake8-type-checking + "INT", # flake8-gettext + "ARG", # flake8-unused-arguments # "PTH", # flake8-use-pathlib - # "TD", # flake8-todos - # "FIX", # flake8-fixme: just shows me FIXMEs and TODOs # "ERA", # eradicate - "PD", # pandas-vet - "PGH", # pygrep-hooks - "PL", # Pylint + "PD", # pandas-vet + "PGH", # pygrep-hooks + "PL", # Pylint # "TRY", # tryceratops, they all sound BS # "FLY", # flynt - "NPY", # NumPy-specific rules - "AIR", # Airflow - "PERF", # Perflint - # "FURB", # refurb --preview - "LOG", # flake8-logging - "RUF", # Ruff-specific rules + "NPY", # NumPy-specific rules + "AIR", # Airflow + "PERF", # Perflint + "FURB", # refurb --preview + "LOG", # flake8-logging + "RUF", # Ruff-specific rules ] lint.ignore = [ - "SLF", # Private member accessed + "SLF", # Private member accessed "PYI034", # py3.11: `__iadd__` methods in classes like `SqEntryList` usually return `self` at runtime "DTZ001", # The use of `datetime.datetime()` without `tzinfo` argument is not allowed "DTZ005", # The use of `datetime.datetime.now()` without `tz` argument is not allowed - "PGH003", # Use specific rule codes when ignoring type issues + "PGH003", # Use specific rule codes when ignoring type issues + "PLR0914", # Too many local variables, 17 cases, --preview + "PLR0917", # Too many positional arguments, 23 cases, --preview "PLR0912", # Too many branches, 38 cases "PLR0915", # Too many statements, 28 cases "PLR2004", # Magic value used in comparison, consider replacing `...` with a constant variable "PLC0415", # `import` should be at the top-level of a file "PLW0603", # Using the global statement to update `mockLog` is discouraged - "PT027", # Use `pytest.raises` instead of unittest-style `assertRaises`, why? - "PD011", # Use `.to_numpy()` instead of `.values`, WTF? - "ICN001", # `tkinter` should be imported as `tk`, WTF? - "RUF005", # Consider `[*_list, x]` instead of concatenation - "PT009", # Use a regular `assert` instead of unittest-style `assertEqual`, why? + "PT027", # Use `pytest.raises` instead of unittest-style `assertRaises`, why? + "PD011", # Use `.to_numpy()` instead of `.values`, WTF? + "ICN001", # `tkinter` should be imported as `tk`, WTF? + "RUF005", # Consider `[*_list, x]` instead of concatenation + "PT009", # Use a regular `assert` instead of unittest-style `assertEqual`, why? "PLR0911", # Too many return statements (x > 6) - "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar` - "BLE001", # Do not catch blind exception: `Exception` - "G004", # Logging statement uses f-string, WTF? - "TRY400", # Use `logging.exception` instead of `logging.error` - "TRY003", # Avoid specifying long messages outside the exception class, ??? - "RUF100", # Unused `noqa` directive (non-enabled: ...) + "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar` + "BLE001", # Do not catch blind exception: `Exception` + "G004", # Logging statement uses f-string, WTF? + "TRY400", # Use `logging.exception` instead of `logging.error` + "TRY003", # Avoid specifying long messages outside the exception class, ??? + "RUF100", # Unused `noqa` directive (non-enabled: ...) "FURB101", # `open` and `read` should be replaced by `Path(rootConfJsonFile).read_text()` - "B019", # Use of `functools.lru_cache` or `functools.cache` on methods can lead to memory leaks - "D100", # Missing docstring in public module - "D101", # Missing docstring in public class - "D102", # Missing docstring in public method - "D103", # Missing docstring in public function - "D104", # Missing docstring in public package - "D105", # Missing docstring in magic method - "D107", # Missing docstring in `__init__` - "D205", # 1 blank line required between summary line and description - "D206", # Docstring should be indented with spaces, not tabs - "D211", # (Do not enable) no-blank-line-before-class - "D212", # multi-line-summary-first-line, conflicts with D213:multi-line-summary-second-line - "D401", # First line of docstring should be in imperative mood - "D417", # Missing argument descriptions in the docstring - "E402", # Module level import not at top of file - "E721", # Do not compare types, use `isinstance()` - "SIM105", # Use contextlib.suppress({exception}) instead of try-except-pass - "SIM117", # Use a single with statement with multiple contexts... - "UP009", # UTF-8 encoding declaration is unnecessary - "UP037", # Remove quotes from type annotation - "W191", # Indentation contains tabs - "SIM110", # Use any(...) - "SIM115", # Use context handler for opening files + "B019", # Use of `functools.lru_cache` or `functools.cache` on methods can lead to memory leaks + "D100", # Missing docstring in public module + "D101", # Missing docstring in public class + "D102", # Missing docstring in public method + "D103", # Missing docstring in public function + "D104", # Missing docstring in public package + "D105", # Missing docstring in magic method + "D107", # Missing docstring in `__init__` + "D205", # 1 blank line required between summary line and description + "D206", # Docstring should be indented with spaces, not tabs + "D211", # (Do not enable) no-blank-line-before-class + "D212", # multi-line-summary-first-line, conflicts with D213:multi-line-summary-second-line + "D401", # First line of docstring should be in imperative mood + "D417", # Missing argument descriptions in the docstring + "E402", # Module level import not at top of file + "E721", # Do not compare types, use `isinstance()` + "SIM105", # Use contextlib.suppress({exception}) instead of try-except-pass + "SIM117", # Use a single with statement with multiple contexts... + "UP009", # UTF-8 encoding declaration is unnecessary + "UP037", # Remove quotes from type annotation + "W191", # Indentation contains tabs + "SIM110", # Use any(...) + "SIM115", # Use context handler for opening files # "SIM111", # Use all(...): warning: `SIM111` has been remapped to `SIM110`. # ERA, PD, "TCH003", # Move standard library import `...` into a type-checking block @@ -182,6 +181,9 @@ lint.dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" [tool.ruff.lint.per-file-ignores] +"pyglossary/plugins/**/*.py" = [ + "PLR0904", # Too many public methods +] "slob.py" = [ "PERF203", # `try`-`except` within a loop incurs performance overhead, FIXME ] @@ -198,24 +200,25 @@ lint.dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" "C901", # `...` is too complex ] - "pyglossary/html_utils.py" = ["RUF003"] "persian_utils.py" = ["RUF001"] "ru.py" = ["RUF001", "RUF003"] "pyglossary/plugins/dikt_json.py" = ["RUF003"] "pyglossary/plugin_lib/*.py" = [ "ANN", - "PT018", # Assertion should be broken down into multiple parts + "PT018", # Assertion should be broken down into multiple parts "D", - "RUF015", # Prefer `next(zip(*_list, strict=False))` over single element slice + "RUF015", # Prefer `next(zip(*_list, strict=False))` over single element slice "PLR2004", # Magic value used in comparison, consider replacing `...` with a constant variable ] "scripts/wiki-formats.py" = ["E501"] "pyglossary/io_utils.py" = ["ANN"] "pyglossary/plugins/babylon_bgl/bgl_reader_debug.py" = ["ANN", "FURB"] -"pyglossary/ui/*.py" = ["ANN", "T201", "PERF203"] -"pyglossary/ui/*/*.py" = ["ANN", "T201", "PERF203"] -"pyglossary/ui/ui_*.py" = [ +"pyglossary/ui/**/*.py" = [ + "ANN", + "T201", + "PERF203", + "PLR0904", # Too many public methods "PLR6301", # Method `...` could be a function, class method, or static method ] "tests/*.py" = [ @@ -226,7 +229,8 @@ lint.dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" "*_test.py" = [ "ANN", "T201", - "RUF001", # String contains ambiguous ... (ARABIC LETTER ...). Did you mean `l` ... + "RUF001", # String contains ambiguous ... (ARABIC LETTER ...). Did you mean `l` ... + "PLR0904", # Too many public methods ] "test.py" = ["ANN", "T201"] "scripts/*.py" = ["ANN", "T201", "INP001"] @@ -251,7 +255,7 @@ max-complexity = 20 [tool.mypy] exclude = [ - # '.*/plugin_lib/.*', + # '.*/plugin_lib/.*', ] [tool.refurb] @@ -315,10 +319,10 @@ disable = [ "useless-return", "method-cache-max-size-none", "global-statement", - "R0801", # Similar lines in 2 files - "ungrouped-imports", # C0412: Imports from package pyglossary are not grouped + "R0801", # Similar lines in 2 files + "ungrouped-imports", # C0412: Imports from package pyglossary are not grouped "inconsistent-return-statements", # R1710: Either all return statements in a function should return an expression, or none of them should - "too-many-ancestors", # R0901: Too many ancestors + "too-many-ancestors", # R0901: Too many ancestors ] [tool.pylint.master] @@ -343,12 +347,12 @@ exclude = [ "pyglossary/plugin_lib/", "pyglossary/text_utils_extra.py", ] -# ignore_decorators = ["@app.route", "@require_*"] +# ignore_decorators = ["@require_*"] ignore_names = [ "_*", "Generator", "GLOSSARY_API_VERSION", - # "Iterable", "AnyStr", + # "Iterable", "AnyStr", # "RawEntryType", # "EntryListType", ] @@ -359,6 +363,4 @@ sort_by_size = false verbose = false [tool.import-analyzer] -exclude = [ - "pyglossary/ui/wcwidth/", -] +exclude = ["pyglossary/ui/wcwidth/"]