From 143cf0164585979431f8e8c408ac760bf4a118c3 Mon Sep 17 00:00:00 2001 From: Federico Ressi Date: Mon, 3 Jan 2022 15:19:37 +0100 Subject: [PATCH] Add support for Python 3.10 Change-Id: I42a3558899c1262b3edb61c177e8856af71529bd --- Dockerfile | 17 ++++++++++++----- tobiko/openstack/heat/_stack.py | 3 ++- tobiko/openstack/heat/_template.py | 10 +++++----- tobiko/openstack/neutron/_agent.py | 8 ++++---- tobiko/openstack/neutron/_client.py | 4 ++-- tobiko/openstack/neutron/_extension.py | 4 ++-- tobiko/openstack/nova/_cloud_init.py | 4 ++-- tobiko/openstack/topology/_address.py | 4 ++-- tobiko/openstack/topology/_topology.py | 3 ++- tobiko/podman/_podman1/libs/tunnel.py | 5 +++-- tobiko/shell/ssh/_client.py | 4 ++-- tobiko/tests/unit/openstack/heat/test_stack.py | 4 ++-- tobiko/tests/unit/test_select.py | 10 +++++----- 13 files changed, 45 insertions(+), 35 deletions(-) diff --git a/Dockerfile b/Dockerfile index b6f508cef..b5807434f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,16 @@ -FROM python:3.9 as base +FROM python:3.10 as base ENV TOBIKO_DIR=/tobiko ENV WHEEL_DIR=/wheel -RUN apt update +ENV INSTALL_PACKAGES="apt install -y" + +# Install binary dependencies +RUN apt update && \ + ${INSTALL_PACKAGES} git + +RUN python3 -m ensurepip --upgrade && \ + python3 -m pip install --upgrade setuptools wheel FROM base as source @@ -28,7 +35,7 @@ ADD tobiko/ ${TOBIKO_DIR}/tobiko/ FROM source as build # Install binary dependencies -RUN apt install -y git +# RUN ${INSTALL_PACKAGES} gcc python3-devel # Build wheel files RUN python3 -m pip wheel -w ${WHEEL_DIR} \ @@ -44,13 +51,13 @@ FROM base as install # Install wheels RUN mkdir -p ${WHEEL_DIR} COPY --from=build ${WHEEL_DIR} ${WHEEL_DIR} -RUN pip install ${WHEEL_DIR}/*.whl +RUN python3 -m pip install ${WHEEL_DIR}/*.whl FROM source as tobiko # Install packages -RUN apt install -y iperf3 iputils-ping ncat +RUN ${INSTALL_PACKAGES} iperf3 iputils-ping ncat # Run tests variables ENV PYTHONWARNINGS=ignore::Warning diff --git a/tobiko/openstack/heat/_stack.py b/tobiko/openstack/heat/_stack.py index 78630a899..6485b53a4 100644 --- a/tobiko/openstack/heat/_stack.py +++ b/tobiko/openstack/heat/_stack.py @@ -14,6 +14,7 @@ from __future__ import absolute_import import collections +from collections import abc import random import time import typing @@ -53,7 +54,7 @@ def heat_stack_parameters(obj, -> 'HeatStackParametersFixture': if isinstance(obj, HeatStackParametersFixture): parameters = obj - elif obj is None or isinstance(obj, collections.Mapping): + elif obj is None or isinstance(obj, abc.Mapping): parameters = HeatStackParametersFixture(stack, obj) else: parameters = tobiko.get_fixture(obj) diff --git a/tobiko/openstack/heat/_template.py b/tobiko/openstack/heat/_template.py index 868a7c675..cb8bf4e15 100644 --- a/tobiko/openstack/heat/_template.py +++ b/tobiko/openstack/heat/_template.py @@ -13,7 +13,7 @@ # under the License. from __future__ import absolute_import -import collections +from collections import abc import os import sys import typing @@ -48,9 +48,9 @@ class HeatTemplateFixture(tobiko.SharedFixture): def setup_template(self): # Ensure main sections are dictionaries - tobiko.check_valid_type(self.outputs, collections.Mapping) - tobiko.check_valid_type(self.parameters, collections.Mapping) - tobiko.check_valid_type(self.resources, collections.Mapping) + tobiko.check_valid_type(self.outputs, abc.Mapping) + tobiko.check_valid_type(self.parameters, abc.Mapping) + tobiko.check_valid_type(self.resources, abc.Mapping) self.template_yaml = tobiko.dump_yaml(self.template) @property @@ -98,7 +98,7 @@ HeatTemplateType = typing.Union[typing.Mapping[str, typing.Any], def heat_template(obj: HeatTemplateType, template_files: typing.Mapping = None) \ -> HeatTemplateFixture: - if isinstance(obj, collections.Mapping): + if isinstance(obj, abc.Mapping): template = HeatTemplateFixture(template=obj, template_files=template_files) else: diff --git a/tobiko/openstack/neutron/_agent.py b/tobiko/openstack/neutron/_agent.py index 01d6175df..590bc2b54 100644 --- a/tobiko/openstack/neutron/_agent.py +++ b/tobiko/openstack/neutron/_agent.py @@ -13,7 +13,7 @@ # under the License. from __future__ import absolute_import -import collections +from collections import abc import re import typing @@ -45,7 +45,7 @@ NeutronAgentType = typing.Dict[str, typing.Any] def list_agents(client=None, **params) \ -> tobiko.Selection[NeutronAgentType]: agents = _client.neutron_client(client).list_agents(**params) - if isinstance(agents, collections.Mapping): + if isinstance(agents, abc.Mapping): agents = agents['agents'] return tobiko.Selection[NeutronAgentType](agents) @@ -53,7 +53,7 @@ def list_agents(client=None, **params) \ def list_l3_agent_hosting_routers(router, client=None, **params): agents = _client.neutron_client(client).list_l3_agent_hosting_routers( router, **params) - if isinstance(agents, collections.Mapping): + if isinstance(agents, abc.Mapping): agents = agents['agents'] return tobiko.select(agents) @@ -71,7 +71,7 @@ def find_l3_agent_hosting_router(router, client=None, unique=False, def list_dhcp_agent_hosting_network(network, client=None, **params): agents = _client.neutron_client(client).list_dhcp_agent_hosting_networks( network, **params) - if isinstance(agents, collections.Mapping): + if isinstance(agents, abc.Mapping): agents = agents['agents'] return tobiko.select(agents) diff --git a/tobiko/openstack/neutron/_client.py b/tobiko/openstack/neutron/_client.py index ee71439fa..53b5a11ae 100644 --- a/tobiko/openstack/neutron/_client.py +++ b/tobiko/openstack/neutron/_client.py @@ -13,7 +13,7 @@ # under the License. from __future__ import absolute_import -import collections +from collections import abc import typing import netaddr @@ -147,7 +147,7 @@ def list_subnets(client=None, ip_version: typing.Optional[int] = None, if ip_version is not None: params['ip_version'] = ip_version subnets = neutron_client(client).list_subnets(**params) - if isinstance(subnets, collections.Mapping): + if isinstance(subnets, abc.Mapping): subnets = subnets['subnets'] return tobiko.select(subnets) diff --git a/tobiko/openstack/neutron/_extension.py b/tobiko/openstack/neutron/_extension.py index f07391cac..1ac1c3784 100644 --- a/tobiko/openstack/neutron/_extension.py +++ b/tobiko/openstack/neutron/_extension.py @@ -13,7 +13,7 @@ # under the License. from __future__ import absolute_import -import collections +from collections import abc import tobiko from tobiko.openstack import keystone @@ -35,7 +35,7 @@ class NetworkingExtensionsFixture(tobiko.SharedFixture): def get_networking_extensions(self): extensions = self.client.list_extensions() - if isinstance(extensions, collections.Mapping): + if isinstance(extensions, abc.Mapping): extensions = extensions['extensions'] ignore_extensions = set( tobiko.tobiko_config().neutron.ignore_extensions) diff --git a/tobiko/openstack/nova/_cloud_init.py b/tobiko/openstack/nova/_cloud_init.py index 3048362fa..df2ab35d8 100644 --- a/tobiko/openstack/nova/_cloud_init.py +++ b/tobiko/openstack/nova/_cloud_init.py @@ -13,7 +13,7 @@ # under the License. from __future__ import absolute_import -import collections +from collections import abc import typing from oslo_log import log @@ -51,7 +51,7 @@ def combine_cloud_configs(objs): extra_params = {} for obj in objs: if obj: - if not isinstance(obj, collections.abc.Mapping): + if not isinstance(obj, abc.Mapping): obj = dict(obj) for package in obj.pop('packages', []): if package and package not in packages: diff --git a/tobiko/openstack/topology/_address.py b/tobiko/openstack/topology/_address.py index 7a811888a..b00fac953 100644 --- a/tobiko/openstack/topology/_address.py +++ b/tobiko/openstack/topology/_address.py @@ -13,7 +13,7 @@ # under the License. from __future__ import absolute_import -import collections +from collections import abc import functools import socket import typing @@ -43,7 +43,7 @@ def list_addresses(obj, ip_version=ip_version, port=port, ssh_config=ssh_config)) - elif isinstance(obj, collections.Sequence): + elif isinstance(obj, abc.Sequence): addresses = tobiko.Selection() for item in iter(obj): addresses.extend(list_addresses(item)) diff --git a/tobiko/openstack/topology/_topology.py b/tobiko/openstack/topology/_topology.py index cad54f72b..2a8015b4b 100644 --- a/tobiko/openstack/topology/_topology.py +++ b/tobiko/openstack/topology/_topology.py @@ -14,6 +14,7 @@ from __future__ import absolute_import import collections +from collections import abc import re import typing from urllib import parse @@ -56,7 +57,7 @@ def list_openstack_nodes(topology: 'OpenStackTopology' = None, elif isinstance(group, PatternType): nodes = topology.get_groups(groups=[group]) else: - assert isinstance(group, collections.Iterable) + assert isinstance(group, abc.Iterable) nodes = topology.get_groups(groups=group) if hostnames: diff --git a/tobiko/podman/_podman1/libs/tunnel.py b/tobiko/podman/_podman1/libs/tunnel.py index b71425f9e..48274ef17 100644 --- a/tobiko/podman/_podman1/libs/tunnel.py +++ b/tobiko/podman/_podman1/libs/tunnel.py @@ -3,6 +3,7 @@ from __future__ import absolute_import import collections +from collections import abc import getpass import logging import os @@ -29,7 +30,7 @@ Context = collections.namedtuple('Context', ( Context.__new__.__defaults__ = (None, ) * len(Context._fields) # type: ignore -class Portal(collections.MutableMapping): +class Portal(abc.MutableMapping): """Expiring container for tunnels.""" def __init__(self, sweap=25): @@ -98,7 +99,7 @@ class Portal(collections.MutableMapping): self._schedule_reaper() -class Tunnel(): +class Tunnel: """SSH tunnel.""" def __init__(self, context): diff --git a/tobiko/shell/ssh/_client.py b/tobiko/shell/ssh/_client.py index 2de9de735..fb07afbf9 100644 --- a/tobiko/shell/ssh/_client.py +++ b/tobiko/shell/ssh/_client.py @@ -15,7 +15,7 @@ # under the License. from __future__ import absolute_import -import collections +from collections import abc import contextlib import getpass import io @@ -163,7 +163,7 @@ def gather_ssh_connect_parameters(source=None, destination=None, schema=None, if source: # gather from object - if isinstance(source, collections.Mapping): + if isinstance(source, abc.Mapping): parameters.update(_items_from_mapping(mapping=source, schema=schema)) else: diff --git a/tobiko/tests/unit/openstack/heat/test_stack.py b/tobiko/tests/unit/openstack/heat/test_stack.py index b11ed7111..fdd62c889 100644 --- a/tobiko/tests/unit/openstack/heat/test_stack.py +++ b/tobiko/tests/unit/openstack/heat/test_stack.py @@ -13,7 +13,7 @@ # under the License. from __future__ import absolute_import -import collections +from collections import abc import time from heatclient.v1 import client as heatclient @@ -297,7 +297,7 @@ class HeatStackFixtureTest(openstack.OpenstackTest): expected_template = template or type(stack).template if tobiko.is_fixture(expected_template): self.assertIs(expected_template, stack.template) - elif isinstance(expected_template, collections.Mapping): + elif isinstance(expected_template, abc.Mapping): self.assertEqual(expected_template, stack.template.template) else: message = "Unsupported template type: {!r}".format( diff --git a/tobiko/tests/unit/test_select.py b/tobiko/tests/unit/test_select.py index 11d602d86..906ff7b51 100644 --- a/tobiko/tests/unit/test_select.py +++ b/tobiko/tests/unit/test_select.py @@ -14,7 +14,7 @@ # under the License. from __future__ import absolute_import -import collections +from collections import abc import re import typing @@ -44,14 +44,14 @@ class SelectionTest(unit.TobikoUnitTest): objects: typing.Iterable[T] = tuple()) \ -> tobiko.Selection[T]: reference = list(objects) - if isinstance(objects, collections.Generator): + if isinstance(objects, abc.Generator): # Can't reiterate the same generator twice objects = (o for o in reference) - assert isinstance(objects, collections.Generator) - elif isinstance(objects, collections.Iterator): + assert isinstance(objects, abc.Generator) + elif isinstance(objects, abc.Iterator): # Can't reiterate the same iterator twice objects = iter(reference) - assert isinstance(objects, collections.Iterator) + assert isinstance(objects, abc.Iterator) selection = self.create_selection(objects) self.assertIsInstance(selection, list)