code: def remove(self, param, keep_field=False):
          
          if isinstance(param, Parameter):
              return self._remove_exact(param, keep_field)
  
          name = str(param).strip()
          removed = False
          to_remove = []
  
          for i, param in enumerate(self.params):
              if param.name.strip() == name:
                  if keep_field:
                      if self._should_remove(i, name):
                          to_remove.append(i)
                      else:
                          self._blank_param_value(param.value)
                          keep_field = False
                  else:
                      self._fix_dependendent_params(i)
                      to_remove.append(i)
                  if not removed:
                      removed = True
  
          if not removed:
              raise ValueError(name)
          for i in reversed(to_remove):
              self.params.pop(i)
docs: Remove a parameter from the template, identified by *param*.
  
          If *param* is a :class:`.Parameter` object, it will be matched exactly,
          otherwise it will be treated like the *name* argument to :meth:`has`
          and :meth:`get`.
  
          If *keep_field* is ``True``, we will keep the parameter's name, but
          blank its value. Otherwise, we will remove the parameter completely.
  
          When removing a parameter with a hidden name, subsequent parameters
          with hidden names will be made visible. For example, removing ``bar``
          from ``{{foo|bar|baz}}`` produces ``{{foo|2=baz}}`` because
          ``{{foo|baz}}`` is incorrect.
  
          If the parameter shows up multiple times in the template and *param* is
          not a :class:`.Parameter` object, we will remove all instances of it
          (and keep only one if *keep_field* is ``True`` - either the one with a
          hidden name, if it exists, or the first instance).