Don't print the estimator like a dict (`{...}`) beyond `maxlevels`

### Describe the bug

Estimator pretty printer doesn't render deeply-nested estimators correctly.

### Steps/Code to Reproduce

```pycon
>>> from sklearn.base import BaseEstimator
>>> from sklearn.utils._pprint import _EstimatorPrettyPrinter
>>>
>>>
>>> # Constructors excerpted to test pprinting
>>> class LogisticRegression(BaseEstimator):
...     def __init__(
...         self,
...         penalty="l2",
...         dual=False,
...         tol=1e-4,
...         C=1.0,
...         fit_intercept=True,
...         intercept_scaling=1,
...         class_weight=None,
...         random_state=None,
...         solver="warn",
...         max_iter=100,
...         multi_class="warn",
...         verbose=0,
...         warm_start=False,
...         n_jobs=None,
...         l1_ratio=None,
...     ):
...         self.penalty = penalty
...         self.dual = dual
...         self.tol = tol
...         self.C = C
...         self.fit_intercept = fit_intercept
...         self.intercept_scaling = intercept_scaling
...         self.class_weight = class_weight
...         self.random_state = random_state
...         self.solver = solver
...         self.max_iter = max_iter
...         self.multi_class = multi_class
...         self.verbose = verbose
...         self.warm_start = warm_start
...         self.n_jobs = n_jobs
...         self.l1_ratio = l1_ratio
...     def fit(self, X, y):
...         return self
... 
>>>
>>> class RFE(BaseEstimator):
...     def __init__(self, estimator, n_features_to_select=None, step=1, verbose=0):
...         self.estimator = estimator
...         self.n_features_to_select = n_features_to_select
...         self.step = step
...         self.verbose = verbose
... 
>>>
>>> pp = _EstimatorPrettyPrinter(depth=1)
>>> rfe = RFE(RFE(RFE(RFE(RFE(LogisticRegression())))))
>>> pp.pformat(rfe)
'RFE(estimator={...})'
```

### Expected Results

```pycon
>>> pp.pformat(rfe)
'RFE(estimator=RFE(...), n_features_to_select=None, step=1, verbose=0)'
```

### Actual Results

```pycon
>>> pp.pformat(rfe)
'RFE(estimator={...})'
```

### Versions

```shell
System:
    python: 3.11.8 (main, Feb 26 2024, 15:36:12) [Clang 14.0.6 ]
executable: /opt/miniconda3/envs/ibis-ml-all/bin/python
   machine: macOS-14.5-arm64-arm-64bit

Python dependencies:
      sklearn: 1.5.0
          pip: 24.0
   setuptools: 69.5.1
        numpy: 1.26.4
        scipy: 1.13.1
       Cython: None
       pandas: 2.2.2
   matplotlib: None
       joblib: 1.4.2
threadpoolctl: 3.5.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 8
         prefix: libopenblas
       filepath: /opt/miniconda3/envs/ibis-ml-all/lib/python3.11/site-packages/numpy/.dylibs/libopenblas64_.0.dylib
        version: 0.3.23.dev
threading_layer: pthreads
   architecture: armv8

       user_api: blas
   internal_api: openblas
    num_threads: 8
         prefix: libopenblas
       filepath: /opt/miniconda3/envs/ibis-ml-all/lib/python3.11/site-packages/scipy/.dylibs/libopenblas.0.dylib
        version: 0.3.27
threading_layer: pthreads
   architecture: neoversen1

       user_api: openmp
   internal_api: openmp
    num_threads: 8
         prefix: libomp
       filepath: /opt/miniconda3/envs/ibis-ml-all/lib/python3.11/site-packages/sklearn/.dylibs/libomp.dylib
        version: None
```

COMMENT:
The code behaves as you all say in #29492:

```pycon
>>> from sklearn.base import BaseEstimator
>>> from sklearn.utils._pprint import _EstimatorPrettyPrinter
>>> class LogisticRegression(BaseEstimator):
...     def __init__(
...         self,
...         penalty="l2",
...     ):
...         self.penalty = penalty
...     def fit(self, X, y):
...         return self
... 
>>> class RFE(BaseEstimator):
...     def __init__(self, estimator, n_features_to_select=None, step=1, verbose=0):
...         self.estimator = estimator
...         self.n_features_to_select = n_features_to_select
...         self.step = step
...         self.verbose = verbose
... 
>>> pp = _EstimatorPrettyPrinter(depth=1)
>>> rfe = RFE(RFE(RFE(RFE(RFE(LogisticRegression())))))
>>> pp.pformat(rfe)
'RFE(estimator=RFE(...))'
>>> pp._changed_only = False
>>> pp.pformat(rfe)
'RFE(estimator=RFE(...), n_features_to_select=None, step=1, verbose=0)'
```

By comparison, here is the existing behavior:

```pycon
>>> # Use the same setup as above.
>>> pp = _EstimatorPrettyPrinter(depth=1)
>>> rfe = RFE(RFE(RFE(RFE(RFE(LogisticRegression())))))
>>> pp.pformat(rfe)
'RFE(estimator={...})'
>>> pp._changed_only = False
>>> pp.pformat(rfe)
'RFE(estimator={...}, n_features_to_select=None, step=1, verbose=0)'
```

As you can see, the difference is just in the condensed representation, because an estimator shouldn't look like a dict (or a list, or something else; it should look like the class instance):

```diff
4c4
< 'RFE(estimator=RFE(...))'
---
> 'RFE(estimator={...})'
7c7
< 'RFE(estimator=RFE(...), n_features_to_select=None, step=1, verbose=0)'
---
> 'RFE(estimator={...}, n_features_to_select=None, step=1, verbose=0)'
```

Labels: Bug