class_docstr: A Type wrapper for `numpy.random.RandomState`.
  
  The reason this exists (and `Generic` doesn't suffice) is that
  `RandomState` objects that would appear to be equal do not compare equal
  with the ``==`` operator.
  
  This `Type` also works with a ``dict`` derived from
  `RandomState.get_state(legacy=False)`, unless the ``strict`` argument to `Type.filter`
  is explicitly set to ``True``.
class_docstr_tok: ["A","Type","wrapper","for","`","numpy.random.RandomState","`",".","The","reason","this","exists","(","and","`","Generic","`","does","n't","suffice",")","is","that","`","RandomState","`","objects","that","would","appear","to","be","equal","do","not","compare","equal","with","the","``","==","``","operator",".","This","`","Type","`","also","works","with","a","``","dict","``","derived","from","`","RandomState.get_state","(","legacy=False",")","`",",","unless","the","``","strict","``","argument","to","`","Type.filter","`","is","explicitly","set","to","``","True","``","."]
docstr: XXX: This doesn't convert `data` to the same type of underlying RNG type
  as `self`.  It really only checks that `data` is of the appropriate type
  to be a valid `RandomStateType`.
  
  In other words, it serves as a `Type.is_valid_value` implementation,
  but, because the default `Type.is_valid_value` depends on
  `Type.filter`, we need to have it here to avoid surprising circular
  dependencies in sub-classes.
docstr_tok: ["XXX",":","This","does","n't","convert","`","data","`","to","the","same","type","of","underlying","RNG","type","as","`","self","`",".","It","really","only","checks","that","`","data","`","is","of","the","appropriate","type","to","be","a","valid","`","RandomStateType","`",".","In","other","words",",","it","serves","as","a","`","Type.is_valid_value","`","implementation",",","but",",","because","the","default","`","Type.is_valid_value","`","depends","on","`","Type.filter","`",",","we","need","to","have","it","here","to","avoid","surprising","circular","dependencies","in","sub-classes","."]
code: def filter(self, data, strict: bool = False, allow_downcast=None):
      """
      XXX: This doesn't convert `data` to the same type of underlying RNG type
      as `self`.  It really only checks that `data` is of the appropriate type
      to be a valid `RandomStateType`.
  
      In other words, it serves as a `Type.is_valid_value` implementation,
      but, because the default `Type.is_valid_value` depends on
      `Type.filter`, we need to have it here to avoid surprising circular
      dependencies in sub-classes.
      """
      if isinstance(data, np.random.RandomState):
          return data
  
      if not strict and isinstance(data, dict):
          gen_keys = ["bit_generator", "gauss", "has_gauss", "state"]
          state_keys = ["key", "pos"]
  
          for key in gen_keys:
              if key not in data:
                  raise TypeError()
  
          for key in state_keys:
              if key not in data["state"]:
                  raise TypeError()
  
          state_key = data["state"]["key"]
          if state_key.shape == (624,) and state_key.dtype == np.uint32:
              # TODO: Add an option to convert to a `RandomState` instance?
              return data
  
      raise TypeError()
  
imports: from typing import TypeVar
  import numpy
  import pytensor
  from pytensor.graph.type import Type
label_desc: Use image node_id 2 for calling the RandomStateType obj's underlying member method code with example usage: obj.filter(data, strict, allow_downcast) and returns: data, data