Bug 2357903 - python-metakernel fails to build with Python 3.14: AssertionError in test_parallel_magic
Summary: python-metakernel fails to build with Python 3.14: AssertionError in test_par...
Keywords:
Status: NEW
Alias: None
Product: Fedora
Classification: Fedora
Component: python-metakernel
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Mattias Ellert
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: PYTHON3.14
TreeView+ depends on / blocked
 
Reported: 2025-04-07 13:04 UTC by Karolina Surma
Modified: 2025-04-07 13:04 UTC (History)
3 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Karolina Surma 2025-04-07 13:04:07 UTC
python-metakernel fails to build with Python 3.14.0a6.

_____________________________ test_parallel_magic ______________________________

    @pytest.mark.skipif(ipyparallel is None, reason="Requires ipyparallel")
    @pytest.mark.skipif(sys.platform == 'darwin', reason="Fails on darwin")
    def test_parallel_magic():
        kernel = get_kernel(EvalKernel)
        # start up an EvalKernel on each node:
        kernel.do_execute("%parallel metakernel_python MetaKernelPython", False)
        # Now, execute something on each one:
        kernel.do_execute("%px cluster_rank", False)
        results = get_log_text(kernel)
>       assert "[0, 1, 2]" in results, results
E       AssertionError: Write: Waiting on cluster to start...
E         Write: 
E         
E         Write: Waiting on cluster to start...
E         Write: 
E         
E         Write: Waiting on cluster to start...
E         Write: 
E         
E         Write: Waiting on cluster to start...
E         Write: 
E         
E         Write: Waiting on cluster to start...
E         Write: 
E         
E         Error: Error in calling magic 'parallel' on line:
E             Cluster was not started.
E             args: ['metakernel_python', 'MetaKernelPython']
E             kwargs: {'ids': None, 'kernel_name': 'default'}
E         Error: Traceback (most recent call last):
E           File "/builddir/build/BUILD/python-metakernel-0.30.3-build/metakernel-0.30.3/metakernel/magic.py", line 96, in call_magic
E             func(*args, **kwargs)
E             ~~~~^^^^^^^^^^^^^^^^^
E           File "/builddir/build/BUILD/python-metakernel-0.30.3-build/metakernel-0.30.3/metakernel/magics/parallel_magic.py", line 63, in line_parallel
E             raise Exception("Cluster was not started.")
E         Exception: Cluster was not started.
E         Error: %parallel MODULE CLASS [-k NAME] [-i [...]] - construct an interface to the cluster.
E         
E         Example:
E         
E             %parallel bash_kernel BashKernel
E             %parallel bash_kernel BashKernel -k bash
E             %parallel bash_kernel BashKernel -i [0,2:5,9,...]
E         
E         cluster_size and cluster_rank variables are set upon
E         initialization of the remote node (if the kernel
E         supports %set).
E         
E         Use %px or %%px to send code to the cluster.
E         
E         Options:
E         -------
E         -i --ids       the machine ids to use from the cluster [default: None]
E         -k --kernel_name arbitrary name given to reference kernel [default: default]
E         'NoneType' object is not subscriptable
E         
E       assert '[0, 1, 2]' in 'Write: Waiting on cluster to start...\nWrite: \n\nWrite: Waiting on cluster to start...\nWrite: \n\nWrite: Waiting on cluster to start...\nWrite: \n\nWrite: Waiting on cluster to start...\nWrite: \n\nWrite: Waiting on cluster to start...\nWrite: \n\nError: Error in calling magic \'parallel\' on line:\n    Cluster was not started.\n    args: [\'metakernel_python\', \'MetaKernelPython\']\n    kwargs: {\'ids\': None, \'kernel_name\': \'default\'}\nError: Traceback (most recent call last):\n  File "/builddir/build/BUILD/python-metakernel-0.30.3-build/metakernel-0.30.3/metakernel/magic.py", line 96, in call_magic\n    func(*args, **kwargs)\n    ~~~~^^^^^^^^^^^^^^^^^\n  File "/builddir/build/BUILD/python-metakernel-0.30.3-build/metakernel-0.30.3/metakernel/magics/parallel_magic.py", line 63, in line_parallel\n    raise Exception("Cluster was not started.")\nException: Cluster was not started.\nError: %parallel MODULE CLASS [-k NAME] [-i [...]] - construct an interface to the cluster.\n\nExample:\n\n    %parallel bash_kernel BashKernel\n    %parallel bash_kernel BashKernel -k bash\n    %parallel bash_kernel BashKernel -i [0,2:5,9,...]\n\ncluster_size and cluster_rank variables are set upon\ninitialization of the remote node (if the kernel\nsupports %set).\n\nUse %px or %%px to send code to the cluster.\n\nOptions:\n-------\n-i --ids       the machine ids to use from the cluster [default: None]\n-k --kernel_name arbitrary name given to reference kernel [default: default]\n\'NoneType\' object is not subscriptable\n'

/builddir/build/BUILD/python-metakernel-0.30.3-build/metakernel-0.30.3/metakernel/magics/tests/test_parallel_magic.py:22: AssertionError

During handling of the above exception, another exception occurred:

cls = <class '_pytest.runner.CallInfo'>
func = <function call_and_report.<locals>.<lambda> at 0x7f57309e3740>
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()

/usr/lib/python3.14/site-packages/_pytest/runner.py:341: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/lib/python3.14/site-packages/_pytest/runner.py:242: in <lambda>
    lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
/usr/lib/python3.14/site-packages/pluggy/_hooks.py:513: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
/usr/lib/python3.14/site-packages/pluggy/_manager.py:120: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
/usr/lib/python3.14/site-packages/_pytest/threadexception.py:92: in pytest_runtest_call
    yield from thread_exception_runtest_hook()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def thread_exception_runtest_hook() -> Generator[None]:
        with catch_threading_exception() as cm:
            try:
                yield
            finally:
                if cm.args:
                    thread_name = (
                        "<unknown>" if cm.args.thread is None else cm.args.thread.name
                    )
                    msg = f"Exception in thread {thread_name}\n\n"
                    msg += "".join(
                        traceback.format_exception(
                            cm.args.exc_type,
                            cm.args.exc_value,
                            cm.args.exc_traceback,
                        )
                    )
>                   warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))
E                   pytest.PytestUnhandledThreadExceptionWarning: Exception in thread Thread-5
E                   
E                   Traceback (most recent call last):
E                     File "/usr/lib64/python3.14/threading.py", line 1054, in _bootstrap_inner
E                       self.run()
E                       ~~~~~~~~^^
E                     File "/usr/lib64/python3.14/threading.py", line 996, in run
E                       self._target(*self._args, **self._kwargs)
E                       ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E                     File "/usr/lib/python3.14/site-packages/ipyparallel/util.py", line 838, in _wrapped_target
E                       return target(*args, **kwargs)
E                     File "/usr/lib/python3.14/site-packages/ipyparallel/client/client.py", line 1080, in _io_main
E                       self._io_loop = self._make_io_loop()
E                                       ~~~~~~~~~~~~~~~~~~^^
E                     File "/usr/lib/python3.14/site-packages/ipyparallel/client/client.py", line 1034, in _make_io_loop
E                       loop = ioloop.IOLoop(make_current=False)
E                     File "/usr/lib64/python3.14/site-packages/tornado/util.py", line 263, in __new__
E                       impl = cls.configured_class()
E                     File "/usr/lib64/python3.14/site-packages/tornado/util.py", line 335, in configured_class
E                       base.__impl_class = cls.configurable_default()
E                                           ~~~~~~~~~~~~~~~~~~~~~~~~^^
E                     File "/usr/lib64/python3.14/site-packages/tornado/ioloop.py", line 360, in configurable_default
E                       from tornado.platform.asyncio import AsyncIOLoop
E                     File "/usr/lib64/python3.14/site-packages/tornado/platform/asyncio.py", line 389, in <module>
E                       _BasePolicy = asyncio.DefaultEventLoopPolicy
E                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E                     File "/usr/lib64/python3.14/asyncio/__init__.py", line 61, in __getattr__
E                       warnings._deprecated(f"asyncio.{name}", remove=(3, 16))
E                       ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E                     File "/usr/lib64/python3.14/warnings.py", line 677, in _deprecated
E                       warn(msg, DeprecationWarning, stacklevel=3)
E                       ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E                   DeprecationWarning: 'asyncio.DefaultEventLoopPolicy' is deprecated and slated for removal in Python 3.16


According to https://docs.python.org/dev/whatsnew/3.14.html#id3

asyncio policy system is deprecated and will be removed in Python 3.16. In particular, the following classes and functions are deprecated:
asyncio.AbstractEventLoopPolicy
asyncio.DefaultEventLoopPolicy
asyncio.WindowsSelectorEventLoopPolicy
asyncio.WindowsProactorEventLoopPolicy
asyncio.get_event_loop_policy()
asyncio.set_event_loop_policy()
asyncio.set_event_loop()
Users should use asyncio.run() or asyncio.Runner with loop_factory to use the desired event loop implementation.)


https://docs.python.org/3.14/whatsnew/3.14.html

For the build logs, see:
https://copr-be.cloud.fedoraproject.org/results/@python/python3.14/fedora-rawhide-x86_64/08861101-python-metakernel/

For all our attempts to build python-metakernel with Python 3.14, see:
https://copr.fedorainfracloud.org/coprs/g/python/python3.14/package/python-metakernel/

Testing and mass rebuild of packages is happening in copr.
You can follow these instructions to test locally in mock if your package builds with Python 3.14:
https://copr.fedorainfracloud.org/coprs/g/python/python3.14/

Let us know here if you have any questions.

Python 3.14 is planned to be included in Fedora 43.
To make that update smoother, we're building Fedora packages with all pre-releases of Python 3.14.
A build failure prevents us from testing all dependent packages (transitive [Build]Requires),
so if this package is required a lot, it's important for us to get it fixed soon.

We'd appreciate help from the people who know this package best,
but if you don't want to work on this now, let us know so we can try to work around it on our side.


Note You need to log in before you can comment on or make changes to this bug.