From ce52dd9e3b71f2074d7821fe62803d4e0eefe512 Mon Sep 17 00:00:00 2001 From: ndparker Date: Tue, 23 Sep 2014 23:28:11 +0200 Subject: improve exception vs. exit handling --- lib/sqlalchemy/dialects/mssql/base.py | 2 ++ lib/sqlalchemy/dialects/mysql/base.py | 4 ++++ lib/sqlalchemy/dialects/mysql/mysqlconnector.py | 2 ++ lib/sqlalchemy/engine/base.py | 2 ++ lib/sqlalchemy/orm/mapper.py | 2 ++ lib/sqlalchemy/orm/state.py | 4 ++-- lib/sqlalchemy/pool.py | 8 ++++---- lib/sqlalchemy/sql/elements.py | 2 ++ lib/sqlalchemy/sql/schema.py | 4 ++-- lib/sqlalchemy/testing/provision.py | 10 ++++++++++ lib/sqlalchemy/util/langhelpers.py | 6 ++++++ 11 files changed, 38 insertions(+), 8 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index ba3050ae5..ade2d00cb 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -846,6 +846,8 @@ class MSExecutionContext(default.DefaultExecutionContext): "SET IDENTITY_INSERT %s OFF" % self.dialect.identifier_preparer. format_table( self.compiled.statement.table))) + except (SystemExit, KeyboardInterrupt): + raise except: pass diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index 7ccd59abb..0994e2416 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -2317,6 +2317,8 @@ class MySQLDialect(default.DefaultDialect): # basic operations via autocommit fail. try: dbapi_connection.commit() + except (SystemExit, KeyboardInterrupt): + raise except: if self.server_version_info < (3, 23, 15): args = sys.exc_info()[1].args @@ -2329,6 +2331,8 @@ class MySQLDialect(default.DefaultDialect): try: dbapi_connection.rollback() + except (SystemExit, KeyboardInterrupt): + raise except: if self.server_version_info < (3, 23, 15): args = sys.exc_info()[1].args diff --git a/lib/sqlalchemy/dialects/mysql/mysqlconnector.py b/lib/sqlalchemy/dialects/mysql/mysqlconnector.py index e51e80005..afa61d85b 100644 --- a/lib/sqlalchemy/dialects/mysql/mysqlconnector.py +++ b/lib/sqlalchemy/dialects/mysql/mysqlconnector.py @@ -103,6 +103,8 @@ class MySQLDialect_mysqlconnector(MySQLDialect): 'client_flags', ClientFlag.get_default()) client_flags |= ClientFlag.FOUND_ROWS opts['client_flags'] = client_flags + except (SystemExit, KeyboardInterrupt): + raise except: pass return [[], opts] diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index d2cc8890f..b3460c240 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -1135,6 +1135,8 @@ class Connection(Connectable): per_fn = fn(ctx) if per_fn is not None: ctx.chained_exception = newraise = per_fn + except (SystemExit, KeyboardInterrupt): + raise except Exception as _raised: # handler raises an exception - stop processing newraise = _raised diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index a59a38a5b..bd28975dd 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -2649,6 +2649,8 @@ def configure_mappers(): mapper._expire_memoizations() mapper.dispatch.mapper_configured( mapper, mapper.class_) + except (SystemExit, KeyboardInterrupt): + raise except: exc = sys.exc_info()[1] if not hasattr(exc, '_configure_failed'): diff --git a/lib/sqlalchemy/orm/state.py b/lib/sqlalchemy/orm/state.py index 3c12fda1a..4756f1707 100644 --- a/lib/sqlalchemy/orm/state.py +++ b/lib/sqlalchemy/orm/state.py @@ -258,8 +258,8 @@ class InstanceState(interfaces.InspectionAttr): try: return manager.original_init(*mixed[1:], **kwargs) except: - manager.dispatch.init_failure(self, args, kwargs) - raise + with util.safe_reraise(): + manager.dispatch.init_failure(self, args, kwargs) def get_history(self, key, passive): return self.manager[key].impl.get_history(self, self.dict, passive) diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py index bc9affe4a..0c162e984 100644 --- a/lib/sqlalchemy/pool.py +++ b/lib/sqlalchemy/pool.py @@ -441,8 +441,8 @@ class _ConnectionRecord(object): try: dbapi_connection = rec.get_connection() except: - rec.checkin() - raise + with util.safe_reraise(): + rec.checkin() echo = pool._should_log_debug() fairy = _ConnectionFairy(dbapi_connection, rec, echo) rec.fairy_ref = weakref.ref( @@ -962,8 +962,8 @@ class QueuePool(Pool): try: return self._create_connection() except: - self._dec_overflow() - raise + with util.safe_reraise(): + self._dec_overflow() else: return self._do_get() diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index 8ec0aa700..8e18a22fe 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -3491,6 +3491,8 @@ def _string_or_unprintable(element): else: try: return str(element) + except (SystemExit, KeyboardInterrupt): + raise except: return "unprintable element %r" % element diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py index d9fd37f92..9afc31be8 100644 --- a/lib/sqlalchemy/sql/schema.py +++ b/lib/sqlalchemy/sql/schema.py @@ -412,8 +412,8 @@ class Table(DialectKWArgs, SchemaItem, TableClause): table.dispatch.after_parent_attach(table, metadata) return table except: - metadata._remove_table(name, schema) - raise + with util.safe_reraise(): + metadata._remove_table(name, schema) @property @util.deprecated('0.9', 'Use ``table.schema.quote``') diff --git a/lib/sqlalchemy/testing/provision.py b/lib/sqlalchemy/testing/provision.py index 0bcdad959..64688d6b5 100644 --- a/lib/sqlalchemy/testing/provision.py +++ b/lib/sqlalchemy/testing/provision.py @@ -120,6 +120,8 @@ def _pg_create_db(cfg, eng, ident): isolation_level="AUTOCOMMIT") as conn: try: _pg_drop_db(cfg, conn, ident) + except (SystemExit, KeyboardInterrupt): + raise except: pass currentdb = conn.scalar("select current_database()") @@ -131,6 +133,8 @@ def _mysql_create_db(cfg, eng, ident): with eng.connect() as conn: try: _mysql_drop_db(cfg, conn, ident) + except (SystemExit, KeyboardInterrupt): + raise except: pass conn.execute("CREATE DATABASE %s" % ident) @@ -173,14 +177,20 @@ def _mysql_drop_db(cfg, eng, ident): with eng.connect() as conn: try: conn.execute("DROP DATABASE %s_test_schema" % ident) + except (SystemExit, KeyboardInterrupt): + raise except: pass try: conn.execute("DROP DATABASE %s_test_schema_2" % ident) + except (SystemExit, KeyboardInterrupt): + raise except: pass try: conn.execute("DROP DATABASE %s" % ident) + except (SystemExit, KeyboardInterrupt): + raise except: pass diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 76f85f605..75c6e7b46 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -490,6 +490,8 @@ def generic_repr(obj, additional_kw=(), to_inspect=None, omit_kwarg=()): val = getattr(obj, arg, missing) if val is not missing and val != defval: output.append('%s=%r' % (arg, val)) + except (SystemExit, KeyboardInterrupt): + raise except: pass @@ -499,6 +501,8 @@ def generic_repr(obj, additional_kw=(), to_inspect=None, omit_kwarg=()): val = getattr(obj, arg, missing) if val is not missing and val != defval: output.append('%s=%r' % (arg, val)) + except (SystemExit, KeyboardInterrupt): + raise except: pass @@ -1185,6 +1189,8 @@ def warn_exception(func, *args, **kwargs): """ try: return func(*args, **kwargs) + except (SystemExit, KeyboardInterrupt): + raise except: warn("%s('%s') ignored" % sys.exc_info()[0:2]) -- cgit v1.2.1 From 690532131d8ce8250c62f1d3e27405902df03e70 Mon Sep 17 00:00:00 2001 From: ndparker Date: Thu, 2 Oct 2014 22:00:31 +0200 Subject: cleanup exception handling - use new exception hierarchy (since python 2.5) --- lib/sqlalchemy/dialects/mssql/base.py | 4 +--- lib/sqlalchemy/dialects/mysql/base.py | 8 ++------ lib/sqlalchemy/dialects/mysql/mysqlconnector.py | 4 +--- lib/sqlalchemy/engine/base.py | 4 ---- lib/sqlalchemy/exc.py | 6 +++--- lib/sqlalchemy/orm/mapper.py | 4 +--- lib/sqlalchemy/pool.py | 12 ++++-------- lib/sqlalchemy/sql/elements.py | 4 +--- lib/sqlalchemy/testing/engines.py | 4 ---- lib/sqlalchemy/testing/provision.py | 20 +++++--------------- lib/sqlalchemy/util/langhelpers.py | 12 +++--------- 11 files changed, 21 insertions(+), 61 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index ade2d00cb..dad02ee0f 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -846,9 +846,7 @@ class MSExecutionContext(default.DefaultExecutionContext): "SET IDENTITY_INSERT %s OFF" % self.dialect.identifier_preparer. format_table( self.compiled.statement.table))) - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: pass def get_result_proxy(self): diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index 0994e2416..277644022 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -2317,9 +2317,7 @@ class MySQLDialect(default.DefaultDialect): # basic operations via autocommit fail. try: dbapi_connection.commit() - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: if self.server_version_info < (3, 23, 15): args = sys.exc_info()[1].args if args and args[0] == 1064: @@ -2331,9 +2329,7 @@ class MySQLDialect(default.DefaultDialect): try: dbapi_connection.rollback() - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: if self.server_version_info < (3, 23, 15): args = sys.exc_info()[1].args if args and args[0] == 1064: diff --git a/lib/sqlalchemy/dialects/mysql/mysqlconnector.py b/lib/sqlalchemy/dialects/mysql/mysqlconnector.py index afa61d85b..6077ce53e 100644 --- a/lib/sqlalchemy/dialects/mysql/mysqlconnector.py +++ b/lib/sqlalchemy/dialects/mysql/mysqlconnector.py @@ -103,9 +103,7 @@ class MySQLDialect_mysqlconnector(MySQLDialect): 'client_flags', ClientFlag.get_default()) client_flags |= ClientFlag.FOUND_ROWS opts['client_flags'] = client_flags - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: pass return [[], opts] diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index b3460c240..220679c12 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -1055,8 +1055,6 @@ class Connection(Connectable): """ try: cursor.close() - except (SystemExit, KeyboardInterrupt): - raise except Exception: # log the error through the connection pool's logger. self.engine.pool.logger.error( @@ -1135,8 +1133,6 @@ class Connection(Connectable): per_fn = fn(ctx) if per_fn is not None: ctx.chained_exception = newraise = per_fn - except (SystemExit, KeyboardInterrupt): - raise except Exception as _raised: # handler raises an exception - stop processing newraise = _raised diff --git a/lib/sqlalchemy/exc.py b/lib/sqlalchemy/exc.py index a82bae33f..5d35dc2e7 100644 --- a/lib/sqlalchemy/exc.py +++ b/lib/sqlalchemy/exc.py @@ -280,7 +280,9 @@ class DBAPIError(StatementError): connection_invalidated=False): # Don't ever wrap these, just return them directly as if # DBAPIError didn't exist. - if isinstance(orig, (KeyboardInterrupt, SystemExit, DontWrapMixin)): + if (isinstance(orig, BaseException) and + not isinstance(orig, Exception)) or \ + isinstance(orig, DontWrapMixin): return orig if orig is not None: @@ -310,8 +312,6 @@ class DBAPIError(StatementError): def __init__(self, statement, params, orig, connection_invalidated=False): try: text = str(orig) - except (KeyboardInterrupt, SystemExit): - raise except Exception as e: text = 'Error in str() of DB-API-generated exception: ' + str(e) StatementError.__init__( diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index bd28975dd..e4c0de188 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -2649,9 +2649,7 @@ def configure_mappers(): mapper._expire_memoizations() mapper.dispatch.mapper_configured( mapper, mapper.class_) - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: exc = sys.exc_info()[1] if not hasattr(exc, '_configure_failed'): mapper._configure_failed = exc diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py index 0c162e984..a174df784 100644 --- a/lib/sqlalchemy/pool.py +++ b/lib/sqlalchemy/pool.py @@ -248,9 +248,7 @@ class Pool(log.Identified): self.logger.debug("Closing connection %r", connection) try: self._dialect.do_close(connection) - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: self.logger.error("Exception closing connection %r", connection, exc_info=True) @@ -569,12 +567,12 @@ def _finalize_fairy(connection, connection_record, # Immediately close detached instances if not connection_record: pool._close_connection(connection) - except Exception as e: + except BaseException as e: pool.logger.error( "Exception during reset or similar", exc_info=True) if connection_record: connection_record.invalidate(e=e) - if isinstance(e, (SystemExit, KeyboardInterrupt)): + if not isinstance(e, Exception): raise if connection_record: @@ -842,9 +840,7 @@ class SingletonThreadPool(Pool): for conn in self._all_conns: try: conn.close() - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: # pysqlite won't even let you close a conn from a thread # that didn't create it pass diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index 8e18a22fe..4bc1683dd 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -3491,9 +3491,7 @@ def _string_or_unprintable(element): else: try: return str(element) - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: return "unprintable element %r" % element diff --git a/lib/sqlalchemy/testing/engines.py b/lib/sqlalchemy/testing/engines.py index 67c13231e..1284f9c2a 100644 --- a/lib/sqlalchemy/testing/engines.py +++ b/lib/sqlalchemy/testing/engines.py @@ -37,8 +37,6 @@ class ConnectionKiller(object): def _safe(self, fn): try: fn() - except (SystemExit, KeyboardInterrupt): - raise except Exception as e: warnings.warn( "testing_reaper couldn't " @@ -168,8 +166,6 @@ class ReconnectFixture(object): def _safe(self, fn): try: fn() - except (SystemExit, KeyboardInterrupt): - raise except Exception as e: warnings.warn( "ReconnectFixture couldn't " diff --git a/lib/sqlalchemy/testing/provision.py b/lib/sqlalchemy/testing/provision.py index 64688d6b5..c8f7fdf30 100644 --- a/lib/sqlalchemy/testing/provision.py +++ b/lib/sqlalchemy/testing/provision.py @@ -120,9 +120,7 @@ def _pg_create_db(cfg, eng, ident): isolation_level="AUTOCOMMIT") as conn: try: _pg_drop_db(cfg, conn, ident) - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: pass currentdb = conn.scalar("select current_database()") conn.execute("CREATE DATABASE %s TEMPLATE %s" % (ident, currentdb)) @@ -133,9 +131,7 @@ def _mysql_create_db(cfg, eng, ident): with eng.connect() as conn: try: _mysql_drop_db(cfg, conn, ident) - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: pass conn.execute("CREATE DATABASE %s" % ident) conn.execute("CREATE DATABASE %s_test_schema" % ident) @@ -177,21 +173,15 @@ def _mysql_drop_db(cfg, eng, ident): with eng.connect() as conn: try: conn.execute("DROP DATABASE %s_test_schema" % ident) - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: pass try: conn.execute("DROP DATABASE %s_test_schema_2" % ident) - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: pass try: conn.execute("DROP DATABASE %s" % ident) - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: pass diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 75c6e7b46..ea8f30e9d 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -490,9 +490,7 @@ def generic_repr(obj, additional_kw=(), to_inspect=None, omit_kwarg=()): val = getattr(obj, arg, missing) if val is not missing and val != defval: output.append('%s=%r' % (arg, val)) - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: pass if additional_kw: @@ -501,9 +499,7 @@ def generic_repr(obj, additional_kw=(), to_inspect=None, omit_kwarg=()): val = getattr(obj, arg, missing) if val is not missing and val != defval: output.append('%s=%r' % (arg, val)) - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: pass return "%s(%s)" % (obj.__class__.__name__, ", ".join(output)) @@ -1189,9 +1185,7 @@ def warn_exception(func, *args, **kwargs): """ try: return func(*args, **kwargs) - except (SystemExit, KeyboardInterrupt): - raise - except: + except Exception: warn("%s('%s') ignored" % sys.exc_info()[0:2]) -- cgit v1.2.1