8000 Use `StrEnums` instead of `str` for generated constant classes in the ASF APIs by dfangl · Pull Request #11176 · localstack/localstack · GitHub
[go: up one dir, main page]

Skip to content

Use StrEnums instead of str for generated constant classes in the ASF APIs #11176

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 11, 2024

Conversation

dfangl
Copy link
Member
@dfangl dfangl commented Jul 10, 2024

Motivation

Currently, the scaffolding currently translates the StringShapes from the botocore specs to enum string classes, for example:

class Architecture(str):
    x86_64 = "x86_64"
    arm64 = "arm64"

The issue here, from a type checking perspective, is that the values, for example Architecture.x86_64, are not of type Architecture, they are simple strings:

from localstack.aws.api.lambda_ import Architecture

print(isinstance(Architecture.x86_64, Architecture))
print(isinstance(Architecture.x86_64, str))

for example, returns:

False
True

This is not really an issue for production - they are strings, and the exact type does not really matter after it is serialized anyway. However, when developing, we are hit with fun IDE warnings and mypy also reports it as an error:

def test(param: Architecture):
    pass


test(Architecture.arm64)

Mypy error:

mypy test.py
test.py:14: error: Argument 1 to "test" has incompatible type "str"; expected "Architecture"  [arg-type]
Found 1 error in 1 file (checked 1 source file)

My proposed solution would be to switch those types to StrEnum, a new type of enum introduced with python3.11 (https://docs.python.org/3/library/enum.html#enum.StrEnum). It is only applicable for code not used by the CLI, but our API scaffolds should not be imported from the CLI.

A StrEnum is both an instance of str and enum, and more importantly, the members are also a type of the respective class.
Also, the dunder str and repr methods are those of string, therefore it should be interchangable (we will see how the testing of this PR works out).

Changes

  • Use StrEnum instead of str for generated API StringShapes, which will lead to correct types for the enum members.

@dfangl dfangl added the semver: patch Non-breaking changes which can be included in patch releases label Jul 10, 2024
@dfangl dfangl self-assigned this Jul 10, 2024
@dfangl dfangl requested a review from alexrashed July 10, 2024 16:43
@@ -315,10 +315,11 @@ def get_order(self):


def generate_service_types(output, service: ServiceModel, doc=True):
output.write("from datetime import datetime\n")
Copy link
Member Author

Choose a reason for hiding this comment

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

I moved this line so it has the right order from the beginning. I know our formatting will reorder it anyway, but why should it need to :P

Copy link
github-actions bot commented Jul 11, 2024

S3 Image Test Results (AMD64 / ARM64)

  2 files  ±0    2 suites  ±0   3m 21s ⏱️ -10s
404 tests ±0  352 ✅ ±0   52 💤 ±0  0 ❌ ±0 
808 runs  ±0  704 ✅ ±0  104 💤 ±0  0 ❌ ±0 

Results for commit b0071ad. ± Comparison against base commit 70af8d0.

♻️ This comment has been updated with latest results.

Copy link

LocalStack Community integration with Pro

    2 files  ±0      2 suites  ±0   1h 32m 54s ⏱️ - 2m 29s
3 179 tests ±0  2 784 ✅ ±0  395 💤 ±0  0 ❌ ±0 
3 181 runs  ±0  2 784 ✅ ±0  397 💤 ±0  0 ❌ ±0 

Results for commit b0071ad. ± Comparison against base commit 70af8d0.

Comment on lines +520 to +521
def get_class_attrs_from_spec_class(spec_class: type[StrEnum]) -> set[str]:
return {str(spec) for spec in spec_class}
Copy link
Member Author

Choose a reason for hiding this comment

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

This is the only actual code change necessary, which iterates over the classes, now an enum.

Copy link
Member
@alexrashed alexrashed left a comment

Choose a reason for hiding this comment

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

Nice change and really well explained! The stronger the typing the better! 💯
The changes are looking good, they update the scaffold, update all generated APIs, as well as a single issue with the usage of the generated code. 🏅

@dfangl dfangl merged commit b58b0f8 into master Jul 11, 2024
39 checks passed
@dfangl dfangl deleted the scaffold/str-enums branch July 11, 2024 11:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver: patch Non-breaking changes which can be included in patch releases
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0