code: def extractArgumentsFromCallStr(callStr):
      
      def isTuple(ele):
          return classname(ele) == 'Tuple'
  
      paramsStr = callStr.split('(', 1)[-1].rsplit(')', 1)[0].strip()
  
      root = ast.parse(paramsStr).body[0].value
      eles = root.elts if isTuple(root) else [root]
  
      # The ast module parses 'a, b' and '(a, b)' identically. Thus, ast.parse()
      # alone can't tell the difference between
      #
      #   ic(a, b)
      #
      # and
      #
      #   ic((a, b))
      #
      # Detect this situation and preserve whole tuples, e.g. '(a, b)', passed to
      # ic() by creating a new, temporary tuple around the original tuple and
      # parsing that.
      if paramsStr[0] == '(' and paramsStr[-1] == ')' and len(eles) > 1:
          newTupleStr = '(' + paramsStr + ", 'ignored')"
          argStrs = extractArgumentsFromCallStr(newTupleStr)[:-1]
          return argStrs
  
      indices = [
          max(0, e.col_offset - 1) if isTuple(e) else e.col_offset for e in eles]
      argStrs = [s.strip(' ,') for s in splitStringAtIndices(paramsStr, indices)]
  
      return argStrs
docs: Parse the argument string via an AST instead of the overly simple
      callStr.split(','). The latter incorrectly splits any string parameters
      that contain commas therein, like ic(1, 'a,b', 2).