parameters: (members='', name='Immutable', verbose=False)
return_statement: return namespace[name]
docstring: Produces a class that either can be used standalone or as a base class for persistent classes.
  
      This is a thin wrapper around a named tuple.
  
      Constructing a type and using it to instantiate objects:
  
      >>> Point = immutable('x, y', name='Point')
      >>> p = Point(1, 2)
      >>> p2 = p.set(x=3)
      >>> p
      Point(x=1, y=2)
      >>> p2
      Point(x=3, y=2)
  
      Inheriting from a constructed type. In this case no type name needs to be supplied:
  
      >>> class PositivePoint(immutable('x, y')):
      ...     __slots__ = tuple()
      ...     def __new__(cls, x, y):
      ...         if x > 0 and y > 0:
      ...             return super(PositivePoint, cls).__new__(cls, x, y)
      ...         raise Exception('Coordinates must be positive!')
      ...
      >>> p = PositivePoint(1, 2)
      >>> p.set(x=3)
      PositivePoint(x=3, y=2)
      >>> p.set(y=-3)
      Traceback (most recent call last):
      Exception: Coordinates must be positive!
  
      The persistent class also supports the notion of frozen members. The value of a frozen member
      cannot be updated. For example it could be used to implement an ID that should remain the same
      over time. A frozen member is denoted by a trailing underscore.
  
      >>> Point = immutable('x, y, id_', name='Point')
      >>> p = Point(1, 2, id_=17)
      >>> p.set(x=3)
      Point(x=3, y=2, id_=17)
      >>> p.set(id_=18)
      Traceback (most recent call last):
      AttributeError: Cannot set frozen members id_
docstring_summary: Produces a class that either can be used standalone or as a base class for persistent classes.
docstring_tokens: Produces a class that either can be used standalone or as a base class for persistent classes .
function: def immutable(members='', name='Immutable', verbose=False):
      """
      Produces a class that either can be used standalone or as a base class for persistent classes.
  
      This is a thin wrapper around a named tuple.
  
      Constructing a type and using it to instantiate objects:
  
      >>> Point = immutable('x, y', name='Point')
      >>> p = Point(1, 2)
      >>> p2 = p.set(x=3)
      >>> p
      Point(x=1, y=2)
      >>> p2
      Point(x=3, y=2)
  
      Inheriting from a constructed type. In this case no type name needs to be supplied:
  
      >>> class PositivePoint(immutable('x, y')):
      ...     __slots__ = tuple()
      ...     def __new__(cls, x, y):
      ...         if x > 0 and y > 0:
      ...             return super(PositivePoint, cls).__new__(cls, x, y)
      ...         raise Exception('Coordinates must be positive!')
      ...
      >>> p = PositivePoint(1, 2)
      >>> p.set(x=3)
      PositivePoint(x=3, y=2)
      >>> p.set(y=-3)
      Traceback (most recent call last):
      Exception: Coordinates must be positive!
  
      The persistent class also supports the notion of frozen members. The value of a frozen member
      cannot be updated. For example it could be used to implement an ID that should remain the same
      over time. A frozen member is denoted by a trailing underscore.
  
      >>> Point = immutable('x, y, id_', name='Point')
      >>> p = Point(1, 2, id_=17)
      >>> p.set(x=3)
      Point(x=3, y=2, id_=17)
      >>> p.set(id_=18)
      Traceback (most recent call last):
      AttributeError: Cannot set frozen members id_
      """
  
      if isinstance(members, six.string_types):
          members = members.replace(',', ' ').split()
  
      def frozen_member_test():
          frozen_members = ["'%s'" % f for f in members if f.endswith('_')]
          if frozen_members:
              return """
          frozen_fields = fields_to_modify & set([{frozen_members}])
          if frozen_fields:
              raise AttributeError('Cannot set frozen members %s' % ', '.join(frozen_fields))
              """.format(frozen_members=', '.join(frozen_members))
  
          return ''
  
      verbose_string = ""
      if sys.version_info < (3, 7):
          # Verbose is no longer supported in Python 3.7
          verbose_string = ", verbose={verbose}".format(verbose=verbose)
  
      quoted_members = ', '.join("'%s'" % m for m in members)
      template = """
  class {class_name}(namedtuple('ImmutableBase', [{quoted_members}]{verbose_string})):
      __slots__ = tuple()
  
      def __repr__(self):
          return super({class_name}, self).__repr__().replace('ImmutableBase', self.__class__.__name__)
  
      def set(self, **kwargs):
          if not kwargs:
              return self
  
          fields_to_modify = set(kwargs.keys())
          if not fields_to_modify <= {member_set}:
              raise AttributeError("'%s' is not a member" % ', '.join(fields_to_modify - {member_set}))
  
          {frozen_member_test}
  
          return self.__class__.__new__(self.__class__, *map(kwargs.pop, [{quoted_members}], self))
  """.format(quoted_members=quoted_members,
                 member_set="set([%s])" % quoted_members if quoted_members else 'set()',
                 frozen_member_test=frozen_member_test(),
                 verbose_string=verbose_string,
                 class_name=name)
  
      if verbose:
          print(template)
  
      from collections import namedtuple
      namespace = dict(namedtuple=namedtuple, __name__='pyrsistent_immutable')
      try:
          six.exec_(template, namespace)
      except SyntaxError as e:
          raise SyntaxError(e.message + ':\n' + template)
  
      return namespace[name]
function_tokens: def immutable ( members = '' , name = 'Immutable' , verbose = False ) : if isinstance ( members , six . string_types ) : members = members . replace ( ',' , ' ' ) . split ( ) def frozen_member_test ( ) : frozen_members = [ "'%s'" % f for f in members if f . endswith ( '_' ) ] if frozen_members : return """
          frozen_fields = fields_to_modify & set([{frozen_members}])
          if frozen_fields:
              raise AttributeError('Cannot set frozen members %s' % ', '.join(frozen_fields))
              """ . format ( frozen_members = ', ' . join ( frozen_members ) ) return '' verbose_string = "" if sys . version_info < ( 3 , 7 ) : # Verbose is no longer supported in Python 3.7 verbose_string = ", verbose={verbose}" . format ( verbose = verbose ) quoted_members = ', ' . join ( "'%s'" % m for m in members ) template = """
  class {class_name}(namedtuple('ImmutableBase', [{quoted_members}]{verbose_string})):
      __slots__ = tuple()
  
      def __repr__(self):
          return super({class_name}, self).__repr__().replace('ImmutableBase', self.__class__.__name__)
  
      def set(self, **kwargs):
          if not kwargs:
              return self
  
          fields_to_modify = set(kwargs.keys())
          if not fields_to_modify <= {member_set}:
              raise AttributeError("'%s' is not a member" % ', '.join(fields_to_modify - {member_set}))
  
          {frozen_member_test}
  
          return self.__class__.__new__(self.__class__, *map(kwargs.pop, [{quoted_members}], self))
  """ . format ( quoted_members = quoted_members , member_set = "set([%s])" % quoted_members if quoted_members else 'set()' , frozen_member_test = frozen_member_test ( ) , verbose_string = verbose_string , class_name = name ) if verbose : print ( template ) from collections import namedtuple namespace = dict ( namedtuple = namedtuple , __name__ = 'pyrsistent_immutable' ) try : six . exec_ ( template , namespace ) except SyntaxError as e : raise SyntaxError ( e . message + ':\n' + template ) return namespace [ name ]