Skip to content

Test failres due to unclosed database on Python 3.13.0 #1379

Description

@mweinelt

Various tests are failing on Python 3.13.0, with the following pattern:

_____________________________ test_paginate[Model] _____________________________

cls = <class '_pytest.runner.CallInfo'>
func = <function call_and_report.<locals>.<lambda> at 0x7ffff425ed40>
when = 'call'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    @classmethod
    def from_call(
        cls,
        func: Callable[[], TResult],
        when: Literal["collect", "setup", "call", "teardown"],
        reraise: type[BaseException] | tuple[type[BaseException], ...] | None = None,
    ) -> CallInfo[TResult]:
        """Call func, wrapping the result in a CallInfo.
    
        :param func:
            The function to call. Called without arguments.
        :type func: Callable[[], _pytest.runner.TResult]
        :param when:
            The phase in which the function is called.
        :param reraise:
            Exception or exceptions that shall propagate if raised by the
            function, instead of being wrapped in the CallInfo.
        """
        excinfo = None
        start = timing.time()
        precise_start = timing.perf_counter()
        try:
>           result: TResult | None = func()

/nix/store/6wq270gc19f8p07jy7892r05avgwb3xz-python3.13-pytest-8.3.3/lib/python3.13/site-packages/_pytest/runner.py:341: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/nix/store/6wq270gc19f8p07jy7892r05avgwb3xz-python3.13-pytest-8.3.3/lib/python3.13/site-packages/_pytest/runner.py:242: in <lambda>
    lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
/nix/store/w91wlq864lgwj9r938gmf8czk5cwlqjy-python3.13-pluggy-1.5.0/lib/python3.13/site-packages/pluggy/_hooks.py:513: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
/nix/store/w91wlq864lgwj9r938gmf8czk5cwlqjy-python3.13-pluggy-1.5.0/lib/python3.13/site-packages/pluggy/_manager.py:120: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
/nix/store/6wq270gc19f8p07jy7892r05avgwb3xz-python3.13-pytest-8.3.3/lib/python3.13/site-packages/_pytest/threadexception.py:92: in pytest_runtest_call
    yield from thread_exception_runtest_hook()
/nix/store/6wq270gc19f8p07jy7892r05avgwb3xz-python3.13-pytest-8.3.3/lib/python3.13/site-packages/_pytest/threadexception.py:68: in thread_exception_runtest_hook
    yield
/nix/store/6wq270gc19f8p07jy7892r05avgwb3xz-python3.13-pytest-8.3.3/lib/python3.13/site-packages/_pytest/unraisableexception.py:95: in pytest_runtest_call
    yield from unraisable_exception_runtest_hook()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def unraisable_exception_runtest_hook() -> Generator[None]:
        with catch_unraisable_exception() as cm:
            try:
                yield
            finally:
                if cm.unraisable:
                    if cm.unraisable.err_msg is not None:
                        err_msg = cm.unraisable.err_msg
                    else:
                        err_msg = "Exception ignored in"
                    msg = f"{err_msg}: {cm.unraisable.object!r}\n\n"
                    msg += "".join(
                        traceback.format_exception(
                            cm.unraisable.exc_type,
                            cm.unraisable.exc_value,
                            cm.unraisable.exc_traceback,
                        )
                    )
>                   warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))
E                   pytest.PytestUnraisableExceptionWarning: Exception ignored in: <sqlite3.Connection object at 0x7ffff3fec7c0>
E                   
E                   Traceback (most recent call last):
E                     File "/nix/store/9q6cs27gcx2h27brmg7nb8xhbzj0zrnm-python3.13-sqlalchemy-2.0.36/lib/python3.13/site-packages/sqlalchemy/event/base.py", line 148, in __init__
E                       self._empty_listeners = self._empty_listener_reg[instance_cls]
E                                               ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
E                     File "/nix/store/0b83hlniyfbpha92k2j0w93mxdalv8kb-python3-3.13.0/lib/python3.13/weakref.py", line 415, in __getitem__
E                       return self.data[ref(key)]
E                              ~~~~~~~~~^^^^^^^^^^
E                   KeyError: <weakref at 0x7ffff3e05ad0; to 'type' at 0x1429b20 (Session)>
E                   
E                   During handling of the above exception, another exception occurred:
E                   
E                   Traceback (most recent call last):
E                     File "/nix/store/0b83hlniyfbpha92k2j0w93mxdalv8kb-python3-3.13.0/lib/python3.13/weakref.py", line 428, in __setitem__
E                       self.data[ref(key, self._remove)] = value
E                                 ~~~^^^^^^^^^^^^^^^^^^^
E                   ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7ffff3fec7c0>

Run the testsuite with Python 3.13.0.

https://gist.github.com/mweinelt/843a1c04973a0ba82c01d09f26167d6f

Environment:

  • Python version: 3.13.0
  • Pytest: version 8.3.3
  • Flask-SQLAlchemy version: 3.1.1
  • SQLAlchemy version: 2.0.36

Activity

  1. added 2 commits that reference this issue on Jan 6, 2025
    ac89adb
    9090790
  2. brassy-endomorph commented on Jul 7, 2025

    @brassy-endomorph

    Just noting that we are getting this while testing against a Postgres DB where, to our knowledge, we are never creating a SQLIte DB.

  3. davidism commented on Jul 7, 2025

    @davidism
    Member

    I don't think this is fixable. I've looked into it quite a few times (also for Flask-SQLAlchemy-Lite), and as far as I can tell we're not doing anything weird or holding open connections longer than we should. Connections are created from the SQLAlchemy engine/pool, and returned when the session is closed at the end of the app context. For some reason, the underlying DBAPI still has open connections during pytest/interpreter shutdown, despite all connection handling being done through the SQLAlchemy pool and session. It happens with at least sqlite and psycopg.

    This error is coming at the very end during interpreter teardown. Pytest indicates this by issuing a warning PytestUnraisableExceptionWarning. Note that this only fails tests when treating warnings as errors. In that case, you can add an extra rule ignore::pytest.PytestUnraisableExceptionWarning to ignore such warnings. This is what I've been doing in my projects.

    Maybe I've missed something, and I'm happy to review a PR that fixes it.

  4. puittenbroek commented on Dec 19, 2025

    @puittenbroek
  5. davidism commented on Dec 19, 2025

    @davidism
  6. puittenbroek commented on Dec 22, 2025

    @puittenbroek
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions