Blob Blame History Raw
From 38b9f3206d86cded04c52e52b0d627079ba44acc Mon Sep 17 00:00:00 2001
From: Adam Williamson <awilliam@redhat.com>
Date: Fri, 6 Jul 2018 15:04:39 -0700
Subject: [PATCH] Make pyanaconda.dbus.typing work with Python 3.7 (#1598574)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

As reported in RHBZ#1598574, the internals of typing changed in
Python 3.7 such that it's no longer so simple to find the 'base'
type of a type hint (it's not just its `__origin__` any more).
There doesn't appear to be any particularly great fix for this,
but this suggestion from Miro HronĨok seems as good as any other
option we have for now. This should work with both 3.6 and 3.7.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
---
 pyanaconda/dbus/typing.py | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/pyanaconda/dbus/typing.py b/pyanaconda/dbus/typing.py
index ea8a2999c..1cb1ea99a 100644
--- a/pyanaconda/dbus/typing.py
+++ b/pyanaconda/dbus/typing.py
@@ -149,24 +149,30 @@ class DBusType(object):
     @staticmethod
     def _is_container_type(type_hint):
         """Is it a container type?"""
-        # Try to get the "base" type of the container type.
+        # Try to get the "origin" of the hint.
         origin = getattr(type_hint, "__origin__", None)
-        return origin in DBusType._container_type_mapping
+        if origin:
+            # Return true if the "origin" is a subclass of a container type
+            # see https://bugzilla.redhat.com/show_bug.cgi?id=1598574
+            return any(issubclass(origin, contype) for contype in DBusType._container_type_mapping)
+        return False
 
     @staticmethod
     def _get_container_type(type_hint):
         """Return a container type."""
-        # Get the "base" type of the container.
-        origin = type_hint.__origin__
+        # Get the "base" type via the "origin" of the hint
+        # see https://bugzilla.redhat.com/show_bug.cgi?id=1598574
+        basetype = tuple(contype for contype in DBusType._container_type_mapping
+                       if issubclass(type_hint.__origin__, contype))[0]
         # Get the arguments of the container.
         args = type_hint.__args__
 
         # Check the typing.
-        if origin == Dict:
+        if basetype == Dict:
             DBusType._check_if_valid_dictionary(type_hint)
 
         # Generate string.
-        container = DBusType._container_type_mapping[origin]
+        container = DBusType._container_type_mapping[basetype]
         items = [DBusType.get_dbus_representation(arg) for arg in args]
         return container % "".join(items)
 
-- 
2.18.0.rc2