[PATCH 12 of 15 yams V3] [mypy] type mostly all of __init__.py

Laurent Peuch cortex at worlddomination.be
Wed Jan 15 20:59:12 CET 2020


# HG changeset patch
# User Laurent Peuch <cortex at worlddomination.be>
# Date 1579099986 -3600
#      Wed Jan 15 15:53:06 2020 +0100
# Node ID 850288bb66c9ef28035c867c5a59c36fa4138d9a
# Parent  bed2125bff5538f5020719e5c512a085068252de
# Available At https://hg.logilab.org/users/lpeuch/yams
#              hg pull https://hg.logilab.org/users/lpeuch/yams -r 850288bb66c9
[mypy] type mostly all of __init__.py

diff --git a/yams/__init__.py b/yams/__init__.py
--- a/yams/__init__.py
+++ b/yams/__init__.py
@@ -22,6 +22,8 @@
 import warnings
 from datetime import datetime, date
 
+from typing import Set, Type, Dict, Tuple, Union, Callable, Any, List, cast
+
 import pkg_resources
 
 from logilab.common.date import strptime, strptime_time
@@ -29,44 +31,48 @@ from logilab.common import nullobject
 
 from yams._exceptions import *
 
+PermissionsType = Dict[str, Union[Tuple,
+                                  Tuple[str],
+                                  Tuple[str, str],
+                                  Tuple[str, str, str]]]
 
-__version__ = pkg_resources.get_distribution('yams').version
-
-_ = str
+__version__: str = pkg_resources.get_distribution('yams').version
 
-MARKER = nullobject()
+_: Type[str] = str
+
+MARKER: nullobject = nullobject()
 
-BASE_TYPES = set(('String', 'Password', 'Bytes',
-                  'Int', 'BigInt', 'Float', 'Boolean', 'Decimal',
-                  'Date', 'Time', 'Datetime', 'TZTime', 'TZDatetime',
-                  'Interval',
-                  ))
+BASE_TYPES: Set[str] = set(('String', 'Password', 'Bytes',
+                            'Int', 'BigInt', 'Float', 'Boolean', 'Decimal',
+                            'Date', 'Time', 'Datetime', 'TZTime', 'TZDatetime',
+                            'Interval',
+                            ))
 
 # base groups used in permissions
-BASE_GROUPS = set((_('managers'), _('users'), _('guests'), _('owners')))
+BASE_GROUPS: Set[str] = set((_('managers'), _('users'), _('guests'), _('owners')))
 
 # default permissions for entity types, relations and attributes
-DEFAULT_ETYPEPERMS = {'read': ('managers', 'users', 'guests',),
-                      'update': ('managers', 'owners',),
-                      'delete': ('managers', 'owners'),
-                      'add': ('managers', 'users',)}
-DEFAULT_RELPERMS = {'read': ('managers', 'users', 'guests',),
-                    'delete': ('managers', 'users'),
-                    'add': ('managers', 'users',)}
-DEFAULT_ATTRPERMS = {'read': ('managers', 'users', 'guests',),
-                     'add': ('managers', 'users'),
-                     'update': ('managers', 'owners')}
-DEFAULT_COMPUTED_RELPERMS = {'read': ('managers', 'users', 'guests',),
-                             'delete': (),
-                             'add': ()}
-DEFAULT_COMPUTED_ATTRPERMS = {'read': ('managers', 'users', 'guests',),
-                              'add': (),
-                              'update': ()}
-
+DEFAULT_ETYPEPERMS: PermissionsType = {'read': ('managers', 'users', 'guests',),
+                                       'update': ('managers', 'owners',),
+                                       'delete': ('managers', 'owners'),
+                                       'add': ('managers', 'users',)}
+DEFAULT_RELPERMS: PermissionsType = {'read': ('managers', 'users', 'guests',),
+                                     'delete': ('managers', 'users'),
+                                     'add': ('managers', 'users',)}
+DEFAULT_ATTRPERMS: PermissionsType = {'read': ('managers', 'users', 'guests',),
+                                      'add': ('managers', 'users'),
+                                      'update': ('managers', 'owners')}
+DEFAULT_COMPUTED_RELPERMS: PermissionsType = {'read': ('managers', 'users', 'guests',),
+                                              'delete': (),
+                                              'add': ()}
+DEFAULT_COMPUTED_ATTRPERMS: PermissionsType = {'read': ('managers', 'users', 'guests',),
+                                               'add': (),
+                                               'update': ()}
 
 # This provides a way to specify callable objects as default values
 # First level is the final type, second is the keyword to callable map
-KEYWORD_MAP = {
+current_date_or_datetime_constructor_type = Callable[[], Union[date, datetime]]
+KEYWORD_MAP: Dict[str, Dict[str, current_date_or_datetime_constructor_type]] = {
     'Datetime': {'NOW': datetime.now,
                  'TODAY': datetime.today},
     'TZDatetime': {'NOW': datetime.utcnow,
@@ -74,18 +80,32 @@ KEYWORD_MAP = {
     'Date': {'TODAY': date.today}
 }
 
+# bw compat for literal date/time values stored as strings in schemas
 
-# bw compat for literal date/time values stored as strings in schemas
-DATE_FACTORY_MAP = {
+# parse_datetime_or_time_type = Union[Callable[[str], datetime],
+#                                     Callable[[str], float],
+#                                     # strptime_time can have an optional format argument
+#                                     Callable[[str, str], float]]
+# Apparently this is not possible, see https://github.com/python/mypy/issues/8282
+# DATE_FACTORY_MAP: Dict[str, parse_datetime_or_time_type] = {
+DATE_FACTORY_MAP: Dict[str, Callable] = {
     'Datetime': lambda x: ':' in x and strptime(x, '%Y/%m/%d %H:%M') or strptime(x, '%Y/%m/%d'),
     'Date': lambda x: strptime(x, '%Y/%m/%d'),
-    'Time': strptime_time
+    'Time': strptime_time  # returns a float (from time())
 }
 
-KNOWN_METAATTRIBUTES = set(('format', 'encoding', 'name'))
+KNOWN_METAATTRIBUTES: Set[str] = set(('format', 'encoding', 'name'))
 
 
-def convert_default_value(rdef, default):
+# this is for documentation purpose to show that convert_default_value can return the type
+# of default
+type_of_default = Any
+
+
+# due to circular import it's hard to grab .schema.RelationDefinitionSchema and
+# .buildobjs.RelationDefinition
+def convert_default_value(rdef, default: type_of_default) -> Union[type_of_default, datetime, date,
+                                                                   float, str]:
     # rdef can be either a .schema.RelationDefinitionSchema
     # or a .buildobjs.RelationDefinition
     rtype = getattr(rdef, 'name', None) or rdef.rtype.type
@@ -108,7 +128,12 @@ def convert_default_value(rdef, default)
                           % (rtype, rdef.object),
                           DeprecationWarning)
             try:
-                return DATE_FACTORY_MAP[rdef.object](default)
+                if rdef.object == "Time":
+                    cast(Callable[[str], float], DATE_FACTORY_MAP[rdef.object])
+                    return DATE_FACTORY_MAP[rdef.object](default)
+                else:
+                    cast(Callable[[str], datetime], DATE_FACTORY_MAP[rdef.object])
+                    return DATE_FACTORY_MAP[rdef.object](default)
             except ValueError as verr:
                 raise ValueError('creating a default value for '
                                  'attribute %s of type %s from the string %r'
@@ -119,7 +144,9 @@ def convert_default_value(rdef, default)
     return default  # general case: untouched default
 
 
-def register_base_type(name, parameters=(), check_function=None):
+def register_base_type(name: str, parameters: Union[Dict[str, Any], Tuple,
+                                                    Tuple[str], List[str]] = (),
+                       check_function=None) -> None:
     """register a yams base (final) type. You'll have to call
     base_type_class to generate the class.
     """
@@ -138,7 +165,7 @@ def register_base_type(name, parameters=
     BASE_CHECKERS[name] = check_function or yes
 
 
-def unregister_base_type(name):
+def unregister_base_type(name: str) -> None:
     """Unregister a yams base (final) type"""
     from yams.schema import RelationDefinitionSchema
     from yams.constraints import BASE_CHECKERS



More information about the cubicweb-devel mailing list