diff options
Diffstat (limited to 'lib/sqlalchemy/sql')
| -rw-r--r-- | lib/sqlalchemy/sql/base.py | 25 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/coercions.py | 39 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 15 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/ddl.py | 5 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/elements.py | 66 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/schema.py | 25 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/selectable.py | 22 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/sqltypes.py | 18 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/type_api.py | 44 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/visitors.py | 7 |
10 files changed, 168 insertions, 98 deletions
diff --git a/lib/sqlalchemy/sql/base.py b/lib/sqlalchemy/sql/base.py index a7324c45f..2d336360f 100644 --- a/lib/sqlalchemy/sql/base.py +++ b/lib/sqlalchemy/sql/base.py @@ -128,8 +128,8 @@ class _DialectArgView(util.collections_abc.MutableMapping): def _key(self, key): try: dialect, value_key = key.split("_", 1) - except ValueError: - raise KeyError(key) + except ValueError as err: + util.raise_(KeyError(key), replace_context=err) else: return dialect, value_key @@ -138,17 +138,20 @@ class _DialectArgView(util.collections_abc.MutableMapping): try: opt = self.obj.dialect_options[dialect] - except exc.NoSuchModuleError: - raise KeyError(key) + except exc.NoSuchModuleError as err: + util.raise_(KeyError(key), replace_context=err) else: return opt[value_key] def __setitem__(self, key, value): try: dialect, value_key = self._key(key) - except KeyError: - raise exc.ArgumentError( - "Keys must be of the form <dialectname>_<argname>" + except KeyError as err: + util.raise_( + exc.ArgumentError( + "Keys must be of the form <dialectname>_<argname>" + ), + replace_context=err, ) else: self.obj.dialect_options[dialect][value_key] = value @@ -634,17 +637,17 @@ class ColumnCollection(object): def __getitem__(self, key): try: return self._index[key] - except KeyError: + except KeyError as err: if isinstance(key, util.int_types): - raise IndexError(key) + util.raise_(IndexError(key), replace_context=err) else: raise def __getattr__(self, key): try: return self._index[key] - except KeyError: - raise AttributeError(key) + except KeyError as err: + util.raise_(AttributeError(key), replace_context=err) def __contains__(self, key): if key not in self._index: diff --git a/lib/sqlalchemy/sql/coercions.py b/lib/sqlalchemy/sql/coercions.py index b3bf4e93b..fc841bb4b 100644 --- a/lib/sqlalchemy/sql/coercions.py +++ b/lib/sqlalchemy/sql/coercions.py @@ -133,7 +133,13 @@ class RoleImpl(object): self._raise_for_expected(element, argname, resolved) def _raise_for_expected( - self, element, argname=None, resolved=None, advice=None, code=None + self, + element, + argname=None, + resolved=None, + advice=None, + code=None, + err=None, ): if argname: msg = "%s expected for argument %r; got %r." % ( @@ -147,7 +153,7 @@ class RoleImpl(object): if advice: msg += " " + advice - raise exc.ArgumentError(msg, code=code) + util.raise_(exc.ArgumentError(msg, code=code), replace_context=err) class _Deannotate(object): @@ -201,16 +207,19 @@ class _ColumnCoercions(object): def _no_text_coercion( - element, argname=None, exc_cls=exc.ArgumentError, extra=None + element, argname=None, exc_cls=exc.ArgumentError, extra=None, err=None ): - raise exc_cls( - "%(extra)sTextual SQL expression %(expr)r %(argname)sshould be " - "explicitly declared as text(%(expr)r)" - % { - "expr": util.ellipses_string(element), - "argname": "for argument %s" % (argname,) if argname else "", - "extra": "%s " % extra if extra else "", - } + util.raise_( + exc_cls( + "%(extra)sTextual SQL expression %(expr)r %(argname)sshould be " + "explicitly declared as text(%(expr)r)" + % { + "expr": util.ellipses_string(element), + "argname": "for argument %s" % (argname,) if argname else "", + "extra": "%s " % extra if extra else "", + } + ), + replace_context=err, ) @@ -290,8 +299,8 @@ class ExpressionElementImpl( return elements.BindParameter( name, element, type_, unique=True ) - except exc.ArgumentError: - self._raise_for_expected(element) + except exc.ArgumentError as err: + self._raise_for_expected(element, err=err) class BinaryElementImpl( @@ -302,8 +311,8 @@ class BinaryElementImpl( ): try: return expr._bind_param(operator, element, type_=bindparam_type) - except exc.ArgumentError: - self._raise_for_expected(element) + except exc.ArgumentError as err: + self._raise_for_expected(element, err=err) def _post_coercion(self, resolved, expr, **kw): if ( diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 9c1f50ce1..d31cf67f8 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -1074,7 +1074,7 @@ class SQLCompiler(Compiled): col = only_froms[element.element] else: col = with_cols[element.element] - except KeyError: + except KeyError as err: coercions._no_text_coercion( element.element, extra=( @@ -1082,6 +1082,7 @@ class SQLCompiler(Compiled): "GROUP BY / DISTINCT etc." ), exc_cls=exc.CompileError, + err=err, ) else: kwargs["render_label_as_label"] = col @@ -1671,8 +1672,11 @@ class SQLCompiler(Compiled): else: try: opstring = OPERATORS[operator_] - except KeyError: - raise exc.UnsupportedCompilationError(self, operator_) + except KeyError as err: + util.raise_( + exc.UnsupportedCompilationError(self, operator_), + replace_context=err, + ) else: return self._generate_generic_binary( binary, opstring, from_linter=from_linter, **kw @@ -3286,11 +3290,12 @@ class DDLCompiler(Compiled): if column.primary_key: first_pk = True except exc.CompileError as ce: - util.raise_from_cause( + util.raise_( exc.CompileError( util.u("(in table '%s', column '%s'): %s") % (table.description, column.name, ce.args[0]) - ) + ), + from_=ce, ) const = self.create_table_constraints( diff --git a/lib/sqlalchemy/sql/ddl.py b/lib/sqlalchemy/sql/ddl.py index 31bcc34a4..5a2095604 100644 --- a/lib/sqlalchemy/sql/ddl.py +++ b/lib/sqlalchemy/sql/ddl.py @@ -801,7 +801,7 @@ class SchemaDropper(DDLBase): ) collection = [(t, ()) for t in unsorted_tables] else: - util.raise_from_cause( + util.raise_( exc.CircularDependencyError( err2.args[0], err2.cycles, @@ -818,7 +818,8 @@ class SchemaDropper(DDLBase): sorted([t.fullname for t in err2.cycles]) ) ), - ) + ), + from_=err2, ) seq_coll = [ diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index df690c383..d0babb1be 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -747,10 +747,13 @@ class ColumnElement( def comparator(self): try: comparator_factory = self.type.comparator_factory - except AttributeError: - raise TypeError( - "Object %r associated with '.type' attribute " - "is not a TypeEngine class or object" % self.type + except AttributeError as err: + util.raise_( + TypeError( + "Object %r associated with '.type' attribute " + "is not a TypeEngine class or object" % self.type + ), + replace_context=err, ) else: return comparator_factory(self) @@ -758,10 +761,17 @@ class ColumnElement( def __getattr__(self, key): try: return getattr(self.comparator, key) - except AttributeError: - raise AttributeError( - "Neither %r object nor %r object has an attribute %r" - % (type(self).__name__, type(self.comparator).__name__, key) + except AttributeError as err: + util.raise_( + AttributeError( + "Neither %r object nor %r object has an attribute %r" + % ( + type(self).__name__, + type(self.comparator).__name__, + key, + ) + ), + replace_context=err, ) def operate(self, op, *other, **kwargs): @@ -1742,10 +1752,13 @@ class TextClause( # a unique/anonymous key in any case, so use the _orig_key # so that a text() construct can support unique parameters existing = new_params[bind._orig_key] - except KeyError: - raise exc.ArgumentError( - "This text() construct doesn't define a " - "bound parameter named %r" % bind._orig_key + except KeyError as err: + util.raise_( + exc.ArgumentError( + "This text() construct doesn't define a " + "bound parameter named %r" % bind._orig_key + ), + replace_context=err, ) else: new_params[existing._orig_key] = bind @@ -1753,10 +1766,13 @@ class TextClause( for key, value in names_to_values.items(): try: existing = new_params[key] - except KeyError: - raise exc.ArgumentError( - "This text() construct doesn't define a " - "bound parameter named %r" % key + except KeyError as err: + util.raise_( + exc.ArgumentError( + "This text() construct doesn't define a " + "bound parameter named %r" % key + ), + replace_context=err, ) else: new_params[key] = existing._with_value(value) @@ -3665,9 +3681,12 @@ class Over(ColumnElement): else: try: lower = int(range_[0]) - except ValueError: - raise exc.ArgumentError( - "Integer or None expected for range value" + except ValueError as err: + util.raise_( + exc.ArgumentError( + "Integer or None expected for range value" + ), + replace_context=err, ) else: if lower == 0: @@ -3678,9 +3697,12 @@ class Over(ColumnElement): else: try: upper = int(range_[1]) - except ValueError: - raise exc.ArgumentError( - "Integer or None expected for range value" + except ValueError as err: + util.raise_( + exc.ArgumentError( + "Integer or None expected for range value" + ), + replace_context=err, ) else: if upper == 0: diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py index e6d3a6b05..5445a1bce 100644 --- a/lib/sqlalchemy/sql/schema.py +++ b/lib/sqlalchemy/sql/schema.py @@ -107,12 +107,13 @@ class SchemaItem(SchemaEventTarget, visitors.Visitable): if item is not None: try: spwd = item._set_parent_with_dispatch - except AttributeError: - util.raise_from_cause( + except AttributeError as err: + util.raise_( exc.ArgumentError( "'SchemaItem' object, such as a 'Column' or a " "'Constraint' expected, got %r" % item - ) + ), + replace_context=err, ) else: spwd(self) @@ -1569,15 +1570,16 @@ class Column(DialectKWArgs, SchemaItem, ColumnClause): _proxies=[self], *fk ) - except TypeError: - util.raise_from_cause( + except TypeError as err: + util.raise_( TypeError( "Could not create a copy of this %r object. " "Ensure the class includes a _constructor() " "attribute or method which accepts the " "standard Column constructor arguments, or " "references the Column class itself." % self.__class__ - ) + ), + from_=err, ) c.table = selectable @@ -3187,10 +3189,13 @@ class ForeignKeyConstraint(ColumnCollectionConstraint): try: ColumnCollectionConstraint._set_parent(self, table) except KeyError as ke: - raise exc.ArgumentError( - "Can't create ForeignKeyConstraint " - "on table '%s': no column " - "named '%s' is present." % (table.description, ke.args[0]) + util.raise_( + exc.ArgumentError( + "Can't create ForeignKeyConstraint " + "on table '%s': no column " + "named '%s' is present." % (table.description, ke.args[0]) + ), + from_=ke, ) for col, fk in zip(self.columns, self.elements): diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index b8d88e160..b972c13be 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -2620,10 +2620,13 @@ class GenerativeSelect(DeprecatedSelectBaseGenerations, SelectBase): return None try: value = clause._limit_offset_value - except AttributeError: - raise exc.CompileError( - "This SELECT structure does not use a simple " - "integer value for %s" % attrname + except AttributeError as err: + util.raise_( + exc.CompileError( + "This SELECT structure does not use a simple " + "integer value for %s" % attrname + ), + replace_context=err, ) else: return util.asint(value) @@ -3489,10 +3492,13 @@ class Select( try: cols_present = bool(columns) - except TypeError: - raise exc.ArgumentError( - "columns argument to select() must " - "be a Python list or other iterable" + except TypeError as err: + util.raise_( + exc.ArgumentError( + "columns argument to select() must " + "be a Python list or other iterable" + ), + from_=err, ) if cols_present: diff --git a/lib/sqlalchemy/sql/sqltypes.py b/lib/sqlalchemy/sql/sqltypes.py index 22c80cc91..e4a029a3e 100644 --- a/lib/sqlalchemy/sql/sqltypes.py +++ b/lib/sqlalchemy/sql/sqltypes.py @@ -1462,7 +1462,7 @@ class Enum(Emulated, String, SchemaType): def _db_value_for_elem(self, elem): try: return self._valid_lookup[elem] - except KeyError: + except KeyError as err: # for unknown string values, we return as is. While we can # validate these if we wanted, that does not allow for lesser-used # end-user use cases, such as using a LIKE comparison with an enum, @@ -1476,8 +1476,11 @@ class Enum(Emulated, String, SchemaType): ): return elem else: - raise LookupError( - '"%s" is not among the defined enum values' % elem + util.raise_( + LookupError( + '"%s" is not among the defined enum values' % elem + ), + replace_context=err, ) class Comparator(String.Comparator): @@ -1496,9 +1499,12 @@ class Enum(Emulated, String, SchemaType): def _object_value_for_elem(self, elem): try: return self._object_lookup[elem] - except KeyError: - raise LookupError( - '"%s" is not among the defined enum values' % elem + except KeyError as err: + util.raise_( + LookupError( + '"%s" is not among the defined enum values' % elem + ), + replace_context=err, ) def __repr__(self): diff --git a/lib/sqlalchemy/sql/type_api.py b/lib/sqlalchemy/sql/type_api.py index c6c860844..739f96195 100644 --- a/lib/sqlalchemy/sql/type_api.py +++ b/lib/sqlalchemy/sql/type_api.py @@ -479,9 +479,12 @@ class TypeEngine(Traversible): try: return dialect._type_memos[self]["literal"] except KeyError: - d = self._dialect_info(dialect) - d["literal"] = lp = d["impl"].literal_processor(dialect) - return lp + pass + # avoid KeyError context coming into literal_processor() function + # raises + d = self._dialect_info(dialect) + d["literal"] = lp = d["impl"].literal_processor(dialect) + return lp def _cached_bind_processor(self, dialect): """Return a dialect-specific bind processor for this type.""" @@ -489,9 +492,12 @@ class TypeEngine(Traversible): try: return dialect._type_memos[self]["bind"] except KeyError: - d = self._dialect_info(dialect) - d["bind"] = bp = d["impl"].bind_processor(dialect) - return bp + pass + # avoid KeyError context coming into bind_processor() function + # raises + d = self._dialect_info(dialect) + d["bind"] = bp = d["impl"].bind_processor(dialect) + return bp def _cached_result_processor(self, dialect, coltype): """Return a dialect-specific result processor for this type.""" @@ -499,21 +505,27 @@ class TypeEngine(Traversible): try: return dialect._type_memos[self][coltype] except KeyError: - d = self._dialect_info(dialect) - # key assumption: DBAPI type codes are - # constants. Else this dictionary would - # grow unbounded. - d[coltype] = rp = d["impl"].result_processor(dialect, coltype) - return rp + pass + # avoid KeyError context coming into result_processor() function + # raises + d = self._dialect_info(dialect) + # key assumption: DBAPI type codes are + # constants. Else this dictionary would + # grow unbounded. + d[coltype] = rp = d["impl"].result_processor(dialect, coltype) + return rp def _cached_custom_processor(self, dialect, key, fn): try: return dialect._type_memos[self][key] except KeyError: - d = self._dialect_info(dialect) - impl = d["impl"] - d[key] = result = fn(impl) - return result + pass + # avoid KeyError context coming into fn() function + # raises + d = self._dialect_info(dialect) + impl = d["impl"] + d[key] = result = fn(impl) + return result def _dialect_info(self, dialect): """Return a dialect-specific registry which diff --git a/lib/sqlalchemy/sql/visitors.py b/lib/sqlalchemy/sql/visitors.py index 77e6b53a8..fda48c657 100644 --- a/lib/sqlalchemy/sql/visitors.py +++ b/lib/sqlalchemy/sql/visitors.py @@ -62,9 +62,10 @@ def _generate_compiler_dispatch(cls): "def _compiler_dispatch(self, visitor, **kw):\n" " try:\n" " meth = visitor.visit_%(name)s\n" - " except AttributeError:\n" - " util.raise_from_cause(\n" - " exc.UnsupportedCompilationError(visitor, cls))\n" + " except AttributeError as err:\n" + " util.raise_(\n" + " exc.UnsupportedCompilationError(visitor, cls), \n" + " replace_context=err)\n" " else:\n" " return meth(self, **kw)\n" ) % {"name": visit_name} |
