client_python icon indicating copy to clipboard operation
client_python copied to clipboard

tests/test_asgi.py failures with python 3.12

Open ncopa opened this issue 1 year ago • 3 comments

I bump into some test failures with python 3.12, alpine linux edge:

======================================= test session starts ========================================
platform linux -- Python 3.12.2, pytest-8.1.1, pluggy-1.4.0
rootdir: /home/ncopa/aports/community/py3-prometheus-client/src/prometheus_client-0.20.0
collected 309 items                                                                                

tests/openmetrics/test_exposition.py ....................                                    [  6%]
tests/openmetrics/test_parser.py .............................................               [ 21%]
tests/test_asgi.py FException ignored in: <function ApplicationCommunicator.__del__ at 0x7f0e7e09d120>
Traceback (most recent call last):
  File "/usr/lib/python3.12/site-packages/asgiref/testing.py", line 58, in __del__
    self.stop(exceptions=False)
  File "/usr/lib/python3.12/site-packages/asgiref/testing.py", line 49, in stop
    if not self.future.done():
           ^^^^^^^^^^^
AttributeError: 'ApplicationCommunicator' object has no attribute 'future'
FFFFException ignored in: <function ApplicationCommunicator.__del__ at 0x7f0e7e09d120>
Traceback (most recent call last):
  File "/usr/lib/python3.12/site-packages/asgiref/testing.py", line 58, in __del__
    self.stop(exceptions=False)
  File "/usr/lib/python3.12/site-packages/asgiref/testing.py", line 49, in stop
    if not self.future.done():
           ^^^^^^^^^^^
AttributeError: 'ApplicationCommunicator' object has no attribute 'future'
Exception ignored in: <function ApplicationCommunicator.__del__ at 0x7f0e7e09d120>
Traceback (most recent call last):
  File "/usr/lib/python3.12/site-packages/asgiref/testing.py", line 58, in __del__
    self.stop(exceptions=False)
  File "/usr/lib/python3.12/site-packages/asgiref/testing.py", line 49, in stop
    if not self.future.done():
           ^^^^^^^^^^^
AttributeError: 'ApplicationCommunicator' object has no attribute 'future'
Exception ignored in: <function ApplicationCommunicator.__del__ at 0x7f0e7e09d120>
Traceback (most recent call last):
  File "/usr/lib/python3.12/site-packages/asgiref/testing.py", line 58, in __del__
    self.stop(exceptions=False)
  File "/usr/lib/python3.12/site-packages/asgiref/testing.py", line 49, in stop
    if not self.future.done():
           ^^^^^^^^^^^
AttributeError: 'ApplicationCommunicator' object has no attribute 'future'
FFF                                                                  [ 23%]
tests/test_core.py ......................................................................... [ 47%]
...........................                                                                  [ 55%]
tests/test_exposition.py ..........................................................          [ 74%]
tests/test_gc_collector.py ..                                                                [ 75%]
tests/test_graphite_bridge.py .......                                                        [ 77%]
tests/test_multiprocess.py .............................                                     [ 87%]
tests/test_parser.py ........................                                                [ 94%]
tests/test_platform_collector.py ..                                                          [ 95%]
tests/test_process_collector.py ....                                                         [ 96%]
tests/test_samples.py ..                                                                     [ 97%]
tests/test_twisted.py .                                                                      [ 97%]
tests/test_wsgi.py .......                                                                   [100%]

============================================= FAILURES =============================================
________________________________________ ASGITest.test_gzip ________________________________________

self = <tests.test_asgi.ASGITest testMethod=test_gzip>

    def test_gzip(self):
        # Increment a metric.
        metric_name = "counter"
        help_text = "A counter"
        increments = 2
        self.increment_metrics(metric_name, help_text, increments)
        app = make_asgi_app(self.registry)
>       self.seed_app(app)

tests/test_asgi.py:151: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_asgi.py:53: in seed_app
    self.communicator = ApplicationCommunicator(app, self.scope)
/usr/lib/python3.12/site-packages/asgiref/testing.py:24: in __init__
    self.future = contextvars.Context().run(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

coro = <coroutine object make_asgi_app.<locals>.prometheus_app at 0x7f0e7d2e3290>

    def create_task(coro, *, name=None, context=None):
        """Schedule the execution of a coroutine object in a spawn task.
    
        Return a Task object.
        """
>       loop = events.get_running_loop()
E       RuntimeError: no running event loop

/usr/lib/python3.12/asyncio/tasks.py:417: RuntimeError
___________________________________ ASGITest.test_gzip_disabled ____________________________________

self = <tests.test_asgi.ASGITest testMethod=test_gzip_disabled>

    def test_gzip_disabled(self):
        # Increment a metric.
        metric_name = "counter"
        help_text = "A counter"
        increments = 2
        self.increment_metrics(metric_name, help_text, increments)
        # Disable compression explicitly.
        app = make_asgi_app(self.registry, disable_compression=True)
>       self.seed_app(app)

tests/test_asgi.py:167: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_asgi.py:53: in seed_app
    self.communicator = ApplicationCommunicator(app, self.scope)
/usr/lib/python3.12/site-packages/asgiref/testing.py:24: in __init__
    self.future = contextvars.Context().run(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

coro = <coroutine object make_asgi_app.<locals>.prometheus_app at 0x7f0e7d2e3570>

    def create_task(coro, *, name=None, context=None):
        """Schedule the execution of a coroutine object in a spawn task.
    
        Return a Task object.
        """
>       loop = events.get_running_loop()
E       RuntimeError: no running event loop

/usr/lib/python3.12/asyncio/tasks.py:417: RuntimeError
________________________________ ASGITest.test_openmetrics_encoding ________________________________

self = <tests.test_asgi.ASGITest testMethod=test_openmetrics_encoding>

    def test_openmetrics_encoding(self):
        """Response content type is application/openmetrics-text when appropriate Accept header is in request"""
        app = make_asgi_app(self.registry)
>       self.seed_app(app)

tests/test_asgi.py:178: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_asgi.py:53: in seed_app
    self.communicator = ApplicationCommunicator(app, self.scope)
/usr/lib/python3.12/site-packages/asgiref/testing.py:24: in __init__
    self.future = contextvars.Context().run(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

coro = <coroutine object make_asgi_app.<locals>.prometheus_app at 0x7f0e7d2e3290>

    def create_task(coro, *, name=None, context=None):
        """Schedule the execution of a coroutine object in a spawn task.
    
        Return a Task object.
        """
>       loop = events.get_running_loop()
E       RuntimeError: no running event loop

/usr/lib/python3.12/asyncio/tasks.py:417: RuntimeError
_________________________________ ASGITest.test_plaintext_encoding _________________________________

self = <tests.test_asgi.ASGITest testMethod=test_plaintext_encoding>

    def test_plaintext_encoding(self):
        """Response content type is text/plain when Accept header is missing in request"""
        app = make_asgi_app(self.registry)
>       self.seed_app(app)

tests/test_asgi.py:188: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_asgi.py:53: in seed_app
    self.communicator = ApplicationCommunicator(app, self.scope)
/usr/lib/python3.12/site-packages/asgiref/testing.py:24: in __init__
    self.future = contextvars.Context().run(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

coro = <coroutine object make_asgi_app.<locals>.prometheus_app at 0x7f0e7d2e3850>

    def create_task(coro, *, name=None, context=None):
        """Schedule the execution of a coroutine object in a spawn task.
    
        Return a Task object.
        """
>       loop = events.get_running_loop()
E       RuntimeError: no running event loop

/usr/lib/python3.12/asyncio/tasks.py:417: RuntimeError
__________________________________ ASGITest.test_report_metrics_1 __________________________________

self = <tests.test_asgi.ASGITest testMethod=test_report_metrics_1>

    def test_report_metrics_1(self):
>       self.validate_metrics("counter", "A counter", 2)

tests/test_asgi.py:133: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_asgi.py:126: in validate_metrics
    self.seed_app(app)
tests/test_asgi.py:53: in seed_app
    self.communicator = ApplicationCommunicator(app, self.scope)
/usr/lib/python3.12/site-packages/asgiref/testing.py:24: in __init__
    self.future = contextvars.Context().run(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

coro = <coroutine object make_asgi_app.<locals>.prometheus_app at 0x7f0e7d2e39c0>

    def create_task(coro, *, name=None, context=None):
        """Schedule the execution of a coroutine object in a spawn task.
    
        Return a Task object.
        """
>       loop = events.get_running_loop()
E       RuntimeError: no running event loop

/usr/lib/python3.12/asyncio/tasks.py:417: RuntimeError
__________________________________ ASGITest.test_report_metrics_2 __________________________________

self = <tests.test_asgi.ASGITest testMethod=test_report_metrics_2>

    def test_report_metrics_2(self):
>       self.validate_metrics("counter", "Another counter", 3)

tests/test_asgi.py:136: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_asgi.py:126: in validate_metrics
    self.seed_app(app)
tests/test_asgi.py:53: in seed_app
    self.communicator = ApplicationCommunicator(app, self.scope)
/usr/lib/python3.12/site-packages/asgiref/testing.py:24: in __init__
    self.future = contextvars.Context().run(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

coro = <coroutine object make_asgi_app.<locals>.prometheus_app at 0x7f0e7d2e3b30>

    def create_task(coro, *, name=None, context=None):
        """Schedule the execution of a coroutine object in a spawn task.
    
        Return a Task object.
        """
>       loop = events.get_running_loop()
E       RuntimeError: no running event loop

/usr/lib/python3.12/asyncio/tasks.py:417: RuntimeError
__________________________________ ASGITest.test_report_metrics_3 __________________________________

self = <tests.test_asgi.ASGITest testMethod=test_report_metrics_3>

    def test_report_metrics_3(self):
>       self.validate_metrics("requests", "Number of requests", 5)

tests/test_asgi.py:139: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_asgi.py:126: in validate_metrics
    self.seed_app(app)
tests/test_asgi.py:53: in seed_app
    self.communicator = ApplicationCommunicator(app, self.scope)
/usr/lib/python3.12/site-packages/asgiref/testing.py:24: in __init__
    self.future = contextvars.Context().run(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

coro = <coroutine object make_asgi_app.<locals>.prometheus_app at 0x7f0e7d2e39c0>

    def create_task(coro, *, name=None, context=None):
        """Schedule the execution of a coroutine object in a spawn task.
    
        Return a Task object.
        """
>       loop = events.get_running_loop()
E       RuntimeError: no running event loop

/usr/lib/python3.12/asyncio/tasks.py:417: RuntimeError
__________________________________ ASGITest.test_report_metrics_4 __________________________________

self = <tests.test_asgi.ASGITest testMethod=test_report_metrics_4>

    def test_report_metrics_4(self):
>       self.validate_metrics("failed_requests", "Number of failed requests", 7)

tests/test_asgi.py:142: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_asgi.py:126: in validate_metrics
    self.seed_app(app)
tests/test_asgi.py:53: in seed_app
    self.communicator = ApplicationCommunicator(app, self.scope)
/usr/lib/python3.12/site-packages/asgiref/testing.py:24: in __init__
    self.future = contextvars.Context().run(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

coro = <coroutine object make_asgi_app.<locals>.prometheus_app at 0x7f0e7d2e3850>

    def create_task(coro, *, name=None, context=None):
        """Schedule the execution of a coroutine object in a spawn task.
    
        Return a Task object.
        """
>       loop = events.get_running_loop()
E       RuntimeError: no running event loop

/usr/lib/python3.12/asyncio/tasks.py:417: RuntimeError
========================================= warnings summary =========================================
../../../../../../../usr/lib/python3.12/site-packages/twisted/web/http.py:103
  /usr/lib/python3.12/site-packages/twisted/web/http.py:103: DeprecationWarning: 'cgi' is deprecated and slated for removal in Python 3.13
    import cgi

tests/test_exposition.py::TestPushGateway::test_metrics_handler_subclassing
  /home/ncopa/aports/community/py3-prometheus-client/src/prometheus_client-0.20.0/prometheus_client/metrics_core.py:27: RuntimeWarning: coroutine 'make_asgi_app.<locals>.prometheus_app' was never awaited
    if not METRIC_NAME_RE.match(name):
  Enable tracemalloc to get traceback where the object was allocated.
  See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.

tests/test_exposition.py::TestPushGateway::test_metrics_handler_subclassing
tests/test_gc_collector.py::TestGCCollector::test_empty
  /usr/lib/python3.12/site-packages/_pytest/unraisableexception.py:80: PytestUnraisableExceptionWarning: Exception ignored in: <function ApplicationCommunicator.__del__ at 0x7f0e7e09d120>
  
  Traceback (most recent call last):
    File "/usr/lib/python3.12/site-packages/asgiref/testing.py", line 58, in __del__
      self.stop(exceptions=False)
    File "/usr/lib/python3.12/site-packages/asgiref/testing.py", line 49, in stop
      if not self.future.done():
             ^^^^^^^^^^^
  AttributeError: 'ApplicationCommunicator' object has no attribute 'future'
  
    warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))

tests/test_gc_collector.py::TestGCCollector::test_empty
  /home/ncopa/aports/community/py3-prometheus-client/src/prometheus_client-0.20.0/tests/test_gc_collector.py:14: RuntimeWarning: coroutine 'make_asgi_app.<locals>.prometheus_app' was never awaited
    gc.collect()
  Enable tracemalloc to get traceback where the object was allocated.
  See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
===================================== short test summary info ======================================
FAILED tests/test_asgi.py::ASGITest::test_gzip - RuntimeError: no running event loop
FAILED tests/test_asgi.py::ASGITest::test_gzip_disabled - RuntimeError: no running event loop
FAILED tests/test_asgi.py::ASGITest::test_openmetrics_encoding - RuntimeError: no running event loop
FAILED tests/test_asgi.py::ASGITest::test_plaintext_encoding - RuntimeError: no running event loop
FAILED tests/test_asgi.py::ASGITest::test_report_metrics_1 - RuntimeError: no running event loop
FAILED tests/test_asgi.py::ASGITest::test_report_metrics_2 - RuntimeError: no running event loop
FAILED tests/test_asgi.py::ASGITest::test_report_metrics_3 - RuntimeError: no running event loop
FAILED tests/test_asgi.py::ASGITest::test_report_metrics_4 - RuntimeError: no running event loop
============================ 8 failed, 301 passed, 5 warnings in 4.16s =============================

ncopa avatar Apr 01 '24 18:04 ncopa

seems like it comes from asgiref 3.8.1 upgrade.

ncopa avatar Apr 01 '24 19:04 ncopa

I also ran into this issue on the tox py3.8 environment when doing PR #1019 and circumvented it py pinning asgiref to 3.6.0 in tox.ini (same solution that was already used for pypy3.8 tox environment).

andy-maier avatar Apr 02 '24 06:04 andy-maier

@ncopa, could you please update the bug summary to mention the cause (asgiref >= 3.8)? That would make it easier to find this.

mgorny avatar Jul 22 '24 13:07 mgorny

Is this still a problem? I can't reproduce it with the newest version. And the pins for py3.9 in tox.ini not only don't seem to make any sense for me, but actually break #1138.

mgorny avatar Sep 12 '25 18:09 mgorny

I am going to close this as it has been awhile and the pinning is now gone.

csmarchbanks avatar Sep 26 '25 02:09 csmarchbanks