Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-matrix-nio for 
openSUSE:Factory checked in at 2023-09-04 22:53:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-matrix-nio (Old)
 and      /work/SRC/openSUSE:Factory/.python-matrix-nio.new.1766 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-matrix-nio"

Mon Sep  4 22:53:16 2023 rev:3 rq:1108788 version:0.21.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-matrix-nio/python-matrix-nio.changes      
2023-07-19 19:10:30.648522905 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-matrix-nio.new.1766/python-matrix-nio.changes
    2023-09-04 22:53:49.812293463 +0200
@@ -1,0 +2,19 @@
+Mon Sep  4 03:30:04 UTC 2023 - Steve Kowalik <steven.kowa...@suse.com>
+
+- Update to 0.21.2:
+  * Breaking Changes
+    + [#416] Drop support for end-of-life python3.7
+    + [#413] Drop usage of logbook in favor of standard library logging
+  * Features
+    + [#409] Support m.space.parent and m.space.child events
+    + [#418] Add ability to knock on a room, and enable knocking for a room
+  * Miscellaneous Tasks
+    + [#401] Removing skip for passing test
+    + [#406] [#407] [#414] Add content to built-with-nio
+  * Bug Fixes
+    + [#422] async_client.whoami will alter the state of async_client
+      correctly, and accept all spec-compliant fields.
+    + [#408] Properly generate code coverage
+- Add patch remove-future-requirement.patch, dropping dependency on future.
+
+-------------------------------------------------------------------

Old:
----
  matrix_nio-0.20.2.tar.gz

New:
----
  matrix_nio-0.21.2.tar.gz
  remove-future-requirement.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-matrix-nio.spec ++++++
--- /var/tmp/diff_new_pack.IxLNsL/_old  2023-09-04 22:53:51.560355254 +0200
+++ /var/tmp/diff_new_pack.IxLNsL/_new  2023-09-04 22:53:51.564355395 +0200
@@ -17,23 +17,23 @@
 
 
 Name:           python-matrix-nio
-Version:        0.20.2
+Version:        0.21.2
 Release:        0
 Summary:        A Python Matrix client library, designed according to sans I/O 
principles
 License:        ISC
 URL:            https://github.com/poljar/matrix-nio
 Source:         
https://files.pythonhosted.org/packages/source/m/matrix_nio/matrix_nio-%{version}.tar.gz
+# PATCH-FIX-UPSTREAM gh#poljar/matrix-nio#440
+Patch0:         remove-future-requirement.patch
 BuildRequires:  %{python_module pip}
 BuildRequires:  %{python_module poetry-core}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  %{python_module wheel}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
-Requires:       python-Logbook >= 1.5.3
 Requires:       python-aiofiles >= 0.6.0
 Requires:       python-aiohttp >= 3.7.4
 Requires:       python-aiohttp-socks >= 0.7.0
-Requires:       python-future >= 0.18.2
 Requires:       python-h11 >= 0.12.0
 Requires:       python-h2 >= 4.0.0
 Requires:       python-jsonschema >= 3.2.0
@@ -46,11 +46,9 @@
 Suggests:       python-python-olm >= 3.1.3
 BuildArch:      noarch
 # SECTION test requirements
-BuildRequires:  %{python_module Logbook >= 1.5.3}
 BuildRequires:  %{python_module aiofiles >= 0.6.0}
 BuildRequires:  %{python_module aiohttp >= 3.7.4}
 BuildRequires:  %{python_module aiohttp-socks >= 0.7.0}
-BuildRequires:  %{python_module future >= 0.18.2}
 BuildRequires:  %{python_module h11 >= 0.12.0}
 BuildRequires:  %{python_module h2 >= 4.0.0}
 BuildRequires:  %{python_module jsonschema >= 3.2.0}

++++++ matrix_nio-0.20.2.tar.gz -> matrix_nio-0.21.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/PKG-INFO 
new/matrix_nio-0.21.2/PKG-INFO
--- old/matrix_nio-0.20.2/PKG-INFO      1970-01-01 01:00:00.000000000 +0100
+++ new/matrix_nio-0.21.2/PKG-INFO      1970-01-01 01:00:00.000000000 +0100
@@ -1,15 +1,14 @@
 Metadata-Version: 2.1
 Name: matrix-nio
-Version: 0.20.2
+Version: 0.21.2
 Summary: A Python Matrix client library, designed according to sans I/O 
principles.
 Home-page: https://github.com/poljar/matrix-nio
 License: ISC
 Author: Damir Jelić
 Author-email: pol...@termina.org.uk
-Requires-Python: >=3.7.0,<4.0.0
+Requires-Python: >=3.8.0,<4.0.0
 Classifier: License :: OSI Approved
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
@@ -20,12 +19,10 @@
 Requires-Dist: aiohttp-socks (>=0.7.0,<0.8.0)
 Requires-Dist: atomicwrites (>=1.4.0,<2.0.0) ; extra == "e2e"
 Requires-Dist: cachetools (>=4.2.1,<5.0.0) ; extra == "e2e"
-Requires-Dist: dataclasses (>=0.7,<0.8) ; python_version >= "3.6" and 
python_version < "3.7"
 Requires-Dist: future (>=0.18.2,<0.19.0)
 Requires-Dist: h11 (>=0.14.0,<0.15.0)
 Requires-Dist: h2 (>=4.0.0,<5.0.0)
 Requires-Dist: jsonschema (>=4.4.0,<5.0.0)
-Requires-Dist: logbook (>=1.5.3,<2.0.0)
 Requires-Dist: peewee (>=3.14.4,<4.0.0) ; extra == "e2e"
 Requires-Dist: pycryptodome (>=3.10.1,<4.0.0)
 Requires-Dist: python-olm (>=3.1.3,<4.0.0) ; extra == "e2e"
@@ -45,7 +42,7 @@
 
 nio is a multilayered [Matrix](https://matrix.org/) client library. The
 underlying base layer doesn't do any network IO on its own, but on top of that
-is a full fledged batteries-included asyncio layer using
+is a full-fledged batteries-included asyncio layer using
 [aiohttp](https://github.com/aio-libs/aiohttp/). File IO is only done if you
 enable end-to-end encryption (E2EE).
 
@@ -62,10 +59,11 @@
 
 - ✅ transparent end-to-end encryption (EE2E)
 - ✅ encrypted file uploads & downloads
+- ✅ space parents/children
 - ✅ manual and emoji verification
 - ✅ custom [authentication 
types](https://matrix.org/docs/spec/client_server/r0.6.0#id183)
 - ✅ well-integrated type system
-- ✅ kick, ban and unban
+- ✅ knocking, kick, ban and unban
 - ✅ typing notifications
 - ✅ message redaction
 - ✅ token based login
@@ -73,12 +71,11 @@
 - ✅ read receipts
 - ✅ live syncing
 - ✅ `m.tag`s
-- ❌ python 2.7 support
 - ❌ cross-signing support
 - ❌ server-side key backups (room key backup, "Secure Backup")
 - ❌ user deactivation 
([#112](https://github.com/poljar/matrix-nio/issues/112))
+- ❌ threading support
 - ❌ in-room emoji verification
-- ❌ room upgrades and `m.room.tombstone` events 
([#47](https://github.com/poljar/matrix-nio/issues/47))
 
 Installation
 ------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/README.md 
new/matrix_nio-0.21.2/README.md
--- old/matrix_nio-0.20.2/README.md     2023-03-28 04:30:52.188544800 +0200
+++ new/matrix_nio-0.21.2/README.md     2023-07-14 12:03:32.938272500 +0200
@@ -9,7 +9,7 @@
 
 nio is a multilayered [Matrix](https://matrix.org/) client library. The
 underlying base layer doesn't do any network IO on its own, but on top of that
-is a full fledged batteries-included asyncio layer using
+is a full-fledged batteries-included asyncio layer using
 [aiohttp](https://github.com/aio-libs/aiohttp/). File IO is only done if you
 enable end-to-end encryption (E2EE).
 
@@ -26,10 +26,11 @@
 
 - ✅ transparent end-to-end encryption (EE2E)
 - ✅ encrypted file uploads & downloads
+- ✅ space parents/children
 - ✅ manual and emoji verification
 - ✅ custom [authentication 
types](https://matrix.org/docs/spec/client_server/r0.6.0#id183)
 - ✅ well-integrated type system
-- ✅ kick, ban and unban
+- ✅ knocking, kick, ban and unban
 - ✅ typing notifications
 - ✅ message redaction
 - ✅ token based login
@@ -37,12 +38,11 @@
 - ✅ read receipts
 - ✅ live syncing
 - ✅ `m.tag`s
-- ❌ python 2.7 support
 - ❌ cross-signing support
 - ❌ server-side key backups (room key backup, "Secure Backup")
 - ❌ user deactivation 
([#112](https://github.com/poljar/matrix-nio/issues/112))
+- ❌ threading support
 - ❌ in-room emoji verification
-- ❌ room upgrades and `m.room.tombstone` events 
([#47](https://github.com/poljar/matrix-nio/issues/47))
 
 Installation
 ------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/__init__.py 
new/matrix_nio-0.21.2/nio/__init__.py
--- old/matrix_nio-0.20.2/nio/__init__.py       2023-03-28 04:30:52.188544800 
+0200
+++ new/matrix_nio-0.21.2/nio/__init__.py       2023-07-14 11:44:32.557834100 
+0200
@@ -10,7 +10,6 @@
 from .event_builders import *
 from .events import *
 from .exceptions import *
-from .log import logger_group
 from .monitors import *
 from .responses import *
 from .rooms import *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/api.py 
new/matrix_nio-0.21.2/nio/api.py
--- old/matrix_nio-0.20.2/nio/api.py    2023-03-28 04:30:52.188544800 +0200
+++ new/matrix_nio-0.21.2/nio/api.py    2023-07-14 11:44:32.557834100 +0200
@@ -778,6 +778,36 @@
         )
 
     @staticmethod
+    def room_knock(
+        access_token: str,
+        room_id: str,
+        reason: Optional[str] = None,
+    ) -> Tuple[str, str, str]:
+        """Knocks on a room for the user.
+
+        Returns the HTTP method, HTTP path and data for the request.
+
+        Args:
+            access_token (str): The access token to be used with the request.
+            room_id (str): The room id of the room that the user will be
+                knocking on.
+            reason (str, optional): The reason the user is knocking.
+        """
+
+        path = ["knock", room_id]
+        query_parameters = {"access_token": access_token}
+        body = {}
+
+        if reason:
+            body["reason"] = reason
+
+        return (
+            "POST",
+            Api._build_path(path, query_parameters),
+            Api.to_json(body),
+        )
+
+    @staticmethod
     def room_invite(access_token, room_id, user_id):
         # type (str, str, str) -> Tuple[str, str, str]
         """Invite a user to a room.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/client/async_client.py 
new/matrix_nio-0.21.2/nio/client/async_client.py
--- old/matrix_nio-0.20.2/nio/client/async_client.py    2023-03-28 
04:30:52.191878300 +0200
+++ new/matrix_nio-0.21.2/nio/client/async_client.py    2023-07-17 
10:39:25.072212500 +0200
@@ -173,6 +173,8 @@
     RoomKeyRequestResponse,
     RoomKickError,
     RoomKickResponse,
+    RoomKnockError,
+    RoomKnockResponse,
     RoomLeaveError,
     RoomLeaveResponse,
     RoomMessagesError,
@@ -187,6 +189,7 @@
     RoomRedactResponse,
     RoomResolveAliasError,
     RoomResolveAliasResponse,
+    RoomSendError,
     RoomSendResponse,
     RoomTypingError,
     RoomTypingResponse,
@@ -1545,7 +1548,7 @@
         content: Dict[Any, Any],
         tx_id: Optional[str] = None,
         ignore_unverified_devices: bool = False,
-    ):
+    ) -> Union[RoomSendResponse, RoomSendError]:
         """Send a message to a room.
 
         Calls receive_response() to update the client state if necessary.
@@ -2235,6 +2238,50 @@
         return await self._send(JoinResponse, method, path, data)
 
     @logged_in_async
+    async def room_knock(
+        self,
+        room_id: str,
+        reason: Optional[str] = None,
+    ) -> Union[RoomKnockResponse, RoomKnockError]:
+        """Knock on a room.
+
+        Calls receive_response() to update the client state if necessary.
+
+        Returns either a `RoomKnockResponse` if the request was successful or
+        a `RoomKnockError` if there was an error with the request.
+
+        Args:
+            room_id (str): The room id of the room that the user is
+                knocking on.
+            reason (str, optional): The reason for the knock.
+        """
+        method, path, data = Api.room_knock(
+            self.access_token,
+            room_id,
+            reason,
+        )
+        return await self._send(RoomKnockResponse, method, path, data)
+
+    @logged_in_async
+    async def room_enable_knocking(
+        self,
+        room_id: str,
+    ) -> Union[RoomPutStateResponse, RoomPutStateError]:
+        """Enables knocking for a room.
+
+        Returns either a `RoomPutStateResponse` if the request was successful
+        or a `RoomPutStateError` if there was an error with the request.
+
+        Args:
+            room_id (str): The room id of the room to enable knocking for.
+        """
+        return await self.room_put_state(
+            room_id,
+            event_type="m.room.join_rules",
+            content={"join_rule": "knock"},
+        )
+
+    @logged_in_async
     async def room_invite(
         self,
         room_id: str,
@@ -3205,7 +3252,15 @@
 
         return await self._send(UploadFilterResponse, method, path, data)
 
-    async def whoami(self):
+    async def whoami(self) -> Union[WhoamiResponse, WhoamiError]:
+        """Get information about the logged-in user from the homeserver.
+
+        Returns either a `WhoamiResponse` if the request was successful
+        or a `WhoamiError` if there was an error with the request.
+
+        On a successful response, the client's state will be updated with
+        the user_id and device_id returned, if different from the current 
state.
+        """
         if self.access_token is None:
             raise ValueError("No access_token is set.")
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/client/base_client.py 
new/matrix_nio-0.21.2/nio/client/base_client.py
--- old/matrix_nio-0.20.2/nio/client/base_client.py     2023-03-28 
04:30:52.191878300 +0200
+++ new/matrix_nio-0.21.2/nio/client/base_client.py     2023-07-17 
10:39:25.072212500 +0200
@@ -14,6 +14,7 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
+import logging
 from collections import defaultdict
 from dataclasses import dataclass, field
 from functools import wraps
@@ -31,8 +32,6 @@
     Union,
 )
 
-from logbook import Logger
-
 from ..crypto import ENCRYPTION_ENABLED, DeviceStore, OlmDevice, 
OutgoingKeyRequest
 from ..events import (
     AccountDataEvent,
@@ -50,7 +49,6 @@
     UnknownBadEvent,
 )
 from ..exceptions import EncryptionError, LocalProtocolError, MembersSyncError
-from ..log import logger_group
 from ..responses import (
     ErrorResponse,
     JoinedMembersResponse,
@@ -71,6 +69,7 @@
     ShareGroupSessionResponse,
     SyncResponse,
     ToDeviceResponse,
+    WhoamiResponse,
 )
 from ..rooms import MatrixInvitedRoom, MatrixRoom
 
@@ -80,17 +79,13 @@
 
 from ..event_builders import ToDeviceMessage
 
-if False:
-    from ..crypto import Sas
-
 try:
     from json.decoder import JSONDecodeError
 except ImportError:
     JSONDecodeError = ValueError  # type: ignore
 
 
-logger = Logger("nio.client")
-logger_group.add_logger(logger)
+logger = logging.getLogger(__name__)
 
 
 def logged_in(func):
@@ -1028,6 +1023,11 @@
             )
             self.rooms[room_id].users[response.user_id].status_msg = 
response.status_msg
 
+    def _handle_whoami_response(self, response: WhoamiResponse):
+        self.user_id = response.user_id
+        self.device_id = response.device_id or self.device_id
+        # self.is_guest = response.is_guest
+
     def receive_response(
         self, response: Response
     ) -> Union[None, Coroutine[Any, Any, None]]:
@@ -1079,6 +1079,8 @@
                     pass
         elif isinstance(response, PresenceGetResponse):
             self._handle_presence_response(response)
+        elif isinstance(response, WhoamiResponse):
+            self._handle_whoami_response(response)
         elif isinstance(response, ErrorResponse):
             if response.soft_logout:
                 self.access_token = ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/client/http_client.py 
new/matrix_nio-0.21.2/nio/client/http_client.py
--- old/matrix_nio-0.20.2/nio/client/http_client.py     2023-03-28 
04:30:52.191878300 +0200
+++ new/matrix_nio-0.21.2/nio/client/http_client.py     2023-07-14 
11:44:32.557834100 +0200
@@ -16,6 +16,7 @@
 
 import cgi
 import json
+import logging
 import pprint
 from builtins import str, super
 from collections import deque
@@ -26,7 +27,6 @@
 
 import h2
 import h11
-from logbook import Logger
 
 try:
     from urllib.parse import urlparse
@@ -45,7 +45,6 @@
     TransportResponse,
     TransportType,
 )
-from ..log import logger_group
 from ..responses import (
     DeleteDevicesAuthResponse,
     DeleteDevicesResponse,
@@ -88,18 +87,13 @@
 from . import Client, ClientConfig
 from .base_client import logged_in, store_loaded
 
-if False:
-    from .crypto import OlmDevice
-    from .event_builders import ToDeviceMessage
-
 try:
     from json.decoder import JSONDecodeError
 except ImportError:
     JSONDecodeError = ValueError  # type: ignore
 
 
-logger = Logger("nio.client")
-logger_group.add_logger(logger)
+logger = logging.getLogger(__name__)
 
 
 def connected(func):
@@ -1187,7 +1181,7 @@
                 logger.info(f"Received response of type: 
{request_info.request_class}")
             else:
                 logger.info(
-                    ("Error with response of type type: {}, " "error code 
{}").format(
+                    "Error with response of type type: {}, error code 
{}".format(
                         request_info.request_class, response.status_code
                     )
                 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/crypto/log.py 
new/matrix_nio-0.21.2/nio/crypto/log.py
--- old/matrix_nio-0.20.2/nio/crypto/log.py     2023-03-28 04:30:52.191878300 
+0200
+++ new/matrix_nio-0.21.2/nio/crypto/log.py     2023-07-14 11:44:32.557834100 
+0200
@@ -14,9 +14,6 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-from logbook import Logger
+import logging
 
-from ..log import logger_group
-
-logger = Logger("nio.encryption")
-logger_group.add_logger(logger)
+logger = logging.getLogger(__name__)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/crypto/olm_machine.py 
new/matrix_nio-0.21.2/nio/crypto/olm_machine.py
--- old/matrix_nio-0.20.2/nio/crypto/olm_machine.py     2023-03-28 
04:30:52.191878300 +0200
+++ new/matrix_nio-0.21.2/nio/crypto/olm_machine.py     2023-07-14 
11:44:32.561834000 +0200
@@ -438,7 +438,7 @@
             if event.algorithm == Olm._megolm_algorithm:
                 self.received_key_requests[event.request_id] = event
             else:
-                logger.warn(
+                logger.warning(
                     f"Received key request from {event.sender} via 
{event.requesting_device_id} "
                     f"with an unknown algorithm: {event.algorithm}"
                 )
@@ -618,13 +618,13 @@
             try:
                 self.share_with_ourselves(event)
             except KeyShareError as error:
-                logger.warn(error)
+                logger.warning(error)
             except EncryptionError as error:
                 # We can safely ignore this, the share_with_ourselves
                 # method will queue up the device for a key claiming
                 # request when that is done the event will be put back
                 # in the received_key_requests queue.
-                logger.warn(error)
+                logger.warning(error)
             except OlmTrustError:
                 return False
 
@@ -672,7 +672,7 @@
                 try:
                     device = self.device_store[user_id][device_id]
                 except KeyError:
-                    logger.warn(
+                    logger.warning(
                         f"Curve key for user {user_id} and device {device_id} 
not found, failed to start Olm session"
                     )
                     continue
@@ -708,7 +708,7 @@
                         self.received_key_requests.update(events)
 
                 else:
-                    logger.warn(
+                    logger.warning(
                         "Signature verification for one-time key of "
                         f"device {device_id} of user {user_id} failed, could 
not start "
                         "Olm session."
@@ -732,7 +732,7 @@
                     continue
 
                 if payload["user_id"] != user_id or payload["device_id"] != 
device_id:
-                    logger.warn(
+                    logger.warning(
                         "Mismatch in keys payload of device "
                         f"{payload['device_id']} "
                         f"({device_id}) of user {payload['user_id']} "
@@ -976,7 +976,7 @@
                 )
 
         except OlmSessionError as e:
-            logger.warn(e)
+            logger.warning(e)
             return
 
         self.inbound_group_store.add(session)
@@ -1007,7 +1007,7 @@
                     continue
 
                 if not self.session_store.get(device.curve25519):
-                    logger.warn(f"Missing session for device {device.id}")
+                    logger.warning(f"Missing session for device {device.id}")
                     missing[user_id].append(device.id)
 
         return missing
@@ -1042,7 +1042,7 @@
 
         if not device:
             # TODO we should probably mark this user for a key query.
-            logger.warn(
+            logger.warning(
                 "Attempted to mark a device for Olm session "
                 f"unwedging, but no device was found for user {sender} with "
                 f"sender key {sender_key}"
@@ -1056,7 +1056,7 @@
         if session:
             session_age = datetime.now() - session.creation_time
             if session_age < self._unwedging_interval:
-                logger.warn(
+                logger.warning(
                     f"Attempted to mark device {device.device_id} of user "
                     f"{device.user_id} for Olm session unwedging, but a new "
                     "session was created recently."
@@ -1216,7 +1216,7 @@
 
         # Only accept forwarded room keys from our own trusted devices
         if not device or not device.verified or not device.user_id == 
self.user_id:
-            logger.warn(
+            logger.warning(
                 "Received a forwarded room key from a untrusted device "
                 f"{event.sender}, {sender_key}"
             )
@@ -1291,7 +1291,7 @@
             return DummyEvent.from_dict(payload, sender, sender_key)
 
         else:
-            logger.warn(f"Received unsupported Olm event of type 
{payload['type']}")
+            logger.warning(f"Received unsupported Olm event of type 
{payload['type']}")
             return None
 
     def message_index_ok(self, message_index, event):
@@ -1332,7 +1332,7 @@
         try:
             device = self.device_store[event.sender][event.device_id]
         except KeyError:
-            logger.warn(
+            logger.warning(
                 f"Received a undecryptable Megolm event from a unknown "
                 f"device: {event.sender} {event.device_id}"
             )
@@ -1342,7 +1342,7 @@
         session = self.session_store.get(device.curve25519)
 
         if not session:
-            logger.warn(
+            logger.warning(
                 f"Received a undecryptable Megolm event from a device "
                 f"with no Olm sessions: {event.sender} {event.device_id}"
             )
@@ -1405,14 +1405,14 @@
                 f"with session id {event.session_id} for room {room_id}"
             )
             self.check_if_wedged(event)
-            logger.warn(message)
+            logger.warning(message)
             raise EncryptionError(message)
 
         try:
             plaintext, message_index = session.decrypt(event.ciphertext)
         except OlmGroupSessionError as e:
             message = f"Error decrypting megolm event: {str(e)}"
-            logger.warn(message)
+            logger.warning(message)
             raise EncryptionError(message)
 
         if not self.message_index_ok(message_index, event):
@@ -1449,7 +1449,7 @@
                         message = (
                             f"Device keys mismatch in event sent by device 
{device.id}."
                         )
-                        logger.warn(message)
+                        logger.warning(message)
                         raise EncryptionError(message)
 
                     logger.info(f"Event {event.event_id} successfully 
verified")
@@ -1506,7 +1506,7 @@
                 own_key = self.account.identity_keys["curve25519"]
                 own_ciphertext = event.ciphertext[own_key]
             except KeyError:
-                logger.warn("Olm event doesn't contain ciphertext for our key")
+                logger.warning("Olm event doesn't contain ciphertext for our 
key")
                 return None
 
             if own_ciphertext["type"] == 0:
@@ -1514,7 +1514,9 @@
             elif own_ciphertext["type"] == 1:
                 message = OlmMessage(own_ciphertext["body"])
             else:
-                logger.warn(f"Unsupported olm message type: 
{own_ciphertext['type']}")
+                logger.warning(
+                    f"Unsupported olm message type: {own_ciphertext['type']}"
+                )
                 return None
 
             return self.decrypt(event.sender, event.sender_key, message)
@@ -1709,7 +1711,7 @@
                 session = self.session_store.get(device.curve25519)
 
                 if not session:
-                    logger.warn(
+                    logger.warning(
                         f"Missing Olm session for user {user_id} and device "
                         f"{device.id}, skipping"
                     )
@@ -1967,7 +1969,7 @@
                 forwarding_chain,
             )
         except OlmSessionError as e:
-            logger.warn(f"Error importing inbound group session: {e}")
+            logger.warning(f"Error importing inbound group session: {e}")
             return None
 
     @staticmethod
@@ -2120,7 +2122,7 @@
             try:
                 device = self.device_store[event.sender][event.from_device]
             except KeyError:
-                logger.warn(
+                logger.warning(
                     f"Received key verification event from unknown device: 
{event.sender} {event.from_device}"
                 )
                 self.users_for_key_query.add(event.sender)
@@ -2135,7 +2137,7 @@
             )
 
             if new_sas.canceled:
-                logger.warn(
+                logger.warning(
                     f"Received malformed key verification event from 
{event.sender} {event.from_device}"
                 )
                 message = new_sas.get_cancellation()
@@ -2165,7 +2167,7 @@
             sas = self.key_verifications.get(event.transaction_id, None)
 
             if not sas:
-                logger.warn(
+                logger.warning(
                     "Received key verification event with an unknown "
                     f"transaction id from {event.sender}"
                 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/events/misc.py 
new/matrix_nio-0.21.2/nio/events/misc.py
--- old/matrix_nio-0.20.2/nio/events/misc.py    2023-03-28 04:30:52.195211600 
+0200
+++ new/matrix_nio-0.21.2/nio/events/misc.py    2023-07-14 11:44:32.561834000 
+0200
@@ -1,4 +1,12 @@
 # -*- coding: utf-8 -*-
+import logging
+from dataclasses import dataclass, field
+from functools import wraps
+from typing import Any, Dict, Optional, Union
+
+from jsonschema.exceptions import SchemaError, ValidationError
+
+from ..schemas import validate_json
 
 # Copyright © 2018-2019 Damir Jelić <pol...@termina.org.uk>
 #
@@ -14,18 +22,8 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-from dataclasses import dataclass, field
-from functools import wraps
-from typing import Any, Dict, Optional, Union
-
-from jsonschema.exceptions import SchemaError, ValidationError
-from logbook import Logger
-
-from ..log import logger_group
-from ..schemas import validate_json
 
-logger = Logger("nio.events")
-logger_group.add_logger(logger)
+logger = logging.getLogger(__name__)
 
 
 def validate_or_badevent(
@@ -36,7 +34,7 @@
     try:
         validate_json(parsed_dict, schema)
     except (ValidationError, SchemaError) as e:
-        logger.warn(f"Error validating event: {str(e)}")
+        logger.warning(f"Error validating event: {str(e)}")
         try:
             return BadEvent.from_dict(parsed_dict)
         except KeyError:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/events/presence.py 
new/matrix_nio-0.21.2/nio/events/presence.py
--- old/matrix_nio-0.20.2/nio/events/presence.py        2023-03-28 
04:30:52.195211600 +0200
+++ new/matrix_nio-0.21.2/nio/events/presence.py        2023-07-14 
11:44:32.561834000 +0200
@@ -1,4 +1,10 @@
 # -*- coding: utf-8 -*-
+import logging
+from dataclasses import dataclass, field
+from typing import Optional
+
+from ..schemas import Schemas
+from .misc import verify
 
 # Copyright © 2018-2019 Damir Jelić <pol...@termina.org.uk>
 #
@@ -14,17 +20,8 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-from dataclasses import dataclass, field
-from typing import Optional
-
-from logbook import Logger
-
-from ..log import logger_group
-from ..schemas import Schemas
-from .misc import verify
 
-logger = Logger("nio.events")
-logger_group.add_logger(logger)
+logger = logging.getLogger(__name__)
 
 
 @dataclass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/events/room_events.py 
new/matrix_nio-0.21.2/nio/events/room_events.py
--- old/matrix_nio-0.20.2/nio/events/room_events.py     2023-03-28 
04:30:52.195211600 +0200
+++ new/matrix_nio-0.21.2/nio/events/room_events.py     2023-07-14 
11:44:32.561834000 +0200
@@ -161,6 +161,10 @@
             return RedactionEvent.from_dict(event_dict)
         elif event_dict["type"] == "m.room.tombstone":
             return RoomUpgradeEvent.from_dict(event_dict)
+        elif event_dict["type"] == "m.space.parent":
+            return RoomSpaceParentEvent.from_dict(event_dict)
+        elif event_dict["type"] == "m.space.child":
+            return RoomSpaceChildEvent.from_dict(event_dict)
         elif event_dict["type"] == "m.room.encrypted":
             return Event.parse_encrypted_event(event_dict)
         elif event_dict["type"] == "m.sticker":
@@ -815,6 +819,48 @@
 
 
 @dataclass
+class RoomSpaceParentEvent(Event):
+    """Event holding the parent space of a room.
+
+    Attributes:
+        state_key (str): The parent space's room
+
+    """
+
+    state_key: str = field()
+    canonical: bool = False
+
+    @classmethod
+    @verify(Schemas.room_space_parent)
+    def from_dict(cls, parsed_dict):
+        content_dict = parsed_dict["content"]
+        return cls(
+            parsed_dict, parsed_dict["state_key"], 
content_dict.get("canonical", False)
+        )
+
+
+@dataclass
+class RoomSpaceChildEvent(Event):
+    """Event holding the child rooms of a space.
+
+    Attributes:
+        state_key (str): The child room of a space
+
+    """
+
+    state_key: str = field()
+    suggested: bool = False
+
+    @classmethod
+    @verify(Schemas.room_space_child)
+    def from_dict(cls, parsed_dict):
+        content_dict = parsed_dict["content"]
+        return cls(
+            parsed_dict, parsed_dict["state_key"], 
content_dict.get("suggested", False)
+        )
+
+
+@dataclass
 class RoomMessage(Event):
     """Abstract room message class.
 
@@ -1437,7 +1483,7 @@
             cases except for when membership is join, the user ID in the sender
             attribute does not need to match the user ID in the state_key.
         membership (str): The membership state of the user. One of "invite",
-            "join", "leave", "ban".
+            "join", "leave", "ban", "knock".
         prev_membership (str, optional): The previous membership state that
             this one is overwriting. Can be None in which case the membership
             state is assumed to have been "leave".
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/events/to_device.py 
new/matrix_nio-0.21.2/nio/events/to_device.py
--- old/matrix_nio-0.20.2/nio/events/to_device.py       2023-03-28 
04:30:52.195211600 +0200
+++ new/matrix_nio-0.21.2/nio/events/to_device.py       2023-07-14 
11:44:32.561834000 +0200
@@ -116,7 +116,7 @@
         if content["algorithm"] == "m.olm.v1.curve25519-aes-sha2":
             return OlmEvent.from_dict(event_dict)
 
-        logger.warn(
+        logger.warning(
             f"Received an encrypted event with an unknown algorithm 
{content['algorithm']}."
         )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/http.py 
new/matrix_nio-0.21.2/nio/http.py
--- old/matrix_nio-0.20.2/nio/http.py   2023-03-28 04:30:52.195211600 +0200
+++ new/matrix_nio-0.21.2/nio/http.py   2023-07-14 11:44:32.561834000 +0200
@@ -17,6 +17,7 @@
 from __future__ import unicode_literals
 
 import json
+import logging
 import pprint
 import time
 from builtins import bytes, super
@@ -28,12 +29,8 @@
 import h2.connection
 import h2.events
 import h11
-from logbook import Logger
 
-from .log import logger_group
-
-logger = Logger("nio.http")
-logger_group.add_logger(logger)
+logger = logging.getLogger(__name__)
 
 USER_AGENT = "nio"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/log.py 
new/matrix_nio-0.21.2/nio/log.py
--- old/matrix_nio-0.20.2/nio/log.py    2023-03-28 04:30:52.195211600 +0200
+++ new/matrix_nio-0.21.2/nio/log.py    1970-01-01 01:00:00.000000000 +0100
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright © 2018 Damir Jelić <pol...@termina.org.uk>
-#
-# Permission to use, copy, modify, and/or distribute this software for
-# any purpose with or without fee is hereby granted, provided that the
-# above copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
-# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
-# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import logbook
-
-logger_group = logbook.LoggerGroup()
-logger_group.level = logbook.CRITICAL
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/responses.py 
new/matrix_nio-0.21.2/nio/responses.py
--- old/matrix_nio-0.20.2/nio/responses.py      2023-03-28 04:30:52.195211600 
+0200
+++ new/matrix_nio-0.21.2/nio/responses.py      2023-07-17 08:15:09.032432800 
+0200
@@ -17,6 +17,7 @@
 
 from __future__ import unicode_literals
 
+import logging
 from builtins import str
 from dataclasses import dataclass, field
 from datetime import datetime
@@ -24,7 +25,6 @@
 from typing import Any, Dict, Generator, List, Optional, Set, Tuple, Union
 
 from jsonschema.exceptions import SchemaError, ValidationError
-from logbook import Logger
 
 from .event_builders import ToDeviceMessage
 from .events import (
@@ -37,11 +37,9 @@
 )
 from .events.presence import PresenceEvent
 from .http import TransportResponse
-from .log import logger_group
 from .schemas import Schemas, validate_json
 
-logger = Logger("nio.responses")
-logger_group.add_logger(logger)
+logger = logging.getLogger(__name__)
 
 
 __all__ = [
@@ -99,6 +97,8 @@
     "RoomInviteError",
     "RoomKickResponse",
     "RoomKickError",
+    "RoomKnockResponse",
+    "RoomKnockError",
     "RoomLeaveResponse",
     "RoomLeaveError",
     "RoomForgetResponse",
@@ -180,10 +180,10 @@
         @wraps(f)
         def wrapper(cls, parsed_dict, *args, **kwargs):
             try:
-                logger.info("Validating response schema")
+                logger.debug("Validating response schema %r: %s", schema, 
parsed_dict)
                 validate_json(parsed_dict, schema)
             except (SchemaError, ValidationError) as e:
-                logger.warn("Error validating response: " + str(e.message))
+                logger.warning("Error validating response: " + str(e.message))
 
                 if pass_arguments:
                     return error_class.from_dict(parsed_dict, *args, **kwargs)
@@ -507,6 +507,12 @@
     pass
 
 
+class RoomKnockError(ErrorResponse):
+    """A response representing a unsuccessful room knock request."""
+
+    pass
+
+
 class RoomLeaveError(ErrorResponse):
     pass
 
@@ -1265,6 +1271,12 @@
         return JoinError.from_dict(parsed_dict)
 
 
+class RoomKnockResponse(RoomIdResponse):
+    @staticmethod
+    def create_error(parsed_dict):
+        return RoomKnockError.from_dict(parsed_dict)
+
+
 class RoomLeaveResponse(EmptyResponse):
     @staticmethod
     def create_error(parsed_dict):
@@ -1900,6 +1912,8 @@
 @dataclass
 class WhoamiResponse(Response):
     user_id: str = field()
+    device_id: Optional[str] = field()
+    is_guest: Optional[bool] = field()
 
     @classmethod
     @verify(Schemas.whoami, WhoamiError)
@@ -1907,7 +1921,11 @@
         cls,
         parsed_dict: Dict[Any, Any],
     ) -> Union["WhoamiResponse", WhoamiError]:
-        return cls(parsed_dict["user_id"])
+        return cls(
+            parsed_dict["user_id"],
+            parsed_dict.get("device_id"),
+            parsed_dict.get("is_guest", False),
+        )
 
 
 @dataclass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/rooms.py 
new/matrix_nio-0.21.2/nio/rooms.py
--- old/matrix_nio-0.20.2/nio/rooms.py  2023-03-28 04:30:52.195211600 +0200
+++ new/matrix_nio-0.21.2/nio/rooms.py  2023-07-14 11:44:32.561834000 +0200
@@ -17,13 +17,13 @@
 
 from __future__ import unicode_literals
 
+import logging
 from builtins import super
 from collections import defaultdict
 from enum import Enum
-from typing import Any, DefaultDict, Dict, List, NamedTuple, Optional, Tuple, 
Union
+from typing import Any, DefaultDict, Dict, List, NamedTuple, Optional, Set, 
Tuple, Union
 
 from jsonschema.exceptions import SchemaError, ValidationError
-from logbook import Logger
 
 from .events import (
     AccountDataEvent,
@@ -46,16 +46,16 @@
     RoomJoinRulesEvent,
     RoomMemberEvent,
     RoomNameEvent,
+    RoomSpaceChildEvent,
+    RoomSpaceParentEvent,
     RoomTopicEvent,
     RoomUpgradeEvent,
     TagEvent,
     TypingNoticeEvent,
 )
-from .log import logger_group
 from .responses import RoomSummary, UnreadNotifications
 
-logger = Logger("nio.rooms")
-logger_group.add_logger(logger)
+logger = logging.getLogger(__name__)
 
 __all__ = [
     "MatrixRoom",
@@ -82,6 +82,8 @@
         self.canonical_alias = None   # type: Optional[str]
         self.topic = None             # type: Optional[str]
         self.name = None              # type: Optional[str]
+        self.parents = set()           # type: Set[str]
+        self.children = set()         # type: Set[str]
         self.users = dict()           # type: Dict[str, MatrixUser]
         self.invited_users = dict()   # type: Dict[str, MatrixUser]
         self.names = defaultdict(list)  # type: DefaultDict[str, List[str]]
@@ -409,6 +411,12 @@
                     )
                     self.users[user_id].power_level = level
 
+        elif isinstance(event, RoomSpaceParentEvent):
+            self.parents.add(event.state_key)
+
+        elif isinstance(event, RoomSpaceChildEvent):
+            self.children.add(event.state_key)
+
     def handle_account_data(self, event: AccountDataEvent) -> None:
         if isinstance(event, FullyReadEvent):
             self.fully_read_marker = event.event_id
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/schemas.py 
new/matrix_nio-0.21.2/nio/schemas.py
--- old/matrix_nio-0.20.2/nio/schemas.py        2023-03-28 04:30:52.195211600 
+0200
+++ new/matrix_nio-0.21.2/nio/schemas.py        2023-07-17 08:15:09.032432800 
+0200
@@ -924,6 +924,43 @@
         "required": ["type", "sender", "content", "state_key"],
     }
 
+    room_space_parent = {
+        "type": "object",
+        "properties": {
+            "sender": {"type": "string", "format": "user_id"},
+            "state_key": {"type": "string"},
+            "type": {"type": "string"},
+            "content": {
+                "type": "object",
+                "properties": {
+                    "canonical": {"type": "boolean", "default": False},
+                    "via": {"type": "array", "items": {"type": "string"}},
+                },
+                "required": ["via"],
+            },
+        },
+        "required": ["type", "sender", "content", "state_key"],
+    }
+
+    room_space_child = {
+        "type": "object",
+        "properties": {
+            "sender": {"type": "string", "format": "user_id"},
+            "state_key": {"type": "string"},
+            "type": {"type": "string"},
+            "content": {
+                "type": "object",
+                "properties": {
+                    "suggested": {"type": "boolean", "default": False},
+                    "via": {"type": "array", "items": {"type": "string"}},
+                    "order": {"type": "string"},
+                },
+                "required": ["via"],
+            },
+        },
+        "required": ["type", "sender", "content", "state_key"],
+    }
+
     room_avatar = {
         "type": "object",
         "properties": {
@@ -1856,7 +1893,11 @@
 
     whoami = {
         "type": "object",
-        "user_id": "string",
+        "properties": {
+            "user_id": {"type": "string", "format": "user_id"},
+            "device_id": {"type": "string"},
+            "is_guest": {"type": "boolean"},
+        },
         "required": ["user_id"],
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/nio/store/log.py 
new/matrix_nio-0.21.2/nio/store/log.py
--- old/matrix_nio-0.20.2/nio/store/log.py      2023-03-28 04:30:52.195211600 
+0200
+++ new/matrix_nio-0.21.2/nio/store/log.py      2023-07-14 11:44:32.565834000 
+0200
@@ -1,4 +1,5 @@
 # -*- coding: utf-8 -*-
+import logging
 
 # Copyright © 2019 Damir Jelić <pol...@termina.org.uk>
 #
@@ -14,9 +15,5 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-from logbook import Logger
 
-from ..log import logger_group
-
-logger = Logger("nio.cryptostore")
-logger_group.add_logger(logger)
+logger = logging.getLogger(__name__)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/matrix_nio-0.20.2/pyproject.toml 
new/matrix_nio-0.21.2/pyproject.toml
--- old/matrix_nio-0.20.2/pyproject.toml        2023-03-28 04:30:52.195211600 
+0200
+++ new/matrix_nio-0.21.2/pyproject.toml        2023-07-17 10:42:00.347297200 
+0200
@@ -4,7 +4,7 @@
 
 [tool.poetry]
 name = "matrix-nio"
-version = "0.20.2"
+version = "0.21.2"
 description = "A Python Matrix client library, designed according to sans I/O 
principles."
 authors = ["Damir Jelić <pol...@termina.org.uk>"]
 license = "ISC"
@@ -16,14 +16,12 @@
 ]
 
 [tool.poetry.dependencies]
-python = "^3.7.0"
+python = "^3.8.0"
 future = "^0.18.2"
 aiohttp = "^3.8.3"
 aiofiles = "^23.1.0"
-dataclasses = { version = "^0.7", python = ">= 3.6, <3.7" }
 h11 = "^0.14.0"
 h2 = "^4.0.0"
-logbook = "^1.5.3"
 jsonschema = "^4.4.0"
 unpaddedbase64 = "^2.1.0"
 pycryptodome = "^3.10.1"

++++++ remove-future-requirement.patch ++++++
>From 572180f38c3c4da74e5cc0dde5cb5bd9581bbbef Mon Sep 17 00:00:00 2001
From: Marc Mueller <30130371+cdc...@users.noreply.github.com>
Date: Sat, 2 Sep 2023 23:32:57 +0200
Subject: [PATCH] Remove future dependency

---
 nio/crypto/sas.py                       | 2 +-
 pyproject.toml                          | 1 -
 4 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/nio/crypto/sas.py b/nio/crypto/sas.py
index 32f04375..51f383ec 100644
--- a/nio/crypto/sas.py
+++ b/nio/crypto/sas.py
@@ -19,11 +19,11 @@
 from builtins import bytes, super
 from datetime import datetime, timedelta
 from enum import Enum
+from itertools import zip_longest
 from typing import List, Optional, Tuple
 from uuid import uuid4
 
 import olm
-from future.moves.itertools import zip_longest
 
 from ..api import Api
 from ..event_builders import ToDeviceMessage
diff --git a/pyproject.toml b/pyproject.toml
index 3048b26d..29c9d551 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -17,7 +17,6 @@ packages = [
 
 [tool.poetry.dependencies]
 python = "^3.8.0"
-future = "^0.18.2"
 aiohttp = "^3.8.3"
 aiofiles = "^23.1.0"
 h11 = "^0.14.0"

Reply via email to