Fix `random.sample` crash when cloning `ClassDef` and `FunctionDef` nodes (#2937)


Signed-off-by: Emmanuel Ferdman <emmanuelferdman@gmail.com>
diff --git a/ChangeLog b/ChangeLog
index a661b96..d92379a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -56,6 +56,10 @@
 
   Closes #2518
 
+* Fix ``random.sample`` crash when cloning ``ClassDef`` or ``FunctionDef`` nodes.
+
+  Closes #2923
+
 What's New in astroid 4.0.3?
 ============================
 Release date: 2026-01-03
diff --git a/astroid/brain/brain_random.py b/astroid/brain/brain_random.py
index d83fda1..849a9f4 100644
--- a/astroid/brain/brain_random.py
+++ b/astroid/brain/brain_random.py
@@ -4,6 +4,7 @@
 
 from __future__ import annotations
 
+import inspect
 import random
 
 from astroid import nodes
@@ -30,11 +31,19 @@
         "end_col_offset": node.end_col_offset,
     }
     postinit_params = {param: getattr(node, param) for param in _astroid_fields}
-    if other_fields:
-        init_params.update({param: getattr(node, param) for param in other_fields})
+
+    valid_init_params = set(inspect.signature(cls.__init__).parameters)
+    for param in other_fields:
+        if param in valid_init_params:
+            init_params[param] = getattr(node, param)
+
     new_node = cls(**init_params)
     if hasattr(node, "postinit") and _astroid_fields:
         new_node.postinit(**postinit_params)
+
+    for param in other_fields:
+        if param not in valid_init_params:
+            setattr(new_node, param, getattr(node, param))
     return new_node
 
 
diff --git a/tests/brain/test_brain.py b/tests/brain/test_brain.py
index 83c8772..b66cf0e 100644
--- a/tests/brain/test_brain.py
+++ b/tests/brain/test_brain.py
@@ -1091,6 +1091,40 @@
         inferred = next(node.infer())
         assert inferred is astroid.Uninferable
 
+    def test_no_crash_on_classdef_clone(self) -> None:
+        """Test that random.sample does not crash when cloning ClassDef nodes.
+
+        Regression test for https://github.com/pylint-dev/astroid/issues/2923
+        """
+        node = astroid.extract_node(
+            """
+        import random
+        random.sample([dict] * 2, 1)  #@
+        """
+        )
+        inferred = next(node.infer())
+        assert isinstance(inferred, nodes.List)
+        assert len(inferred.elts) == 1
+        assert isinstance(inferred.elts[0], nodes.ClassDef)
+        assert inferred.elts[0].name == "dict"
+
+    def test_no_crash_on_functiondef_clone(self) -> None:
+        """Test that random.sample does not crash when cloning FunctionDef nodes.
+
+        Regression test for https://github.com/pylint-dev/astroid/issues/2923
+        """
+        node = astroid.extract_node(
+            """
+        import random
+        random.sample([len] * 2, 1)  #@
+        """
+        )
+        inferred = next(node.infer())
+        assert isinstance(inferred, nodes.List)
+        assert len(inferred.elts) == 1
+        assert isinstance(inferred.elts[0], nodes.FunctionDef)
+        assert inferred.elts[0].name == "len"
+
 
 class SubprocessTest(unittest.TestCase):
     """Test subprocess brain"""