diff --git a/docs/coding/functions.rst b/docs/coding/functions.rst
index a929934062f5d55757d6e714f87cf04da7ce9e93..97d4a0a8dd4585f23dd8606920b5eee073a95fae 100644
--- a/docs/coding/functions.rst
+++ b/docs/coding/functions.rst
@@ -69,6 +69,14 @@ Function overloading
 .. autoclass:: satella.coding.overload
     :members:
 
+.. autofunction:: satella.coding.is_signature_a_more_generic_than_b
+
+
+.. autofunction:: satella.coding.is_type_a_more_generic_than_b
+
+
+.. autofunction:: satella.coding.extract_type_signature_from
+
 DocsFromParent
 --------------
 
diff --git a/satella/__init__.py b/satella/__init__.py
index 32815b254730f32de279dbc62335d4a5877b39aa..1c24e3331d9c331f3786944f0d8c003c36aa6c6a 100644
--- a/satella/__init__.py
+++ b/satella/__init__.py
@@ -1 +1 @@
-__version__ = '2.23.1a1'
+__version__ = '2.23.1b1'
diff --git a/satella/coding/__init__.py b/satella/coding/__init__.py
index 72369906bb3573798f10f2a4e46f1d937e6bf79d..9752da5be0a9fcef608046b273b8c8b21582e1e8 100644
--- a/satella/coding/__init__.py
+++ b/satella/coding/__init__.py
@@ -18,7 +18,8 @@ from .misc import update_if_not_none, update_key_if_none, update_attr_if_none, q
     get_arguments, call_with_arguments, chain_callables, Closeable, contains, \
     enum_value, length
 from .environment import Context
-from .overloading import overload, class_or_instancemethod
+from .overloading import overload, class_or_instancemethod, is_signature_a_more_generic_than_b, \
+    is_type_a_more_generic_than_b, extract_type_signature_from
 from .recast_exceptions import rethrow_as, silence_excs, catch_exception, log_exceptions, \
     raises_exception, reraise_as
 from .expect_exception import expect_exception
@@ -29,7 +30,8 @@ __all__ = [
     'assert_equal', 'InequalityReason', 'Inequal',
     'Closeable', 'contains', 'enum_value', 'reraise_as',
     'expect_exception',
-    'overload', 'class_or_instancemethod',
+    'overload', 'class_or_instancemethod', 'extract_type_signature_from', 'is_signature_a_more_generic_than_b',
+    'is_type_a_more_generic_than_b',
     'update_if_not_none', 'DocsFromParent', 'update_key_if_none', 'queue_iterator',
     'update_attr_if_none', 'update_key_if_not_none', 'source_to_function',
     'update_key_if_true',
diff --git a/satella/coding/overloading.py b/satella/coding/overloading.py
index 8270de48803d56eab6fe99ccac20020a7109b7bc..d52567bed94b500a7fa4d08ad6f57040bdd1cb89 100644
--- a/satella/coding/overloading.py
+++ b/satella/coding/overloading.py
@@ -3,16 +3,27 @@ import typing as tp
 from inspect import Parameter
 
 
-def extract_type_signature_from(fun: tp.Callable) -> tp.Tuple[type, ...]:
-    sign = []
+def extract_type_signature_from(fun: tp.Callable) -> tp.Dict[str, type]:
+    """
+    Extract type signature of a function
+    :param fun: function to extract signature from
+    :return: a dict, having all parameters normally passed to the function
+    """
+    sign = {}
     params = inspect.signature(fun).parameters
     for parameter in params.values():
         if parameter.kind in (Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD):
             if parameter.annotation == Parameter.empty:
-                sign.append(None)
+                sign[parameter.name] = None
+            else:
+                sign[parameter.name] = parameter.annotation
+        elif parameter.kind in (Parameter.KEYWORD_ONLY, Parameter.VAR_KEYWORD):
+            if parameter.annotation == Parameter.empty:
+                annot = None
             else:
-                sign.append(parameter.annotation)
-    return tuple(sign)
+                annot = parameter.annotation
+            sign[parameter.name] = (parameter.kind == Parameter.KEYWORD_ONLY), annot
+    return sign
 
 
 # Taken from https://stackoverflow.com/questions/28237955/same-name-for-classmethod-and-
@@ -38,6 +49,37 @@ class class_or_instancemethod(classmethod):
         return descr_get(instance, type_)
 
 
+def is_type_a_more_generic_than_b(a: tp.Dict[str, tp.Type], b: tp.Dict[str, tp.Type]) -> bool:
+    """
+    Can it be said that type a is more generic than b
+    :param a: type extracted from a with :func:`~satella.coding.overloading.
+    :param b:
+    :return:
+    """
+    if a is None:
+        return True
+    for key in a:
+        key = b.get(key, None)
+
+        a_ = a[key]
+        b_ = b[key]
+        if isinstance(a_, tuple):
+            if not isinstance(b_, tuple):
+                raise TypeError('Type mismatch %s to %s' % (a_, b_))
+        if issubclass(b_, a_):
+            return True
+    return False
+
+
+def is_signature_a_more_generic_than_b(a: tp.Tuple[{}, [], []], b) -> bool:
+    """
+
+    :param a:
+    @param b:
+    :return: is A more generic than B
+    """
+
+
 class overload:
     """
     A class used for method overloading.