Review feedback.
This commit is contained in:
parent
17a48c3bc3
commit
88f33a9375
|
@ -13,21 +13,21 @@ def asdict(inst, recurse=True, filter=None, dict_factory=dict):
|
||||||
|
|
||||||
:param inst: Instance of a ``attrs``-decorated class.
|
:param inst: Instance of a ``attrs``-decorated class.
|
||||||
|
|
||||||
:param recurse: Recurse into classes that are also ``attrs``-decorated.
|
:param bool recurse: Recurse into classes that are also ``attrs``-decorated.
|
||||||
:type recurse: bool
|
|
||||||
|
|
||||||
:param filter: A callable whose return code deteremines whether an
|
:param callable filter: A callable whose return code deteremines whether an
|
||||||
attribute or element is included (``True``) or dropped (``False``). Is
|
attribute or element is included (``True``) or dropped (``False``). Is
|
||||||
called with the :class:`attr.Attribute` as the first argument and the
|
called with the :class:`attr.Attribute` as the first argument and the
|
||||||
value as the second argument.
|
value as the second argument.
|
||||||
:type filer: callable
|
|
||||||
|
|
||||||
:param dict_factory: A callable to produce dictionaries from. For example,
|
:param callable dict_factory: A callable to produce dictionaries from. For
|
||||||
to produce ordered dictionaries instead of normal Python dictionaries,
|
example, to produce ordered dictionaries instead of normal Python
|
||||||
pass in ``collections.OrderedDict``.
|
dictionaries, pass in ``collections.OrderedDict``.
|
||||||
:type dict_factory: callable
|
|
||||||
|
|
||||||
:rtype: :class:`dict`
|
:rtype: :class:`dict`
|
||||||
|
|
||||||
|
.. versionadded:: 16.0.0
|
||||||
|
*dict_factory*
|
||||||
"""
|
"""
|
||||||
attrs = fields(inst.__class__)
|
attrs = fields(inst.__class__)
|
||||||
rv = dict_factory()
|
rv = dict_factory()
|
||||||
|
|
|
@ -4,7 +4,8 @@ import string
|
||||||
|
|
||||||
from hypothesis import strategies as st
|
from hypothesis import strategies as st
|
||||||
|
|
||||||
from attr import Attribute, ib
|
import attr
|
||||||
|
from attr import Attribute
|
||||||
from attr._make import NOTHING, make_class
|
from attr._make import NOTHING, make_class
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,18 +47,30 @@ class TestSimpleClass(object):
|
||||||
assert simple_class() is not simple_class()
|
assert simple_class() is not simple_class()
|
||||||
|
|
||||||
|
|
||||||
def create_class(attrs):
|
def _gen_attr_names():
|
||||||
|
"""
|
||||||
|
Generate names for attributes, 'a'...'z', then 'aa'...'zz'.
|
||||||
|
|
||||||
|
702 different attribute names should be enough in practice.
|
||||||
|
"""
|
||||||
|
lc = string.ascii_lowercase
|
||||||
|
for c in lc:
|
||||||
|
yield c
|
||||||
|
for outer in lc:
|
||||||
|
for inner in lc:
|
||||||
|
yield outer + inner
|
||||||
|
|
||||||
|
def _create_hyp_class(attrs):
|
||||||
"""
|
"""
|
||||||
A helper function for Hypothesis to generate attrs classes.
|
A helper function for Hypothesis to generate attrs classes.
|
||||||
"""
|
"""
|
||||||
# What if we get more than len(string.ascii_lowercase) attributes?
|
return make_class('HypClass', dict(zip(_gen_attr_names(), attrs)))
|
||||||
return make_class('HypClass', dict(zip(string.ascii_lowercase, attrs)))
|
|
||||||
|
|
||||||
bare_attrs = st.just(ib(default=None))
|
bare_attrs = st.just(attr.ib(default=None))
|
||||||
int_attrs = st.integers().map(lambda i: ib(default=i))
|
int_attrs = st.integers().map(lambda i: attr.ib(default=i))
|
||||||
str_attrs = st.text().map(lambda s: ib(default=s))
|
str_attrs = st.text().map(lambda s: attr.ib(default=s))
|
||||||
float_attrs = st.floats().map(lambda f: ib(default=f))
|
float_attrs = st.floats().map(lambda f: attr.ib(default=f))
|
||||||
|
|
||||||
simple_attrs = st.one_of(bare_attrs, int_attrs, str_attrs, float_attrs)
|
simple_attrs = st.one_of(bare_attrs, int_attrs, str_attrs, float_attrs)
|
||||||
|
|
||||||
simple_classes = st.lists(simple_attrs).map(create_class)
|
simple_classes = st.lists(simple_attrs).map(_create_hyp_class)
|
||||||
|
|
|
@ -3,6 +3,7 @@ Tests for `attr._funcs`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -14,20 +15,23 @@ from . import simple_classes
|
||||||
from attr._funcs import (
|
from attr._funcs import (
|
||||||
asdict,
|
asdict,
|
||||||
assoc,
|
assoc,
|
||||||
has,
|
|
||||||
fields,
|
fields,
|
||||||
|
has,
|
||||||
)
|
)
|
||||||
from attr._make import (
|
from attr._make import (
|
||||||
attr,
|
attr,
|
||||||
attributes,
|
attributes,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
MAPPING_TYPES = (dict, OrderedDict)
|
||||||
|
SEQUENCE_TYPES = (list, tuple)
|
||||||
|
|
||||||
|
|
||||||
class TestAsDict(object):
|
class TestAsDict(object):
|
||||||
"""
|
"""
|
||||||
Tests for `asdict`.
|
Tests for `asdict`.
|
||||||
"""
|
"""
|
||||||
@given(st.sampled_from([dict, OrderedDict]))
|
@given(st.sampled_from(MAPPING_TYPES))
|
||||||
def test_shallow(self, C, dict_factory):
|
def test_shallow(self, C, dict_factory):
|
||||||
"""
|
"""
|
||||||
Shallow asdict returns correct dict.
|
Shallow asdict returns correct dict.
|
||||||
|
@ -37,7 +41,7 @@ class TestAsDict(object):
|
||||||
"y": 2,
|
"y": 2,
|
||||||
} == asdict(C(x=1, y=2), False, dict_factory=dict_factory)
|
} == asdict(C(x=1, y=2), False, dict_factory=dict_factory)
|
||||||
|
|
||||||
@given(st.sampled_from([dict, OrderedDict]))
|
@given(st.sampled_from(MAPPING_TYPES))
|
||||||
def test_recurse(self, C, dict_factory):
|
def test_recurse(self, C, dict_factory):
|
||||||
"""
|
"""
|
||||||
Deep asdict returns correct dict.
|
Deep asdict returns correct dict.
|
||||||
|
@ -50,7 +54,7 @@ class TestAsDict(object):
|
||||||
C(3, 4),
|
C(3, 4),
|
||||||
), dict_factory=dict_factory)
|
), dict_factory=dict_factory)
|
||||||
|
|
||||||
@given(st.sampled_from([dict, OrderedDict]))
|
@given(st.sampled_from(MAPPING_TYPES))
|
||||||
def test_filter(self, C, dict_factory):
|
def test_filter(self, C, dict_factory):
|
||||||
"""
|
"""
|
||||||
Attributes that are supposed to be skipped are skipped.
|
Attributes that are supposed to be skipped are skipped.
|
||||||
|
@ -62,10 +66,7 @@ class TestAsDict(object):
|
||||||
C(3, 4),
|
C(3, 4),
|
||||||
), filter=lambda a, v: a.name != "y", dict_factory=dict_factory)
|
), filter=lambda a, v: a.name != "y", dict_factory=dict_factory)
|
||||||
|
|
||||||
@pytest.mark.parametrize("container", [
|
@given(container=st.sampled_from(SEQUENCE_TYPES))
|
||||||
list,
|
|
||||||
tuple,
|
|
||||||
])
|
|
||||||
def test_lists_tuples(self, container, C):
|
def test_lists_tuples(self, container, C):
|
||||||
"""
|
"""
|
||||||
If recurse is True, also recurse into lists.
|
If recurse is True, also recurse into lists.
|
||||||
|
@ -75,7 +76,7 @@ class TestAsDict(object):
|
||||||
"y": [{"x": 2, "y": 3}, {"x": 4, "y": 5}, "a"],
|
"y": [{"x": 2, "y": 3}, {"x": 4, "y": 5}, "a"],
|
||||||
} == asdict(C(1, container([C(2, 3), C(4, 5), "a"])))
|
} == asdict(C(1, container([C(2, 3), C(4, 5), "a"])))
|
||||||
|
|
||||||
@given(st.sampled_from([dict, OrderedDict]))
|
@given(st.sampled_from(MAPPING_TYPES))
|
||||||
def test_dicts(self, C, dict_factory):
|
def test_dicts(self, C, dict_factory):
|
||||||
"""
|
"""
|
||||||
If recurse is True, also recurse into dicts.
|
If recurse is True, also recurse into dicts.
|
||||||
|
@ -87,10 +88,10 @@ class TestAsDict(object):
|
||||||
} == res
|
} == res
|
||||||
assert isinstance(res, dict_factory)
|
assert isinstance(res, dict_factory)
|
||||||
|
|
||||||
@given(simple_classes, st.sampled_from([dict, OrderedDict]))
|
@given(simple_classes, st.sampled_from(MAPPING_TYPES))
|
||||||
def test_roundtrip(self, cls, dict_factory):
|
def test_roundtrip(self, cls, dict_factory):
|
||||||
"""
|
"""
|
||||||
Test roundtripping for Hypothesis-generated classes.
|
Test dumping to dicts and back for Hypothesis-generated classes.
|
||||||
"""
|
"""
|
||||||
instance = cls()
|
instance = cls()
|
||||||
dict_instance = asdict(instance, dict_factory=dict_factory)
|
dict_instance = asdict(instance, dict_factory=dict_factory)
|
||||||
|
|
Loading…
Reference in New Issue