[arch-commits] Commit in cantarell-fonts/repos/extra-any (5 files)
Jan Steffens
heftig at archlinux.org
Mon Jan 13 08:38:00 UTC 2020
Date: Monday, January 13, 2020 @ 08:38:00
Author: heftig
Revision: 373414
archrelease: copy trunk to extra-any
Added:
cantarell-fonts/repos/extra-any/PKGBUILD
(from rev 373413, cantarell-fonts/trunk/PKGBUILD)
cantarell-fonts/repos/extra-any/cattrs.diff
(from rev 373413, cantarell-fonts/trunk/cattrs.diff)
Deleted:
cantarell-fonts/repos/extra-any/PKGBUILD
cantarell-fonts/repos/extra-any/PKGBUILD.prebuilt
cantarell-fonts/repos/extra-any/cattrs.diff
-------------------+
PKGBUILD | 66 +---
PKGBUILD.prebuilt | 25 -
cattrs.diff | 830 ++++++++++++++++++++++++++--------------------------
3 files changed, 440 insertions(+), 481 deletions(-)
Deleted: PKGBUILD
===================================================================
--- PKGBUILD 2020-01-13 08:37:46 UTC (rev 373413)
+++ PKGBUILD 2020-01-13 08:38:00 UTC (rev 373414)
@@ -1,41 +0,0 @@
-# Maintainer: Jan Alexander Steffens (heftig) <jan.steffens at gmail.com>
-
-pkgname=cantarell-fonts
-pkgver=0.200
-pkgrel=1
-epoch=1
-pkgdesc="Humanist sans serif font"
-url="https://gitlab.gnome.org/GNOME/cantarell-fonts"
-arch=(any)
-license=(custom:SIL)
-makedepends=(meson appstream-glib git)
-_commit=b4f71a432aec52c250c2b7af4692376659cb085c # tags/v0.200^0
-source=("git+https://gitlab.gnome.org/GNOME/cantarell-fonts.git#commit=$_commit"
- cattrs.diff)
-sha256sums=('SKIP'
- 'e6e8cce13fbce7e6923425b6a5de81dd50eadf7ea4b7d6d096cb91648535b214')
-
-pkgver() {
- cd $pkgname
- git describe --tags | sed 's/^v//;s/-/+/g'
-}
-
-prepare() {
- python -m venv venv
- venv/bin/pip install -r $pkgname/requirements.txt
-
- # https://github.com/Tinche/cattrs/compare/v0.9.0..v1.0.0
- patch -d venv/lib/python3.8/site-packages -Np2 < cattrs.diff
-}
-
-build() {
- PATH="$srcdir/venv/bin:$PATH" arch-meson $pkgname build
- ninja -C build
-}
-
-package() {
- DESTDIR="$pkgdir" meson install -C build
- install -Dt "$pkgdir/usr/share/licenses/$pkgname" -m644 $pkgname/COPYING
-}
-
-# vim:set ts=2 sw=2 et:
Copied: cantarell-fonts/repos/extra-any/PKGBUILD (from rev 373413, cantarell-fonts/trunk/PKGBUILD)
===================================================================
--- PKGBUILD (rev 0)
+++ PKGBUILD 2020-01-13 08:38:00 UTC (rev 373414)
@@ -0,0 +1,25 @@
+# Maintainer: Jan Alexander Steffens (heftig) <jan.steffens at gmail.com>
+
+pkgname=cantarell-fonts
+pkgver=0.201
+pkgrel=1
+epoch=1
+pkgdesc="Humanist sans serif font"
+url="https://gitlab.gnome.org/GNOME/cantarell-fonts"
+arch=(any)
+license=(custom:SIL)
+makedepends=(meson appstream-glib git)
+source=("https://download.gnome.org/sources/$pkgname/$pkgver/$pkgname-$pkgver.tar.xz")
+sha256sums=('b61f64e5f6a48aa0abc7a53cdcbce60de81908ca36048a64730978fcd9ac9863')
+
+build() {
+ arch-meson $pkgname-$pkgver build -D useprebuilt=true
+ ninja -C build
+}
+
+package() {
+ DESTDIR="$pkgdir" meson install -C build
+ install -Dt "$pkgdir/usr/share/licenses/$pkgname" -m644 $pkgname-$pkgver/COPYING
+}
+
+# vim:set ts=2 sw=2 et:
Deleted: PKGBUILD.prebuilt
===================================================================
--- PKGBUILD.prebuilt 2020-01-13 08:37:46 UTC (rev 373413)
+++ PKGBUILD.prebuilt 2020-01-13 08:38:00 UTC (rev 373414)
@@ -1,25 +0,0 @@
-# Maintainer: Jan Alexander Steffens (heftig) <jan.steffens at gmail.com>
-
-pkgname=cantarell-fonts
-pkgver=0.200
-pkgrel=1
-epoch=1
-pkgdesc="Humanist sans serif font"
-url="https://gitlab.gnome.org/GNOME/cantarell-fonts"
-arch=(any)
-license=(custom:SIL)
-makedepends=(meson appstream-glib git)
-source=("https://download.gnome.org/sources/$pkgname/$pkgver/$pkgname-$pkgver.tar.xz")
-sha256sums=('a30131f7ab9d78e70415a7f601cbcc443ff5bcc44b0332ddc84d8624ba177661')
-
-build() {
- arch-meson $pkgname-$pkgver build -D useprebuilt=true
- ninja -C build
-}
-
-package() {
- DESTDIR="$pkgdir" meson install -C build
- install -Dt "$pkgdir/usr/share/licenses/$pkgname" -m644 $pkgname-$pkgver/COPYING
-}
-
-# vim:set ts=2 sw=2 et:
Deleted: cattrs.diff
===================================================================
--- cattrs.diff 2020-01-13 08:37:46 UTC (rev 373413)
+++ cattrs.diff 2020-01-13 08:38:00 UTC (rev 373414)
@@ -1,415 +0,0 @@
-diff --git a/src/cattr/_compat.py b/src/cattr/_compat.py
-index 73d81d5..7cd4c54 100644
---- a/src/cattr/_compat.py
-+++ b/src/cattr/_compat.py
-@@ -13,20 +13,21 @@ version_info = sys.version_info[0:3]
- is_py2 = version_info[0] == 2
- is_py3 = version_info[0] == 3
- is_py37 = version_info[:2] == (3, 7)
-+is_py38 = version_info[:2] == (3, 8)
-
- if is_py2:
- from functools32 import lru_cache
- from singledispatch import singledispatch
-
- unicode = unicode # noqa
- bytes = str
- else:
- from functools import lru_cache, singledispatch # noqa
-
- unicode = str
- bytes = bytes
-
--if is_py37:
-+if is_py37 or is_py38:
- from typing import List, Union, _GenericAlias
-
- def is_union_type(obj):
-@@ -96,7 +97,11 @@ else:
- return issubclass(type, MutableSet)
-
- def is_sequence(type):
-- return issubclass(type, Sequence)
-+ if is_py2:
-+ is_string = issubclass(type, basestring) # noqa:F821
-+ else:
-+ is_string = issubclass(type, str)
-+ return issubclass(type, Sequence) and not is_string
-
- def is_tuple(type):
- return issubclass(type, Tuple)
-diff --git a/src/cattr/converters.py b/src/cattr/converters.py
-index 57b9f4d..24b039c 100644
---- a/src/cattr/converters.py
-+++ b/src/cattr/converters.py
-@@ -1,5 +1,17 @@
- from enum import Enum
--from typing import Mapping, Sequence, Optional, TypeVar, Any
-+from typing import ( # noqa: F401, imported for Mypy.
-+ Any,
-+ Callable,
-+ Dict,
-+ FrozenSet,
-+ Mapping,
-+ Optional,
-+ Sequence,
-+ Set,
-+ Tuple,
-+ Type,
-+ TypeVar,
-+)
- from ._compat import (
- bytes,
- is_bare,
-@@ -79,6 +91,8 @@ class Converter(object):
- [
- (_subclass(Mapping), self._unstructure_mapping),
- (_subclass(Sequence), self._unstructure_seq),
-+ (_subclass(Set), self._unstructure_seq),
-+ (_subclass(FrozenSet), self._unstructure_seq),
- (_subclass(Enum), self._unstructure_enum),
- (_is_attrs_class, self._unstructure_attrs),
- ]
-@@ -121,95 +135,96 @@ class Converter(object):
- self._union_registry = {}
-
- def unstructure(self, obj):
-+ # type: (Any) -> Any
- return self._unstructure_func.dispatch(obj.__class__)(obj)
-
- @property
- def unstruct_strat(self):
- # type: () -> UnstructureStrategy
- """The default way of unstructuring ``attrs`` classes."""
- return (
- UnstructureStrategy.AS_DICT
- if self._unstructure_attrs == self.unstructure_attrs_asdict
- else UnstructureStrategy.AS_TUPLE
- )
-
- def register_unstructure_hook(self, cls, func):
- # type: (Type[T], Callable[[T], Any]) -> None
- """Register a class-to-primitive converter function for a class.
-
- The converter function should take an instance of the class and return
- its Python equivalent.
- """
- self._unstructure_func.register_cls_list([(cls, func)])
-
- def register_unstructure_hook_func(self, check_func, func):
- """Register a class-to-primitive converter function for a class, using
- a function to check if it's a match.
- """
-- # type: (Callable[Any], Callable[T], Any]) -> None
- self._unstructure_func.register_func_list([(check_func, func)])
-
- def register_structure_hook(self, cl, func):
- """Register a primitive-to-class converter function for a type.
-
- The converter function should take two arguments:
- * a Python object to be converted,
- * the type to convert to
-
- and return the instance of the class. The type may seem redundant, but
- is sometimes needed (for example, when dealing with generic classes).
- """
-- # type: (Type[T], Callable[[Any, Type], T) -> None
- if is_union_type(cl):
- self._union_registry[cl] = func
- else:
- self._structure_func.register_cls_list([(cl, func)])
-
- def register_structure_hook_func(self, check_func, func):
-- # type: (Callable[Any], Callable[T], Any]) -> None
-+ # type: (Callable[[Any], Any], Callable[[T], Any]) -> None
- """Register a class-to-primitive converter function for a class, using
- a function to check if it's a match.
- """
- self._structure_func.register_func_list([(check_func, func)])
-
- def structure(self, obj, cl):
-+ # type: (Any, Type[T]) -> T
- """Convert unstructured Python data structures to structured data."""
-- # type: (Any, Type) -> Any
-+
- return self._structure_func.dispatch(cl)(obj, cl)
-
- # Classes to Python primitives.
- def unstructure_attrs_asdict(self, obj):
-+ # type: (Any) -> Dict[str, Any]
- """Our version of `attrs.asdict`, so we can call back to us."""
- attrs = obj.__class__.__attrs_attrs__
- dispatch = self._unstructure_func.dispatch
- rv = self._dict_factory()
- for a in attrs:
- name = a.name
- v = getattr(obj, name)
- rv[name] = dispatch(v.__class__)(v)
- return rv
-
- def unstructure_attrs_astuple(self, obj):
-+ # type: (Any) -> Tuple
- """Our version of `attrs.astuple`, so we can call back to us."""
- attrs = obj.__class__.__attrs_attrs__
- return tuple(self.unstructure(getattr(obj, a.name)) for a in attrs)
-
- def _unstructure_enum(self, obj):
- """Convert an enum to its value."""
- return obj.value
-
- def _unstructure_identity(self, obj):
- """Just pass it through."""
- return obj
-
- def _unstructure_seq(self, seq):
- """Convert a sequence to primitive equivalents."""
- # We can reuse the sequence class, so tuples stay tuples.
- dispatch = self._unstructure_func.dispatch
- return seq.__class__(dispatch(e.__class__)(e) for e in seq)
-
- def _unstructure_mapping(self, mapping):
-- # type: (Mapping) -> Any
- """Convert a mapping of attr classes to primitive equivalents."""
-
- # We can reuse the mapping class, so dicts stay dicts and OrderedDicts
-@@ -258,159 +273,159 @@ class Converter(object):
- # Attrs classes.
-
- def structure_attrs_fromtuple(self, obj, cl):
-- # type: (Sequence[Any], Type) -> Any
-+ # type: (Tuple, Type[T]) -> T
- """Load an attrs class from a sequence (tuple)."""
- conv_obj = [] # A list of converter parameters.
-- for a, value in zip(cl.__attrs_attrs__, obj):
-+ for a, value in zip(cl.__attrs_attrs__, obj): # type: ignore
- # We detect the type by the metadata.
- converted = self._structure_attr_from_tuple(a, a.name, value)
- conv_obj.append(converted)
-
-- return cl(*conv_obj)
-+ return cl(*conv_obj) # type: ignore
-
- def _structure_attr_from_tuple(self, a, name, value):
- """Handle an individual attrs attribute."""
- type_ = a.type
- if type_ is None:
- # No type metadata.
- return value
- return self._structure_func.dispatch(type_)(value, type_)
-
- def structure_attrs_fromdict(self, obj, cl):
-- # type: (Mapping, Type) -> Any
-+ # type: (Mapping[str, Any], Type[T]) -> T
- """Instantiate an attrs class from a mapping (dict)."""
- # For public use.
-- conv_obj = obj.copy() # Dict of converted parameters.
-+ conv_obj = {} # Start with a fresh dict, to ignore extra keys.
- dispatch = self._structure_func.dispatch
-- for a in cl.__attrs_attrs__:
-+ for a in cl.__attrs_attrs__: # type: ignore
- # We detect the type by metadata.
- type_ = a.type
-- if type_ is None:
-- # No type.
-- continue
- name = a.name
-+
- try:
- val = obj[name]
- except KeyError:
- continue
-- conv_obj[name] = dispatch(type_)(val, type_)
-
-- return cl(**conv_obj)
-+ if name[0] == "_":
-+ name = name[1:]
-+
-+ conv_obj[name] = (
-+ dispatch(type_)(val, type_) if type_ is not None else val
-+ )
-+
-+ return cl(**conv_obj) # type: ignore
-
- def _structure_list(self, obj, cl):
-- # type: (Type[GenericMeta], Iterable[T]) -> List[T]
- """Convert an iterable to a potentially generic list."""
- if is_bare(cl) or cl.__args__[0] is Any:
- return [e for e in obj]
- else:
- elem_type = cl.__args__[0]
- return [
- self._structure_func.dispatch(elem_type)(e, elem_type)
- for e in obj
- ]
-
- def _structure_set(self, obj, cl):
-- # type: (Type[GenericMeta], Iterable[T]) -> MutableSet[T]
- """Convert an iterable into a potentially generic set."""
- if is_bare(cl) or cl.__args__[0] is Any:
- return set(obj)
- else:
- elem_type = cl.__args__[0]
- return {
- self._structure_func.dispatch(elem_type)(e, elem_type)
- for e in obj
- }
-
- def _structure_frozenset(self, obj, cl):
-- # type: (Type[GenericMeta], Iterable[T]) -> FrozenSet[T]
- """Convert an iterable into a potentially generic frozenset."""
- if is_bare(cl) or cl.__args__[0] is Any:
- return frozenset(obj)
- else:
- elem_type = cl.__args__[0]
- dispatch = self._structure_func.dispatch
- return frozenset(dispatch(elem_type)(e, elem_type) for e in obj)
-
- def _structure_dict(self, obj, cl):
-- # type: (Type[GenericMeta], Mapping[T, V]) -> Dict[T, V]
- """Convert a mapping into a potentially generic dict."""
- if is_bare(cl) or cl.__args__ == (Any, Any):
- return dict(obj)
- else:
- key_type, val_type = cl.__args__
- if key_type is Any:
- val_conv = self._structure_func.dispatch(val_type)
- return {k: val_conv(v, val_type) for k, v in obj.items()}
- elif val_type is Any:
- key_conv = self._structure_func.dispatch(key_type)
- return {key_conv(k, key_type): v for k, v in obj.items()}
- else:
- key_conv = self._structure_func.dispatch(key_type)
- val_conv = self._structure_func.dispatch(val_type)
- return {
- key_conv(k, key_type): val_conv(v, val_type)
- for k, v in obj.items()
- }
-
- def _structure_union(self, obj, union):
-- # type: (_Union, Any): -> Any
- """Deal with converting a union."""
- # Unions with NoneType in them are basically optionals.
- # We check for NoneType early and handle the case of obj being None,
- # so disambiguation functions don't need to handle NoneType.
- union_params = union.__args__
-- if NoneType in union_params:
-+ if NoneType in union_params: # type: ignore
- if obj is None:
- return None
- if len(union_params) == 2:
- # This is just a NoneType and something else.
- other = (
- union_params[0]
-- if union_params[1] is NoneType
-+ if union_params[1] is NoneType # type: ignore
- else union_params[1]
- )
- # We can't actually have a Union of a Union, so this is safe.
- return self._structure_func.dispatch(other)(obj, other)
-
- # Check the union registry first.
- handler = self._union_registry.get(union)
- if handler is not None:
- return handler(obj, union)
-
- # Getting here means either this is not an optional, or it's an
- # optional with more than one parameter.
- # Let's support only unions of attr classes for now.
- cl = self._dis_func_cache(union)(obj)
- return self._structure_func.dispatch(cl)(obj, cl)
-
- def _structure_tuple(self, obj, tup):
-- # type: (Type[Tuple], Iterable) -> Any
- """Deal with converting to a tuple."""
- tup_params = tup.__args__
- has_ellipsis = tup_params and tup_params[-1] is Ellipsis
- if tup_params is None or (has_ellipsis and tup_params[0] is Any):
- # Just a Tuple. (No generic information.)
- return tuple(obj)
- if has_ellipsis:
- # We're dealing with a homogenous tuple, Tuple[int, ...]
- tup_type = tup_params[0]
- conv = self._structure_func.dispatch(tup_type)
- return tuple(conv(e, tup_type) for e in obj)
- else:
- # We're dealing with a heterogenous tuple.
- return tuple(
- self._structure_func.dispatch(t)(e, t)
- for t, e in zip(tup_params, obj)
- )
-
- def _get_dis_func(self, union):
- # type: (Type) -> Callable[..., Type]
- """Fetch or try creating a disambiguation function for a union."""
- union_types = union.__args__
-- if NoneType in union_types:
-+ if NoneType in union_types: # type: ignore
- # We support unions of attrs classes and NoneType higher in the
- # logic.
-- union_types = tuple(e for e in union_types if e is not NoneType)
-+ union_types = tuple(
-+ e for e in union_types if e is not NoneType # type: ignore
-+ )
-
- if not all(hasattr(e, "__attrs_attrs__") for e in union_types):
- raise ValueError(
-diff --git a/src/cattr/disambiguators.py b/src/cattr/disambiguators.py
-index 4daa078..765a630 100644
---- a/src/cattr/disambiguators.py
-+++ b/src/cattr/disambiguators.py
-@@ -3,42 +3,48 @@ from collections import OrderedDict
- from functools import reduce
- from operator import or_
-
--from typing import Mapping
-+from typing import ( # noqa: F401, imported for Mypy.
-+ Callable,
-+ Dict,
-+ Mapping,
-+ Optional,
-+ Type,
-+)
-
- from attr import fields
-
-
--def create_uniq_field_dis_func(*cls):
-- # type: (*Sequence[Type]) -> Callable
-+def create_uniq_field_dis_func(*classes):
-+ # type: (*Type) -> Callable
- """Given attr classes, generate a disambiguation function.
-
- The function is based on unique fields."""
-- if len(cls) < 2:
-+ if len(classes) < 2:
- raise ValueError("At least two classes required.")
-- cls_and_attrs = [(cl, set(at.name for at in fields(cl))) for cl in cls]
-+ cls_and_attrs = [(cl, set(at.name for at in fields(cl))) for cl in classes]
- if len([attrs for _, attrs in cls_and_attrs if len(attrs) == 0]) > 1:
- raise ValueError("At least two classes have no attributes.")
- # TODO: Deal with a single class having no required attrs.
- # For each class, attempt to generate a single unique required field.
-- uniq_attrs_dict = OrderedDict()
-+ uniq_attrs_dict = OrderedDict() # type: Dict[str, Type]
- cls_and_attrs.sort(key=lambda c_a: -len(c_a[1]))
-
- fallback = None # If none match, try this.
-
- for i, (cl, cl_reqs) in enumerate(cls_and_attrs):
- other_classes = cls_and_attrs[i + 1 :]
- if other_classes:
- other_reqs = reduce(or_, (c_a[1] for c_a in other_classes))
- uniq = cl_reqs - other_reqs
- if not uniq:
- m = "{} has no usable unique attributes.".format(cl)
- raise ValueError(m)
- uniq_attrs_dict[next(iter(uniq))] = cl
- else:
- fallback = cl
-
- def dis_func(data):
-- # type: (Mapping) -> Union
-+ # type: (Mapping) -> Optional[Type]
- if not isinstance(data, Mapping):
- raise ValueError("Only input mappings are supported.")
- for k, v in uniq_attrs_dict.items():
Copied: cantarell-fonts/repos/extra-any/cattrs.diff (from rev 373413, cantarell-fonts/trunk/cattrs.diff)
===================================================================
--- cattrs.diff (rev 0)
+++ cattrs.diff 2020-01-13 08:38:00 UTC (rev 373414)
@@ -0,0 +1,415 @@
+diff --git a/src/cattr/_compat.py b/src/cattr/_compat.py
+index 73d81d5..7cd4c54 100644
+--- a/src/cattr/_compat.py
++++ b/src/cattr/_compat.py
+@@ -13,20 +13,21 @@ version_info = sys.version_info[0:3]
+ is_py2 = version_info[0] == 2
+ is_py3 = version_info[0] == 3
+ is_py37 = version_info[:2] == (3, 7)
++is_py38 = version_info[:2] == (3, 8)
+
+ if is_py2:
+ from functools32 import lru_cache
+ from singledispatch import singledispatch
+
+ unicode = unicode # noqa
+ bytes = str
+ else:
+ from functools import lru_cache, singledispatch # noqa
+
+ unicode = str
+ bytes = bytes
+
+-if is_py37:
++if is_py37 or is_py38:
+ from typing import List, Union, _GenericAlias
+
+ def is_union_type(obj):
+@@ -96,7 +97,11 @@ else:
+ return issubclass(type, MutableSet)
+
+ def is_sequence(type):
+- return issubclass(type, Sequence)
++ if is_py2:
++ is_string = issubclass(type, basestring) # noqa:F821
++ else:
++ is_string = issubclass(type, str)
++ return issubclass(type, Sequence) and not is_string
+
+ def is_tuple(type):
+ return issubclass(type, Tuple)
+diff --git a/src/cattr/converters.py b/src/cattr/converters.py
+index 57b9f4d..24b039c 100644
+--- a/src/cattr/converters.py
++++ b/src/cattr/converters.py
+@@ -1,5 +1,17 @@
+ from enum import Enum
+-from typing import Mapping, Sequence, Optional, TypeVar, Any
++from typing import ( # noqa: F401, imported for Mypy.
++ Any,
++ Callable,
++ Dict,
++ FrozenSet,
++ Mapping,
++ Optional,
++ Sequence,
++ Set,
++ Tuple,
++ Type,
++ TypeVar,
++)
+ from ._compat import (
+ bytes,
+ is_bare,
+@@ -79,6 +91,8 @@ class Converter(object):
+ [
+ (_subclass(Mapping), self._unstructure_mapping),
+ (_subclass(Sequence), self._unstructure_seq),
++ (_subclass(Set), self._unstructure_seq),
++ (_subclass(FrozenSet), self._unstructure_seq),
+ (_subclass(Enum), self._unstructure_enum),
+ (_is_attrs_class, self._unstructure_attrs),
+ ]
+@@ -121,95 +135,96 @@ class Converter(object):
+ self._union_registry = {}
+
+ def unstructure(self, obj):
++ # type: (Any) -> Any
+ return self._unstructure_func.dispatch(obj.__class__)(obj)
+
+ @property
+ def unstruct_strat(self):
+ # type: () -> UnstructureStrategy
+ """The default way of unstructuring ``attrs`` classes."""
+ return (
+ UnstructureStrategy.AS_DICT
+ if self._unstructure_attrs == self.unstructure_attrs_asdict
+ else UnstructureStrategy.AS_TUPLE
+ )
+
+ def register_unstructure_hook(self, cls, func):
+ # type: (Type[T], Callable[[T], Any]) -> None
+ """Register a class-to-primitive converter function for a class.
+
+ The converter function should take an instance of the class and return
+ its Python equivalent.
+ """
+ self._unstructure_func.register_cls_list([(cls, func)])
+
+ def register_unstructure_hook_func(self, check_func, func):
+ """Register a class-to-primitive converter function for a class, using
+ a function to check if it's a match.
+ """
+- # type: (Callable[Any], Callable[T], Any]) -> None
+ self._unstructure_func.register_func_list([(check_func, func)])
+
+ def register_structure_hook(self, cl, func):
+ """Register a primitive-to-class converter function for a type.
+
+ The converter function should take two arguments:
+ * a Python object to be converted,
+ * the type to convert to
+
+ and return the instance of the class. The type may seem redundant, but
+ is sometimes needed (for example, when dealing with generic classes).
+ """
+- # type: (Type[T], Callable[[Any, Type], T) -> None
+ if is_union_type(cl):
+ self._union_registry[cl] = func
+ else:
+ self._structure_func.register_cls_list([(cl, func)])
+
+ def register_structure_hook_func(self, check_func, func):
+- # type: (Callable[Any], Callable[T], Any]) -> None
++ # type: (Callable[[Any], Any], Callable[[T], Any]) -> None
+ """Register a class-to-primitive converter function for a class, using
+ a function to check if it's a match.
+ """
+ self._structure_func.register_func_list([(check_func, func)])
+
+ def structure(self, obj, cl):
++ # type: (Any, Type[T]) -> T
+ """Convert unstructured Python data structures to structured data."""
+- # type: (Any, Type) -> Any
++
+ return self._structure_func.dispatch(cl)(obj, cl)
+
+ # Classes to Python primitives.
+ def unstructure_attrs_asdict(self, obj):
++ # type: (Any) -> Dict[str, Any]
+ """Our version of `attrs.asdict`, so we can call back to us."""
+ attrs = obj.__class__.__attrs_attrs__
+ dispatch = self._unstructure_func.dispatch
+ rv = self._dict_factory()
+ for a in attrs:
+ name = a.name
+ v = getattr(obj, name)
+ rv[name] = dispatch(v.__class__)(v)
+ return rv
+
+ def unstructure_attrs_astuple(self, obj):
++ # type: (Any) -> Tuple
+ """Our version of `attrs.astuple`, so we can call back to us."""
+ attrs = obj.__class__.__attrs_attrs__
+ return tuple(self.unstructure(getattr(obj, a.name)) for a in attrs)
+
+ def _unstructure_enum(self, obj):
+ """Convert an enum to its value."""
+ return obj.value
+
+ def _unstructure_identity(self, obj):
+ """Just pass it through."""
+ return obj
+
+ def _unstructure_seq(self, seq):
+ """Convert a sequence to primitive equivalents."""
+ # We can reuse the sequence class, so tuples stay tuples.
+ dispatch = self._unstructure_func.dispatch
+ return seq.__class__(dispatch(e.__class__)(e) for e in seq)
+
+ def _unstructure_mapping(self, mapping):
+- # type: (Mapping) -> Any
+ """Convert a mapping of attr classes to primitive equivalents."""
+
+ # We can reuse the mapping class, so dicts stay dicts and OrderedDicts
+@@ -258,159 +273,159 @@ class Converter(object):
+ # Attrs classes.
+
+ def structure_attrs_fromtuple(self, obj, cl):
+- # type: (Sequence[Any], Type) -> Any
++ # type: (Tuple, Type[T]) -> T
+ """Load an attrs class from a sequence (tuple)."""
+ conv_obj = [] # A list of converter parameters.
+- for a, value in zip(cl.__attrs_attrs__, obj):
++ for a, value in zip(cl.__attrs_attrs__, obj): # type: ignore
+ # We detect the type by the metadata.
+ converted = self._structure_attr_from_tuple(a, a.name, value)
+ conv_obj.append(converted)
+
+- return cl(*conv_obj)
++ return cl(*conv_obj) # type: ignore
+
+ def _structure_attr_from_tuple(self, a, name, value):
+ """Handle an individual attrs attribute."""
+ type_ = a.type
+ if type_ is None:
+ # No type metadata.
+ return value
+ return self._structure_func.dispatch(type_)(value, type_)
+
+ def structure_attrs_fromdict(self, obj, cl):
+- # type: (Mapping, Type) -> Any
++ # type: (Mapping[str, Any], Type[T]) -> T
+ """Instantiate an attrs class from a mapping (dict)."""
+ # For public use.
+- conv_obj = obj.copy() # Dict of converted parameters.
++ conv_obj = {} # Start with a fresh dict, to ignore extra keys.
+ dispatch = self._structure_func.dispatch
+- for a in cl.__attrs_attrs__:
++ for a in cl.__attrs_attrs__: # type: ignore
+ # We detect the type by metadata.
+ type_ = a.type
+- if type_ is None:
+- # No type.
+- continue
+ name = a.name
++
+ try:
+ val = obj[name]
+ except KeyError:
+ continue
+- conv_obj[name] = dispatch(type_)(val, type_)
+
+- return cl(**conv_obj)
++ if name[0] == "_":
++ name = name[1:]
++
++ conv_obj[name] = (
++ dispatch(type_)(val, type_) if type_ is not None else val
++ )
++
++ return cl(**conv_obj) # type: ignore
+
+ def _structure_list(self, obj, cl):
+- # type: (Type[GenericMeta], Iterable[T]) -> List[T]
+ """Convert an iterable to a potentially generic list."""
+ if is_bare(cl) or cl.__args__[0] is Any:
+ return [e for e in obj]
+ else:
+ elem_type = cl.__args__[0]
+ return [
+ self._structure_func.dispatch(elem_type)(e, elem_type)
+ for e in obj
+ ]
+
+ def _structure_set(self, obj, cl):
+- # type: (Type[GenericMeta], Iterable[T]) -> MutableSet[T]
+ """Convert an iterable into a potentially generic set."""
+ if is_bare(cl) or cl.__args__[0] is Any:
+ return set(obj)
+ else:
+ elem_type = cl.__args__[0]
+ return {
+ self._structure_func.dispatch(elem_type)(e, elem_type)
+ for e in obj
+ }
+
+ def _structure_frozenset(self, obj, cl):
+- # type: (Type[GenericMeta], Iterable[T]) -> FrozenSet[T]
+ """Convert an iterable into a potentially generic frozenset."""
+ if is_bare(cl) or cl.__args__[0] is Any:
+ return frozenset(obj)
+ else:
+ elem_type = cl.__args__[0]
+ dispatch = self._structure_func.dispatch
+ return frozenset(dispatch(elem_type)(e, elem_type) for e in obj)
+
+ def _structure_dict(self, obj, cl):
+- # type: (Type[GenericMeta], Mapping[T, V]) -> Dict[T, V]
+ """Convert a mapping into a potentially generic dict."""
+ if is_bare(cl) or cl.__args__ == (Any, Any):
+ return dict(obj)
+ else:
+ key_type, val_type = cl.__args__
+ if key_type is Any:
+ val_conv = self._structure_func.dispatch(val_type)
+ return {k: val_conv(v, val_type) for k, v in obj.items()}
+ elif val_type is Any:
+ key_conv = self._structure_func.dispatch(key_type)
+ return {key_conv(k, key_type): v for k, v in obj.items()}
+ else:
+ key_conv = self._structure_func.dispatch(key_type)
+ val_conv = self._structure_func.dispatch(val_type)
+ return {
+ key_conv(k, key_type): val_conv(v, val_type)
+ for k, v in obj.items()
+ }
+
+ def _structure_union(self, obj, union):
+- # type: (_Union, Any): -> Any
+ """Deal with converting a union."""
+ # Unions with NoneType in them are basically optionals.
+ # We check for NoneType early and handle the case of obj being None,
+ # so disambiguation functions don't need to handle NoneType.
+ union_params = union.__args__
+- if NoneType in union_params:
++ if NoneType in union_params: # type: ignore
+ if obj is None:
+ return None
+ if len(union_params) == 2:
+ # This is just a NoneType and something else.
+ other = (
+ union_params[0]
+- if union_params[1] is NoneType
++ if union_params[1] is NoneType # type: ignore
+ else union_params[1]
+ )
+ # We can't actually have a Union of a Union, so this is safe.
+ return self._structure_func.dispatch(other)(obj, other)
+
+ # Check the union registry first.
+ handler = self._union_registry.get(union)
+ if handler is not None:
+ return handler(obj, union)
+
+ # Getting here means either this is not an optional, or it's an
+ # optional with more than one parameter.
+ # Let's support only unions of attr classes for now.
+ cl = self._dis_func_cache(union)(obj)
+ return self._structure_func.dispatch(cl)(obj, cl)
+
+ def _structure_tuple(self, obj, tup):
+- # type: (Type[Tuple], Iterable) -> Any
+ """Deal with converting to a tuple."""
+ tup_params = tup.__args__
+ has_ellipsis = tup_params and tup_params[-1] is Ellipsis
+ if tup_params is None or (has_ellipsis and tup_params[0] is Any):
+ # Just a Tuple. (No generic information.)
+ return tuple(obj)
+ if has_ellipsis:
+ # We're dealing with a homogenous tuple, Tuple[int, ...]
+ tup_type = tup_params[0]
+ conv = self._structure_func.dispatch(tup_type)
+ return tuple(conv(e, tup_type) for e in obj)
+ else:
+ # We're dealing with a heterogenous tuple.
+ return tuple(
+ self._structure_func.dispatch(t)(e, t)
+ for t, e in zip(tup_params, obj)
+ )
+
+ def _get_dis_func(self, union):
+ # type: (Type) -> Callable[..., Type]
+ """Fetch or try creating a disambiguation function for a union."""
+ union_types = union.__args__
+- if NoneType in union_types:
++ if NoneType in union_types: # type: ignore
+ # We support unions of attrs classes and NoneType higher in the
+ # logic.
+- union_types = tuple(e for e in union_types if e is not NoneType)
++ union_types = tuple(
++ e for e in union_types if e is not NoneType # type: ignore
++ )
+
+ if not all(hasattr(e, "__attrs_attrs__") for e in union_types):
+ raise ValueError(
+diff --git a/src/cattr/disambiguators.py b/src/cattr/disambiguators.py
+index 4daa078..765a630 100644
+--- a/src/cattr/disambiguators.py
++++ b/src/cattr/disambiguators.py
+@@ -3,42 +3,48 @@ from collections import OrderedDict
+ from functools import reduce
+ from operator import or_
+
+-from typing import Mapping
++from typing import ( # noqa: F401, imported for Mypy.
++ Callable,
++ Dict,
++ Mapping,
++ Optional,
++ Type,
++)
+
+ from attr import fields
+
+
+-def create_uniq_field_dis_func(*cls):
+- # type: (*Sequence[Type]) -> Callable
++def create_uniq_field_dis_func(*classes):
++ # type: (*Type) -> Callable
+ """Given attr classes, generate a disambiguation function.
+
+ The function is based on unique fields."""
+- if len(cls) < 2:
++ if len(classes) < 2:
+ raise ValueError("At least two classes required.")
+- cls_and_attrs = [(cl, set(at.name for at in fields(cl))) for cl in cls]
++ cls_and_attrs = [(cl, set(at.name for at in fields(cl))) for cl in classes]
+ if len([attrs for _, attrs in cls_and_attrs if len(attrs) == 0]) > 1:
+ raise ValueError("At least two classes have no attributes.")
+ # TODO: Deal with a single class having no required attrs.
+ # For each class, attempt to generate a single unique required field.
+- uniq_attrs_dict = OrderedDict()
++ uniq_attrs_dict = OrderedDict() # type: Dict[str, Type]
+ cls_and_attrs.sort(key=lambda c_a: -len(c_a[1]))
+
+ fallback = None # If none match, try this.
+
+ for i, (cl, cl_reqs) in enumerate(cls_and_attrs):
+ other_classes = cls_and_attrs[i + 1 :]
+ if other_classes:
+ other_reqs = reduce(or_, (c_a[1] for c_a in other_classes))
+ uniq = cl_reqs - other_reqs
+ if not uniq:
+ m = "{} has no usable unique attributes.".format(cl)
+ raise ValueError(m)
+ uniq_attrs_dict[next(iter(uniq))] = cl
+ else:
+ fallback = cl
+
+ def dis_func(data):
+- # type: (Mapping) -> Union
++ # type: (Mapping) -> Optional[Type]
+ if not isinstance(data, Mapping):
+ raise ValueError("Only input mappings are supported.")
+ for k, v in uniq_attrs_dict.items():
More information about the arch-commits
mailing list