diff --git a/ChangeLog b/ChangeLog index 1247fd8b25..eddc4aec2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,9 @@ Release date: TBA .. Put bug fixes that should not wait for a new minor version here +* ``unspecified-encoding`` now checks the encoding of ``pathlib.Path()`` correctly + + Closes #5017 What's New in Pylint 2.11.0? diff --git a/pylint/checkers/stdlib.py b/pylint/checkers/stdlib.py index bdc42d8a7f..a4cd88a4de 100644 --- a/pylint/checkers/stdlib.py +++ b/pylint/checkers/stdlib.py @@ -531,7 +531,7 @@ def visit_call(self, node: nodes.Call) -> None: or isinstance(node.func, nodes.Attribute) and node.func.attrname in OPEN_FILES_ENCODING ): - self._check_open_encoded(node) + self._check_open_encoded(node, inferred.root().name) elif inferred.root().name == UNITTEST_CASE: self._check_redundant_assert(node, inferred) elif isinstance(inferred, nodes.ClassDef): @@ -609,11 +609,18 @@ def _check_open_mode(self, node): ): self.add_message("bad-open-mode", node=node, args=mode_arg.value) - def _check_open_encoded(self, node: nodes.Call) -> None: + def _check_open_encoded(self, node: nodes.Call, open_module: str) -> None: """Check that the encoded argument of an open call is valid.""" mode_arg = None try: - mode_arg = utils.get_argument_from_call(node, position=1, keyword="mode") + if open_module == "_io": + mode_arg = utils.get_argument_from_call( + node, position=1, keyword="mode" + ) + elif open_module == "pathlib": + mode_arg = utils.get_argument_from_call( + node, position=0, keyword="mode" + ) except utils.NoSuchArgumentError: pass diff --git a/tests/functional/u/unspecified_encoding_py38.py b/tests/functional/u/unspecified_encoding_py38.py index 1b3ae37958..8f143474ba 100644 --- a/tests/functional/u/unspecified_encoding_py38.py +++ b/tests/functional/u/unspecified_encoding_py38.py @@ -72,3 +72,11 @@ Path(FILENAME).write_text("string") # [unspecified-encoding] Path(FILENAME).write_text("string", encoding=None) # [unspecified-encoding] Path(FILENAME).write_text("string", encoding=LOCALE_ENCODING) # [unspecified-encoding] + +LOCALE_ENCODING = locale.getlocale()[1] +Path(FILENAME).open("w+b") +Path(FILENAME).open() # [unspecified-encoding] +Path(FILENAME).open("wt") # [unspecified-encoding] +Path(FILENAME).open("w+") # [unspecified-encoding] +Path(FILENAME).open("w", encoding=None) # [unspecified-encoding] +Path(FILENAME).open("w", encoding=LOCALE_ENCODING) diff --git a/tests/functional/u/unspecified_encoding_py38.txt b/tests/functional/u/unspecified_encoding_py38.txt index 45bf15f5a9..832b3c7509 100644 --- a/tests/functional/u/unspecified_encoding_py38.txt +++ b/tests/functional/u/unspecified_encoding_py38.txt @@ -19,3 +19,7 @@ unspecified-encoding:65:0::Using open without explicitly specifying an encoding: unspecified-encoding:72:0::Using open without explicitly specifying an encoding:HIGH unspecified-encoding:73:0::Using open without explicitly specifying an encoding:HIGH unspecified-encoding:74:0::Using open without explicitly specifying an encoding:HIGH +unspecified-encoding:78:0::Using open without explicitly specifying an encoding:HIGH +unspecified-encoding:79:0::Using open without explicitly specifying an encoding:HIGH +unspecified-encoding:80:0::Using open without explicitly specifying an encoding:HIGH +unspecified-encoding:81:0::Using open without explicitly specifying an encoding:HIGH