code: def _frozen_get_del_attr(cls, fields):
      # XXX: globals is modified on the first call to _create_fn, then
      # the modified version is used in the second call.  Is this okay?
      globals = {"cls": cls, "FrozenInstanceError": FrozenInstanceError}
      if fields:
          fields_str = (
              "(" + ",".join(repr(f.name) for f in fields) + ",)"
          )
      else:
          # Special case for the zero-length tuple.
          fields_str = "()"
      return (
          _create_fn(
              "__setattr__",
              ("self", "name", "value"),
              (
                  f"if type(self) is cls or name in {fields_str}:",
                  ' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
                  f"super(cls, self).__setattr__(name, value)",
              ),
              globals=globals,
          ),
          _create_fn(
              "__delattr__",
              ("self", "name"),
              (
                  f"if type(self) is cls or name in {fields_str}:",
                  ' raise FrozenInstanceError(f"cannot delete field {name!r}")',
                  f"super(cls, self).__delattr__(name)",
              ),
              globals=globals,
          ),
      )
  
imports: import re
  import sys
  import copy
  import types
  import inspect
  import keyword
label_desc: Use image node_id 9 for calling a global function with example usage: _frozen_get_del_attr(cls, fields) and returns: _create_fn,  _create_fn