[PATCH 23 of 24 yams V2] [mypy] type xy.py

Laurent Peuch cortex at worlddomination.be
Wed Mar 4 15:17:59 CET 2020


# HG changeset patch
# User Laurent Peuch <cortex at worlddomination.be>
# Date 1580319772 -3600
#      Wed Jan 29 18:42:52 2020 +0100
# Node ID c52784b56910b156b78bfda6922938fd6b5850b1
# Parent  32c9c906e3aa867eab3bd9c529c1ea45b29af909
# Available At https://hg.logilab.org/users/lpeuch/yams
#              hg pull https://hg.logilab.org/users/lpeuch/yams -r c52784b56910
# EXP-Topic type_annotations
[mypy] type xy.py

diff --git a/yams/xy.py b/yams/xy.py
--- a/yams/xy.py
+++ b/yams/xy.py
@@ -18,12 +18,16 @@
 """XML vocabularies <-> Yams schema mapping"""
 
 from warnings import warn
+from typing import Any, List, Union, Tuple, Dict
 
 
 class UnsupportedVocabulary(Exception):
     pass
 
 
+_XYType = Tuple[str, Union[str, Tuple[str, str]], str]
+
+
 class XYRegistry(object):
     """registry of equivalence to translate yams into various xml schema such
     as dublin core, foaf, doap...
@@ -31,88 +35,122 @@ class XYRegistry(object):
     """
 
     def __init__(self):
-        self.prefixes = {}
-        self._y2x = {}
-        self._x2y = {}
+        self.prefixes: Dict[str, str] = {}
+        self._y2x: Dict[_XYType, List[_XYType]] = {}
+        self._x2y: Dict[_XYType, List[_XYType]] = {}
 
-    def register_prefix(self, prefix, xmlns, overwrite=False):
+    def register_prefix(self, prefix: str, xmlns: str, overwrite: bool = False) -> None:
         if ':' in prefix:
             warn('[yams 0.30] register_prefix arguments has been switched to '
                  '(prefix, xmlns)', DeprecationWarning, stacklevel=2)
+
             prefix, xmlns = xmlns, prefix
+
         if not overwrite and prefix in self.prefixes \
                 and self.prefixes.get(prefix) != xmlns:
             raise Exception('prefix %r already defined with different value'
                             % prefix)
+
         self.prefixes[prefix] = xmlns
 
-    def _norm_yams_key(self, yamssnippet):
+    def _norm_yams_key(self, yamssnippet: str) -> Tuple[str, str, str]:
         parts = yamssnippet.split(' ')
+
         if len(parts) == 1:
             if parts[0][0].islower():
                 return '*', parts[0], '*'
-            return parts[0]
+
+            # mypy: Incompatible return value type (got "str", expected "Tuple[str, str, str]")
+            # XXX or is it a bug? You'll get a str here which breaks add_equivalence
+            return parts[0]  # type: ignore
+
         if len(parts) == 2:
             parts.append('*')
+
         assert len(parts) == 3
-        return tuple(parts)
 
-    def _norm_xml_key(self, xmlsnippet, isentity=False):
-        parts = []
+        # mypy: Incompatible return value type (got "Tuple[str, ...]",
+        # mypy: expected "Tuple[str, str, str]")
+        # but we know that "parts" is of len 3 because of the assert
+        return tuple(parts)  # type: ignore
+
+    def _norm_xml_key(self, xmlsnippet: str, isentity: bool = False) -> _XYType:
+
+        parts: List[Union[str, Tuple[Any, str]]] = []
+
         for xmlsnippet in xmlsnippet.split(' '):
             pfx, tag = xmlsnippet.rsplit(':', 1)
             xmlns = self.prefixes.get(pfx, pfx)
+
             parts.append((xmlns, tag))
+
         if isentity:
             assert len(parts) == 1
-            return parts[0]
+
+            # mypy: Incompatible return value type (got "Union[str, Tuple[Any, str]]",
+            # mypy: expected "Tuple[str, Union[str, Tuple[str, str]], str]")
+            # franckly, I'm not sure here...
+            return parts[0]  # type: ignore
+
         if len(parts) == 1:
             return '*', parts[0], '*'
+
         if len(parts) == 2:
             parts.append('*')
+
         assert len(parts) == 3
-        return tuple(parts)
 
-    def add_equivalence(self, yamssnippet, xmlsnippet):
+        # mypy: Incompatible return value type (got "Tuple[Union[str, Tuple[Any, str]], ...]",
+        # mypy: expected "Tuple[str, Union[str, Tuple[str, str]], str]")
+        # should be good because of the assert before
+        return tuple(parts)  # type: ignore
+
+    def add_equivalence(self, yamssnippet: str, xmlsnippet: str) -> None:
         ykey = self._norm_yams_key(yamssnippet)
         isentity = not isinstance(ykey, tuple)
         xkey = self._norm_xml_key(xmlsnippet, isentity=isentity)
+
         self._y2x.setdefault(ykey, []).append(xkey)
         self._x2y.setdefault(xkey, []).append(ykey)
+
         if not isentity:
             for dict_, key, value in ((self._x2y, xkey, ykey),
                                       (self._y2x, ykey, xkey)):
                 if key[0] != '*':
                     wkey = ('*',) + key[1:]
                     dict_.setdefault(wkey, []).append(value)
+
                 if key[2] != '*':
                     wkey = key[:2] + ('*',)
                     dict_.setdefault(wkey, []).append(value)
 
-    def remove_equivalence(self, yamssnippet, xmlsnippet):
+    def remove_equivalence(self, yamssnippet: str, xmlsnippet: str) -> None:
         ykey = self._norm_yams_key(yamssnippet)
         isentity = not isinstance(ykey, tuple)
         xkey = self._norm_xml_key(xmlsnippet, isentity=isentity)
+
         self._y2x.setdefault(ykey, []).remove(xkey)
         self._x2y.setdefault(xkey, []).remove(ykey)
+
         if not isentity:
             for dict_, key, value in ((self._x2y, xkey, ykey),
                                       (self._y2x, ykey, xkey)):
                 if key[0] != '*':
                     wkey = ('*',) + key[1:]
                     dict_.setdefault(wkey, []).remove(value)
+
                 if key[2] != '*':
                     wkey = key[:2] + ('*',)
                     dict_.setdefault(wkey, []).remove(value)
 
-    def yeq(self, xmlsnippet, isentity=False):
+    def yeq(self, xmlsnippet: str, isentity: bool = False) -> List[_XYType]:
         key = self._norm_xml_key(xmlsnippet, isentity)
         try:
             return self._x2y[key]
         except KeyError:
             raise UnsupportedVocabulary(key)
 
-    def xeq(self, yamssnippet):
+    def xeq(self, yamssnippet: str) -> List[_XYType]:
         key = self._norm_yams_key(yamssnippet)
         try:
             return self._y2x[key]
@@ -120,7 +158,7 @@ class XYRegistry(object):
             raise UnsupportedVocabulary(key)
 
 
-XY = XYRegistry()
+XY: XYRegistry = XYRegistry()
 register_prefix = XY.register_prefix
 add_equivalence = XY.add_equivalence
 remove_equivalence = XY.remove_equivalence



More information about the cubicweb-devel mailing list