code: def p_param_types(self, p):
          '''param_types : type
                         | type OPT
                         | type COMMA param_types
                         | type OPT COMMA default_types'''
          if len(p) == 2:
              p[0] = tuple((t,) for t in p[1])
          elif len(p) == 3:
              p[0] = tuple((t,) for t in p[1]) + ((),)
          elif len(p) == 4:
              p[0] = tuple((t,) + ts for t in p[1] for ts in p[3])
          else:
              non_defaults = [t for t in p[4] if len(t) == len(p[4][0])]
              p[0] = tuple((t,) + ts for t in p[1] for ts in non_defaults) + p[4f p_param_types(self, p):
          '''param_types : type
                         | type OPT
                         | type COMMA param_types
                         | type OPT COMMA default_types'''
          if len(p) == 2:
              p[0] = tuple((t,) for t in p[1])
          elif len(p) == 3:
              p[0] = tuple((t,) for t in p[1]) + ((),)
          elif len(p) == 4:
              p[0] = tuple((t,) + ts for t in p[1] for ts in p[3])
          else:
              non_defaults = [t for t in p[4] if len(t) == len(p[4][0])]
              p[0] = tuple((t,) + ts for t in p[1] for ts in non_defaults) + p[4]
docs: param_types : type
                         | type OPT
                         | type COMMA param_types
                         | type OPT COMMA default_types