Repository: sympy/sympy
File: sympy/solvers/solvers.py (Python)

Code before:
                    fi = Add(fi.lhs, -fi.rhs, evaluate=False)
            f[i] = fi

        # *** dispatch and handle as a system of relationals
        # **************************************************
        if fi.is_Relational:
            if len(symbols) != 1:
                raise ValueError("can only solve for one symbol at a time")
            if warn and symbols[0].assumptions0:
                warnings.warn(filldedent("""
                    \tWarning: assumptions about variable '%s' are
                    not handled currently.""" % symbols[0]))
            return reduce_inequalities(f, symbols=symbols)

        # convert Poly to expression
        if isinstance(fi, Poly):
            f[i] = fi.as_expr()

        # rewrite hyperbolics in terms of exp if they have symbols of
        # interest
        f[i] = f[i].replace(lambda w: isinstance(w, HyperbolicFunction) and \
            w.has_free(*symbols), lambda w: w.rewrite(exp))

        # if we have a Matrix, we need to iterate over its elements again
        if f[i].is_Matrix:
            f[i] = f[i].as_explicit()
            bare_f = False
            f.extend(list(f[i]))
            f[i] = S.Zero

        # if we can split it into real and imaginary parts then do so
        freei = f[i].free_symbols
        if freei and all(s.is_extended_real or s.is_imaginary for s in freei):
            fr, fi = f[i].as_real_imag()
            # accept as long as new re, im, arg or atan2 are not introduced
            had = f[i].atoms(re, im, arg, atan2)
            if fr and fi and fr != fi and not any(
                    i.atoms(re, im, arg, atan2) - had for i in (fr, fi)):
                if bare_f:
                    bare_f = False
                f[i: i + 1] = [fr, fi]

    # real/imag handling -----------------------------
    if any(isinstance(fi, (bool, BooleanAtom)) for fi in f):
        if as_set:
            return [], set()
        return []

    for i, fi in enumerate(f):
        # Abs
        while True:

Review comment (suggestion):
What is needed now is to catch the exception here and then raise a new exception with a better error message saying that `solve` cannot handle matrices with symbolic shape.

Code after:
                    fi = Add(fi.lhs, -fi.rhs, evaluate=False)
            f[i] = fi

        # *** dispatch and handle as a system of relationals
        # **************************************************
        if fi.is_Relational:
            if len(symbols) != 1:
                raise ValueError("can only solve for one symbol at a time")
            if warn and symbols[0].assumptions0:
                warnings.warn(filldedent("""
                    \tWarning: assumptions about variable '%s' are
                    not handled currently.""" % symbols[0]))
            return reduce_inequalities(f, symbols=symbols)

        # convert Poly to expression
        if isinstance(fi, Poly):
            f[i] = fi.as_expr()

        # rewrite hyperbolics in terms of exp if they have symbols of
        # interest
        f[i] = f[i].replace(lambda w: isinstance(w, HyperbolicFunction) and \
            w.has_free(*symbols), lambda w: w.rewrite(exp))

        # if we have a Matrix, we need to iterate over its elements again
        if f[i].is_Matrix:
            try:
                f[i] = f[i].as_explicit()
            except ValueError:
                raise ValueError(
                    "solve cannot handle matrices with symbolic shape."
                )
            bare_f = False
            f.extend(list(f[i]))
            f[i] = S.Zero

        # if we can split it into real and imaginary parts then do so
        freei = f[i].free_symbols
        if freei and all(s.is_extended_real or s.is_imaginary for s in freei):
            fr, fi = f[i].as_real_imag()
            # accept as long as new re, im, arg or atan2 are not introduced
            had = f[i].atoms(re, im, arg, atan2)
            if fr and fi and fr != fi and not any(
                    i.atoms(re, im, arg, atan2) - had for i in (fr, fi)):
                if bare_f:
                    bare_f = False
                f[i: i + 1] = [fr, fi]

    # real/imag handling -----------------------------
    if any(isinstance(fi, (bool, BooleanAtom)) for fi in f):
        if as_set:
            return [], set()