Deprecate nodes import from astroid (#2837)

diff --git a/ChangeLog b/ChangeLog
index 4447594..45e8821 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -96,6 +96,11 @@
   Closes pylint-dev/pylint#8985
   Closes pylint-dev/pylint#10558
 
+* Deprecate importing node classes from ``astroid`` directly. This will be removed in v5.
+  It's recommended to import them from ``astroid.nodes`` instead.
+
+  Refs #2837
+
 
 What's New in astroid 3.3.11?
 =============================
diff --git a/astroid/__init__.py b/astroid/__init__.py
index f420c31..abb45cf 100644
--- a/astroid/__init__.py
+++ b/astroid/__init__.py
@@ -80,91 +80,91 @@
 from astroid.astroid_manager import MANAGER
 from astroid.nodes import (
     CONST_CLS,
-    AnnAssign,
-    Arguments,
-    Assert,
-    Assign,
-    AssignAttr,
-    AssignName,
-    AsyncFor,
-    AsyncFunctionDef,
-    AsyncWith,
-    Attribute,
-    AugAssign,
-    Await,
-    BinOp,
-    BoolOp,
-    Break,
-    Call,
-    ClassDef,
-    Compare,
-    Comprehension,
-    ComprehensionScope,
-    Const,
-    Continue,
-    Decorators,
-    DelAttr,
-    Delete,
-    DelName,
-    Dict,
-    DictComp,
-    DictUnpack,
-    EmptyNode,
-    EvaluatedObject,
-    ExceptHandler,
-    Expr,
-    For,
-    FormattedValue,
-    FunctionDef,
-    GeneratorExp,
-    Global,
-    If,
-    IfExp,
-    Import,
-    ImportFrom,
-    Interpolation,
-    JoinedStr,
-    Keyword,
-    Lambda,
-    List,
-    ListComp,
-    Match,
-    MatchAs,
-    MatchCase,
-    MatchClass,
-    MatchMapping,
-    MatchOr,
-    MatchSequence,
-    MatchSingleton,
-    MatchStar,
-    MatchValue,
-    Module,
-    Name,
-    NamedExpr,
-    NodeNG,
-    Nonlocal,
-    ParamSpec,
-    Pass,
-    Raise,
-    Return,
-    Set,
-    SetComp,
-    Slice,
-    Starred,
-    Subscript,
-    TemplateStr,
-    Try,
-    TryStar,
-    Tuple,
-    TypeAlias,
-    TypeVar,
-    TypeVarTuple,
-    UnaryOp,
-    Unknown,
-    While,
-    With,
-    Yield,
-    YieldFrom,
+    AnnAssign as _DEPRECATED_AnnAssign,
+    Arguments as _DEPRECATED_Arguments,
+    Assert as _DEPRECATED_Assert,
+    Assign as _DEPRECATED_Assign,
+    AssignAttr as _DEPRECATED_AssignAttr,
+    AssignName as _DEPRECATED_AssignName,
+    AsyncFor as _DEPRECATED_AsyncFor,
+    AsyncFunctionDef as _DEPRECATED_AsyncFunctionDef,
+    AsyncWith as _DEPRECATED_AsyncWith,
+    Attribute as _DEPRECATED_Attribute,
+    AugAssign as _DEPRECATED_AugAssign,
+    Await as _DEPRECATED_Await,
+    BinOp as _DEPRECATED_BinOp,
+    BoolOp as _DEPRECATED_BoolOp,
+    Break as _DEPRECATED_Break,
+    Call as _DEPRECATED_Call,
+    ClassDef as _DEPRECATED_ClassDef,
+    Compare as _DEPRECATED_Compare,
+    Comprehension as _DEPRECATED_Comprehension,
+    ComprehensionScope as _DEPRECATED_ComprehensionScope,
+    Const as _DEPRECATED_Const,
+    Continue as _DEPRECATED_Continue,
+    Decorators as _DEPRECATED_Decorators,
+    DelAttr as _DEPRECATED_DelAttr,
+    Delete as _DEPRECATED_Delete,
+    DelName as _DEPRECATED_DelName,
+    Dict as _DEPRECATED_Dict,
+    DictComp as _DEPRECATED_DictComp,
+    DictUnpack as _DEPRECATED_DictUnpack,
+    EmptyNode as _DEPRECATED_EmptyNode,
+    EvaluatedObject as _DEPRECATED_EvaluatedObject,
+    ExceptHandler as _DEPRECATED_ExceptHandler,
+    Expr as _DEPRECATED_Expr,
+    For as _DEPRECATED_For,
+    FormattedValue as _DEPRECATED_FormattedValue,
+    FunctionDef as _DEPRECATED_FunctionDef,
+    GeneratorExp as _DEPRECATED_GeneratorExp,
+    Global as _DEPRECATED_Global,
+    If as _DEPRECATED_If,
+    IfExp as _DEPRECATED_IfExp,
+    Import as _DEPRECATED_Import,
+    ImportFrom as _DEPRECATED_ImportFrom,
+    Interpolation as _DEPRECATED_Interpolation,
+    JoinedStr as _DEPRECATED_JoinedStr,
+    Keyword as _DEPRECATED_Keyword,
+    Lambda as _DEPRECATED_Lambda,
+    List as _DEPRECATED_List,
+    ListComp as _DEPRECATED_ListComp,
+    Match as _DEPRECATED_Match,
+    MatchAs as _DEPRECATED_MatchAs,
+    MatchCase as _DEPRECATED_MatchCase,
+    MatchClass as _DEPRECATED_MatchClass,
+    MatchMapping as _DEPRECATED_MatchMapping,
+    MatchOr as _DEPRECATED_MatchOr,
+    MatchSequence as _DEPRECATED_MatchSequence,
+    MatchSingleton as _DEPRECATED_MatchSingleton,
+    MatchStar as _DEPRECATED_MatchStar,
+    MatchValue as _DEPRECATED_MatchValue,
+    Module as _DEPRECATED_Module,
+    Name as _DEPRECATED_Name,
+    NamedExpr as _DEPRECATED_NamedExpr,
+    NodeNG as _DEPRECATED_NodeNG,
+    Nonlocal as _DEPRECATED_Nonlocal,
+    ParamSpec as _DEPRECATED_ParamSpec,
+    Pass as _DEPRECATED_Pass,
+    Raise as _DEPRECATED_Raise,
+    Return as _DEPRECATED_Return,
+    Set as _DEPRECATED_Set,
+    SetComp as _DEPRECATED_SetComp,
+    Slice as _DEPRECATED_Slice,
+    Starred as _DEPRECATED_Starred,
+    Subscript as _DEPRECATED_Subscript,
+    TemplateStr as _DEPRECATED_TemplateStr,
+    Try as _DEPRECATED_Try,
+    TryStar as _DEPRECATED_TryStar,
+    Tuple as _DEPRECATED_Tuple,
+    TypeAlias as _DEPRECATED_TypeAlias,
+    TypeVar as _DEPRECATED_TypeVar,
+    TypeVarTuple as _DEPRECATED_TypeVarTuple,
+    UnaryOp as _DEPRECATED_UnaryOp,
+    Unknown as _DEPRECATED_Unknown,
+    While as _DEPRECATED_While,
+    With as _DEPRECATED_With,
+    Yield as _DEPRECATED_Yield,
+    YieldFrom as _DEPRECATED_YieldFrom,
     are_exclusive,
     builtin_lookup,
     unpack_infer,
@@ -174,3 +174,69 @@
 # isort: on
 
 from astroid.util import Uninferable
+
+__all__ = [
+    "CONST_CLS",
+    "MANAGER",
+    "AstroidBuildingError",
+    "AstroidError",
+    "AstroidImportError",
+    "AstroidIndexError",
+    "AstroidSyntaxError",
+    "AstroidTypeError",
+    "AstroidValueError",
+    "AttributeInferenceError",
+    "BaseInstance",
+    "BoundMethod",
+    "Context",
+    "DuplicateBasesError",
+    "ExceptionInstance",
+    "InconsistentMroError",
+    "InferenceError",
+    "InferenceOverwriteError",
+    "Instance",
+    "MroError",
+    "NameInferenceError",
+    "NoDefault",
+    "NotFoundError",
+    "ParentMissingError",
+    "ResolveError",
+    "StatementMissing",
+    "SuperArgumentTypeError",
+    "SuperError",
+    "TooManyLevelsError",
+    "UnboundMethod",
+    "Uninferable",
+    "UnresolvableName",
+    "UseInferenceDefault",
+    "__version__",
+    "_inference_tip_cached",
+    "are_exclusive",
+    "builtin_lookup",
+    "extract_node",
+    "function_to_method",
+    "inference_tip",
+    "node_classes",
+    "parse",
+    "raw_building",
+    "register_module_extender",
+    "scoped_nodes",
+    "unpack_infer",
+    "version",
+]
+
+
+def __getattr__(name: str):
+    if (val := globals().get(f"_DEPRECATED_{name}")) is None:
+        msg = f"module '{__name__}' has no attribute '{name}"
+        raise AttributeError(msg)
+
+    # pylint: disable-next=import-outside-toplevel
+    import warnings
+
+    msg = (
+        f"importing '{name}' from 'astroid' is deprecated and will be removed in v5, "
+        "import it from 'astroid.nodes' instead"
+    )
+    warnings.warn(msg, DeprecationWarning, stacklevel=2)
+    return val
diff --git a/tests/test_nodes.py b/tests/test_nodes.py
index 6ff4e81..8d2f4d5 100644
--- a/tests/test_nodes.py
+++ b/tests/test_nodes.py
@@ -13,6 +13,7 @@
 import sys
 import textwrap
 import unittest
+import warnings
 from typing import Any
 
 import pytest
@@ -2311,3 +2312,21 @@
 
     node = extract_node("def fruit(seeds, flavor='good', *, peel='maybe'): ...")
     assert node.args.default_value("flavor").value == "good"
+
+
+def test_deprecated_nodes_import_from_toplevel():
+    # pylint: disable=import-outside-toplevel,no-name-in-module
+    with pytest.raises(
+        DeprecationWarning, match="importing 'For' from 'astroid' is deprecated"
+    ):
+        from astroid import For
+
+    with warnings.catch_warnings():
+        warnings.simplefilter("ignore", DeprecationWarning)
+        from astroid import For
+
+        assert For is nodes.For
+
+    # This should not raise a DeprecationWarning
+    # pylint: disable-next=unused-import
+    from astroid import builtin_lookup