Skip to content

Commit

Permalink
add IntegerSetAttribute
Browse files Browse the repository at this point in the history
  • Loading branch information
knap1930 committed Mar 12, 2024
1 parent fe416dd commit 22d666c
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ This Python 3 library contains compound and high-level PynamoDB attributes:

- `FloatAttribute` – same as `NumberAttribute` but whose value is typed as `float`
- `IntegerAttribute` – same as `NumberAttribute` but whose value is typed as `int` (rather than `float`)
- `IntegerSetAttribute` – same as `NumberSetAttribute` but whose value is typed as `int` (rather than `float`)
- `UnicodeDelimitedTupleAttribute` - a delimiter-separated value, useful for storing composite keys
- `UnicodeEnumAttribute` - serializes a string-valued `Enum` into a Unicode (`S`-typed) attribute
- `UnicodeProtobufEnumAttribute` - serializes a Protobuf enum into a Unicode (`S`-typed) attribute
Expand Down
2 changes: 2 additions & 0 deletions pynamodb_attributes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .float import FloatAttribute
from .integer import IntegerAttribute
from .integer_set import IntegerSetAttribute
from .integer_date import IntegerDateAttribute
from .integer_enum import IntegerEnumAttribute
from .timedelta import TimedeltaAttribute
Expand All @@ -16,6 +17,7 @@
__all__ = [
"FloatAttribute",
"IntegerAttribute",
"IntegerSetAttribute",
"IntegerDateAttribute",
"IntegerEnumAttribute",
"UnicodeDelimitedTupleAttribute",
Expand Down
15 changes: 15 additions & 0 deletions pynamodb_attributes/integer_set.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from typing import Set

from pynamodb.attributes import Attribute
from pynamodb.attributes import NumberSetAttribute


class IntegerSetAttribute(Attribute[Set[int]]):
"""
Unlike NumberSetAttribute, this attribute has its type hinted as 'Set[int]'.
"""

attr_type = NumberSetAttribute.attr_type
null = NumberSetAttribute.null
serialize = NumberSetAttribute.serialize # type: ignore
deserialize = NumberSetAttribute.deserialize # type: ignore
56 changes: 56 additions & 0 deletions tests/integer_set_attribute_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from typing import Set

import pytest
from pynamodb.attributes import UnicodeAttribute
from pynamodb.models import Model
from typing_extensions import assert_type

from pynamodb_attributes import IntegerSetAttribute
from tests.connection import _connection
from tests.meta import dynamodb_table_meta


class MyModel(Model):
Meta = dynamodb_table_meta(__name__)

key = UnicodeAttribute(hash_key=True)
value = IntegerSetAttribute(null=True)


assert_type(MyModel.value, IntegerSetAttribute)
assert_type(MyModel().value, Set[int])


@pytest.fixture(scope="module", autouse=True)
def create_table():
MyModel.create_table()


def test_serialization_non_null(uuid_key):
model = MyModel()
model.key = uuid_key
model.value = {456, 789}
model.save()

# verify underlying storage
item = _connection(MyModel).get_item(uuid_key)
assert item["Item"]["value"] == {"NS": ["456", "789"]}

# verify deserialization
model = MyModel.get(uuid_key)
assert model.value == {456, 789}


def test_serialization_null(uuid_key):
model = MyModel()
model.key = uuid_key
model.value = None
model.save()

# verify underlying storage
item = _connection(MyModel).get_item(uuid_key)
assert "value" not in item["Item"]

# verify deserialization
model = MyModel.get(uuid_key)
assert model.value is None

0 comments on commit 22d666c

Please sign in to comment.