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:

Reply via email to