Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-astroid for openSUSE:Factory checked in at 2023-01-15 17:57:59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-astroid (Old) and /work/SRC/openSUSE:Factory/.python-astroid.new.32243 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-astroid" Sun Jan 15 17:57:59 2023 rev:41 rq:1058347 version:2.12.14 Changes: -------- --- /work/SRC/openSUSE:Factory/python-astroid/python-astroid.changes 2022-12-04 14:57:53.320109290 +0100 +++ /work/SRC/openSUSE:Factory/.python-astroid.new.32243/python-astroid.changes 2023-01-15 17:58:07.662189228 +0100 @@ -1,0 +2,12 @@ +Sat Jan 7 08:50:36 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to v2.12.14: + * Handle the effect of properties on the __init__ of a dataclass + correctly. + * Handle the effect of kw_only=True in dataclass fields correctly. + * Handle the effect of init=False in dataclass fields correctly. + * Fix crash if numpy module doesn't have version attribute. + * Handle AttributeError during str.format template inference tip + evaluation + +------------------------------------------------------------------- Old: ---- astroid-2.12.13-gh.tar.gz New: ---- astroid-2.12.14-gh.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-astroid.spec ++++++ --- /var/tmp/diff_new_pack.froSq0/_old 2023-01-15 17:58:08.258192766 +0100 +++ /var/tmp/diff_new_pack.froSq0/_new 2023-01-15 17:58:08.262192789 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-astroid # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: python-astroid -Version: 2.12.13 +Version: 2.12.14 Release: 0 Summary: Representation of Python source as an AST for pylint License: LGPL-2.1-or-later ++++++ astroid-2.12.13-gh.tar.gz -> astroid-2.12.14-gh.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/.coveragerc new/astroid-2.12.14/.coveragerc --- old/astroid-2.12.13/.coveragerc 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/.coveragerc 2023-01-06 20:32:02.000000000 +0100 @@ -1,12 +1,10 @@ -[paths] -source = - astroid +[run] +relative_files = true [report] -include = - astroid/* omit = */tests/* + */tmp*/* exclude_lines = # Re-enable default pragma pragma: no cover diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/.github/workflows/backport.yml new/astroid-2.12.14/.github/workflows/backport.yml --- old/astroid-2.12.13/.github/workflows/backport.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/astroid-2.12.14/.github/workflows/backport.yml 2023-01-06 20:32:02.000000000 +0100 @@ -0,0 +1,29 @@ +name: Backport +on: + pull_request_target: + types: + - closed + - labeled + +permissions: + pull-requests: write + contents: write + +jobs: + backport: + name: Backport + runs-on: ubuntu-latest + # Only react to merged PRs for security reasons. + # See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target. + if: > + github.event.pull_request.merged && ( + github.event.action == 'closed' + || ( + github.event.action == 'labeled' + && contains(github.event.label.name, 'backport') + ) + ) + steps: + - uses: tibdex/backport@2e217641d82d02ba0603f46b1aeedefb258890ac # v2.0.3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/.github/workflows/ci.yaml new/astroid-2.12.14/.github/workflows/ci.yaml --- old/astroid-2.12.13/.github/workflows/ci.yaml 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/.github/workflows/ci.yaml 2023-01-06 20:32:02.000000000 +0100 @@ -10,7 +10,7 @@ env: CACHE_VERSION: 1 KEY_PREFIX: venv - DEFAULT_PYTHON: "3.10" + DEFAULT_PYTHON: "3.11" PRE_COMMIT_CACHE: ~/.cache/pre-commit jobs: @@ -122,59 +122,13 @@ - name: Run pytest run: | . venv/bin/activate - pytest --cov --cov-report= tests/ + pytest --cov - name: Upload coverage artifact uses: actions/upload-artifact@v3.1.0 with: - name: coverage-${{ matrix.python-version }} + name: coverage-linux-${{ matrix.python-version }} path: .coverage - coverage: - name: tests / process / coverage - runs-on: ubuntu-latest - timeout-minutes: 5 - needs: ["tests-linux"] - strategy: - matrix: - python-version: ["3.10"] - env: - COVERAGERC_FILE: .coveragerc - steps: - - name: Check out code from GitHub - uses: actions/checkout@v3.0.2 - - name: Set up Python ${{ matrix.python-version }} - id: python - uses: actions/setup-python@v4.0.0 - with: - python-version: ${{ matrix.python-version }} - check-latest: true - - name: Restore Python virtual environment - id: cache-venv - uses: actions/cache@v3.0.4 - with: - path: venv - key: - ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ - needs.tests-linux.outputs.python-key }} - - name: Fail job if Python cache restore failed - if: steps.cache-venv.outputs.cache-hit != 'true' - run: | - echo "Failed to restore Python venv from cache" - exit 1 - - name: Download all coverage artifacts - uses: actions/download-artifact@v3.0.0 - - name: Combine coverage results - run: | - . venv/bin/activate - coverage combine coverage*/.coverage - coverage report --rcfile=${{ env.COVERAGERC_FILE }} - - name: Upload coverage to Coveralls - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - . venv/bin/activate - coveralls --rcfile=${{ env.COVERAGERC_FILE }} --service=github - tests-windows: name: tests / run / ${{ matrix.python-version }} / Windows runs-on: windows-latest @@ -222,7 +176,12 @@ - name: Run pytest run: | . venv\\Scripts\\activate - pytest tests/ + pytest --cov + - name: Upload coverage artifact + uses: actions/upload-artifact@v3.1.1 + with: + name: coverage-windows-${{ matrix.python-version }} + path: .coverage tests-pypy: name: tests / run / ${{ matrix.python-version }} / Linux @@ -266,4 +225,58 @@ - name: Run pytest run: | . venv/bin/activate - pytest tests/ + pytest --cov + - name: Upload coverage artifact + uses: actions/upload-artifact@v3.1.1 + with: + name: coverage-pypy-${{ matrix.python-version }} + path: .coverage + + coverage: + name: tests / process / coverage + runs-on: ubuntu-latest + timeout-minutes: 10 + needs: ["tests-linux", "tests-windows", "tests-pypy"] + steps: + - name: Check out code from GitHub + uses: actions/checkout@v3.2.0 + - name: Set up Python 3.11 + id: python + uses: actions/setup-python@v4.4.0 + with: + python-version: "3.11" + check-latest: true + - name: Install dependencies + run: pip install -U -r requirements_test_min.txt + - name: Download all coverage artifacts + uses: actions/download-artifact@v3.0.1 + - name: Combine Linux coverage results + run: | + coverage combine coverage-linux*/.coverage + coverage xml -o coverage-linux.xml + - uses: codecov/codecov-action@v3 + with: + fail_ci_if_error: true + verbose: true + flags: linux + files: coverage-linux.xml + - name: Combine Windows coverage results + run: | + coverage combine coverage-windows*/.coverage + coverage xml -o coverage-windows.xml + - uses: codecov/codecov-action@v3 + with: + fail_ci_if_error: true + verbose: true + flags: windows + files: coverage-windows.xml + - name: Combine PyPy coverage results + run: | + coverage combine coverage-pypy*/.coverage + coverage xml -o coverage-pypy.xml + - uses: codecov/codecov-action@v3 + with: + fail_ci_if_error: true + verbose: true + flags: pypy + files: coverage-pypy.xml diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/CONTRIBUTORS.txt new/astroid-2.12.14/CONTRIBUTORS.txt --- old/astroid-2.12.13/CONTRIBUTORS.txt 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/CONTRIBUTORS.txt 2023-01-06 20:32:02.000000000 +0100 @@ -14,16 +14,16 @@ Maintainers ----------- - Pierre Sassoulas <pierre.sassou...@gmail.com> -- Hippo91 <guillaume.peil...@gmail.com> - Daniël van Noord <13665637+danielno...@users.noreply.github.com> +- Hippo91 <guillaume.peil...@gmail.com> - Marc Mueller <30130371+cdc...@users.noreply.github.com> -- Bryce Guinta <bryce.paul.gui...@gmail.com> - Jacob Walls <jacobtylerwa...@gmail.com> +- Bryce Guinta <bryce.paul.gui...@gmail.com> - Ceridwen <ceridw...@gmail.com> - Åukasz Rogalski <rogalski...@gmail.com> +- Mark Byrne <31762852+mbyrne...@users.noreply.github.com> - Florian Bruhin <m...@the-compiler.org> - Ashley Whetter <ash...@awhetter.co.uk> -- Mark Byrne <31762852+mbyrne...@users.noreply.github.com> - Dimitri Prybysh <dm...@yandex.ru> - Areveny <arev...@protonmail.com> @@ -40,11 +40,11 @@ - David Gilman <davidgilm...@gmail.com> - Julien Jehannet <julien.jehan...@logilab.fr> - Calen Pennington <calen.penning...@gmail.com> +- Tushar Sadhwani <86737547+tushar-deepsou...@users.noreply.github.com> - Tim Martin <t...@asymptotic.co.uk> - Phil Schaf <flying-sh...@web.de> - Hugo van Kemenade <hug...@users.noreply.github.com> - Alex Hall <alex.moj...@gmail.com> -- Tushar Sadhwani <86737547+tushar-deepsou...@users.noreply.github.com> - Raphael Gaschignard <raph...@makeleaps.com> - RadosÅaw Ganczarek <rados...@ganczarek.in> - Paligot Gérard <androwi...@gmail.com> @@ -52,6 +52,7 @@ - Derek Gustafson <degus...@gmail.com> - David Shea <ds...@redhat.com> - Daniel Harding <dhard...@gmail.com> +- Christian Clauss <ccla...@me.com> - Ville Skyttä <ville.sky...@iki.fi> - Rene Zhang <r...@cornell.edu> - Philip Lorenz <phi...@bithub.de> @@ -68,9 +69,11 @@ - doranid <dda...@gmail.com> - brendanator <brendan.magin...@gmail.com> - Tomas Gavenciak <gave...@ucw.cz> +- Tim Paine <t.paine...@gmail.com> - Thomas Hisch <t.hi...@gmail.com> - Stefan Scherfke <ste...@sofa-rockers.org> - Sergei Lebedev <185856+superbo...@users.noreply.github.com> +- Saugat Pachhai (सà¥à¤à¤¾à¤¤) <suagatchhe...@outlook.com> - Ram Rachum <r...@rachum.com> - Pierre-Yves David <pierre-yves.da...@logilab.fr> - Peter Pentchev <r...@ringlet.net> @@ -105,13 +108,11 @@ - Valentin Valls <valentin.va...@esrf.fr> - Uilian Ries <uilianr...@gmail.com> - Tomas Novak <ext.tomas.no...@skoda-auto.cz> -- Tim Paine <t.paine...@gmail.com> - Thirumal Venkat <m...@thirumal.in> - SupImDos <62866982+supim...@users.noreply.github.com> - Stanislav Levin <s...@altlinux.org> - Simon Hewitt <s...@sjhewitt.co.uk> - Serhiy Storchaka <storch...@gmail.com> -- Saugat Pachhai (सà¥à¤à¤¾à¤¤) <suagatchhe...@outlook.com> - Roy Wright <r...@wright.org> - Robin Jarry <robin.ja...@6wind.com> - René Fritze <47802+renefri...@users.noreply.github.com> @@ -135,6 +136,7 @@ - Jeff Quast <cont...@jeffquast.com> - Jarrad Hope <m...@jarradhope.com> - Jared Garst <jga...@users.noreply.github.com> +- James Addison <55152140+jayaddi...@users.noreply.github.com> - Jakub Wilk <jw...@jwilk.net> - Iva Miholic <ivam...@gmail.com> - Ionel Maries Cristian <cont...@ionelmc.ro> @@ -156,6 +158,7 @@ - Dave Baum <db...@google.com> - Daniel Martin <daniel.mar...@crowdstrike.com> - Daniel Colascione <dan...@dancol.org> +- Dani Alcala <112832187+clavedel...@users.noreply.github.com> - Damien Baty <dam...@damienbaty.com> - Craig Franklin <craigjfrank...@gmail.com> - Colin Kennedy <colin...@gmail.com> @@ -188,4 +191,3 @@ - carl - alain lefroy - Mark Gius -- jarradhope diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/ChangeLog new/astroid-2.12.14/ChangeLog --- old/astroid-2.12.13/ChangeLog 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/ChangeLog 2023-01-06 20:32:02.000000000 +0100 @@ -9,6 +9,30 @@ +What's New in astroid 2.12.14? +============================== +Release date: 2023-01-06 + +* Handle the effect of properties on the ``__init__`` of a dataclass correctly. + + Closes PyCQA/pylint#5225 + +* Handle the effect of ``kw_only=True`` in dataclass fields correctly. + + Closes PyCQA/pylint#7623 + +* Handle the effect of ``init=False`` in dataclass fields correctly. + + Closes PyCQA/pylint#7291 + +* Fix crash if ``numpy`` module doesn't have ``version`` attribute. + + Refs PyCQA/pylint#7868 + +* Handle ``AttributeError`` during ``str.format`` template inference tip evaluation + + Closes PyCQA/pylint#1902 + What's New in astroid 2.12.13? ============================== Release date: 2022-11-19 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/README.rst new/astroid-2.12.14/README.rst --- old/astroid-2.12.13/README.rst 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/README.rst 2023-01-06 20:32:02.000000000 +0100 @@ -1,9 +1,9 @@ Astroid ======= -.. image:: https://coveralls.io/repos/github/PyCQA/astroid/badge.svg?branch=main - :target: https://coveralls.io/github/PyCQA/astroid?branch=main - :alt: Coverage badge from coveralls.io +.. image:: https://codecov.io/gh/PyCQA/astroid/branch/main/graph/badge.svg?token=Buxy4WptLb + :target: https://codecov.io/gh/PyCQA/astroid + :alt: Coverage badge from codecov .. image:: https://readthedocs.org/projects/astroid/badge/?version=latest :target: http://astroid.readthedocs.io/en/latest/?badge=latest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/astroid/__pkginfo__.py new/astroid-2.12.14/astroid/__pkginfo__.py --- old/astroid-2.12.13/astroid/__pkginfo__.py 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/astroid/__pkginfo__.py 2023-01-06 20:32:02.000000000 +0100 @@ -2,5 +2,5 @@ # For details: https://github.com/PyCQA/astroid/blob/main/LICENSE # Copyright (c) https://github.com/PyCQA/astroid/blob/main/CONTRIBUTORS.txt -__version__ = "2.12.13" +__version__ = "2.12.14" version = __version__ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/astroid/brain/brain_builtin_inference.py new/astroid-2.12.14/astroid/brain/brain_builtin_inference.py --- old/astroid-2.12.13/astroid/brain/brain_builtin_inference.py 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/astroid/brain/brain_builtin_inference.py 2023-01-06 20:32:02.000000000 +0100 @@ -954,7 +954,8 @@ try: formatted_string = format_template.format(*pos_values, **keyword_values) - except (IndexError, KeyError, TypeError, ValueError): + except (AttributeError, IndexError, KeyError, TypeError, ValueError): + # AttributeError: processing a replacement field using the arguments failed # IndexError: there are too few arguments to interpolate # TypeError: Unsupported format string # ValueError: Unknown format code diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/astroid/brain/brain_dataclasses.py new/astroid-2.12.14/astroid/brain/brain_dataclasses.py --- old/astroid-2.12.13/astroid/brain/brain_dataclasses.py 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/astroid/brain/brain_dataclasses.py 2023-01-06 20:32:02.000000000 +0100 @@ -115,8 +115,7 @@ ) -> Iterator[nodes.AnnAssign]: """Yield the AnnAssign nodes of dataclass attributes for the node. - If init is True, also include InitVars, but exclude attributes from calls to - field where init=False. + If init is True, also include InitVars. """ for assign_node in node.body: if not isinstance(assign_node, nodes.AnnAssign) or not isinstance( @@ -124,24 +123,15 @@ ): continue - if _is_class_var(assign_node.annotation): # type: ignore[arg-type] # annotation is never None + # Annotation is never None + if _is_class_var(assign_node.annotation): # type: ignore[arg-type] continue if _is_keyword_only_sentinel(assign_node.annotation): continue - if init: - value = assign_node.value - if ( - isinstance(value, nodes.Call) - and _looks_like_dataclass_field_call(value, check_scope=False) - and any( - keyword.arg == "init" and not keyword.value.bool_value() - for keyword in value.keywords - ) - ): - continue - elif _is_init_var(assign_node.annotation): # type: ignore[arg-type] # annotation is never None + # Annotation is never None + if not init and _is_init_var(assign_node.annotation): # type: ignore[arg-type] continue yield assign_node @@ -231,11 +221,31 @@ return pos_only, kw_only -def _generate_dataclass_init( +def _get_previous_field_default(node: nodes.ClassDef, name: str) -> nodes.NodeNG | None: + """Get the default value of a previously defined field.""" + for base in reversed(node.mro()): + if not base.is_dataclass: + continue + if name in base.locals: + for assign in base.locals[name]: + if ( + isinstance(assign.parent, nodes.AnnAssign) + and assign.parent.value + and isinstance(assign.parent.value, nodes.Call) + and _looks_like_dataclass_field_call(assign.parent.value) + ): + default = _get_field_default(assign.parent.value) + if default: + return default[1] + return None + + +def _generate_dataclass_init( # pylint: disable=too-many-locals node: nodes.ClassDef, assigns: list[nodes.AnnAssign], kw_only_decorated: bool ) -> str: """Return an init method for a dataclass given the targets.""" params: list[str] = [] + kw_only_params: list[str] = [] assignments: list[str] = [] assign_names: list[str] = [] @@ -243,6 +253,29 @@ name, annotation, value = assign.target.name, assign.annotation, assign.value assign_names.append(name) + # Check whether this assign is overriden by a property assignment + property_node: nodes.FunctionDef | None = None + for additional_assign in node.locals[name]: + if not isinstance(additional_assign, nodes.FunctionDef): + continue + if not additional_assign.decorators: + continue + if "builtins.property" in additional_assign.decoratornames(): + property_node = additional_assign + break + + is_field = isinstance(value, nodes.Call) and _looks_like_dataclass_field_call( + value, check_scope=False + ) + + if is_field: + # Skip any fields that have `init=False` + if any( + keyword.arg == "init" and not keyword.value.bool_value() + for keyword in value.keywords # type: ignore[union-attr] # value is never None + ): + continue + if _is_init_var(annotation): # type: ignore[arg-type] # annotation is never None init_var = True if isinstance(annotation, nodes.Subscript): @@ -261,10 +294,8 @@ param_str = name if value: - if isinstance(value, nodes.Call) and _looks_like_dataclass_field_call( - value, check_scope=False - ): - result = _get_field_default(value) + if is_field: + result = _get_field_default(value) # type: ignore[arg-type] if result: default_type, default_node = result if default_type == "default": @@ -277,8 +308,38 @@ ) else: param_str += f" = {value.as_string()}" + elif property_node: + # We set the result of the property call as default + # This hides the fact that this would normally be a 'property object' + # But we can't represent those as string + try: + param_str += f" = {next(property_node.infer_call_result()).as_string()}" + except (InferenceError, StopIteration): + pass + else: + # Even with `init=False` the default value still can be propogated to + # later assignments. Creating weird signatures like: + # (self, a: str = 1) -> None + previous_default = _get_previous_field_default(node, name) + if previous_default: + param_str += f" = {previous_default.as_string()}" + + # If the field is a kw_only field, we need to add it to the kw_only_params + # This overwrites whether or not the class is kw_only decorated + if is_field: + kw_only = [k for k in value.keywords if k.arg == "kw_only"] # type: ignore[union-attr] + if kw_only: + if kw_only[0].value.bool_value(): + kw_only_params.append(param_str) + else: + params.append(param_str) + continue + # If kw_only decorated, we need to add all parameters to the kw_only_params + if kw_only_decorated: + kw_only_params.append(param_str) + else: + params.append(param_str) - params.append(param_str) if not init_var: assignments.append(assignment_str) @@ -287,21 +348,16 @@ ) # Construct the new init method paramter string - params_string = "self, " - if prev_pos_only: - params_string += prev_pos_only - if not kw_only_decorated: - params_string += ", ".join(params) - + # First we do the positional only parameters, making sure to add the + # the self parameter and the comma to allow adding keyword only parameters + params_string = f"self, {prev_pos_only}{', '.join(params)}" if not params_string.endswith(", "): params_string += ", " - if prev_kw_only: - params_string += "*, " + prev_kw_only - if kw_only_decorated: - params_string += ", ".join(params) + ", " - elif kw_only_decorated: - params_string += "*, " + ", ".join(params) + ", " + # Then we add the keyword only parameters + if prev_kw_only or kw_only_params: + params_string += "*, " + params_string += f"{prev_kw_only}{', '.join(kw_only_params)}" assignments_string = "\n ".join(assignments) if assignments else "pass" return f"def __init__({params_string}) -> None:\n {assignments_string}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/astroid/brain/brain_numpy_utils.py new/astroid-2.12.14/astroid/brain/brain_numpy_utils.py --- old/astroid-2.12.13/astroid/brain/brain_numpy_utils.py 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/astroid/brain/brain_numpy_utils.py 2023-01-06 20:32:02.000000000 +0100 @@ -30,7 +30,7 @@ import numpy # pylint: disable=import-outside-toplevel return tuple(numpy.version.version.split(".")) - except ImportError: + except (ImportError, AttributeError): return ("0", "0", "0") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/codecov.yml new/astroid-2.12.14/codecov.yml --- old/astroid-2.12.13/codecov.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/astroid-2.12.14/codecov.yml 2023-01-06 20:32:02.000000000 +0100 @@ -0,0 +1,10 @@ +coverage: + status: + patch: + default: + target: 100% + project: + default: + target: 92% +comment: + layout: "reach, diff, flags, files" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/requirements_test.txt new/astroid-2.12.14/requirements_test.txt --- old/astroid-2.12.13/requirements_test.txt 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/requirements_test.txt 2023-01-06 20:32:02.000000000 +0100 @@ -1,10 +1,7 @@ -r requirements_test_min.txt -r requirements_test_pre_commit.txt contributors-txt>=0.7.4 -coveralls~=3.3 -coverage~=6.4 -pre-commit~=2.19 -pytest-cov~=3.0 +pre-commit~=2.21 tbump~=6.9.0 types-typed-ast; implementation_name=="cpython" and python_version<"3.8" types-pkg_resources==0.1.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/requirements_test_min.txt new/astroid-2.12.14/requirements_test_min.txt --- old/astroid-2.12.13/requirements_test_min.txt 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/requirements_test_min.txt 2023-01-06 20:32:02.000000000 +0100 @@ -1,2 +1,4 @@ +coverage~=7.0 pytest +pytest-cov~=4.0 typing-extensions>=3.10 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/script/.contributors_aliases.json new/astroid-2.12.14/script/.contributors_aliases.json --- old/astroid-2.12.13/script/.contributors_aliases.json 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/script/.contributors_aliases.json 2023-01-06 20:32:02.000000000 +0100 @@ -44,7 +44,8 @@ "b...@noreply.github.com": { "mails": [ "66853113+pre-commit-ci[bot]@users.noreply.github.com", - "49699333+dependabot[bot]@users.noreply.github.com" + "49699333+dependabot[bot]@users.noreply.github.com", + "41898282+github-actions[bot]@users.noreply.github.com" ], "name": "bot" }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/tbump.toml new/astroid-2.12.14/tbump.toml --- old/astroid-2.12.13/tbump.toml 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/tbump.toml 2023-01-06 20:32:02.000000000 +0100 @@ -1,7 +1,7 @@ github_url = "https://github.com/PyCQA/astroid" [version] -current = "2.12.13" +current = "2.12.14" regex = ''' ^(?P<major>0|[1-9]\d*) \. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/tests/unittest_brain_builtin.py new/astroid-2.12.14/tests/unittest_brain_builtin.py --- old/astroid-2.12.13/tests/unittest_brain_builtin.py 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/tests/unittest_brain_builtin.py 2023-01-06 20:32:02.000000000 +0100 @@ -109,6 +109,10 @@ """ "My hex format is {:4x}".format('1') """, + """ + daniel_age = 12 + "My name is {0.name}".format(daniel_age) + """, ], ) def test_string_format_uninferable(self, format_string: str) -> None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/tests/unittest_brain_dataclasses.py new/astroid-2.12.14/tests/unittest_brain_dataclasses.py --- old/astroid-2.12.13/tests/unittest_brain_dataclasses.py 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/tests/unittest_brain_dataclasses.py 2023-01-06 20:32:02.000000000 +0100 @@ -826,6 +826,49 @@ assert [a.name for a in dee_init.args.kwonlyargs] == [] +def test_kw_only_in_field_call() -> None: + """Test that keyword only fields get correctly put at the end of the __init__.""" + + first, second, third = astroid.extract_node( + """ + from dataclasses import dataclass, field + + @dataclass + class Parent: + p1: int = field(kw_only=True, default=0) + + @dataclass + class Child(Parent): + c1: str + + @dataclass(kw_only=True) + class GrandChild(Child): + p2: int = field(kw_only=False, default=1) + p3: int = field(kw_only=True, default=2) + + Parent.__init__ #@ + Child.__init__ #@ + GrandChild.__init__ #@ + """ + ) + + first_init: bases.UnboundMethod = next(first.infer()) + assert [a.name for a in first_init.args.args] == ["self"] + assert [a.name for a in first_init.args.kwonlyargs] == ["p1"] + assert [d.value for d in first_init.args.kw_defaults] == [0] + + second_init: bases.UnboundMethod = next(second.infer()) + assert [a.name for a in second_init.args.args] == ["self", "c1"] + assert [a.name for a in second_init.args.kwonlyargs] == ["p1"] + assert [d.value for d in second_init.args.kw_defaults] == [0] + + third_init: bases.UnboundMethod = next(third.infer()) + assert [a.name for a in third_init.args.args] == ["self", "c1", "p2"] + assert [a.name for a in third_init.args.kwonlyargs] == ["p1", "p3"] + assert [d.value for d in third_init.args.defaults] == [1] + assert [d.value for d in third_init.args.kw_defaults] == [0, 2] + + def test_dataclass_with_unknown_base() -> None: """Regression test for dataclasses with unknown base classes. @@ -1062,6 +1105,62 @@ assert next(impossible.infer()) is Uninferable +def test_dataclass_with_field_init_is_false() -> None: + """When init=False it shouldn't end up in the __init__.""" + first, second, second_child, third_child, third = astroid.extract_node( + """ + from dataclasses import dataclass, field + + + @dataclass + class First: + a: int + + @dataclass + class Second(First): + a: int = field(init=False, default=1) + + @dataclass + class SecondChild(Second): + a: float + + @dataclass + class ThirdChild(SecondChild): + a: str + + @dataclass + class Third(First): + a: str + + First.__init__ #@ + Second.__init__ #@ + SecondChild.__init__ #@ + ThirdChild.__init__ #@ + Third.__init__ #@ + """ + ) + + first_init: bases.UnboundMethod = next(first.infer()) + assert [a.name for a in first_init.args.args] == ["self", "a"] + assert [a.value for a in first_init.args.defaults] == [] + + second_init: bases.UnboundMethod = next(second.infer()) + assert [a.name for a in second_init.args.args] == ["self"] + assert [a.value for a in second_init.args.defaults] == [] + + second_child_init: bases.UnboundMethod = next(second_child.infer()) + assert [a.name for a in second_child_init.args.args] == ["self", "a"] + assert [a.value for a in second_child_init.args.defaults] == [1] + + third_child_init: bases.UnboundMethod = next(third_child.infer()) + assert [a.name for a in third_child_init.args.args] == ["self", "a"] + assert [a.value for a in third_child_init.args.defaults] == [1] + + third_init: bases.UnboundMethod = next(third.infer()) + assert [a.name for a in third_init.args.args] == ["self", "a"] + assert [a.value for a in third_init.args.defaults] == [] + + def test_dataclass_inits_of_non_dataclasses() -> None: """Regression test for __init__ mangling for non dataclasses. @@ -1114,3 +1213,72 @@ third_init: bases.UnboundMethod = next(third.infer()) assert [a.name for a in third_init.args.args] == ["self", "ef"] assert [a.value for a in third_init.args.defaults] == [3] + + +def test_dataclass_with_properties() -> None: + """Tests for __init__ creation for dataclasses that use properties.""" + first, second, third = astroid.extract_node( + """ + from dataclasses import dataclass + + @dataclass + class Dataclass: + attr: int + + @property + def attr(self) -> int: + return 1 + + @attr.setter + def attr(self, value: int) -> None: + pass + + class ParentOne(Dataclass): + '''Docstring''' + + @dataclass + class ParentTwo(Dataclass): + '''Docstring''' + + Dataclass.__init__ #@ + ParentOne.__init__ #@ + ParentTwo.__init__ #@ + """ + ) + + first_init: bases.UnboundMethod = next(first.infer()) + assert [a.name for a in first_init.args.args] == ["self", "attr"] + assert [a.value for a in first_init.args.defaults] == [1] + + second_init: bases.UnboundMethod = next(second.infer()) + assert [a.name for a in second_init.args.args] == ["self", "attr"] + assert [a.value for a in second_init.args.defaults] == [1] + + third_init: bases.UnboundMethod = next(third.infer()) + assert [a.name for a in third_init.args.args] == ["self", "attr"] + assert [a.value for a in third_init.args.defaults] == [1] + + fourth = astroid.extract_node( + """ + from dataclasses import dataclass + + @dataclass + class Dataclass: + other_attr: str + attr: str + + @property + def attr(self) -> str: + return self.other_attr[-1] + + @attr.setter + def attr(self, value: int) -> None: + pass + + Dataclass.__init__ #@ + """ + ) + + fourth_init: bases.UnboundMethod = next(fourth.infer()) + assert [a.name for a in fourth_init.args.args] == ["self", "other_attr", "attr"] + assert [a.name for a in fourth_init.args.defaults] == ["Uninferable"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/tests/unittest_builder.py new/astroid-2.12.14/tests/unittest_builder.py --- old/astroid-2.12.13/tests/unittest_builder.py 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/tests/unittest_builder.py 2023-01-06 20:32:02.000000000 +0100 @@ -155,15 +155,23 @@ b = ast_module.body[1] assert isinstance(b, nodes.ClassDef) - assert b.fromlineno == 6 + if PY38 and IS_PYPY: + # Not perfect, but best we can do for PyPy 3.8 + assert b.fromlineno == 7 + else: + assert b.fromlineno == 6 assert b.tolineno == 7 c = ast_module.body[2] assert isinstance(c, nodes.ClassDef) - if not PY38_PLUS or PY38 and IS_PYPY: - # Not perfect, but best we can do for Python 3.7 and PyPy 3.8 + if not PY38_PLUS: + # Not perfect, but best we can do for Python 3.7 # Can't detect closing bracket on new line. assert c.fromlineno == 12 + elif PY38 and IS_PYPY: + # Not perfect, but best we can do for PyPy 3.8 + # Can't detect closing bracket on new line. + assert c.fromlineno == 16 else: assert c.fromlineno == 13 assert c.tolineno == 14 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/astroid-2.12.13/tests/unittest_nodes_position.py new/astroid-2.12.14/tests/unittest_nodes_position.py --- old/astroid-2.12.13/tests/unittest_nodes_position.py 2022-11-19 15:50:34.000000000 +0100 +++ new/astroid-2.12.14/tests/unittest_nodes_position.py 2023-01-06 20:32:02.000000000 +0100 @@ -7,6 +7,7 @@ import textwrap from astroid import builder, nodes +from astroid.const import IS_PYPY, PY38 class TestNodePosition: @@ -64,9 +65,11 @@ assert isinstance(e, nodes.ClassDef) assert e.position == (13, 0, 13, 7) - f = ast_nodes[5] - assert isinstance(f, nodes.ClassDef) - assert f.position == (18, 0, 18, 7) + if not PY38 or not IS_PYPY: + # The new (2022-12) version of pypy 3.8 broke this + f = ast_nodes[5] + assert isinstance(f, nodes.ClassDef) + assert f.position == (18, 0, 18, 7) @staticmethod def test_position_function() -> None: