def symbols(names, **args):
result = []<EOL>if isinstance(names, string_types):<EOL><INDENT>marker = <NUM_LIT:0><EOL>literals = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>for i in range(len(literals)):<EOL><INDENT>lit = literals.pop(<NUM_LIT:0>)<EOL>if lit in names:<EOL><INDENT>while chr(marker) in names:<EOL><INDENT>marker += <NUM_LIT:1><EOL><DEDENT>lit_char = chr(marker)<EOL>marker += <NUM_LIT:1><EOL>names = names.replace(lit, lit_char)<EOL>literals.append((lit_char, lit[<NUM_LIT:1>:]))<EOL><DEDENT><DEDENT>def literal(s):<EOL><INDENT>if literals:<EOL><INDENT>for c, l in literals:<EOL><INDENT>s = s.replace(c, l)<EOL><DEDENT><DEDENT>return s<EOL><DEDENT>names = names.strip()<EOL>as_seq = names.endswith('<STR_LIT:U+002C>')<EOL>if as_seq:<EOL><INDENT>names = names[:-<NUM_LIT:1>].rstrip()<EOL><DEDENT>if not names:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>names = [n.strip() for n in names.split('<STR_LIT:U+002C>')]<EOL>if not all(n for n in names):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>for i in range(len(names) - <NUM_LIT:1>, -<NUM_LIT:1>, -<NUM_LIT:1>):<EOL><INDENT>names[i: i + <NUM_LIT:1>] = names[i].split()<EOL><DEDENT>cls = args.pop('<STR_LIT>', Symbol)<EOL>seq = args.pop('<STR_LIT>', as_seq)<EOL>for name in names:<EOL><INDENT>if not name:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT::>' not in name:<EOL><INDENT>symbol = cls(literal(name), **args)<EOL>result.append(symbol)<EOL>continue<EOL><DEDENT>split = _range.split(name)<EOL>for i in range(len(split) - <NUM_LIT:1>):<EOL><INDENT>if i and '<STR_LIT::>' in split[i] and split[i] != '<STR_LIT::>' andsplit[i - <NUM_LIT:1>].endswith('<STR_LIT:(>') andsplit[i + <NUM_LIT:1>].startswith('<STR_LIT:)>'):<EOL><INDENT>split[i - <NUM_LIT:1>] = split[i - <NUM_LIT:1>][:-<NUM_LIT:1>]<EOL>split[i + <NUM_LIT:1>] = split[i + <NUM_LIT:1>][<NUM_LIT:1>:]<EOL><DEDENT><DEDENT>for i, s in enumerate(split):<EOL><INDENT>if '<STR_LIT::>' in s:<EOL><INDENT>if s[-<NUM_LIT:1>].endswith('<STR_LIT::>'):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>a, b = s.split('<STR_LIT::>')<EOL>if b[-<NUM_LIT:1>] in string.digits:<EOL><INDENT>a = <NUM_LIT:0> if not a else int(a)<EOL>b = int(b)<EOL>split[i] = [str(c) for c in range(a, b)]<EOL><DEDENT>else:<EOL><INDENT>a = a or '<STR_LIT:a>'<EOL>split[i] = [string.ascii_letters[c] for c in range(<EOL>string.ascii_letters.index(a),<EOL>string.ascii_letters.index(b) + <NUM_LIT:1>)]  <EOL><DEDENT>if not split[i]:<EOL><INDENT>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>split[i] = [s]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>seq = True<EOL>if len(split) == <NUM_LIT:1>:<EOL><INDENT>names = split[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>names = ['<STR_LIT>'.join(s) for s in cartes(*split)]<EOL><DEDENT>if literals:<EOL><INDENT>result.extend([cls(literal(s), **args) for s in names])<EOL><DEDENT>else:<EOL><INDENT>result.extend([cls(s, **args) for s in names])<EOL><DEDENT><DEDENT><DEDENT>if not seq and len(result) <= <NUM_LIT:1>:<EOL><INDENT>if not result:<EOL><INDENT>return ()<EOL><DEDENT>return result[<NUM_LIT:0>]<EOL><DEDENT>return tuple(result)<EOL><DEDENT>else:<EOL><INDENT>for name in names:<EOL><INDENT>result.append(symbols(name, **args))<EOL><DEDENT>return type(names)(result)<EOL><DEDENT>
Transform strings into instances of :class:`Symbol` class.
:func:`symbols` function returns a sequence of symbols with names taken
from ``names`` argument, which can be a comma or whitespace delimited
string, or a sequence of strings::
    >>> from symengine import symbols
    >>> x, y, z = symbols('x,y,z')
    >>> a, b, c = symbols('a b c')
The type of output is dependent on the properties of input arguments::
    >>> symbols('x')
    x
    >>> symbols('x,')
    (x,)
    >>> symbols('x,y')
    (x, y)
    >>> symbols(('a', 'b', 'c'))
    (a, b, c)
    >>> symbols(['a', 'b', 'c'])
    [a, b, c]
    >>> symbols(set(['a', 'b', 'c']))
    set([a, b, c])
If an iterable container is needed for a single symbol, set the ``seq``
argument to ``True`` or terminate the symbol name with a comma::
    >>> symbols('x', seq=True)
    (x,)
To reduce typing, range syntax is supported to create indexed symbols.
Ranges are indicated by a colon and the type of range is determined by
the character to the right of the colon. If the character is a digit
then all contiguous digits to the left are taken as the nonnegative
starting value (or 0 if there is no digit left of the colon) and all
contiguous digits to the right are taken as 1 greater than the ending
value::
    >>> symbols('x:10')
    (x0, x1, x2, x3, x4, x5, x6, x7, x8, x9)
    >>> symbols('x5:10')
    (x5, x6, x7, x8, x9)
    >>> symbols('x5(:2)')
    (x50, x51)
    >>> symbols('x5:10,y:5')
    (x5, x6, x7, x8, x9, y0, y1, y2, y3, y4)
    >>> symbols(('x5:10', 'y:5'))
    ((x5, x6, x7, x8, x9), (y0, y1, y2, y3, y4))
If the character to the right of the colon is a letter, then the single
letter to the left (or 'a' if there is none) is taken as the start
and all characters in the lexicographic range *through* the letter to
the right are used as the range::
    >>> symbols('x:z')
    (x, y, z)
    >>> symbols('x:c')  # null range
    ()
    >>> symbols('x(:c)')
    (xa, xb, xc)
    >>> symbols(':c')
    (a, b, c)
    >>> symbols('a:d, x:z')
    (a, b, c, d, x, y, z)
    >>> symbols(('a:d', 'x:z'))
    ((a, b, c, d), (x, y, z))
Multiple ranges are supported; contiguous numerical ranges should be
separated by parentheses to disambiguate the ending number of one
range from the starting number of the next::
    >>> symbols('x:2(1:3)')
    (x01, x02, x11, x12)
    >>> symbols(':3:2')  # parsing is from left to right
    (00, 01, 10, 11, 20, 21)
Only one pair of parentheses surrounding ranges are removed, so to
include parentheses around ranges, double them. And to include spaces,
commas, or colons, escape them with a backslash::
    >>> symbols('x((a:b))')
    (x(a), x(b))
    >>> symbols('x(:1\,:2)')  # or 'x((:1)\,(:2))'
    (x(0,0), x(0,1))