Repository: scipy/scipy
File: scipy/stats/_resampling.py (Python)

Code before:

        If this argument is passed by position or `random_state` is passed by keyword
        into the initializer, or if the `random_state` attribute is used directly,
        legacy behavior for `random_state` applies:

        - If `random_state` is None (or `numpy.random`), the `numpy.random.RandomState`
          singleton is used.
        - If `random_state` is an int, a new ``RandomState`` instance is used,
          seeded with `random_state`.
        - If `random_state` is already a ``Generator`` or ``RandomState`` instance then
          that instance is used.

        .. versionchanged:: 1.15.0

            As part of the `SPEC-007 <https://scientific-python.org/specs/spec-0007/>`_
            transition from use of `numpy.random.RandomState` to
            `numpy.random.Generator`, this attribute name was changed from
            `random_state` to `rng`. For an interim period, both names will continue to
            work, although only one may be specified at a time. After the interim
            period, uses of `random_state` will emit warnings. The behavior of both
            `random_state` and `rng` are outlined above, but only `rng` should be used
            in new code.

    """
    rng: int
    _rng: int = field(init=False, repr=False, default=9999)

    @property
    def random_state(self):
        # warnings.warn(_rs_deprecation, DeprecationWarning, level=2)
        return self._rng

    @random_state.setter
    def random_state(self, val):
        # warnings.warn(_rs_deprecation, DeprecationWarning, level=2)
        self._rng = val

    @property
    def rng(self):
        return self._rng

    @random_state.setter
    def rng(self, val):
        self._rng = np.random.default_rng(val)

    @_transition_to_rng('random_state', position_num=3, replace_doc=False)
    def __init__(self, n_resamples=9999, batch=None, rng=None):
        self._rng = rng  # don't validate with `default_rng` during SPEC 7 transition
        super().__init__(n_resamples=n_resamples, batch=batch)

    def _asdict(self):

Review comment (suggestion):
This is a little complicated because we're trying to preserve all the niceties of a dataclass (e.g. automatic `__repr__`). Solution draws from https://florimond.dev/en/posts/2018/10/reconciling-dataclasses-and-properties-in-python.

Code after:
        If `rng` is already a ``Generator`` instance, then the provided instance is
        used. Specify `rng` for repeatable behavior.

        If this argument is passed by position, if `random_state` is passed by keyword
        into the initializer, or if the `random_state` attribute is used directly,
        legacy behavior for `random_state` applies:

        - If `random_state` is None (or `numpy.random`), the `numpy.random.RandomState`
          singleton is used.
        - If `random_state` is an int, a new ``RandomState`` instance is used,
          seeded with `random_state`.
        - If `random_state` is already a ``Generator`` or ``RandomState`` instance then
          that instance is used.

        .. versionchanged:: 1.15.0

            As part of the `SPEC-007 <https://scientific-python.org/specs/spec-0007/>`_
            transition from use of `numpy.random.RandomState` to
            `numpy.random.Generator`, this attribute name was changed from
            `random_state` to `rng`. For an interim period, both names will continue to
            work, although only one may be specified at a time. After the interim
            period, uses of `random_state` will emit warnings. The behavior of both
            `random_state` and `rng` are outlined above, but only `rng` should be used
            in new code.

    """
    rng: object  # type: ignore[misc]
    _rng: object = field(init=False, repr=False, default=None)  # type: ignore[assignment]

    @property
    def random_state(self):
        # Uncomment in SciPy 1.17.0
        # warnings.warn(_rs_deprecation, DeprecationWarning, stacklevel=2)
        return self._rng

    @random_state.setter
    def random_state(self, val):
        # Uncomment in SciPy 1.17.0
        # warnings.warn(_rs_deprecation, DeprecationWarning, stacklevel=2)
        self._rng = val

    @property  # type: ignore[no-redef]
    def rng(self):  # noqa: F811
        return self._rng

    @random_state.setter
    def rng(self, val):  # noqa: F811
        self._rng = np.random.default_rng(val)

    @_transition_to_rng('random_state', position_num=3, replace_doc=False)
    def __init__(self, n_resamples=9999, batch=None, rng=None):