Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pyrsistent/_checked_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,8 +510,8 @@ def create(cls, source_data, _factory_fields=None, ignore_extra=False):
checked_value_type = next((t for t in value_types if issubclass(t, CheckedType)), None)

if checked_key_type or checked_value_type:
return cls(dict((checked_key_type.create(key) if checked_key_type and not any(isinstance(key, t) for t in key_types) else key,
checked_value_type.create(value) if checked_value_type and not any(isinstance(value, t) for t in value_types) else value)
return cls(dict((checked_key_type.create(key, ignore_extra=ignore_extra) if checked_key_type and not any(isinstance(key, t) for t in key_types) else key,
checked_value_type.create(value, ignore_extra=ignore_extra) if checked_value_type and not any(isinstance(value, t) for t in value_types) else value)
for key, value in source_data.items()))

return cls(source_data)
Expand Down
43 changes: 42 additions & 1 deletion tests/checked_map_test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pickle
import pytest
from pyrsistent import CheckedPMap, InvariantException, PMap, CheckedType, CheckedPSet, CheckedPVector, \
CheckedKeyTypeError, CheckedValueTypeError
CheckedKeyTypeError, CheckedValueTypeError, PRecord, field


class FloatToIntMap(CheckedPMap):
Expand Down Expand Up @@ -100,6 +100,47 @@ class IntSetToFloatVectorMap(CheckedPMap):

assert str(x) == "IntSetToFloatVectorMap({IntSet([1, 2]): FloatVector([1.25, 2.5])})"


class ARecord(PRecord):
x = field()


class StrToARecordMap(CheckedPMap):
__key_type__ = str
__value_type__ = ARecord


def test_create_forwards_ignore_extra_to_value():
# ``ignore_extra`` must be threaded through to the nested checked
# value type, just like it is for CheckedPVector/CheckedPSet.
# https://github.com/tobgu/pyrsistent/issues/326
x = StrToARecordMap.create({'k': {'x': 1, 'extra': 2}}, ignore_extra=True)

assert x['k'] == ARecord(x=1)
assert isinstance(x['k'], ARecord)


def test_create_without_ignore_extra_still_raises_for_value():
with pytest.raises(AttributeError):
StrToARecordMap.create({'k': {'x': 1, 'extra': 2}})


def test_create_forwards_ignore_extra_to_nested_checked_value():
# The value type is itself a CheckedPVector of records, so
# ``ignore_extra`` has to be forwarded all the way down.
class ARecordVector(CheckedPVector):
__type__ = ARecord

class StrToARecordVectorMap(CheckedPMap):
__key_type__ = str
__value_type__ = ARecordVector

x = StrToARecordVectorMap.create(
{'k': [{'x': 1, 'extra': 2}]}, ignore_extra=True)

assert x['k'] == ARecordVector([ARecord(x=1)])


def test_evolver_returns_same_instance_when_no_updates():
x = FloatToIntMap({1.25: 1, 2.25: 2})

Expand Down