code: def __new__(
      mcs,
      name,
      bases,
      dict_,
      /,
      strict: Union[bool, StrictConfig] = False,
      **kwargs,
  ):
      if isinstance(strict, bool):
          strict_config = StrictConfig()
      elif isinstance(strict, StrictConfig):
          strict_config = strict
          strict = True
      else:
          raise TypeError(
              "The `strict` parameter in `class Foo(equinox.Module, strict=...)` "
              "must either be a `bool` or `equinox.StrictConfig` object."
          )
  
      # [Step 1] Create the class as normal.
      cls = super().__new__(mcs, name, bases, dict_, **kwargs)
      # [Step 2] Arrange for bound methods to be treated as PyTrees as well. This
      # ensures that
      # ```
      # @jax.jit
      # def run(fn):
      #     ...
      # run(SomeModule().some_method)
      # ```
      # works.
      for k, v in cls.__dict__.items():
          if _not_magic(k) and inspect.isfunction(v):
              setattr(cls, k, _wrap_method(v))
  
      # [Step 3] Handle initialisation.
      #
      # For context, with any Python dataclass, there are three possible scenarios for
      # initialisation:
      # (a) a user-provided `__init__` method is supplied;
      # (b) dataclasses creates `__init__` , without a user-provided `__post_init__`
      # (c) dataclasses creates `__init__` , with a user-provided `__post_init__`
  
      # Create a dataclass `__init__` method if a user method isn't provided.
      # If a user passed one on this class, then we definitely have a custom __init__.
      # Else just use whatever our superclass does. Note that this is different to
      # default dataclass behaviour. Given
      # ```
      # @dataclass
      # class Foo: def __init__(...): ...
      # @dataclass
      # class Bar(Foo): pass
      # ```
      # then `Bar` will end up with a dataclass-provided `__init__`. That ends up
      # being ergonomically very annoying, so we disable it.
      added_custom_init = "__init__" in cls.__dict__
      if added_custom_init:
          has_dataclass_init = False
      else:
          for kls in cls.__mro__[1:-1]:
              try:
                  has_dataclass_init = _has_dataclass_init[kls]
              except KeyError:
                  # Non-Module superclasses.
                  if kls.__init__ is not object.__init__:
                      has_dataclass_init = False
                      break
              else:
                  break
          else:
              assert name == "Module"
              has_dataclass_init = True  # eqx.Module itself
  
      # Check for a common error. (Check for `_Initable` to avoid duplicate warnings.)
      if (
          not has_dataclass_init
          and hasattr(cls, "__post_init__")
          and not issubclass(cls, _Initable)
      ):
          warnings.warn(
              f"Class `{cls.__module__}.{cls.__qualname__}` has both an "
              "`__init__` method and a `__post_init__` method. This means that "
              "the `__post_init__` method will not be run!\n"
              "The reason for this is that `__post_init__` is intended to be "
              "used with the automatically-generated `__init__` method provided "
              "by Python dataclasses, which are generated of the form:\n"
              "```\n"
              "def __init__(self, field1, field2)\n"
              "    self.field1 = field1\n"
              "    self.field2 = field2\n"
              "    self.__post_init__()\n"
              "```\n"
              "and as such a user-provided `__init__` overrides both the setting "
              "of fields, and the calling of `__post_init__`.\n"
              "The above is how Python dataclasses work, and has nothing "
              "to do with Equinox!\n"
              "If you are using `__post_init__` to check that certain invariants "
              "hold, then consider using `__check_init__` instead. This is an "
              "Equinox-specific extension that is always ran. See here for more "
              "details: "
              "https://docs.kidger.site/equinox/api/module/advanced_fields/#checking-invariants"  # noqa: E501
          )
  
      # Add support for `eqx.field(converter=...)` when using `__post_init__`.
      # (Scenario (c) above. Scenarios (a) and (b) are handled later.)
      if has_dataclass_init and hasattr(cls, "__post_init__"):
          post_init = cls.__post_init__
  
          @ft.wraps(post_init)  # pyright: ignore
          def __post_init__(self, *args, **kwargs):
              # This `if` is to handle `super()` correctly.
              # We want to only convert once, at the top level.
              #
              # This check is basically testing whether or not the function we're in
              # now (`cls.__post_init__`) is at the top level
              # (`self.__class__.__post_init__`). If we are, do conversion. If we're
              # not, it's presumably because someone is calling us via `super()` in
              # the middle of their own `__post_init__`. No conversion then; their own
              # version of this wrapper will do it at the appropriate time instead.
              #
              # One small foible: we write `cls.__post_init__`, rather than just
              # `__post_init__`, to refer to this function. This allows someone else
              # to also monkey-patch `cls.__post_init__` if they wish, and this won't
              # remove conversion. (Conversion is a at-the-top-level thing, not a
              # this-particular-function thing.)
              #
              # This top-level business means that this is very nearly the same as
              # doing conversion in `_ModuleMeta.__call__`. The differences are that
              # (a) that wouldn't allow us to convert fields before the user-provided
              # `__post_init__`, and (b) it allows other libraries (i.e. jaxtyping)
              # to later monkey-patch `__init__`, and we have our converter run before
              # their own monkey-patched-in code.
              if self.__class__.__post_init__ is cls.__post_init__:
                  # Convert all fields currently available.
                  _convert_fields(self, init=True)
              post_init(self, *args, **kwargs)  # pyright: ignore
              if self.__class__.__post_init__ is cls.__post_init__:
                  # Convert all the fields filled in by `__post_init__` as well.
                  _convert_fields(self, init=False)
  
          cls.__post_init__ = __post_init__  # pyright: ignore
      else:
          post_init = None
  
      # Fairly common to write `Superclass.__init__.__doc__ = "..."` with
      # dataclass-provided inits; here we look through the class hierarchy and will
      # copy this doc forward.
      if has_dataclass_init:
          init_doc = cls.__init__.__doc__
  
      # [Step 4] Register as a dataclass.
      cls = dataclass(
          eq=False, repr=False, frozen=True, init=has_dataclass_init
      )(
          cls  # pyright: ignore
      )
      # [Step 3b] -- finish off building `__init__` methods. Until we'd done
      # dataclass'ification then we didn't necessarily have our `__init__` method.
  
      # Registering here records that the `dataclass(...)` call has happened.
      _has_dataclass_init[cls] = has_dataclass_init
  
      # Now handle conversion for cases (a) and (b) above, in which there is no
      # `__post_init__`.
      if post_init is None:
          init = cls.__init__
  
          @ft.wraps(init)  # pyright: ignore
          def __init__(self, *args, **kwargs):
              __tracebackhide__ = True
              init(self, *args, **kwargs)
              # Same `if` trick as with `__post_init__`.
              if self.__class__.__init__ is cls.__init__:
                  _convert_fields(self, init=True)
                  _convert_fields(self, init=False)
  
          cls.__init__ = __init__
  
      # Assign `__doc__` in case it has been manually overriden:
      # ```
      # class Foo(eqx.Module):
      #     x: int
      #
      # Foo.__init__.__doc__ = "Foo should be called with with an integer `x`."
      #
      # class Bar(Foo):
      #     pass
      #
      # # Now we try to access `Bar.__init__.__doc__`. (E.g. during docgen.)
      # ```
      if has_dataclass_init:
          cls.__init__.__doc__ = init_doc  # pyright: ignore
          # TODO: is this next line still necessary?
          cls.__init__.__module__ = cls.__module__
  
      # [Step 5] We support an optional `strict` mode for Rust-like strictness in the
      # type checking.
      # In practice this is probably too much for your average user, but it's a great
      # way to build robust libraries.
      _is_force_abstract[cls] = strict_config.force_abstract
      _is_strict[cls] = strict
      if strict:
          for base in bases:
              if base is Module:
                  # We shouldn't check `Module` itself: we can't make it strict as to
                  # be able to inherit from it we would need to make it abstract. To
                  # be able to make it abstract its name must start with `Abstract`.
                  # That we cannot do for backward compatibility.
                  continue
              if _is_special_form(base):
                  # Skip `typing.Generic` etc.
                  continue
              # Invariant: all base classes are also strict modules.
              if not issubclass(base, Module):
                  raise TypeError(
                      "Strict `eqx.Module`s must only inherit from other strict "
                      f"`eqx.Module`s. `{cls.__module__}.{cls.__qualname__}` is a "
                      "strict Module inheriting from "
                      f"`{base.__module__}.{base.__qualname__}`, which is not a "
                      "`Module` at all."
                  )
              if not _is_strict[base]:
                  raise TypeError(
                      "Strict `eqx.Module`s must only inherit from other strict "
                      f"`eqx.Module`s. `{cls.__module__}.{cls.__qualname__}` is a "
                      "strict Module inheriting from "
                      f"`{base.__module__}.{base.__qualname__}`, which is a "
                      "`Module`, but not a strict `Module`."
                  )
              # Invariant: concrete means final.
              if not _is_abstract(base):
                  raise TypeError(
                      "Every strict `eqx.Module` must be either abstract or final. "
                      "This means that it is not possible to inherit from a concrete "
                      f"strict `eqx.Module`. `{cls.__module__}.{cls.__qualname__}` "
                      "is a strict Module inheriting from "
                      f"`{base.__module__}.{base.__qualname__}`, which is a concrete "
                      "strict `Module`."
                  )
              # Invariant: field definitions and __init__ methods must all appear on
              # just one class in a hierarchy.
              base_num_fields = len(dataclasses.fields(base))
              if (base_num_fields > 0) or (
                  not _has_dataclass_init[base]
              ):
                  # If we've added more fields, or added a custom init method, then
                  # error.
                  if len(dataclasses.fields(cls)) != base_num_fields:
                      raise TypeError(
                          "For readability, any custom `__init__` method, and all "
                          "fields, must all be defined on the same strict Module. "
                          f"{cls.__module__}.{cls.__qualname__} is a strict Module "
                          "that is attempting to add fields, and inherit from "
                          f"{base.__module__}.{base.__qualname__}. However the "
                          "latter already has fields or a custom `__init__` defined."
                      )
                  if added_custom_init:
                      raise TypeError(
                          "For readability, any custom `__init__` method, and all "
                          "fields, must all be defined on the same strict Module. "
                          f"{cls.__module__}.{cls.__qualname__} is a strict Module "
                          "that is attempting to define a custom `__init__` method, "
                          f"and inherit from {base.__module__}.{base.__qualname__}. "
                          "However the latter already has fields "
                          "or a custom `__init__` defined."
                      )
          if not strict_config.allow_abstract_name:
              has_abstract_name = cls.__name__.startswith(
                  "Abstract"
              ) or cls.__name__.startswith("_Abstract")
              if _is_abstract(cls):
                  if not has_abstract_name:
                      # Invariant: abstract classes have names beginning with
                      # `Abstract`.
                      raise TypeError(
                          "Abstract strict `eqx.Module`s must be named starting "
                          f"with 'Abstract' or '_Abstract'. Got {name} when defining "
                          f"{cls.__module__}.{cls.__qualname__}.",
                      )
              else:
                  if has_abstract_name:
                      # Invariant: concrete classes do not have names beginning with
                      # `Abstract`.
                      raise TypeError(
                          "Concrete strict `eqx.Module`s should not have names "
                          f"starting with 'Abstract' or '_Abstract'. Got '{name}' "
                          f"when defining {cls.__module__}.{cls.__qualname__}.",
                      )
          for k, v in cls.__dict__.items():
              if isinstance(v, _wrap_method):
                  v = v.method
                  # Invariant: concrete methods are not overridden.
                  if not getattr(v, "__isabstractmethod__", False):
                      for base in bases:
                          old_v = getattr(base, k, _dummy_abstract)
                          if not inspect.isfunction(old_v):
                              raise TypeError(
                                  "Strict `eqx.Module`s cannot override non-methods "
                                  "with methods. "
                                  f"`{cls.__module__}.{cls.__qualname__}.{k}` is "
                                  "attempting to override "
                                  f"`{base.__module__}.{base.__qualname__}.{k}`."
                              )
                          if (
                              not strict_config.allow_method_override
                              and not getattr(
                                  old_v, "__isabstractmethod__", False
                              )
                          ):
                              raise TypeError(
                                  "Strict `eqx.Module`s cannot override concrete "
                                  "methods. "
                                  f"`{cls.__module__}.{cls.__qualname__}.{k}` is "
                                  "attempting to override "
                                  f"`{base.__module__}.{base.__qualname__}.{k}`."
                              )
      # [Step 6] Register as a pytree.
      jtu.register_pytree_with_keys(
          cls,
          flatten_with_keys=ft.partial(
              _flatten_module, with_keys=True
          ),  # pyright: ignore
          flatten_func=ft.partial(
              _flatten_module, with_keys=False
          ),  # pyright: ignore
          unflatten_func=ft.partial(
              _unflatten_module, cls
          ),  # pyright: ignore
      )
      # Done!
      return cls
  
imports: import abc
  import dataclasses
  import functools
  import inspect
  import types
  import warnings
  import weakref
  from collections.abc import Callable
  from typing import Any, cast, Optional, Protocol, TYPE_CHECKING, TypeVar, Union
  from typing_extensions import dataclass_transform, ParamSpec
  import jax._src.traceback_util
  import jax.tree_util
  import numpy
  from jaxtyping import Array, Bool, PyTreeDef
  from ._better_abstract import ABCMeta, dataclass
  from ._caches import internal_lru_caches
  from ._doc_utils import doc_repr
  from ._pretty_print import tree_pformat
  from ._tree import tree_equal
label_desc: Use image node_id 1 for calling the _ModuleMeta obj's underlying member method code with example usage: obj.__new__(strict) and returns: cls