Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-pylint for openSUSE:Factory checked in at 2023-12-18 22:56:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pylint (Old) and /work/SRC/openSUSE:Factory/.python-pylint.new.9037 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pylint" Mon Dec 18 22:56:05 2023 rev:40 rq:1133805 version:3.0.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pylint/python-pylint.changes 2023-11-27 22:45:32.322622379 +0100 +++ /work/SRC/openSUSE:Factory/.python-pylint.new.9037/python-pylint.changes 2023-12-18 22:56:16.248331872 +0100 @@ -1,0 +2,22 @@ +Mon Dec 18 08:23:50 UTC 2023 - Dirk Müller <[email protected]> + +- update to 3.0.3: + * Fixed false positive for ``unnecessary-lambda`` when the call + has keyword arguments but not the lambda. + * Fixed incorrect suggestion for shallow copy in unnecessary- + comprehension + * After changing b = [x for x in a] to b = a based on the + suggestion, the script now prints [0, 2, 3]. The correct + suggestion should be use list(a) to preserve the original + behavior. + * Fix false positives for ``undefined-variable`` and ``unused- + argument`` for classes and functions using Python 3.12 generic + type syntax. + * Fixed ``pointless-string-statement`` false positive for + docstrings on Python 3.12 type aliases. + * Fix false positive for ``invalid-exception-operation`` when + concatenating tuples of exception types. + * Fix a bug where pylint was unable to walk recursively through + a directory if the directory has an `__init__.py` file. + +------------------------------------------------------------------- Old: ---- pylint-3.0.2-gh.tar.gz New: ---- pylint-3.0.3-gh.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pylint.spec ++++++ --- /var/tmp/diff_new_pack.AylRzd/_old 2023-12-18 22:56:17.324371279 +0100 +++ /var/tmp/diff_new_pack.AylRzd/_new 2023-12-18 22:56:17.328371425 +0100 @@ -19,7 +19,7 @@ %{?sle15_python_module_pythons} %bcond_without tests Name: python-pylint -Version: 3.0.2 +Version: 3.0.3 Release: 0 Summary: Syntax and style checker for Python code License: GPL-2.0-or-later ++++++ pylint-3.0.2-gh.tar.gz -> pylint-3.0.3-gh.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/doc/data/messages/i/implicit-str-concat/details.rst new/pylint-3.0.3/doc/data/messages/i/implicit-str-concat/details.rst --- old/pylint-3.0.2/doc/data/messages/i/implicit-str-concat/details.rst 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/doc/data/messages/i/implicit-str-concat/details.rst 2023-12-11 14:16:40.000000000 +0100 @@ -11,7 +11,7 @@ .. code-block:: toml [STRING_CONSTANT] - check-str-concat-over-line-jumps = yes + check-str-concat-over-line-jumps = true However, the drawback of this setting is that it will trigger false positive for string parameters passed on multiple lines in function calls: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/doc/data/messages/p/pointless-string-statement/related.rst new/pylint-3.0.3/doc/data/messages/p/pointless-string-statement/related.rst --- old/pylint-3.0.2/doc/data/messages/p/pointless-string-statement/related.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-3.0.3/doc/data/messages/p/pointless-string-statement/related.rst 2023-12-11 14:16:40.000000000 +0100 @@ -0,0 +1 @@ +- `Discussion thread re: docstrings on assignments <https://discuss.python.org/t/docstrings-for-new-type-aliases-as-defined-in-pep-695/39816>`_ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/doc/whatsnew/3/3.0/index.rst new/pylint-3.0.3/doc/whatsnew/3/3.0/index.rst --- old/pylint-3.0.2/doc/whatsnew/3/3.0/index.rst 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/doc/whatsnew/3/3.0/index.rst 2023-12-11 14:16:40.000000000 +0100 @@ -65,6 +65,58 @@ .. towncrier release notes start +What's new in Pylint 3.0.3? +--------------------------- +Release date: 2023-12-11 + + +False Positives Fixed +--------------------- + +- Fixed false positive for ``unnecessary-lambda`` when the call has keyword arguments but not the lambda. + + Closes #9148 (`#9148 <https://github.com/pylint-dev/pylint/issues/9148>`_) + +- Fixed incorrect suggestion for shallow copy in unnecessary-comprehension + + Example of the suggestion: + #pylint: disable=missing-module-docstring + a = [1, 2, 3] + b = [x for x in a] + b[0] = 0 + print(a) # [1, 2, 3] + + After changing b = [x for x in a] to b = a based on the suggestion, the script now prints [0, 2, 3]. The correct suggestion should be use list(a) to preserve the original behavior. + + Closes #9172 (`#9172 <https://github.com/pylint-dev/pylint/issues/9172>`_) + +- Fix false positives for ``undefined-variable`` and ``unused-argument`` for + classes and functions using Python 3.12 generic type syntax. + + Closes #9193 (`#9193 <https://github.com/pylint-dev/pylint/issues/9193>`_) + +- Fixed ``pointless-string-statement`` false positive for docstrings + on Python 3.12 type aliases. + + Closes #9268 (`#9268 <https://github.com/pylint-dev/pylint/issues/9268>`_) + +- Fix false positive for ``invalid-exception-operation`` when concatenating tuples + of exception types. + + Closes #9288 (`#9288 <https://github.com/pylint-dev/pylint/issues/9288>`_) + + + +Other Bug Fixes +--------------- + +- Fix a bug where pylint was unable to walk recursively through a directory if the + directory has an `__init__.py` file. + + Closes #9210 (`#9210 <https://github.com/pylint-dev/pylint/issues/9210>`_) + + + What's new in Pylint 3.0.2? --------------------------- Release date: 2023-10-22 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/pylint/__pkginfo__.py new/pylint-3.0.3/pylint/__pkginfo__.py --- old/pylint-3.0.2/pylint/__pkginfo__.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/pylint/__pkginfo__.py 2023-12-11 14:16:40.000000000 +0100 @@ -9,7 +9,7 @@ from __future__ import annotations -__version__ = "3.0.2" +__version__ = "3.0.3" def get_numversion_from_version(v: str) -> tuple[int, int, int]: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/pylint/checkers/base/basic_checker.py new/pylint-3.0.3/pylint/checkers/base/basic_checker.py --- old/pylint-3.0.2/pylint/checkers/base/basic_checker.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/pylint/checkers/base/basic_checker.py 2023-12-11 14:16:40.000000000 +0100 @@ -446,7 +446,9 @@ if ( sibling is not None and sibling.scope() is scope - and isinstance(sibling, (nodes.Assign, nodes.AnnAssign)) + and isinstance( + sibling, (nodes.Assign, nodes.AnnAssign, nodes.TypeAlias) + ) ): return self.add_message("pointless-string-statement", node=node) @@ -519,7 +521,6 @@ ) @utils.only_required_for_messages("unnecessary-lambda") - # pylint: disable-next=too-many-return-statements def visit_lambda(self, node: nodes.Lambda) -> None: """Check whether the lambda is suspicious.""" # if the body of the lambda is a call expression with the same @@ -544,12 +545,13 @@ # return something else (but we don't check that, yet). return - call_site = astroid.arguments.CallSite.from_call(call) ordinary_args = list(node.args.args) new_call_args = list(self._filter_vararg(node, call.args)) if node.args.kwarg: - if self._has_variadic_argument(call.kwargs, node.args.kwarg): + if self._has_variadic_argument(call.keywords, node.args.kwarg): return + elif call.keywords: + return if node.args.vararg: if self._has_variadic_argument(call.starargs, node.args.vararg): @@ -557,16 +559,6 @@ elif call.starargs: return - if call.keywords: - # Look for additional keyword arguments that are not part - # of the lambda's signature - lambda_kwargs = {keyword.name for keyword in node.args.defaults} - if len(lambda_kwargs) != len(call_site.keyword_arguments): - # Different lengths, so probably not identical - return - if set(call_site.keyword_arguments).difference(lambda_kwargs): - return - # The "ordinary" arguments must be in a correspondence such that: # ordinary_args[i].name == call.args[i].name. if len(ordinary_args) != len(new_call_args): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/pylint/checkers/exceptions.py new/pylint-3.0.3/pylint/checkers/exceptions.py --- old/pylint-3.0.2/pylint/checkers/exceptions.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/pylint/checkers/exceptions.py 2023-12-11 14:16:40.000000000 +0100 @@ -533,8 +533,19 @@ @utils.only_required_for_messages("wrong-exception-operation") def visit_binop(self, node: nodes.BinOp) -> None: if isinstance(node.parent, nodes.ExceptHandler): + both_sides_tuple_or_uninferable = isinstance( + utils.safe_infer(node.left), (nodes.Tuple, util.UninferableBase) + ) and isinstance( + utils.safe_infer(node.right), (nodes.Tuple, util.UninferableBase) + ) + # Tuple concatenation allowed + if both_sides_tuple_or_uninferable: + if node.op == "+": + return + suggestion = f"Did you mean '({node.left.as_string()} + {node.right.as_string()})' instead?" # except (V | A) - suggestion = f"Did you mean '({node.left.as_string()}, {node.right.as_string()})' instead?" + else: + suggestion = f"Did you mean '({node.left.as_string()}, {node.right.as_string()})' instead?" self.add_message("wrong-exception-operation", node=node, args=(suggestion,)) @utils.only_required_for_messages("wrong-exception-operation") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/pylint/checkers/refactoring/refactoring_checker.py new/pylint-3.0.3/pylint/checkers/refactoring/refactoring_checker.py --- old/pylint-3.0.2/pylint/checkers/refactoring/refactoring_checker.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/pylint/checkers/refactoring/refactoring_checker.py 2023-12-11 14:16:40.000000000 +0100 @@ -1779,15 +1779,15 @@ if isinstance(node.parent, nodes.DictComp) and isinstance( inferred, astroid.objects.DictItems ): - args = (f"{node.iter.func.expr.as_string()}",) - elif ( - isinstance(node.parent, nodes.ListComp) - and isinstance(inferred, nodes.List) - ) or ( - isinstance(node.parent, nodes.SetComp) - and isinstance(inferred, nodes.Set) + args = (f"dict({node.iter.func.expr.as_string()})",) + elif isinstance(node.parent, nodes.ListComp) and isinstance( + inferred, nodes.List ): - args = (f"{node.iter.as_string()}",) + args = (f"list({node.iter.as_string()})",) + elif isinstance(node.parent, nodes.SetComp) and isinstance( + inferred, nodes.Set + ): + args = (f"set({node.iter.as_string()})",) if args: self.add_message( "unnecessary-comprehension", node=node.parent, args=args diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/pylint/checkers/similar.py new/pylint-3.0.3/pylint/checkers/similar.py --- old/pylint-3.0.2/pylint/checkers/similar.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/pylint/checkers/similar.py 2023-12-11 14:16:40.000000000 +0100 @@ -839,7 +839,7 @@ stream must implement the readlines method """ if self.linter.current_name is None: - # TODO: 3.0 Fix current_name + # TODO: 4.0 Fix current_name warnings.warn( ( "In pylint 3.0 the current_name attribute of the linter object should be a string. " diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/pylint/checkers/variables.py new/pylint-3.0.3/pylint/checkers/variables.py --- old/pylint-3.0.2/pylint/checkers/variables.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/pylint/checkers/variables.py 2023-12-11 14:16:40.000000000 +0100 @@ -1738,6 +1738,9 @@ elif consumer.scope_type == "function" and self._defined_in_function_definition( node, consumer.node ): + if any(node.name == param.name.name for param in consumer.node.type_params): + return False + # If the name node is used as a function default argument's value or as # a decorator, then start from the parent frame of the function instead # of the function frame - and thus open an inner class scope @@ -2262,10 +2265,13 @@ isinstance(defframe, nodes.FunctionDef) and frame is defframe and defframe.parent_of(node) - and stmt is not defstmt + and ( + defnode in defframe.type_params + # Single statement function, with the statement on the + # same line as the function definition + or stmt is not defstmt + ) ): - # Single statement function, with the statement on the - # same line as the function definition maybe_before_assign = False elif ( isinstance(defstmt, NODES_WITH_VALUE_ATTR) @@ -2565,7 +2571,7 @@ else_stmt, (nodes.Return, nodes.Raise, nodes.Break, nodes.Continue) ): return - # TODO: 3.0: Consider using RefactoringChecker._is_function_def_never_returning + # TODO: 4.0: Consider using RefactoringChecker._is_function_def_never_returning if isinstance(else_stmt, nodes.Expr) and isinstance( else_stmt.value, nodes.Call ): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/pylint/config/callback_actions.py new/pylint-3.0.3/pylint/config/callback_actions.py --- old/pylint-3.0.2/pylint/config/callback_actions.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/pylint/config/callback_actions.py 2023-12-11 14:16:40.000000000 +0100 @@ -243,7 +243,7 @@ values: str | Sequence[Any] | None, option_string: str | None = "--generate-rcfile", ) -> None: - # TODO: 3.x: Deprecate this after the auto-upgrade functionality of + # TODO: 4.x: Deprecate this after the auto-upgrade functionality of # pylint-config is sufficient. self.run.linter._generate_config(skipsections=("Commands",)) sys.exit(0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/pylint/config/config_initialization.py new/pylint-3.0.3/pylint/config/config_initialization.py --- old/pylint-3.0.2/pylint/config/config_initialization.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/pylint/config/config_initialization.py 2023-12-11 14:16:40.000000000 +0100 @@ -110,13 +110,14 @@ "unrecognized-option", args=unrecognized_options_message, line=0 ) - # TODO 3.1: Change this to emit unknown-option-value + # TODO: Change this to be checked only when upgrading the configuration for exc_name in linter.config.overgeneral_exceptions: if "." not in exc_name: warnings.warn_explicit( f"'{exc_name}' is not a proper value for the 'overgeneral-exceptions' option. " f"Use fully qualified name (maybe 'builtins.{exc_name}' ?) instead. " - "This will cease to be checked at runtime in 3.1.0.", + "This will cease to be checked at runtime when the configuration " + "upgrader is released.", category=UserWarning, filename="pylint: Command line or configuration file", lineno=1, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/pylint/lint/expand_modules.py new/pylint-3.0.3/pylint/lint/expand_modules.py --- old/pylint-3.0.2/pylint/lint/expand_modules.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/pylint/lint/expand_modules.py 2023-12-11 14:16:40.000000000 +0100 @@ -144,8 +144,9 @@ ) if has_init or is_namespace or is_directory: for subfilepath in modutils.get_module_files( - os.path.dirname(filepath), ignore_list, list_all=is_namespace + os.path.dirname(filepath) or ".", ignore_list, list_all=is_namespace ): + subfilepath = os.path.normpath(subfilepath) if filepath == subfilepath: continue if _is_in_ignore_list_re( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/pylint/testutils/functional/test_file.py new/pylint-3.0.3/pylint/testutils/functional/test_file.py --- old/pylint-3.0.2/pylint/testutils/functional/test_file.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/pylint/testutils/functional/test_file.py 2023-12-11 14:16:40.000000000 +0100 @@ -56,7 +56,7 @@ def __init__(self, directory: str, filename: str) -> None: self._directory = directory self.base = filename.replace(".py", "") - # TODO: 3.0: Deprecate FunctionalTestFile.options and related code + # TODO:4.0: Deprecate FunctionalTestFile.options and related code # We should just parse these options like a normal configuration file. self.options: TestFileOptions = { "min_pyver": (2, 5), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/pylint/utils/utils.py new/pylint-3.0.3/pylint/utils/utils.py --- old/pylint-3.0.2/pylint/utils/utils.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/pylint/utils/utils.py 2023-12-11 14:16:40.000000000 +0100 @@ -315,7 +315,7 @@ ) -> None: """Format an option's section using the INI format.""" warnings.warn( - "format_section has been deprecated. It will be removed in pylint 3.0.", + "format_section has been deprecated. It will be removed in pylint 4.0.", DeprecationWarning, stacklevel=2, ) @@ -330,7 +330,7 @@ def _ini_format(stream: TextIO, options: list[tuple[str, OptionDict, Any]]) -> None: """Format options using the INI format.""" warnings.warn( - "_ini_format has been deprecated. It will be removed in pylint 3.0.", + "_ini_format has been deprecated. It will be removed in pylint 4.0.", DeprecationWarning, stacklevel=2, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/pyproject.toml new/pylint-3.0.3/pyproject.toml --- old/pylint-3.0.2/pyproject.toml 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/pyproject.toml 2023-12-11 14:16:40.000000000 +0100 @@ -42,7 +42,7 @@ # Pinned to dev of second minor update to allow editable installs and fix primer issues, # see https://github.com/pylint-dev/astroid/issues/1341 "astroid>=3.0.1,<=3.1.0-dev0", - "isort>=4.2.5,<6", + "isort>=4.2.5,<6,!=5.13.0", "mccabe>=0.6,<0.8", "tomli>=1.1.0;python_version<'3.11'", "tomlkit>=0.10.1", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/tbump.toml new/pylint-3.0.3/tbump.toml --- old/pylint-3.0.2/tbump.toml 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/tbump.toml 2023-12-11 14:16:40.000000000 +0100 @@ -1,7 +1,7 @@ github_url = "https://github.com/pylint-dev/pylint" [version] -current = "3.0.2" +current = "3.0.3" regex = ''' ^(?P<major>0|[1-9]\d*) \. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/tests/functional/s/statement_without_effect_py312.py new/pylint-3.0.3/tests/functional/s/statement_without_effect_py312.py --- old/pylint-3.0.2/tests/functional/s/statement_without_effect_py312.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-3.0.3/tests/functional/s/statement_without_effect_py312.py 2023-12-11 14:16:40.000000000 +0100 @@ -0,0 +1,7 @@ +"""Move this into statement_without_effect.py when python 3.12 is minimum.""" + +type MyTuple = tuple[str, str] +""" +Multiline docstring +for Python3.12 type alias (PEP 695) +""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/tests/functional/s/statement_without_effect_py312.rc new/pylint-3.0.3/tests/functional/s/statement_without_effect_py312.rc --- old/pylint-3.0.2/tests/functional/s/statement_without_effect_py312.rc 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-3.0.3/tests/functional/s/statement_without_effect_py312.rc 2023-12-11 14:16:40.000000000 +0100 @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.12 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/tests/functional/u/undefined/undefined_variable_py312.py new/pylint-3.0.3/tests/functional/u/undefined/undefined_variable_py312.py --- old/pylint-3.0.2/tests/functional/u/undefined/undefined_variable_py312.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-3.0.3/tests/functional/u/undefined/undefined_variable_py312.py 2023-12-11 14:16:40.000000000 +0100 @@ -0,0 +1,7 @@ +# pylint: disable=missing-function-docstring,missing-module-docstring,missing-class-docstring,too-few-public-methods + +def f[T](a: T) -> T: + print(a) + +class ChildClass[T, *Ts, **P]: + ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/tests/functional/u/undefined/undefined_variable_py312.rc new/pylint-3.0.3/tests/functional/u/undefined/undefined_variable_py312.rc --- old/pylint-3.0.2/tests/functional/u/undefined/undefined_variable_py312.rc 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-3.0.3/tests/functional/u/undefined/undefined_variable_py312.rc 2023-12-11 14:16:40.000000000 +0100 @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.12 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/tests/functional/u/unnecessary/unnecessary_comprehension.py new/pylint-3.0.3/tests/functional/u/unnecessary/unnecessary_comprehension.py --- old/pylint-3.0.2/tests/functional/u/unnecessary/unnecessary_comprehension.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/tests/functional/u/unnecessary/unnecessary_comprehension.py 2023-12-11 14:16:40.000000000 +0100 @@ -4,7 +4,9 @@ # List comprehensions [x for x in iterable] # [unnecessary-comprehension] [y for x in iterable] # expression != target_list +[x for x in iterable] # [unnecessary-comprehension] use list(iterable) [x for x,y,z in iterable] # expression != target_list +[(x, y) for x, y in iterable] # [unnecessary-comprehension] [(x,y,z) for x,y,z in iterable] # [unnecessary-comprehension] [(x,y,z) for (x,y,z) in iterable] # [unnecessary-comprehension] [x for x, *y in iterable] # expression != target_list diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/tests/functional/u/unnecessary/unnecessary_comprehension.txt new/pylint-3.0.3/tests/functional/u/unnecessary/unnecessary_comprehension.txt --- old/pylint-3.0.2/tests/functional/u/unnecessary/unnecessary_comprehension.txt 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/tests/functional/u/unnecessary/unnecessary_comprehension.txt 2023-12-11 14:16:40.000000000 +0100 @@ -1,13 +1,15 @@ unnecessary-comprehension:5:0:5:21::Unnecessary use of a comprehension, use list(iterable) instead.:UNDEFINED -unnecessary-comprehension:8:0:8:31::Unnecessary use of a comprehension, use list(iterable) instead.:UNDEFINED -unnecessary-comprehension:9:0:9:33::Unnecessary use of a comprehension, use list(iterable) instead.:UNDEFINED -unnecessary-comprehension:17:7:17:42::Unnecessary use of a comprehension, use list(a_dict.items()) instead.:UNDEFINED -unnecessary-comprehension:20:0:20:21::Unnecessary use of a comprehension, use set(iterable) instead.:UNDEFINED -unnecessary-comprehension:23:0:23:31::Unnecessary use of a comprehension, use set(iterable) instead.:UNDEFINED -unnecessary-comprehension:24:7:24:42::Unnecessary use of a comprehension, use set(iterable) instead.:UNDEFINED -unnecessary-comprehension:32:0:32:27::Unnecessary use of a comprehension, use dict(iterable) instead.:UNDEFINED -unnecessary-comprehension:34:0:34:29::Unnecessary use of a comprehension, use dict(iterable) instead.:UNDEFINED -unnecessary-comprehension:46:0:46:26::Unnecessary use of a comprehension, use my_list instead.:UNDEFINED -unnecessary-comprehension:47:8:47:42::Unnecessary use of a comprehension, use my_dict instead.:UNDEFINED -consider-using-dict-items:48:0:None:None::Consider iterating with .items():UNDEFINED -unnecessary-comprehension:49:0:49:25::Unnecessary use of a comprehension, use my_set instead.:UNDEFINED +unnecessary-comprehension:7:0:7:21::Unnecessary use of a comprehension, use list(iterable) instead.:UNDEFINED +unnecessary-comprehension:9:0:9:29::Unnecessary use of a comprehension, use list(iterable) instead.:UNDEFINED +unnecessary-comprehension:10:0:10:31::Unnecessary use of a comprehension, use list(iterable) instead.:UNDEFINED +unnecessary-comprehension:11:0:11:33::Unnecessary use of a comprehension, use list(iterable) instead.:UNDEFINED +unnecessary-comprehension:19:7:19:42::Unnecessary use of a comprehension, use list(a_dict.items()) instead.:UNDEFINED +unnecessary-comprehension:22:0:22:21::Unnecessary use of a comprehension, use set(iterable) instead.:UNDEFINED +unnecessary-comprehension:25:0:25:31::Unnecessary use of a comprehension, use set(iterable) instead.:UNDEFINED +unnecessary-comprehension:26:7:26:42::Unnecessary use of a comprehension, use set(iterable) instead.:UNDEFINED +unnecessary-comprehension:34:0:34:27::Unnecessary use of a comprehension, use dict(iterable) instead.:UNDEFINED +unnecessary-comprehension:36:0:36:29::Unnecessary use of a comprehension, use dict(iterable) instead.:UNDEFINED +unnecessary-comprehension:48:0:48:26::Unnecessary use of a comprehension, use list(my_list) instead.:UNDEFINED +unnecessary-comprehension:49:8:49:42::Unnecessary use of a comprehension, use dict(my_dict) instead.:UNDEFINED +consider-using-dict-items:50:0:None:None::Consider iterating with .items():UNDEFINED +unnecessary-comprehension:51:0:51:25::Unnecessary use of a comprehension, use set(my_set) instead.:UNDEFINED diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/tests/functional/u/unnecessary/unnecessary_lambda.py new/pylint-3.0.3/tests/functional/u/unnecessary/unnecessary_lambda.py --- old/pylint-3.0.2/tests/functional/u/unnecessary/unnecessary_lambda.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/tests/functional/u/unnecessary/unnecessary_lambda.py 2023-12-11 14:16:40.000000000 +0100 @@ -52,6 +52,10 @@ _ = lambda: _ANYARGS(*[3], **{'three': 3}) _ = lambda: _ANYARGS(func=42) +# pylint: disable=missing-function-docstring +def f(d): + print(lambda x: str(x, **d)) + # Don't warn about this. _ = lambda: code().analysis() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/tests/functional/w/wrong_exception_operation.py new/pylint-3.0.3/tests/functional/w/wrong_exception_operation.py --- old/pylint-3.0.2/tests/functional/w/wrong_exception_operation.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/tests/functional/w/wrong_exception_operation.py 2023-12-11 14:16:40.000000000 +0100 @@ -16,3 +16,24 @@ 1/0 except (ValueError < TypeError): # [wrong-exception-operation] pass + + +# Concatenation of exception type tuples +DIVISION_BY_ZERO = (ZeroDivisionError,) +VALUE_ERROR = (ValueError,) +UNINFERABLE = DIVISION_BY_ZERO | VALUE_ERROR + +try: + 1/0 +except (ValueError, ) + DIVISION_BY_ZERO: + pass + +try: + 1/0 +except (ValueError, ) | DIVISION_BY_ZERO: # [wrong-exception-operation] + pass + +try: + 1/0 +except (ValueError, ) + UNINFERABLE: + pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/tests/functional/w/wrong_exception_operation.txt new/pylint-3.0.3/tests/functional/w/wrong_exception_operation.txt --- old/pylint-3.0.2/tests/functional/w/wrong_exception_operation.txt 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/tests/functional/w/wrong_exception_operation.txt 2023-12-11 14:16:40.000000000 +0100 @@ -2,3 +2,4 @@ wrong-exception-operation:6:8:6:30::Invalid exception operation. Did you mean '(ValueError, TypeError)' instead?:UNDEFINED wrong-exception-operation:11:8:11:30::Invalid exception operation. Did you mean '(ValueError, TypeError)' instead?:UNDEFINED wrong-exception-operation:17:8:17:30::Invalid exception operation. Did you mean '(ValueError, TypeError)' instead?:UNDEFINED +wrong-exception-operation:33:7:33:40::Invalid exception operation. Did you mean '((ValueError, ) + DIVISION_BY_ZERO)' instead?:UNDEFINED diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/tests/lint/unittest_expand_modules.py new/pylint-3.0.3/tests/lint/unittest_expand_modules.py --- old/pylint-3.0.2/tests/lint/unittest_expand_modules.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/tests/lint/unittest_expand_modules.py 2023-12-11 14:16:40.000000000 +0100 @@ -4,7 +4,11 @@ from __future__ import annotations +import copy +import os import re +from collections.abc import Iterator +from contextlib import contextmanager from pathlib import Path import pytest @@ -28,7 +32,8 @@ TEST_DIRECTORY = Path(__file__).parent.parent INIT_PATH = str(TEST_DIRECTORY / "lint/__init__.py") -EXPAND_MODULES = str(TEST_DIRECTORY / "lint/unittest_expand_modules.py") +EXPAND_MODULES_BASE = "unittest_expand_modules.py" +EXPAND_MODULES = str(TEST_DIRECTORY / "lint" / EXPAND_MODULES_BASE) this_file = { "basename": "lint.unittest_expand_modules", "basepath": EXPAND_MODULES, @@ -37,6 +42,14 @@ "path": EXPAND_MODULES, } +this_file_relative_to_parent = { + "basename": "lint.unittest_expand_modules", + "basepath": EXPAND_MODULES_BASE, + "isarg": True, + "name": "lint.unittest_expand_modules", + "path": EXPAND_MODULES_BASE, +} + this_file_from_init = { "basename": "lint", "basepath": INIT_PATH, @@ -117,6 +130,27 @@ ) +def _list_expected_package_modules_relative() -> tuple[dict[str, object], ...]: + """Generates reusable list of modules for our package with relative path input.""" + abs_result = copy.deepcopy(_list_expected_package_modules()) + for item in abs_result: + assert isinstance(item["basepath"], str) + assert isinstance(item["path"], str) + item["basepath"] = os.path.relpath(item["basepath"], str(Path(__file__).parent)) + item["path"] = os.path.relpath(item["path"], str(Path(__file__).parent)) + return abs_result + + +@contextmanager +def pushd(path: Path) -> Iterator[None]: + prev = os.getcwd() + os.chdir(path) + try: + yield + finally: + os.chdir(prev) + + class TestExpandModules(CheckerTestCase): """Test the expand_modules function while allowing options to be set.""" @@ -161,6 +195,40 @@ @pytest.mark.parametrize( "files_or_modules,expected", + [ + ( + [Path(__file__).name], + {this_file_relative_to_parent["path"]: this_file_relative_to_parent}, + ), + ( + ["./"], + { + module["path"]: module # pylint: disable=unsubscriptable-object + for module in _list_expected_package_modules_relative() + }, + ), + ], + ) + @set_config(ignore_paths="") + def test_expand_modules_relative_path( + self, files_or_modules: list[str], expected: dict[str, ModuleDescriptionDict] + ) -> None: + """Test expand_modules with the default value of ignore-paths and relative path as input.""" + ignore_list: list[str] = [] + ignore_list_re: list[re.Pattern[str]] = [] + with pushd(Path(__file__).parent): + modules, errors = expand_modules( + files_or_modules, + [], + ignore_list, + ignore_list_re, + self.linter.config.ignore_paths, + ) + assert modules == expected + assert not errors + + @pytest.mark.parametrize( + "files_or_modules,expected", [ ([__file__, __file__], {this_file["path"]: this_file}), ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/tests/test_check_parallel.py new/pylint-3.0.3/tests/test_check_parallel.py --- old/pylint-3.0.2/tests/test_check_parallel.py 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/tests/test_check_parallel.py 2023-12-11 14:16:40.000000000 +0100 @@ -269,7 +269,7 @@ linter.load_plugin_modules(["pylint.extensions.overlapping_exceptions"]) try: dill.dumps(linter) - # TODO: 3.0: Fix this test by raising this assertion again + # TODO: 4.0: Fix this test by raising this assertion again # raise AssertionError( # "Plugins loaded were pickle-safe! This test needs altering" # ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-3.0.2/towncrier.toml new/pylint-3.0.3/towncrier.toml --- old/pylint-3.0.2/towncrier.toml 2023-10-22 15:48:35.000000000 +0200 +++ new/pylint-3.0.3/towncrier.toml 2023-12-11 14:16:40.000000000 +0100 @@ -1,5 +1,5 @@ [tool.towncrier] -version = "3.0.2" +version = "3.0.3" directory = "doc/whatsnew/fragments" filename = "doc/whatsnew/3/3.0/index.rst" template = "doc/whatsnew/fragments/_template.rst"
