[ruff] Activate pydocstyle and fix existing issues
diff --git a/examples/custom_raw.py b/examples/custom_raw.py
index 68e6855..5adb777 100644
--- a/examples/custom_raw.py
+++ b/examples/custom_raw.py
@@ -11,8 +11,8 @@
 
 
 class MyRawChecker(BaseRawFileChecker):
-    """Check for line continuations with '\' instead of using triple
-    quoted string or parenthesis
+    r"""Check for line continuations with '\' instead of using triple
+    quoted string or parenthesis.
     """
 
     name = "custom_raw"
diff --git a/pylint/checkers/base/comparison_checker.py b/pylint/checkers/base/comparison_checker.py
index 14d40c7..6fb053e 100644
--- a/pylint/checkers/base/comparison_checker.py
+++ b/pylint/checkers/base/comparison_checker.py
@@ -89,7 +89,6 @@
         checking_for_absence: bool = False,
     ) -> None:
         """Check if == or != is being used to compare a singleton value."""
-
         if utils.is_singleton_const(left_value):
             singleton, other_value = left_value.value, right_value
         elif utils.is_singleton_const(right_value):
diff --git a/pylint/checkers/classes/class_checker.py b/pylint/checkers/classes/class_checker.py
index d77465b..ffe47ab 100644
--- a/pylint/checkers/classes/class_checker.py
+++ b/pylint/checkers/classes/class_checker.py
@@ -454,7 +454,6 @@
     Returns ``True`` if the name is a property in the given klass,
     ``False`` otherwise.
     """
-
     try:
         attributes = klass.getattr(name)
     except astroid.NotFoundError:
@@ -748,7 +747,6 @@
 
     def set_accessed(self, node: _AccessNodes) -> None:
         """Set the given node as accessed."""
-
         frame = node_frame_class(node)
         if frame is None:
             # The node does not live in a class.
@@ -1946,7 +1944,6 @@
         Returns ``True`` if the name is a property in the given klass,
         ``False`` otherwise.
         """
-
         if utils.is_class_attr(name, klass):
             return True
 
diff --git a/pylint/checkers/deprecated.py b/pylint/checkers/deprecated.py
index 3428e73..028dc13 100644
--- a/pylint/checkers/deprecated.py
+++ b/pylint/checkers/deprecated.py
@@ -236,7 +236,6 @@
 
         This method should be called from the checker implementing this mixin.
         """
-
         # Reject nodes which aren't of interest to us.
         if not isinstance(inferred, ACCEPTABLE_NODES):
             return
@@ -272,7 +271,6 @@
         self, node: nodes.NodeNG, mod_name: str, class_names: Iterable[str]
     ) -> None:
         """Checks if the class is deprecated."""
-
         for class_name in class_names:
             if class_name in self.deprecated_classes(mod_name):
                 self.add_message(
@@ -281,7 +279,6 @@
 
     def check_deprecated_class_in_call(self, node: nodes.Call) -> None:
         """Checks if call the deprecated class."""
-
         if isinstance(node.func, nodes.Attribute) and isinstance(
             node.func.expr, nodes.Name
         ):
diff --git a/pylint/checkers/design_analysis.py b/pylint/checkers/design_analysis.py
index de9cac6..78378e9 100644
--- a/pylint/checkers/design_analysis.py
+++ b/pylint/checkers/design_analysis.py
@@ -185,7 +185,6 @@
 
 def _is_exempt_from_public_methods(node: astroid.ClassDef) -> bool:
     """Check if a class is exempt from too-few-public-methods."""
-
     # If it's a typing.Namedtuple, typing.TypedDict or an Enum
     for ancestor in node.ancestors():
         if is_enum(ancestor):
diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py
index c68877a..afef027 100644
--- a/pylint/checkers/imports.py
+++ b/pylint/checkers/imports.py
@@ -1079,7 +1079,6 @@
 
     def _check_preferred_module(self, node: ImportNode, mod_path: str) -> None:
         """Check if the module has a preferred replacement."""
-
         mod_compare = [mod_path]
         # build a comparison list of possible names using importfrom
         if isinstance(node, astroid.nodes.node_classes.ImportFrom):
diff --git a/pylint/checkers/non_ascii_names.py b/pylint/checkers/non_ascii_names.py
index 825db1b..693d852 100644
--- a/pylint/checkers/non_ascii_names.py
+++ b/pylint/checkers/non_ascii_names.py
@@ -65,7 +65,6 @@
 
     def _check_name(self, node_type: str, name: str | None, node: nodes.NodeNG) -> None:
         """Check whether a name is using non-ASCII characters."""
-
         if name is None:
             # For some nodes i.e. *kwargs from a dict, the name will be empty
             return
diff --git a/pylint/checkers/refactoring/recommendation_checker.py b/pylint/checkers/refactoring/recommendation_checker.py
index a1e4108..c5b19e1 100644
--- a/pylint/checkers/refactoring/recommendation_checker.py
+++ b/pylint/checkers/refactoring/recommendation_checker.py
@@ -113,7 +113,6 @@
         """Add message when accessing first or last elements of a str.split() or
         str.rsplit().
         """
-
         # Check if call is split() or rsplit()
         if not (
             isinstance(node.func, nodes.Attribute)
diff --git a/pylint/checkers/refactoring/refactoring_checker.py b/pylint/checkers/refactoring/refactoring_checker.py
index edfff03..24d13c3 100644
--- a/pylint/checkers/refactoring/refactoring_checker.py
+++ b/pylint/checkers/refactoring/refactoring_checker.py
@@ -586,7 +586,6 @@
         the result of the statement's test, then this can be reduced
         to `bool(test)` without losing any functionality.
         """
-
         if self._is_actual_elif(node):
             # Not interested in if statements with multiple branches.
             return
diff --git a/pylint/checkers/similar.py b/pylint/checkers/similar.py
index 6aa0f7c..b06b9d7 100644
--- a/pylint/checkers/similar.py
+++ b/pylint/checkers/similar.py
@@ -611,7 +611,6 @@
             """Recursively get all functions including nested in the classes from the
             tree.
             """
-
             for node in tree.body:
                 if isinstance(node, (nodes.FunctionDef, nodes.AsyncFunctionDef)):
                     functions.append(node)
diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py
index 814c392..56bd729 100644
--- a/pylint/checkers/typecheck.py
+++ b/pylint/checkers/typecheck.py
@@ -1228,7 +1228,6 @@
     )
     def visit_assign(self, node: nodes.Assign) -> None:
         """Process assignments in the AST."""
-
         self._check_assignment_from_function_call(node)
         self._check_dundername_is_string(node)
 
@@ -1309,7 +1308,6 @@
 
     def _check_dundername_is_string(self, node: nodes.Assign) -> None:
         """Check a string is assigned to self.__name__."""
-
         # Check the left-hand side of the assignment is <something>.__name__
         lhs = node.targets[0]
         if not isinstance(lhs, nodes.AssignAttr):
@@ -1926,7 +1924,6 @@
     @only_required_for_messages("invalid-unary-operand-type")
     def visit_unaryop(self, node: nodes.UnaryOp) -> None:
         """Detect TypeErrors for unary operands."""
-
         for error in node.type_errors():
             # Let the error customize its output.
             self.add_message("invalid-unary-operand-type", args=str(error), node=node)
diff --git a/pylint/checkers/unicode.py b/pylint/checkers/unicode.py
index deb8186..c90ace9 100644
--- a/pylint/checkers/unicode.py
+++ b/pylint/checkers/unicode.py
@@ -165,7 +165,6 @@
     Also takes care of encodings for which the length of an encoded code point does not
     default to 8 Bit.
     """
-
     result: dict[int, _BadChar] = {}
 
     for search_for, char in search_dict.items():
@@ -248,7 +247,7 @@
 
 
 def _fix_utf16_32_line_stream(steam: Iterable[bytes], codec: str) -> Iterable[bytes]:
-    """Handle line ending for UTF16 and UTF32 correctly.
+    r"""Handle line ending for UTF16 and UTF32 correctly.
 
     Currently, Python simply strips the required zeros after \n after the
     line ending. Leading to lines that can't be decoded properly
diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py
index 130e8a2..a3e6496 100644
--- a/pylint/checkers/utils.py
+++ b/pylint/checkers/utils.py
@@ -1484,7 +1484,6 @@
 
 def is_registered_in_singledispatch_function(node: nodes.FunctionDef) -> bool:
     """Check if the given function node is a singledispatch function."""
-
     singledispatch_qnames = (
         "functools.singledispatch",
         "singledispatch.singledispatch",
@@ -1540,7 +1539,6 @@
 
 def is_registered_in_singledispatchmethod_function(node: nodes.FunctionDef) -> bool:
     """Check if the given function node is a singledispatchmethod function."""
-
     singledispatchmethod_qnames = (
         "functools.singledispatchmethod",
         "singledispatch.singledispatchmethod",
@@ -2276,7 +2274,6 @@
     """Return `True` if `node` is an Enum member (is an item of the
     `__members__` container).
     """
-
     frame = node.frame()
     if (
         not isinstance(frame, nodes.ClassDef)
diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py
index ebc27c1..0a5a60c 100644
--- a/pylint/checkers/variables.py
+++ b/pylint/checkers/variables.py
@@ -1017,7 +1017,6 @@
         the loop can depend on it being assigned.
 
         Example:
-
         for _ in range(3):
             try:
                 do_something()
diff --git a/pylint/extensions/empty_comment.py b/pylint/extensions/empty_comment.py
index 61e257f..7f54322 100644
--- a/pylint/extensions/empty_comment.py
+++ b/pylint/extensions/empty_comment.py
@@ -16,7 +16,6 @@
 
 def is_line_commented(line: bytes) -> bool:
     """Checks if a `# symbol that is not part of a string was found in line."""
-
     comment_idx = line.find(b"#")
     if comment_idx == -1:
         return False
@@ -27,7 +26,6 @@
 
 def comment_part_of_string(line: bytes, comment_idx: int) -> bool:
     """Checks if the symbol at comment_idx is part of a string."""
-
     if (
         line[:comment_idx].count(b"'") % 2 == 1
         and line[comment_idx:].count(b"'") % 2 == 1
diff --git a/pylint/lint/__init__.py b/pylint/lint/__init__.py
index adc9207..1c0c6d9 100644
--- a/pylint/lint/__init__.py
+++ b/pylint/lint/__init__.py
@@ -4,15 +4,15 @@
 
 """Pylint [options] modules_or_packages.
 
-  Check that module(s) satisfy a coding standard (and more !).
+Check that module(s) satisfy a coding standard (and more !).
 
-    pylint --help
+pylint --help
 
-  Display this help message and exit.
+Display this help message and exit.
 
-    pylint --help-msg <msg-id>[,<msg-id>]
+pylint --help-msg <msg-id>[,<msg-id>]
 
-  Display help messages about given message identifiers and exit.
+Display help messages about given message identifiers and exit.
 """
 import sys
 
diff --git a/pylint/pyreverse/diadefslib.py b/pylint/pyreverse/diadefslib.py
index 3b76948..88aea48 100644
--- a/pylint/pyreverse/diadefslib.py
+++ b/pylint/pyreverse/diadefslib.py
@@ -222,7 +222,6 @@
         :returns: The list of diagram definitions
         :rtype: list(:class:`pylint.pyreverse.diagrams.ClassDiagram`)
         """
-
         #  read and interpret diagram definitions (Diadefs)
         diagrams = []
         generator = ClassDiadefGenerator(linker, self)
diff --git a/pylint/pyreverse/utils.py b/pylint/pyreverse/utils.py
index cf2a0ab..bdd28dc 100644
--- a/pylint/pyreverse/utils.py
+++ b/pylint/pyreverse/utils.py
@@ -218,7 +218,6 @@
     """Return a set containing the node annotation if it exists
     otherwise return a set of the inferred types using the NodeNG.infer method.
     """
-
     ann = get_annotation(node)
     try:
         if ann:
diff --git a/pylint/utils/utils.py b/pylint/utils/utils.py
index 2f30b95..203c543 100644
--- a/pylint/utils/utils.py
+++ b/pylint/utils/utils.py
@@ -209,7 +209,7 @@
 
 
 def _splitstrip(string: str, sep: str = ",") -> list[str]:
-    """Return a list of stripped string by splitting the string given as
+    r"""Return a list of stripped string by splitting the string given as
     argument on `sep` (',' by default), empty strings are discarded.
 
     >>> _splitstrip('a, b, c   ,  4,,')
@@ -254,7 +254,8 @@
 
 def _check_regexp_csv(value: list[str] | tuple[str] | str) -> Iterable[str]:
     r"""Split a comma-separated list of regexps, taking care to avoid splitting
-    a regex employing a comma as quantifier, as in `\d{1,2}`."""
+    a regex employing a comma as quantifier, as in `\d{1,2}`.
+    """
     if isinstance(value, (list, tuple)):
         yield from value
     else:
diff --git a/pyproject.toml b/pyproject.toml
index 32ef9dc..07a4291 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -147,6 +147,7 @@
 [tool.ruff.lint]
 select = [
     "B",  # bugbear
+    "D",  # pydocstyle
     "E",  # pycodestyle
     "F",  # pyflakes
     "I",  # isort
@@ -159,5 +160,19 @@
 
 ignore = [
     "B905",  # `zip()` without an explicit `strict=` parameter
+    "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
+    "D106",  # Missing docstring in public nested class
+    "D107",  # Missing docstring in `__init__`
+    "D205",  # 1 blank line required between summary line and description
+    "D400",  # First line should end with a period
+    "D401",  # First line of docstring should be in imperative mood
     "RUF012",  # mutable default values in class attributes
 ]
+
+[tool.ruff.lint.pydocstyle]
+convention = "pep257"
diff --git a/tests/checkers/unittest_design.py b/tests/checkers/unittest_design.py
index 379fee5..1f3df78 100644
--- a/tests/checkers/unittest_design.py
+++ b/tests/checkers/unittest_design.py
@@ -19,7 +19,6 @@
         """Make sure that classes listed in ``ignored-parents`` aren't counted
         by the too-many-ancestors message.
         """
-
         node = astroid.extract_node(
             """
         class Aaaa(object):
diff --git a/tests/checkers/unittest_format.py b/tests/checkers/unittest_format.py
index dfaf037..c0659ad 100644
--- a/tests/checkers/unittest_format.py
+++ b/tests/checkers/unittest_format.py
@@ -157,7 +157,7 @@
 
 def test_disable_global_option_end_of_line() -> None:
     """Test for issue with disabling tokenizer messages
-    that extend beyond the scope of the ast tokens
+    that extend beyond the scope of the ast tokens.
     """
     file_ = tempfile.NamedTemporaryFile("w", delete=False)
     with file_:
diff --git a/tests/checkers/unittest_imports.py b/tests/checkers/unittest_imports.py
index 4a8d6e5..2a5547d 100644
--- a/tests/checkers/unittest_imports.py
+++ b/tests/checkers/unittest_imports.py
@@ -117,9 +117,7 @@
 
     @staticmethod
     def test_preferred_module(capsys: CaptureFixture[str]) -> None:
-        """
-        Tests preferred-module configuration option
-        """
+        """Tests preferred-module configuration option."""
         # test preferred-modules case with base module import
         Run(
             [
@@ -212,7 +210,6 @@
     @staticmethod
     def test_allow_reexport_package(capsys: CaptureFixture[str]) -> None:
         """Test --allow-reexport-from-package option."""
-
         # Option disabled - useless-import-alias should always be emitted
         Run(
             [
diff --git a/tests/checkers/unittest_spelling.py b/tests/checkers/unittest_spelling.py
index 08c1fa0..71fed57 100644
--- a/tests/checkers/unittest_spelling.py
+++ b/tests/checkers/unittest_spelling.py
@@ -335,7 +335,8 @@
     )
     def test_tool_directives_handling(self, prefix: str, suffix: str) -> None:
         """We're not raising when the directive is at the beginning of comments,
-        but we raise if a directive appears later in comment."""
+        but we raise if a directive appears later in comment.
+        """
         full_comment = f"# {prefix}{suffix} {prefix}"
         args = (
             prefix,
diff --git a/tests/checkers/unittest_unicode/unittest_bad_chars.py b/tests/checkers/unittest_unicode/unittest_bad_chars.py
index e5cdcfe..1009eba 100644
--- a/tests/checkers/unittest_unicode/unittest_bad_chars.py
+++ b/tests/checkers/unittest_unicode/unittest_bad_chars.py
@@ -219,7 +219,7 @@
         codec_and_msg: tuple[str, tuple[pylint.testutils.MessageTest]],
     ) -> None:
         """Special test for a file containing chars that lead to
-        Python or Astroid crashes (which causes Pylint to exit early)
+        Python or Astroid crashes (which causes Pylint to exit early).
         """
         codec, start_msg = codec_and_msg
         # Create file that will fail loading in astroid.
diff --git a/tests/checkers/unittest_unicode/unittest_bidirectional_unicode.py b/tests/checkers/unittest_unicode/unittest_bidirectional_unicode.py
index 95b2b46..91e4f36 100644
--- a/tests/checkers/unittest_unicode/unittest_bidirectional_unicode.py
+++ b/tests/checkers/unittest_unicode/unittest_bidirectional_unicode.py
@@ -27,11 +27,10 @@
 
     def test_finds_bidirectional_unicode_that_currently_not_parsed(self) -> None:
         """Test an example from https://github.com/nickboucher/trojan-source/tree/main/Python
-        that is currently not working Python but producing a syntax error
+        that is currently not working Python but producing a syntax error.
 
         So we test this to make sure it stays like this
         """
-
         test_file = UNICODE_TESTS / "invisible_function.txt"
 
         with pytest.raises(astroid.AstroidSyntaxError):
diff --git a/tests/checkers/unittest_variables.py b/tests/checkers/unittest_variables.py
index 858873a..f43a712 100644
--- a/tests/checkers/unittest_variables.py
+++ b/tests/checkers/unittest_variables.py
@@ -164,7 +164,7 @@
 
     def test_nested_lambda(self) -> None:
         """Make sure variables from parent lambdas
-        aren't noted as undefined
+        aren't noted as undefined.
 
         https://github.com/pylint-dev/pylint/issues/760
         """
@@ -179,7 +179,7 @@
     @set_config(ignored_argument_names=re.compile("arg"))
     def test_ignored_argument_names_no_message(self) -> None:
         """Make sure is_ignored_argument_names properly ignores
-        function arguments
+        function arguments.
         """
         node = astroid.parse(
             """
diff --git a/tests/config/test_argparse_config.py b/tests/config/test_argparse_config.py
index dfa0fd4..b818b7a 100644
--- a/tests/config/test_argparse_config.py
+++ b/tests/config/test_argparse_config.py
@@ -2,7 +2,7 @@
 # For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE
 # Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt
 
-"""Test for the (new) implementation of option parsing with argparse"""
+"""Test for the (new) implementation of option parsing with argparse."""
 
 import re
 from os.path import abspath, dirname, join
diff --git a/tests/config/test_find_default_config_files.py b/tests/config/test_find_default_config_files.py
index 6a8095c..ae879a1 100644
--- a/tests/config/test_find_default_config_files.py
+++ b/tests/config/test_find_default_config_files.py
@@ -24,7 +24,7 @@
 
 @pytest.fixture
 def pop_pylintrc() -> None:
-    """Remove the PYLINTRC environment variable"""
+    """Remove the PYLINTRC environment variable."""
     os.environ.pop("PYLINTRC", None)
 
 
@@ -166,7 +166,7 @@
 
 @pytest.mark.usefixtures("pop_pylintrc")
 def test_pyproject_toml_parentdir() -> None:
-    """Test the search of pyproject.toml file in parent directories"""
+    """Test the search of pyproject.toml file in parent directories."""
     with tempdir() as chroot:
         with fake_home():
             chroot_path = Path(chroot)
diff --git a/tests/extensions/test_private_import.py b/tests/extensions/test_private_import.py
index a10384e..156025e 100644
--- a/tests/extensions/test_private_import.py
+++ b/tests/extensions/test_private_import.py
@@ -2,7 +2,7 @@
 # For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE
 # Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt
 
-"""Tests the local module directory comparison logic which requires mocking file directories"""
+"""Tests the local module directory comparison logic which requires mocking file directories."""
 
 from unittest.mock import MagicMock, patch
 
@@ -14,7 +14,7 @@
 
 
 class TestPrivateImport(CheckerTestCase):
-    """The mocked dirname is the directory of the file being linted, the node is code inside that file"""
+    """The mocked dirname is the directory of the file being linted, the node is code inside that file."""
 
     CHECKER_CLASS = private_import.PrivateImportChecker
 
diff --git a/tests/lint/unittest_lint.py b/tests/lint/unittest_lint.py
index 00e410b..119dd84 100644
--- a/tests/lint/unittest_lint.py
+++ b/tests/lint/unittest_lint.py
@@ -1171,7 +1171,7 @@
 
 
 def test_relative_imports(initialized_linter: PyLinter) -> None:
-    """Regression test for https://github.com/pylint-dev/pylint/issues/3651"""
+    """Regression test for https://github.com/pylint-dev/pylint/issues/3651."""
     linter = initialized_linter
     with tempdir() as tmpdir:
         create_files(["x/y/__init__.py", "x/y/one.py", "x/y/two.py"], tmpdir)
@@ -1204,7 +1204,8 @@
 
 def test_import_sibling_module_from_namespace(initialized_linter: PyLinter) -> None:
     """If the parent directory above `namespace` is on sys.path, ensure that
-    modules under `namespace` can import each other without raising `import-error`."""
+    modules under `namespace` can import each other without raising `import-error`.
+    """
     linter = initialized_linter
     with tempdir() as tmpdir:
         create_files(["namespace/submodule1.py", "namespace/submodule2.py"])
@@ -1226,7 +1227,7 @@
 
 
 def test_lint_namespace_package_under_dir(initialized_linter: PyLinter) -> None:
-    """Regression test for https://github.com/pylint-dev/pylint/issues/1667"""
+    """Regression test for https://github.com/pylint-dev/pylint/issues/1667."""
     linter = initialized_linter
     with tempdir():
         create_files(["outer/namespace/__init__.py", "outer/namespace/module.py"])
@@ -1236,7 +1237,8 @@
 
 def test_lint_namespace_package_under_dir_on_path(initialized_linter: PyLinter) -> None:
     """If the directory above a namespace package is on sys.path,
-    the namespace module under it is linted."""
+    the namespace module under it is linted.
+    """
     linter = initialized_linter
     with tempdir() as tmpdir:
         create_files(["namespace_on_path/submodule1.py"])
diff --git a/tests/pyreverse/test_diadefs.py b/tests/pyreverse/test_diadefs.py
index cdcdea7..2b8bd5e 100644
--- a/tests/pyreverse/test_diadefs.py
+++ b/tests/pyreverse/test_diadefs.py
@@ -160,7 +160,7 @@
         self, default_config: PyreverseConfig, get_project: GetProjectCallable
     ) -> None:
         """Functional test of relations extraction;
-        different classes possibly in different modules
+        different classes possibly in different modules.
         """
         # XXX should be catching pyreverse environment problem but doesn't
         # pyreverse doesn't extract the relations but this test ok
diff --git a/tests/pyreverse/test_main.py b/tests/pyreverse/test_main.py
index 1721d89..e8e46df 100644
--- a/tests/pyreverse/test_main.py
+++ b/tests/pyreverse/test_main.py
@@ -59,7 +59,7 @@
 @pytest.mark.usefixtures("setup_path")
 def test_project_root_in_sys_path() -> None:
     """Test the context manager adds the project root directory to sys.path.
-    This should happen when pyreverse is run from any directory
+    This should happen when pyreverse is run from any directory.
     """
     with augmented_sys_path([discover_package_path(TEST_DATA_DIR, [])]):
         assert sys.path == [PROJECT_ROOT_DIR]
diff --git a/tests/pyreverse/test_utils.py b/tests/pyreverse/test_utils.py
index ef843fd..6a6afc1 100644
--- a/tests/pyreverse/test_utils.py
+++ b/tests/pyreverse/test_utils.py
@@ -107,7 +107,7 @@
 @patch("astroid.nodes.NodeNG.infer", side_effect=astroid.InferenceError)
 def test_infer_node_1(mock_infer: Any, mock_get_annotation: Any) -> None:
     """Return set() when astroid.InferenceError is raised and an annotation has
-    not been returned
+    not been returned.
     """
     mock_get_annotation.return_value = None
     node = astroid.extract_node("a: str = 'mystr'")
@@ -120,7 +120,7 @@
 @patch("astroid.nodes.NodeNG.infer")
 def test_infer_node_2(mock_infer: Any, mock_get_annotation: Any) -> None:
     """Return set(node.infer()) when InferenceError is not raised and an
-    annotation has not been returned
+    annotation has not been returned.
     """
     mock_get_annotation.return_value = None
     node = astroid.extract_node("a: str = 'mystr'")
@@ -131,7 +131,7 @@
 
 def test_infer_node_3() -> None:
     """Return a set containing a nodes.ClassDef object when the attribute
-    has a type annotation
+    has a type annotation.
     """
     node = astroid.extract_node(
         """
@@ -150,7 +150,7 @@
 
 def test_infer_node_4() -> None:
     """Verify the label for an argument with a typehint of the type
-    nodes.Subscript
+    nodes.Subscript.
     """
     node = astroid.extract_node(
         """
diff --git a/tests/reporters/unittest_reporting.py b/tests/reporters/unittest_reporting.py
index 6273f70..015401a 100644
--- a/tests/reporters/unittest_reporting.py
+++ b/tests/reporters/unittest_reporting.py
@@ -84,7 +84,7 @@
 def test_template_option_non_existing(linter: PyLinter) -> None:
     """Test the msg-template option with non-existent options.
     This makes sure that this option remains backwards compatible as new
-    parameters do not break on previous versions
+    parameters do not break on previous versions.
     """
     output = StringIO()
     linter.reporter.out = output
@@ -309,8 +309,7 @@
 
 
 def test_multi_reporter_independant_messages() -> None:
-    """Messages should not be modified by multiple reporters"""
-
+    """Messages should not be modified by multiple reporters."""
     check_message = "Not modified"
 
     class ReporterModify(BaseReporter):
diff --git a/tests/test_check_parallel.py b/tests/test_check_parallel.py
index 0ae3b1a..969fde3 100644
--- a/tests/test_check_parallel.py
+++ b/tests/test_check_parallel.py
@@ -263,7 +263,7 @@
         assert stats.warning == 0
 
     def test_linter_with_unpickleable_plugins_is_pickleable(self) -> None:
-        """The linter needs to be pickle-able in order to be passed between workers"""
+        """The linter needs to be pickle-able in order to be passed between workers."""
         linter = PyLinter(reporter=Reporter())
         # We load an extension that we know is not pickle-safe
         linter.load_plugin_modules(["pylint.extensions.overlapping_exceptions"])
@@ -479,7 +479,6 @@
         This test becomes more important if we want to change how we parameterize the
         checkers, for example if we aim to batch the files across jobs.
         """
-
         # define the stats we expect to get back from the runs, these should only vary
         # with the number of files.
         expected_stats = LinterStats(
@@ -572,7 +571,6 @@
 
         Checks regression of https://github.com/pylint-dev/pylint/issues/4118
         """
-
         # define the stats we expect to get back from the runs, these should only vary
         # with the number of files.
         file_infos = _gen_file_datas(num_files)
diff --git a/tests/test_func.py b/tests/test_func.py
index 351acce..99805d1 100644
--- a/tests/test_func.py
+++ b/tests/test_func.py
@@ -29,7 +29,7 @@
     self: Exception, ex: Exception  # pylint: disable=unused-argument
 ) -> str:
     """Function used to replace default __str__ method of exception instances
-    This function is not typed because it is legacy code
+    This function is not typed because it is legacy code.
     """
     return f"in {ex.file}\n:: {', '.join(ex.args)}"  # type: ignore[attr-defined] # Defined in the caller
 
diff --git a/tests/test_regr.py b/tests/test_regr.py
index 19fc009..850dfa5 100644
--- a/tests/test_regr.py
+++ b/tests/test_regr.py
@@ -3,7 +3,7 @@
 # Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt
 
 """Non regression tests for pylint, which requires a too specific configuration
-to be incorporated in the automatic functional test framework
+to be incorporated in the automatic functional test framework.
 """
 
 # pylint: disable=redefined-outer-name
diff --git a/tests/test_self.py b/tests/test_self.py
index 0291e9c..74da8e8 100644
--- a/tests/test_self.py
+++ b/tests/test_self.py
@@ -885,7 +885,8 @@
     @staticmethod
     def test_plugin_that_imports_from_open() -> None:
         """Test that a plugin that imports a source file from a checker open()
-        function (ala pylint_django) does not raise an exception."""
+        function (ala pylint_django) does not raise an exception.
+        """
         with _test_sys_path():
             # Enable --load-plugins=importing_plugin
             sys.path.append(join(HERE, "regrtest_data", "importing_plugin"))
@@ -1140,7 +1141,7 @@
     def test_regex_paths_csv_validator() -> None:
         """Test to see if _regexp_paths_csv_validator works.
         Previously the validator crashed when encountering already validated values.
-        Reported in https://github.com/pylint-dev/pylint/issues/5437
+        Reported in https://github.com/pylint-dev/pylint/issues/5437.
         """
         with pytest.raises(SystemExit) as ex:
             args = _add_rcfile_default_pylintrc(
@@ -1165,14 +1166,14 @@
         assert not ex.value.code % 2
 
     def test_recursive(self) -> None:
-        """Tests if running linter over directory using --recursive=y"""
+        """Tests if running linter over directory using --recursive=y."""
         self._runtest(
             [join(HERE, "regrtest_data", "directory", "subdirectory"), "--recursive=y"],
             code=0,
         )
 
     def test_recursive_globbing(self) -> None:
-        """Tests if running linter over directory using --recursive=y and globbing"""
+        """Tests if running linter over directory using --recursive=y and globbing."""
         self._runtest(
             [join(HERE, "regrtest_data", "d?rectory", "subd*"), "--recursive=y"],
             code=0,
@@ -1244,7 +1245,7 @@
                 )
 
     def test_ignore_path_recursive_current_dir(self) -> None:
-        """Tests that path is normalized before checked that is ignored. GitHub issue #6964"""
+        """Tests that path is normalized before checked that is ignored. GitHub issue #6964."""
         with _test_sys_path():
             # pytest is including directory HERE/regrtest_data to sys.path which causes
             # astroid to believe that directory is a package.
@@ -1284,7 +1285,7 @@
         )
 
     def test_line_too_long_useless_suppression(self) -> None:
-        """A test that demonstrates a known false positive for useless-suppression
+        """A test that demonstrates a known false positive for useless-suppression.
 
         See https://github.com/pylint-dev/pylint/issues/3368
 
@@ -1315,7 +1316,8 @@
 
     def test_no_name_in_module(self) -> None:
         """Test that a package with both a variable name `base` and a module `base`
-        does not emit a no-name-in-module msg."""
+        does not emit a no-name-in-module msg.
+        """
         module = join(HERE, "regrtest_data", "test_no_name_in_module.py")
         unexpected = "No name 'errors' in module 'list' (no-name-in-module)"
         self._test_output(
@@ -1509,7 +1511,8 @@
     @staticmethod
     def test_errors_only_functions_as_disable() -> None:
         """--errors-only functions as a shortcut for --disable=W,C,R,I;
-        it no longer enables any messages."""
+        it no longer enables any messages.
+        """
         run = Run(
             [str(UNNECESSARY_LAMBDA), "--disable=import-error", "--errors-only"],
             exit=False,
diff --git a/tests/test_similar.py b/tests/test_similar.py
index 8a09b45..4c12d43 100644
--- a/tests/test_similar.py
+++ b/tests/test_similar.py
@@ -225,7 +225,8 @@
 
     def test_duplicate_code_raw_strings_disable_scope_function(self) -> None:
         """Tests disabling duplicate-code at an inner scope level with another scope with
-        similarity."""
+        similarity.
+        """
         path = join(DATA, "raw_strings_disable_scope_second_function")
         expected_output = "Similar lines in 2 files"
         self._test_output(
diff --git a/tests/testutils/_primer/test_primer.py b/tests/testutils/_primer/test_primer.py
index 869ae6a..798b5a4 100644
--- a/tests/testutils/_primer/test_primer.py
+++ b/tests/testutils/_primer/test_primer.py
@@ -2,7 +2,7 @@
 # For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE
 # Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt
 
-"""Test the primer commands. """
+"""Test the primer commands."""
 from __future__ import annotations
 
 import sys
@@ -55,7 +55,8 @@
     def test_compare(self, directory: Path) -> None:
         """Test for the standard case.
 
-        Directory in 'fixtures/' with 'main.json', 'pr.json' and 'expected.txt'."""
+        Directory in 'fixtures/' with 'main.json', 'pr.json' and 'expected.txt'.
+        """
         self.__assert_expected(directory)
 
     def test_compare_batched(self) -> None: