code: def kernS(s):
      """Use a hack to try keep autosimplification from distributing a
      a number into an Add; this modification does not
      prevent the 2-arg Mul from becoming an Add, however.
  
      Examples
      ========
  
      >>> from sympy.core.sympify import kernS
      >>> from sympy.abc import x, y
  
      The 2-arg Mul distributes a number (or minus sign) across the terms
      of an expression, but kernS will prevent that:
  
      >>> 2*(x + y), -(x + 1)
      (2*x + 2*y, -x - 1)
      >>> kernS('2*(x + y)')
      2*(x + y)
      >>> kernS('-(x + 1)')
      -(x + 1)
  
      If use of the hack fails, the un-hacked string will be passed to sympify...
      and you get what you get.
  
      XXX This hack should not be necessary once issue 4596 has been resolved.
      """
      hit = False
      quoted = '"' in s or "'" in s
      if "(" in s and not quoted:
          if s.count("(") != s.count(")"):
              raise SympifyError("unmatched left parenthesis")
  
          # strip all space from s
          s = "".join(s.split())
          olds = s
          # now use space to represent a symbol that
          # will
          # step 1. turn potential 2-arg Muls into 3-arg versions
          # 1a. *( -> * *(
          s = s.replace("*(", "* *(")
          # 1b. close up exponentials
          s = s.replace("** *", "**")
          # 2. handle the implied multiplication of a negated
          # parenthesized expression in two steps
          # 2a:  -(...)  -->  -( *(...)
          target = "-( *("
          s = s.replace("-(", target)
          # 2b: double the matching closing parenthesis
          # -( *(...)  -->  -( *(...))
          i = nest = 0
          assert target.endswith("(")  # assumption below
          while True:
              j = s.find(target, i)
              if j == -1:
                  break
              j += len(target) - 1
              for j in range(j, len(s)):
                  if s[j] == "(":
                      nest += 1
                  elif s[j] == ")":
                      nest -= 1
                  if nest == 0:
                      break
              s = s[:j] + ")" + s[j:]
              i = j + 2  # the first char after 2nd )
          if " " in s:
              # get a unique kern
              kern = "_"
              while kern in s:
                  kern += choice(string.ascii_letters + string.digits)
              s = s.replace(" ", kern)
              hit = kern in s
          else:
              hit = False
  
      for i in range(2):
          try:
              expr = sympify(s)
              break
          except TypeError:  # the kern might cause unknown errors...
              if hit:
                  s = olds  # maybe it didn't like the kern; use un-kerned s
                  hit = False
                  continue
              expr = sympify(s)  # let original error raise
  
      if not hit:
          return expr
  
      from .symbol import Symbol
  
      rep = {Symbol(kern): 1}
  
      def _clear(expr):
          if isinstance(expr, (list, tuple, set)):
              return type(expr)([_clear(e) for e in expr])
          if hasattr(expr, "subs"):
              return expr.subs(rep, hack2=True)
          return expr
  
      expr = _clear(expr)
      # hope that kern is not there anymore
      return expr
  
file_path: sympy/sympy/core/sympify.py
imports: from __future__ import annotations
  from typing import Any, Callable
  from inspect import getmro
  import string
  from sympy.core.random import choice
  from .parameters import global_parameters
  from sympy.utilities.iterables import iterable
  from .basic import Basic
label_desc: Use image node_id 5 for calling a global function with example usage: kernS(s) and returns: expr, expr, expr, type, expr