docstr: :param parameterset:
      a legacy style parameterset that may or may not be a tuple,
      and may or may not be wrapped into a mess of mark objects
  
  :param force_tuple:
      enforce tuple wrapping so single argument tuple values
      don't get decomposed and break tests
code: def extract_from(cls, parameterset, force_tuple=False):
      """
      :param parameterset:
          a legacy style parameterset that may or may not be a tuple,
          and may or may not be wrapped into a mess of mark objects
  
      :param force_tuple:
          enforce tuple wrapping so single argument tuple values
          don't get decomposed and break tests
      """
  
      if isinstance(parameterset, cls):
          return parameterset
      if force_tuple:
          return cls.param(parameterset)
      else:
          return cls(parameterset, marks=[], id=None)
  
imports: import inspect
  import warnings
  from collections import namedtuple
  from operator import attrgetter
  import attr
  import six
  from ..compat import ascii_escaped
  from ..compat import ATTRS_EQ_FIELD
  from ..compat import getfslineno
  from ..compat import MappingMixin
  from ..compat import NOTSET
  from _pytest.deprecated import PYTEST_PARAM_UNKNOWN_KWARGS
  from _pytest.outcomes import fail
  from _pytest.warning_types import PytestUnknownMarkWarning
label_desc: Use image node_id 2 for calling the ParameterSet obj's underlying member method code with example usage: obj.extract_from(cls, parameterset, force_tuple) and returns: parameterset, cls, cls