Bug#1025189: spyder: (autopkgtest) needs update for python3.11: Signal sig_response(QString, PyQt_PyObject) not emitted after 30000 ms

Paul Gevers elbrus at debian.org
Wed Nov 30 20:11:02 GMT 2022


Source: spyder
Version: 5.3.3+dfsg-3
Severity: serious
Tags: sid bookworm
User: debian-ci at lists.debian.org
Usertags: needs-update
User: debian-python at lists.debian.org
Usertags: python3.11
Control: affects -1 src:python3-defaults

Dear maintainer(s),

We are in the transition of adding python3.11 as a supported Python 
version [0]. With a recent upload of python3-defaults the autopkgtest of 
spyder fails in testing when that autopkgtest is run with the binary 
packages of python3-defaults from unstable. It passes when run with only 
packages from testing. In tabular form:

                        pass            fail
python3-defaults       from testing    3.10.6-3
spyder                 from testing    5.3.3+dfsg-3
all others             from testing    from testing

I copied some of the output at the bottom of this report.

Currently this regression is blocking the migration of python3-defaults 
to testing [1]. https://docs.python.org/3/whatsnew/3.11.html lists 
what's new in Python3.11, it may help to identify what needs to be updated.

More information about this bug and the reason for filing it can be found on
https://wiki.debian.org/ContinuousIntegration/RegressionEmailInformation

Paul

[0] https://bugs.debian.org/1021984
[1] https://qa.debian.org/excuses.php?package=python3-defaults

https://ci.debian.net/data/autopkgtest/testing/amd64/s/spyder/28806955/log.gz

=================================== FAILURES 
===================================
______________________ test_plugin_first_response_request 
______________________

qtbot_module = <pytestqt.qtbot.QtBot object at 0x7fb11dceb110>
completion_receiver = 
(<spyder.plugins.completion.plugin.CompletionPlugin object at 
0x7fb1231c7a30>, 
<spyder.plugins.completion.tests.test_plugin.DummyCompletionReceiver 
object at 0x7fb11dcc7910>)

     @pytest.mark.order(1)
     def test_plugin_first_response_request(qtbot_module, 
completion_receiver):
         completion, receiver = completion_receiver
             # Parameters to perform a textDocument/didOpen request
         params = {
             'file': 'test2.py',
             'language': 'python',
             'version': 2,
             'text': "# This is some text with some classe\nimport os\n\n",
             'response_instance': receiver,
             'offset': 1,
             'diff': '',
             'selection_start': 0,
             'selection_end': 0,
             'codeeditor': receiver,
             'requires_response': False
         }
             with qtbot_module.waitSignal(receiver.sig_response, 
timeout=30000) as blocker:
             completion.send_request(
                 'python', CompletionRequestTypes.DOCUMENT_DID_OPEN, params)
                 params = {
             'file': 'test2.py',
             'line': 1,
             'column': 8,
             'offset': 43,
             'diff': '',
             'response_instance': receiver,
             'codeeditor': receiver,
             'requires_response': True
         }
             with qtbot_module.waitSignal(receiver.sig_response, 
timeout=30000) as blocker:
             completion.send_request(
                 'python', CompletionRequestTypes.DOCUMENT_HOVER, params)
             _, response = blocker.args
>       assert len(response['params']) > 0
E       AssertionError: assert 0 > 0
E        +  where 0 = len('')

spyder/plugins/completion/tests/test_plugin.py:253: AssertionError
_______________________ test_get_signature[lsp_provider] 
_______________________

lsp_client_and_completion = 
(<spyder.plugins.completion.providers.languageserver.client.LSPClient 
object at 0x7fb11da1eb00>, 
<spyder.plugins.completion.providers.languageserver.tests.test_client.CompletionManager 
object at 0x7fb11da1ed40>)
qtbot = <pytestqt.qtbot.QtBot object at 0x7fb11db42510>

     @pytest.mark.order(3)
     def test_get_signature(lsp_client_and_completion, qtbot):
         client, completion = lsp_client_and_completion
             # Parameters to perform a textDocument/didChange request
         params = {
             'file': 'test.py',
             'language': 'python',
             'version': 1,
             'text': "import os\nos.walk(\n",
             'codeeditor': completion,
             'requires_response': False
         }
             # Perform the request
>       with qtbot.waitSignal(completion.sig_response, timeout=30000):
E       pytestqt.exceptions.TimeoutError: Signal 
sig_response(QString,PyQt_PyObject) not emitted after 30000 ms

spyder/plugins/completion/providers/languageserver/tests/test_client.py:76: 
TimeoutError
______________________ test_get_completions[lsp_provider] 
______________________

lsp_client_and_completion = 
(<spyder.plugins.completion.providers.languageserver.client.LSPClient 
object at 0x7fb11da1eb00>, 
<spyder.plugins.completion.providers.languageserver.tests.test_client.CompletionManager 
object at 0x7fb11da1ed40>)
qtbot = <pytestqt.qtbot.QtBot object at 0x7fb141c38cd0>

     @pytest.mark.order(3)
     def test_get_completions(lsp_client_and_completion, qtbot):
         client, completion = lsp_client_and_completion
             # Parameters to perform a textDocument/didChange request
         params = {
             'file': 'test.py',
             'language': 'python',
             'version': 1,
             'text': "import o",
             'codeeditor': completion,
             'requires_response': False
         }
             # Perform the request
>       with qtbot.waitSignal(completion.sig_response, timeout=30000):
E       pytestqt.exceptions.TimeoutError: Signal 
sig_response(QString,PyQt_PyObject) not emitted after 30000 ms

spyder/plugins/completion/providers/languageserver/tests/test_client.py:114: 
TimeoutError
_____________________ test_go_to_definition[lsp_provider] 
______________________

lsp_client_and_completion = 
(<spyder.plugins.completion.providers.languageserver.client.LSPClient 
object at 0x7fb11da1eb00>, 
<spyder.plugins.completion.providers.languageserver.tests.test_client.CompletionManager 
object at 0x7fb11da1ed40>)
qtbot = <pytestqt.qtbot.QtBot object at 0x7fb141c0fc50>

     @pytest.mark.order(3)
     def test_go_to_definition(lsp_client_and_completion, qtbot):
         client, completion = lsp_client_and_completion
             # Parameters to perform a textDocument/didChange request
         params = {
             'file': 'test.py',
             'language': 'python',
             'version': 1,
             'text': "import os\nos.walk\n",
             'codeeditor': completion,
             'requires_response': False
         }
             # Perform the request
>       with qtbot.waitSignal(completion.sig_response, timeout=30000):
E       pytestqt.exceptions.TimeoutError: Signal 
sig_response(QString,PyQt_PyObject) not emitted after 30000 ms

spyder/plugins/completion/providers/languageserver/tests/test_client.py:153: 
TimeoutError
______________________ test_local_signature[lsp_provider] 
______________________

lsp_client_and_completion = 
(<spyder.plugins.completion.providers.languageserver.client.LSPClient 
object at 0x7fb11da1eb00>, 
<spyder.plugins.completion.providers.languageserver.tests.test_client.CompletionManager 
object at 0x7fb11da1ed40>)
qtbot = <pytestqt.qtbot.QtBot object at 0x7fb141c1b150>

     @pytest.mark.order(3)
     def test_local_signature(lsp_client_and_completion, qtbot):
         client, completion = lsp_client_and_completion
             # Parameters to perform a textDocument/didOpen request
         text = dedent('''
         def test(a, b):
             """Test docstring"""
             pass
         test''')
         params = {
             'file': 'test.py',
             'language': 'python',
             'version': 1,
             'text': text,
             'codeeditor': completion,
             'requires_response': False
         }
             # Perform the request
>       with qtbot.waitSignal(completion.sig_response, timeout=30000) as blocker:
E       pytestqt.exceptions.TimeoutError: Signal 
sig_response(QString,PyQt_PyObject) not emitted after 30000 ms

spyder/plugins/completion/providers/languageserver/tests/test_client.py:197: 
TimeoutError
____________________ test_get_signature[lsp_stdio_provider] 
____________________

lsp_client_and_completion = 
(<spyder.plugins.completion.providers.languageserver.client.LSPClient 
object at 0x7fb11da1f6d0>, 
<spyder.plugins.completion.providers.languageserver.tests.test_client.CompletionManager 
object at 0x7fb11da1f910>)
qtbot = <pytestqt.qtbot.QtBot object at 0x7fb141c44650>

     @pytest.mark.order(3)
     def test_get_signature(lsp_client_and_completion, qtbot):
         client, completion = lsp_client_and_completion
             # Parameters to perform a textDocument/didChange request
         params = {
             'file': 'test.py',
             'language': 'python',
             'version': 1,
             'text': "import os\nos.walk(\n",
             'codeeditor': completion,
             'requires_response': False
         }
             # Perform the request
>       with qtbot.waitSignal(completion.sig_response, timeout=30000):
E       pytestqt.exceptions.TimeoutError: Signal 
sig_response(QString,PyQt_PyObject) not emitted after 30000 ms

spyder/plugins/completion/providers/languageserver/tests/test_client.py:76: 
TimeoutError
___________________ test_get_completions[lsp_stdio_provider] 
___________________

lsp_client_and_completion = 
(<spyder.plugins.completion.providers.languageserver.client.LSPClient 
object at 0x7fb11da1f6d0>, 
<spyder.plugins.completion.providers.languageserver.tests.test_client.CompletionManager 
object at 0x7fb11da1f910>)
qtbot = <pytestqt.qtbot.QtBot object at 0x7fb141c1a110>

     @pytest.mark.order(3)
     def test_get_completions(lsp_client_and_completion, qtbot):
         client, completion = lsp_client_and_completion
             # Parameters to perform a textDocument/didChange request
         params = {
             'file': 'test.py',
             'language': 'python',
             'version': 1,
             'text': "import o",
             'codeeditor': completion,
             'requires_response': False
         }
             # Perform the request
>       with qtbot.waitSignal(completion.sig_response, timeout=30000):
E       pytestqt.exceptions.TimeoutError: Signal 
sig_response(QString,PyQt_PyObject) not emitted after 30000 ms

spyder/plugins/completion/providers/languageserver/tests/test_client.py:114: 
TimeoutError
__________________ test_go_to_definition[lsp_stdio_provider] 
___________________

lsp_client_and_completion = 
(<spyder.plugins.completion.providers.languageserver.client.LSPClient 
object at 0x7fb11da1f6d0>, 
<spyder.plugins.completion.providers.languageserver.tests.test_client.CompletionManager 
object at 0x7fb11da1f910>)
qtbot = <pytestqt.qtbot.QtBot object at 0x7fb141c5eed0>

     @pytest.mark.order(3)
     def test_go_to_definition(lsp_client_and_completion, qtbot):
         client, completion = lsp_client_and_completion
             # Parameters to perform a textDocument/didChange request
         params = {
             'file': 'test.py',
             'language': 'python',
             'version': 1,
             'text': "import os\nos.walk\n",
             'codeeditor': completion,
             'requires_response': False
         }
             # Perform the request
>       with qtbot.waitSignal(completion.sig_response, timeout=30000):
E       pytestqt.exceptions.TimeoutError: Signal 
sig_response(QString,PyQt_PyObject) not emitted after 30000 ms

spyder/plugins/completion/providers/languageserver/tests/test_client.py:153: 
TimeoutError
___________________ test_local_signature[lsp_stdio_provider] 
___________________

lsp_client_and_completion = 
(<spyder.plugins.completion.providers.languageserver.client.LSPClient 
object at 0x7fb11da1f6d0>, 
<spyder.plugins.completion.providers.languageserver.tests.test_client.CompletionManager 
object at 0x7fb11da1f910>)
qtbot = <pytestqt.qtbot.QtBot object at 0x7fb141a62ed0>

     @pytest.mark.order(3)
     def test_local_signature(lsp_client_and_completion, qtbot):
         client, completion = lsp_client_and_completion
             # Parameters to perform a textDocument/didOpen request
         text = dedent('''
         def test(a, b):
             """Test docstring"""
             pass
         test''')
         params = {
             'file': 'test.py',
             'language': 'python',
             'version': 1,
             'text': text,
             'codeeditor': completion,
             'requires_response': False
         }
             # Perform the request
>       with qtbot.waitSignal(completion.sig_response, timeout=30000) as blocker:
E       pytestqt.exceptions.TimeoutError: Signal 
sig_response(QString,PyQt_PyObject) not emitted after 30000 ms

spyder/plugins/completion/providers/languageserver/tests/test_client.py:197: 
TimeoutError
________________ test_objectexplorer_collection_types[params0] 
_________________

objectexplorer = <function objectexplorer.<locals>.create_objectexplorer 
at 0x7fb11746f740>
params = ('kjkj kj k j j kj k jkj', [71, 80])

     @pytest.mark.parametrize('params', [
         # variable to show, rowCount for different Python 3 versions
         ('kjkj kj k j j kj k jkj', [71, 80]),
         ([1, 3, 4, 'kjkj', None], [45, 47]),
         ({1, 2, 1, 3, None, 'A', 'B', 'C', True, False}, [54, 56]),
         (1.2233, [57, 59]),
         (np.random.rand(10, 10), [166, 162]),
         (datetime.date(1945, 5, 8), [43, 47])
     ])
     def test_objectexplorer_collection_types(objectexplorer, params):
         """Test to validate proper handling of collection data types."""
         test, row_count = params
         CONF.set('variable_explorer', 'show_special_attributes', True)
             # Editor was created
         editor = objectexplorer(test, name='variable')
         assert editor
             # Check number of rows and row content
         model = editor.obj_tree.model()
             # The row for the variable
         assert model.rowCount() == 1
             # Root row with children
         # Since rowCount for python 3 and 2 varies on differents systems,
         # we use a range of values
         expected_output_range = list(range(min(row_count), 
max(row_count) + 1))
>       assert model.rowCount(model.index(0, 0)) in expected_output_range
E       assert 81 in [71, 72, 73, 74, 75, 76, ...]
E        +  where 81 = <built-in method rowCount of TreeProxyModel 
object at 0x7fb117404e50>(<PyQt5.QtCore.QModelIndex object at 
0x7fb159fb43c0>)
E        +    where <built-in method rowCount of TreeProxyModel object 
at 0x7fb117404e50> = 
<spyder.plugins.variableexplorer.widgets.objectexplorer.tree_model.TreeProxyModel 
object at 0x7fb117404e50>.rowCount
E        +    and   <PyQt5.QtCore.QModelIndex object at 0x7fb159fb43c0> 
= <built-in method index of TreeProxyModel object at 0x7fb117404e50>(0, 0)
E        +      where <built-in method index of TreeProxyModel object at 
0x7fb117404e50> = 
<spyder.plugins.variableexplorer.widgets.objectexplorer.tree_model.TreeProxyModel 
object at 0x7fb117404e50>.index

spyder/plugins/variableexplorer/widgets/objectexplorer/tests/test_objectexplorer.py:136: 
AssertionError
________________ test_objectexplorer_collection_types[params1] 
_________________

objectexplorer = <function objectexplorer.<locals>.create_objectexplorer 
at 0x7fb1174b7240>
params = ([1, 3, 4, 'kjkj', None], [45, 47])

     @pytest.mark.parametrize('params', [
         # variable to show, rowCount for different Python 3 versions
         ('kjkj kj k j j kj k jkj', [71, 80]),
         ([1, 3, 4, 'kjkj', None], [45, 47]),
         ({1, 2, 1, 3, None, 'A', 'B', 'C', True, False}, [54, 56]),
         (1.2233, [57, 59]),
         (np.random.rand(10, 10), [166, 162]),
         (datetime.date(1945, 5, 8), [43, 47])
     ])
     def test_objectexplorer_collection_types(objectexplorer, params):
         """Test to validate proper handling of collection data types."""
         test, row_count = params
         CONF.set('variable_explorer', 'show_special_attributes', True)
             # Editor was created
         editor = objectexplorer(test, name='variable')
         assert editor
             # Check number of rows and row content
         model = editor.obj_tree.model()
             # The row for the variable
         assert model.rowCount() == 1
             # Root row with children
         # Since rowCount for python 3 and 2 varies on differents systems,
         # we use a range of values
         expected_output_range = list(range(min(row_count), 
max(row_count) + 1))
>       assert model.rowCount(model.index(0, 0)) in expected_output_range
E       assert 48 in [45, 46, 47]
E        +  where 48 = <built-in method rowCount of TreeProxyModel 
object at 0x7fb1174070a0>(<PyQt5.QtCore.QModelIndex object at 
0x7fb1174f00b0>)
E        +    where <built-in method rowCount of TreeProxyModel object 
at 0x7fb1174070a0> = 
<spyder.plugins.variableexplorer.widgets.objectexplorer.tree_model.TreeProxyModel 
object at 0x7fb1174070a0>.rowCount
E        +    and   <PyQt5.QtCore.QModelIndex object at 0x7fb1174f00b0> 
= <built-in method index of TreeProxyModel object at 0x7fb1174070a0>(0, 0)
E        +      where <built-in method index of TreeProxyModel object at 
0x7fb1174070a0> = 
<spyder.plugins.variableexplorer.widgets.objectexplorer.tree_model.TreeProxyModel 
object at 0x7fb1174070a0>.index

spyder/plugins/variableexplorer/widgets/objectexplorer/tests/test_objectexplorer.py:136: 
AssertionError
________________ test_objectexplorer_collection_types[params2] 
_________________

objectexplorer = <function objectexplorer.<locals>.create_objectexplorer 
at 0x7fb1174cb1a0>
params = ({False, 'B', 'C', 1, 2, 3, ...}, [54, 56])

     @pytest.mark.parametrize('params', [
         # variable to show, rowCount for different Python 3 versions
         ('kjkj kj k j j kj k jkj', [71, 80]),
         ([1, 3, 4, 'kjkj', None], [45, 47]),
         ({1, 2, 1, 3, None, 'A', 'B', 'C', True, False}, [54, 56]),
         (1.2233, [57, 59]),
         (np.random.rand(10, 10), [166, 162]),
         (datetime.date(1945, 5, 8), [43, 47])
     ])
     def test_objectexplorer_collection_types(objectexplorer, params):
         """Test to validate proper handling of collection data types."""
         test, row_count = params
         CONF.set('variable_explorer', 'show_special_attributes', True)
             # Editor was created
         editor = objectexplorer(test, name='variable')
         assert editor
             # Check number of rows and row content
         model = editor.obj_tree.model()
             # The row for the variable
         assert model.rowCount() == 1
             # Root row with children
         # Since rowCount for python 3 and 2 varies on differents systems,
         # we use a range of values
         expected_output_range = list(range(min(row_count), 
max(row_count) + 1))
>       assert model.rowCount(model.index(0, 0)) in expected_output_range
E       assert 57 in [54, 55, 56]
E        +  where 57 = <built-in method rowCount of TreeProxyModel 
object at 0x7fb1174d8ca0>(<PyQt5.QtCore.QModelIndex object at 
0x7fb1174f1690>)
E        +    where <built-in method rowCount of TreeProxyModel object 
at 0x7fb1174d8ca0> = 
<spyder.plugins.variableexplorer.widgets.objectexplorer.tree_model.TreeProxyModel 
object at 0x7fb1174d8ca0>.rowCount
E        +    and   <PyQt5.QtCore.QModelIndex object at 0x7fb1174f1690> 
= <built-in method index of TreeProxyModel object at 0x7fb1174d8ca0>(0, 0)
E        +      where <built-in method index of TreeProxyModel object at 
0x7fb1174d8ca0> = 
<spyder.plugins.variableexplorer.widgets.objectexplorer.tree_model.TreeProxyModel 
object at 0x7fb1174d8ca0>.index

spyder/plugins/variableexplorer/widgets/objectexplorer/tests/test_objectexplorer.py:136: 
AssertionError
________________ test_objectexplorer_collection_types[params5] 
_________________

objectexplorer = <function objectexplorer.<locals>.create_objectexplorer 
at 0x7fb1174b63e0>
params = (datetime.date(1945, 5, 8), [43, 47])

     @pytest.mark.parametrize('params', [
         # variable to show, rowCount for different Python 3 versions
         ('kjkj kj k j j kj k jkj', [71, 80]),
         ([1, 3, 4, 'kjkj', None], [45, 47]),
         ({1, 2, 1, 3, None, 'A', 'B', 'C', True, False}, [54, 56]),
         (1.2233, [57, 59]),
         (np.random.rand(10, 10), [166, 162]),
         (datetime.date(1945, 5, 8), [43, 47])
     ])
     def test_objectexplorer_collection_types(objectexplorer, params):
         """Test to validate proper handling of collection data types."""
         test, row_count = params
         CONF.set('variable_explorer', 'show_special_attributes', True)
             # Editor was created
         editor = objectexplorer(test, name='variable')
         assert editor
             # Check number of rows and row content
         model = editor.obj_tree.model()
             # The row for the variable
         assert model.rowCount() == 1
             # Root row with children
         # Since rowCount for python 3 and 2 varies on differents systems,
         # we use a range of values
         expected_output_range = list(range(min(row_count), 
max(row_count) + 1))
>       assert model.rowCount(model.index(0, 0)) in expected_output_range
E       assert 48 in [43, 44, 45, 46, 47]
E        +  where 48 = <built-in method rowCount of TreeProxyModel 
object at 0x7fb1174da830>(<PyQt5.QtCore.QModelIndex object at 
0x7fb1174f1a10>)
E        +    where <built-in method rowCount of TreeProxyModel object 
at 0x7fb1174da830> = 
<spyder.plugins.variableexplorer.widgets.objectexplorer.tree_model.TreeProxyModel 
object at 0x7fb1174da830>.rowCount
E        +    and   <PyQt5.QtCore.QModelIndex object at 0x7fb1174f1a10> 
= <built-in method index of TreeProxyModel object at 0x7fb1174da830>(0, 0)
E        +      where <built-in method index of TreeProxyModel object at 
0x7fb1174da830> = 
<spyder.plugins.variableexplorer.widgets.objectexplorer.tree_model.TreeProxyModel 
object at 0x7fb1174da830>.index

spyder/plugins/variableexplorer/widgets/objectexplorer/tests/test_objectexplorer.py:136: 
AssertionError
______________________ test_objectexplorer_types[params0] 
______________________

objectexplorer = <function objectexplorer.<locals>.create_objectexplorer 
at 0x7fb1174c80e0>
params = (True, True, [34, 26])

     @pytest.mark.parametrize('params', [
                 # show_callable_, show_special_, rowCount for python 3 
and 2
                 (True, True, [34, 26], ),
                 (False, False, [8, 8], )
             ])
     def test_objectexplorer_types(objectexplorer, params):
         """Test to validate proper handling of data types inside an 
object."""
         class Foobar(object):
             def __init__(self):
                 self.text = "toto"
                 self.list = [1, 3, 4, 'kjkj', None]
                 self.set = {1, 2, 1, 3, None, 'A', 'B', 'C', True, False},
                 self.dict = {'d': 1, 'a': np.random.rand(10, 10), 'b': 
[1, 2]},
                 self.float = 1.2233,
                 self.array = np.random.rand(10, 10),
                 self.date = datetime.date(1945, 5, 8),
                 self.datetime = datetime.datetime(1945, 5, 8)
         foo = Foobar()
             show_callable, show_special, row_count = params
         CONF.set('variable_explorer', 'show_callable_attributes', 
show_callable)
         CONF.set('variable_explorer', 'show_special_attributes', 
show_special)
             # Editor was created
         editor = objectexplorer(foo, name='foo')
         assert editor
             # Check number of rows and row content
         model = editor.obj_tree.model()
         # The row for the object
         assert model.rowCount() == 1
         # Rows from the object attributes
>       assert model.rowCount(model.index(0, 0)) in row_count
E       assert 35 in [34, 26]
E        +  where 35 = <built-in method rowCount of TreeProxyModel 
object at 0x7fb117200670>(<PyQt5.QtCore.QModelIndex object at 
0x7fb1174f28f0>)
E        +    where <built-in method rowCount of TreeProxyModel object 
at 0x7fb117200670> = 
<spyder.plugins.variableexplorer.widgets.objectexplorer.tree_model.TreeProxyModel 
object at 0x7fb117200670>.rowCount
E        +    and   <PyQt5.QtCore.QModelIndex object at 0x7fb1174f28f0> 
= <built-in method index of TreeProxyModel object at 0x7fb117200670>(0, 0)
E        +      where <built-in method index of TreeProxyModel object at 
0x7fb117200670> = 
<spyder.plugins.variableexplorer.widgets.objectexplorer.tree_model.TreeProxyModel 
object at 0x7fb117200670>.index

spyder/plugins/variableexplorer/widgets/objectexplorer/tests/test_objectexplorer.py:172: 
AssertionError
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 495 bytes
Desc: OpenPGP digital signature
URL: <http://alioth-lists.debian.net/pipermail/debian-science-maintainers/attachments/20221130/c5ca2043/attachment-0001.sig>


More information about the debian-science-maintainers mailing list