Skip to content
Merged
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
3 changes: 3 additions & 0 deletions packages/aws-event-stream/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ build-backend = "hatchling.build"
exclude = [
"tests",
]

[tool.ruff]
src = ["src"]
45 changes: 26 additions & 19 deletions packages/aws-event-stream/src/aws_event_stream/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from dataclasses import dataclass
from io import BytesIO
from struct import pack, unpack
from types import MappingProxyType
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL

from typing import Literal, Self

from smithy_core.aio.interfaces import AsyncByteStream
Expand Down Expand Up @@ -610,11 +611,13 @@ class _DecodeUtils:
INT64_BYTE_FORMAT = "!q"

# uint byte size to unpack format
UINT_BYTE_FORMAT: dict[_ArraySize, str] = {
1: UINT8_BYTE_FORMAT,
2: UINT16_BYTE_FORMAT,
4: UINT32_BYTE_FORMAT,
}
UINT_BYTE_FORMAT: Mapping[_ArraySize, str] = MappingProxyType(
{
1: UINT8_BYTE_FORMAT,
2: UINT16_BYTE_FORMAT,
4: UINT32_BYTE_FORMAT,
}
)

@staticmethod
def unpack_uint8(data: BytesLike) -> tuple[int, int]:
Expand Down Expand Up @@ -749,20 +752,24 @@ class EventHeaderDecoder(Iterator[tuple[str, HEADER_VALUE]]):

# Maps header type to appropriate unpacking function
# These unpacking functions return the value and the amount unpacked
_HEADER_TYPE_MAP: dict[int, Callable[[BytesLike], tuple[HEADER_VALUE, int]]] = {
# Boolean headers have no data bytes following the type signifier, so they
# can just return static values.
0: lambda b: (True, 0), # boolean_true
1: lambda b: (False, 0), # boolean_false
2: _DecodeUtils.unpack_int8, # byte
3: _DecodeUtils.unpack_int16, # short
4: _DecodeUtils.unpack_int32, # integer
5: _DecodeUtils.unpack_int64, # long
6: _DecodeUtils.unpack_byte_array, # byte_array
7: _DecodeUtils.unpack_utf8_string, # string
8: _DecodeUtils.unpack_timestamp, # timestamp
9: _DecodeUtils.unpack_uuid, # uuid
}
_HEADER_TYPE_MAP: Mapping[int, Callable[[BytesLike], tuple[HEADER_VALUE, int]]] = (
MappingProxyType(
{
# Boolean headers have no data bytes following the type signifier, so they
# can just return static values.
0: lambda b: (True, 0), # boolean_true
1: lambda b: (False, 0), # boolean_false
2: _DecodeUtils.unpack_int8, # byte
3: _DecodeUtils.unpack_int16, # short
4: _DecodeUtils.unpack_int32, # integer
5: _DecodeUtils.unpack_int64, # long
6: _DecodeUtils.unpack_byte_array, # byte_array
7: _DecodeUtils.unpack_utf8_string, # string
8: _DecodeUtils.unpack_timestamp, # timestamp
9: _DecodeUtils.unpack_uuid, # uuid
}
)
)

def __init__(self, header_bytes: BytesLike) -> None:
"""Initialize an event header decoder.
Expand Down
3 changes: 3 additions & 0 deletions packages/smithy-aws-core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@ build-backend = "hatchling.build"
exclude = [
"tests",
]

[tool.ruff]
src = ["src"]
3 changes: 3 additions & 0 deletions packages/smithy-core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ build-backend = "hatchling.build"
exclude = [
"tests",
]

[tool.ruff]
src = ["src"]
2 changes: 1 addition & 1 deletion packages/smithy-core/src/smithy_core/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ def _wrap_map(self, value: Mapping[str, DocumentValue]) -> dict[str, "Document"]
member_schema = self._schema.members["value"]
return {k: self._new_document(v, member_schema) for k, v in value.items()}

result: dict[str, "Document"] = {}
result: dict[str, Document] = {}
for k, v in value.items():
result[k] = self._new_document(v, self._schema.members[k])
return result
Expand Down
4 changes: 2 additions & 2 deletions packages/smithy-core/src/smithy_core/identity.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
from datetime import datetime, timezone
from datetime import UTC, datetime

from .interfaces import identity as identity_interface
from .utils import ensure_utc
Expand Down Expand Up @@ -28,4 +28,4 @@ def is_expired(self) -> bool:
"""Whether the identity is expired."""
if self.expiration is None:
return False
return datetime.now(tz=timezone.utc) >= self.expiration
return datetime.now(tz=UTC) >= self.expiration
12 changes: 0 additions & 12 deletions packages/smithy-core/src/smithy_core/interceptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ def read_before_execution(
the `response`. If multiple `read_before_execution` methods throw exceptions,
the latest will be used and earlier ones will be logged and dropped.
"""
pass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these be raising NotImplementedError rather than just passing? Having the functions be no-ops seems odd.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They very specifically need to be no-ops. The usage is something like

for interceptor in interceptors:
    interceptor.read_before_execution(...)

But not every implementation will implement all of these hooks. So if we had them throwing not implemented then we'd have to catch and ignore that, adding a bunch of useless thrashing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this explicitly be return None then as a default if we're not expecting all of these to be implemented? Having a completely bare function is abnormal.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently this has already been a hotly debated topic that ruff has taken an opinionated stance on. It feels weird, but we can go with it if people feel strongly about it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah iirc there are some that prefer pass some that prefer ... and so on. Functions have to have some sort of statement to be valid, but that statement can be the doc string. I really don't care so long as it doesn't impact performance.


def modify_before_serialization(
self, context: InterceptorContext[Request, None, None, None]
Expand Down Expand Up @@ -193,7 +192,6 @@ def read_before_serialization(
If exceptions are thrown by this hook, execution will jump to
`modify_before_completion` with the thrown exception as the `response`.
"""
pass

def read_after_serialization(
self, context: InterceptorContext[Request, None, TransportRequest, None]
Expand All @@ -214,7 +212,6 @@ def read_after_serialization(
If exceptions are thrown by this hook, execution will jump to
`modify_before_completion` with the thrown exception as the `response`.
"""
pass

def modify_before_retry_loop(
self, context: InterceptorContext[Request, None, TransportRequest, None]
Expand Down Expand Up @@ -259,7 +256,6 @@ def read_before_attempt(
exception as the `response` If multiple `read_before_attempt` methods throw
exceptions, the latest will be used and earlier ones will be logged and dropped.
"""
pass

def modify_before_signing(
self, context: InterceptorContext[Request, None, TransportRequest, None]
Expand Down Expand Up @@ -309,7 +305,6 @@ def read_before_signing(
If exceptions are thrown by this hook, execution will jump to
`modify_before_attempt_completion` with the thrown exception as the `response`.
"""
pass

def read_after_signing(
self, context: InterceptorContext[Request, None, TransportRequest, None]
Expand All @@ -333,7 +328,6 @@ def read_after_signing(
If exceptions are thrown by this hook, execution will jump to
`modify_before_attempt_completion` with the thrown exception as the `response`.
"""
pass

def modify_before_transmit(
self, context: InterceptorContext[Request, None, TransportRequest, None]
Expand Down Expand Up @@ -384,7 +378,6 @@ def read_before_transmit(
If exceptions are thrown by this hook, execution will jump to
`modify_before_attempt_completion` with the thrown exception as the `response`.
"""
pass

def read_after_transmit(
self,
Expand All @@ -411,7 +404,6 @@ def read_after_transmit(
If exceptions are thrown by this hook, execution will jump to
`modify_before_attempt_completion` with the thrown exception as the `response`.
"""
pass

def modify_before_deserialization(
self,
Expand Down Expand Up @@ -467,7 +459,6 @@ def read_before_deserialization(
If exceptions are thrown by this hook, execution will jump to
`modify_before_attempt_completion` with the thrown exception as the `response`.
"""
pass

def read_after_deserialization(
self,
Expand Down Expand Up @@ -495,7 +486,6 @@ def read_after_deserialization(
If exceptions are thrown by this hook, execution will jump to
`modify_before_attempt_completion` with the thrown exception as the `response`.
"""
pass

def modify_before_attempt_completion(
self,
Expand Down Expand Up @@ -554,7 +544,6 @@ def read_after_attempt(
execution will then jump to `read_before_attempt`. Otherwise, execution will
jump to `modify_before_completion` with the thrown exception as the `response`.
"""
pass

def modify_before_completion(
self,
Expand Down Expand Up @@ -605,4 +594,3 @@ def read_after_execution(
final response. If multiple `read_after_execution` methods throw exceptions,
the latest will be used and earlier ones will be logged and dropped.
"""
pass
2 changes: 0 additions & 2 deletions packages/smithy-core/src/smithy_core/interfaces/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ def is_expired(self) -> bool:
class IdentityProperties(TypedDict):
"""Properties used to help determine the identity to return."""

...


IdentityPropertiesType = TypeVar("IdentityPropertiesType", bound=IdentityProperties)
IdentityPropertiesType_contra = TypeVar(
Expand Down
1 change: 0 additions & 1 deletion packages/smithy-core/src/smithy_core/retries.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,4 +242,3 @@ def refresh_retry_token_for_retry(

def record_success(self, *, token: retries_interface.RetryToken) -> None:
"""Not used by this retry strategy."""
pass
8 changes: 4 additions & 4 deletions packages/smithy-core/src/smithy_core/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ def __init__(
if any(_member_props) and not all(_member_props):
raise SmithyException(
"If any member property is set, all member properties must be set. "
f"member_name: {repr(id.member)}, member_target: "
f"{repr(member_target)}, member_index: {repr(member_index)}"
f"member_name: {id.member!r}, member_target: "
f"{member_target!r}, member_index: {member_index!r}"
)

# setattr is required because the class is frozen
Expand All @@ -67,7 +67,7 @@ def __init__(

if members:
if isinstance(members, list):
m: dict[str, "Schema"] = {}
m: dict[str, Schema] = {}
for member in members:
m[member.expect_member_name()] = member
members = m
Expand Down Expand Up @@ -140,7 +140,7 @@ def collection(
constructor, this is a dict of member names to a simplified dict containing
only ``traits`` and a ``target``. Member schemas will be generated from this.
"""
struct_members: dict[str, "Schema"] = {}
struct_members: dict[str, Schema] = {}
if members:
for k in members.keys():
struct_members[k] = cls.member(
Expand Down
4 changes: 2 additions & 2 deletions packages/smithy-core/src/smithy_core/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from datetime import datetime
from email.utils import format_datetime, parsedate_to_datetime
from enum import Enum
from typing import Any, TypeAlias
from typing import Any

from .exceptions import ExpectationNotMetException
from .utils import (
Expand All @@ -16,7 +16,7 @@
serialize_rfc3339,
)

Document: TypeAlias = (
type Document = (
Copy link
Contributor

@JordonPhillips JordonPhillips Feb 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot this was still here - probably needs to be deleted (that can be done later)

Mapping[str, "Document"] | Sequence["Document"] | str | int | float | bool | None
)

Expand Down
10 changes: 5 additions & 5 deletions packages/smithy-core/src/smithy_core/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
import re
from datetime import datetime, timedelta, timezone
from datetime import UTC, datetime, timedelta
from decimal import Decimal
from math import isinf, isnan
from types import UnionType
Expand All @@ -24,9 +24,9 @@ def ensure_utc(value: datetime) -> datetime:
:returns: A UTC timezone-aware equivalent datetime.
"""
if value.tzinfo is None:
return value.replace(tzinfo=timezone.utc)
return value.replace(tzinfo=UTC)
else:
return value.astimezone(timezone.utc)
return value.astimezone(UTC)


# Python is way more permissive on value of non-numerical floats than Smithy is, so we
Expand Down Expand Up @@ -61,9 +61,9 @@ def epoch_seconds_to_datetime(value: int | float) -> datetime:
to years from 1970 through 2038." This affects 32-bit systems.
"""
try:
return datetime.fromtimestamp(value, tz=timezone.utc)
return datetime.fromtimestamp(value, tz=UTC)
except OverflowError:
epoch_zero = datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
epoch_zero = datetime(1970, 1, 1, 0, 0, 0, tzinfo=UTC)
return epoch_zero + timedelta(seconds=value)


Expand Down
12 changes: 6 additions & 6 deletions packages/smithy-core/tests/unit/test_identity.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
from datetime import datetime, timedelta, timezone
from datetime import UTC, datetime, timedelta, timezone

import pytest
from freezegun import freeze_time
Expand All @@ -14,7 +14,7 @@
None,
timezone(timedelta(hours=3)),
timezone(timedelta(hours=-3)),
timezone.utc,
UTC,
timezone(timedelta(hours=0)),
timezone(timedelta(hours=0, minutes=30)),
timezone(timedelta(hours=0, minutes=-30)),
Expand All @@ -24,28 +24,28 @@ def test_expiration_timezone(time_zone: timezone) -> None:
expiration = datetime.now(tz=time_zone)
identity = Identity(expiration=expiration)
assert identity.expiration is not None
assert identity.expiration.tzinfo == timezone.utc
assert identity.expiration.tzinfo == UTC


@pytest.mark.parametrize(
"identity, expected_expired",
[
(
Identity(
expiration=datetime(year=2023, month=1, day=1, tzinfo=timezone.utc),
expiration=datetime(year=2023, month=1, day=1, tzinfo=UTC),
),
True,
),
(Identity(), False),
(
Identity(
expiration=datetime(year=2023, month=1, day=2, tzinfo=timezone.utc),
expiration=datetime(year=2023, month=1, day=2, tzinfo=UTC),
),
False,
),
(
Identity(
expiration=datetime(year=2022, month=12, day=31, tzinfo=timezone.utc),
expiration=datetime(year=2022, month=12, day=31, tzinfo=UTC),
),
True,
),
Expand Down
2 changes: 0 additions & 2 deletions packages/smithy-core/tests/unit/test_retries.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ def test_exponential_backoff_strategy(

for delay_index, delay_expected in enumerate(expected_delays):
delay_actual = bos.compute_next_backoff_delay(retry_attempt=delay_index)
delay_expected2 = delay_expected
print(f"{delay_index=} {delay_actual=} {delay_expected2=}")
assert delay_actual == pytest.approx(delay_expected) # type: ignore


Expand Down
Loading
Loading