Skip to content

Commit

Permalink
Format repository with black (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
NazarioJL authored Jul 9, 2021
1 parent 9c87736 commit a6f8823
Show file tree
Hide file tree
Showing 25 changed files with 255 additions and 169 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*.egg-info
.*.swp
.DS_Store
.venv/
venv/
venv3/
.cache/
Expand Down
4 changes: 4 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
repos:
- repo: https://github.com/psf/black
rev: stable
hooks:
- id: black
- repo: https://github.com/asottile/reorder_python_imports
rev: v2.3.6
hooks:
Expand Down
26 changes: 13 additions & 13 deletions pynamodb_attributes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
from .uuid import UUIDAttribute

__all__ = [
'FloatAttribute',
'IntegerAttribute',
'IntegerDateAttribute',
'IntegerEnumAttribute',
'UnicodeDelimitedTupleAttribute',
'UnicodeEnumAttribute',
'TimedeltaAttribute',
'TimedeltaMsAttribute',
'TimedeltaUsAttribute',
'TimestampAttribute',
'TimestampMsAttribute',
'TimestampUsAttribute',
'UUIDAttribute',
"FloatAttribute",
"IntegerAttribute",
"IntegerDateAttribute",
"IntegerEnumAttribute",
"UnicodeDelimitedTupleAttribute",
"UnicodeEnumAttribute",
"TimedeltaAttribute",
"TimedeltaMsAttribute",
"TimedeltaUsAttribute",
"TimestampAttribute",
"TimestampMsAttribute",
"TimestampUsAttribute",
"UUIDAttribute",
]
1 change: 1 addition & 0 deletions pynamodb_attributes/float.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class FloatAttribute(Attribute[float]):
"""
Unlike NumberAttribute, this attribute has its type hinted as 'float'.
"""

attr_type = NumberAttribute.attr_type
serialize = NumberAttribute.serialize # type: ignore
deserialize = NumberAttribute.deserialize # type: ignore
1 change: 1 addition & 0 deletions pynamodb_attributes/integer.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class IntegerAttribute(Attribute[int]):
"""
Unlike NumberAttribute, this attribute has its type hinted as 'int'.
"""

attr_type = NumberAttribute.attr_type
serialize = NumberAttribute.serialize # type: ignore
deserialize = NumberAttribute.deserialize # type: ignore
1 change: 1 addition & 0 deletions pynamodb_attributes/integer_date.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

class IntegerDateAttribute(Attribute[date]):
"""Represents a date as an integer (e.g. 2015_12_31 for December 31st, 2015)."""

attr_type = IntegerAttribute.attr_type

def serialize(self, value: date) -> str:
Expand Down
11 changes: 8 additions & 3 deletions pynamodb_attributes/integer_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import pynamodb.constants
from pynamodb.attributes import Attribute

T = TypeVar('T', bound=Enum)
T = TypeVar("T", bound=Enum)
_fail: Any = object()


Expand All @@ -28,9 +28,12 @@ class IntegerEnumAttribute(Attribute[T]):
>>> class Shake(Model):
>>> flavor = IntegerEnumAttribute(ShakeFlavor)
"""

attr_type = pynamodb.constants.NUMBER

def __init__(self, enum_type: Type[T], unknown_value: Optional[T] = _fail, **kwargs: Any) -> None:
def __init__(
self, enum_type: Type[T], unknown_value: Optional[T] = _fail, **kwargs: Any
) -> None:
"""
:param enum_type: The type of the enum
"""
Expand All @@ -50,5 +53,7 @@ def deserialize(self, value: str) -> Optional[T]:

def serialize(self, value: T) -> str:
if not isinstance(value, self.enum_type):
raise TypeError(f"value has invalid type '{type(value)}'; expected '{self.enum_type}'")
raise TypeError(
f"value has invalid type '{type(value)}'; expected '{self.enum_type}'",
)
return str(value.value)
13 changes: 9 additions & 4 deletions pynamodb_attributes/timedelta.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@


class TimedeltaAttribute(Attribute[timedelta]):
""""
""" "
Stores a timedelta as a number of seconds (truncated).
>>> class MyModel(Model):
>>> delta = TimedeltaAttribute(default=lambda: timedelta(seconds=5))
>>> delta_ms = TimedeltaMsAttribute(default=lambda: timedelta(milliseconds=500))
"""

attr_type = pynamodb.constants.NUMBER
_multiplier = 1.0

Expand All @@ -25,19 +26,23 @@ def serialize(self, td: timedelta) -> int:

def __set__(self, instance: Any, value: Optional[Any]) -> None:
if value is not None and not isinstance(value, timedelta):
raise TypeError(f"value has invalid type '{type(value)}'; Optional[timedelta] expected")
raise TypeError(
f"value has invalid type '{type(value)}'; Optional[timedelta] expected",
)
return super().__set__(instance, value)


class TimedeltaMsAttribute(TimedeltaAttribute):
""""
""" "
Stores a timedelta as a number of milliseconds AKA ms (truncated).
"""

_multiplier = 1000.0


class TimedeltaUsAttribute(TimedeltaAttribute):
""""
""" "
Stores a timedelta as a number of microseconds AKA μs (truncated).
"""

_multiplier = 1000000.0
13 changes: 9 additions & 4 deletions pynamodb_attributes/timestamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@


class TimestampAttribute(Attribute[datetime]):
""""
""" "
Stores time as a Unix epoch timestamp (in seconds) in a DynamoDB number.
>>> class MyModel(Model):
>>> created_at_seconds = TimestampAttribute(default=lambda: datetime.now(tz=timezone.utc))
>>> created_at_ms = TimestampMsAttribute(default=lambda: datetime.now(tz=timezone.utc))
"""

attr_type = pynamodb.constants.NUMBER
_multiplier = 1.0

Expand All @@ -27,21 +28,25 @@ def serialize(self, value: datetime) -> str:
def __set__(self, instance: Any, value: Optional[Any]) -> None:
if value is not None:
if not isinstance(value, datetime):
raise TypeError(f"value has invalid type '{type(value)}'; datetime expected")
raise TypeError(
f"value has invalid type '{type(value)}'; datetime expected",
)
if value.tzinfo is None or value.tzinfo.utcoffset(value) is None:
raise TypeError("aware datetime expected")
return super().__set__(instance, value)


class TimestampMsAttribute(TimestampAttribute):
""""
""" "
Stores time as a Unix epoch timestamp in milliseconds (ms) in a DynamoDB number.
"""

_multiplier = 1000.0


class TimestampUsAttribute(TimestampAttribute):
""""
""" "
Stores times as a Unix epoch timestamp in microseconds (μs) in a DynamoDB number.
"""

_multiplier = 1000000.0
27 changes: 19 additions & 8 deletions pynamodb_attributes/unicode_delimited_tuple.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import pynamodb.constants
from pynamodb.attributes import Attribute

T = TypeVar('T', bound=Tuple[Any, ...])
_DEFAULT_FIELD_DELIMITER = '::'
T = TypeVar("T", bound=Tuple[Any, ...])
_DEFAULT_FIELD_DELIMITER = "::"


class UnicodeDelimitedTupleAttribute(Attribute[T]):
Expand All @@ -29,7 +29,12 @@ class UnicodeDelimitedTupleAttribute(Attribute[T]):

attr_type = pynamodb.constants.STRING

def __init__(self, tuple_type: Type[T], delimiter: str = _DEFAULT_FIELD_DELIMITER, **kwargs: Any) -> None:
def __init__(
self,
tuple_type: Type[T],
delimiter: str = _DEFAULT_FIELD_DELIMITER,
**kwargs: Any,
) -> None:
"""
:param tuple_type: The type of the tuple -- may be a named or plain tuple
:param delimiter: The delimiter to separate the tuple elements
Expand All @@ -39,21 +44,27 @@ def __init__(self, tuple_type: Type[T], delimiter: str = _DEFAULT_FIELD_DELIMITE
self.delimiter = delimiter

def deserialize(self, value: str) -> T:
fields = getattr(self.tuple_type, '_fields', None)
field_types = getattr(self.tuple_type, '_field_types', None)
fields = getattr(self.tuple_type, "_fields", None)
field_types = getattr(self.tuple_type, "_field_types", None)
if fields and field_types:
values = value.split(self.delimiter, maxsplit=len(fields))
return self.tuple_type(**{f: field_types[f](v) for f, v in zip(fields, values)})
return self.tuple_type(
**{f: field_types[f](v) for f, v in zip(fields, values)}
)
else:
return self.tuple_type(value.split(self.delimiter))

def serialize(self, value: T) -> str:
if not isinstance(value, self.tuple_type):
raise TypeError(f"value has invalid type '{type(value)}'; expected '{self.tuple_type}'")
raise TypeError(
f"value has invalid type '{type(value)}'; expected '{self.tuple_type}'",
)
values: List[T] = list(value)
while values and values[-1] is None:
del values[-1]
strings = [str(e) for e in values]
if any(self.delimiter in s for s in strings):
raise ValueError(f"Tuple elements may not contain delimiter '{self.delimiter}'")
raise ValueError(
f"Tuple elements may not contain delimiter '{self.delimiter}'",
)
return self.delimiter.join(strings)
15 changes: 11 additions & 4 deletions pynamodb_attributes/unicode_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import pynamodb.constants
from pynamodb.attributes import Attribute

T = TypeVar('T', bound=Enum)
T = TypeVar("T", bound=Enum)
_fail: Any = object()


Expand All @@ -28,17 +28,22 @@ class UnicodeEnumAttribute(Attribute[T]):
>>> class Shake(Model):
>>> flavor = UnicodeEnumAttribute(ShakeFlavor)
"""

attr_type = pynamodb.constants.STRING

def __init__(self, enum_type: Type[T], unknown_value: Optional[T] = _fail, **kwargs: Any) -> None:
def __init__(
self, enum_type: Type[T], unknown_value: Optional[T] = _fail, **kwargs: Any
) -> None:
"""
:param enum_type: The type of the enum
"""
super().__init__(**kwargs)
self.enum_type = enum_type
self.unknown_value = unknown_value
if not all(isinstance(e.value, str) for e in self.enum_type):
raise TypeError(f"Enumeration '{self.enum_type}' values must be all strings")
raise TypeError(
f"Enumeration '{self.enum_type}' values must be all strings",
)

def deserialize(self, value: str) -> Optional[T]:
try:
Expand All @@ -50,5 +55,7 @@ def deserialize(self, value: str) -> Optional[T]:

def serialize(self, value: T) -> str:
if not isinstance(value, self.enum_type):
raise TypeError(f"value has invalid type '{type(value)}'; expected '{self.enum_type}'")
raise TypeError(
f"value has invalid type '{type(value)}'; expected '{self.enum_type}'",
)
return value.value
2 changes: 1 addition & 1 deletion pynamodb_attributes/uuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def serialize(self, value: UUID) -> str:
result = str(value)

if self._remove_dashes:
result = result.replace('-', '')
result = result.replace("-", "")

return result

Expand Down
18 changes: 9 additions & 9 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
from setuptools import setup

setup(
name='pynamodb-attributes',
version='0.3.0',
description='Common attributes for PynamoDB',
url='https://www.github.com/lyft/pynamodb-attributes',
maintainer='Lyft',
maintainer_email='[email protected]',
packages=find_packages(exclude=['tests*']),
name="pynamodb-attributes",
version="0.3.0",
description="Common attributes for PynamoDB",
url="https://www.github.com/lyft/pynamodb-attributes",
maintainer="Lyft",
maintainer_email="[email protected]",
packages=find_packages(exclude=["tests*"]),
dependency_links=[],
install_requires=[
"pynamodb>=5.0.0",
],
python_requires='>=3',
package_data={'pynamodb_attributes': ['py.typed']},
python_requires=">=3",
package_data={"pynamodb_attributes": ["py.typed"]},
)
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
@pytest.fixture
def uuid_key():
from uuid import uuid4

return str(uuid4())
6 changes: 3 additions & 3 deletions tests/float_attribute_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class MyModel(Model):
value = FloatAttribute(null=True)


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

Expand All @@ -27,7 +27,7 @@ def test_serialization_non_null(uuid_key):

# verify underlying storage
item = _connection(MyModel).get_item(uuid_key)
assert item['Item']['value'] == {'N': '45.6'}
assert item["Item"]["value"] == {"N": "45.6"}

# verify deserialization
model = MyModel.get(uuid_key)
Expand All @@ -42,7 +42,7 @@ def test_serialization_null(uuid_key):

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

# verify deserialization
model = MyModel.get(uuid_key)
Expand Down
6 changes: 3 additions & 3 deletions tests/integer_attribute_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class MyModel(Model):
value = IntegerAttribute(null=True)


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

Expand All @@ -27,7 +27,7 @@ def test_serialization_non_null(uuid_key):

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

# verify deserialization
model = MyModel.get(uuid_key)
Expand All @@ -42,7 +42,7 @@ def test_serialization_null(uuid_key):

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

# verify deserialization
model = MyModel.get(uuid_key)
Expand Down
Loading

0 comments on commit a6f8823

Please sign in to comment.