I have questions about using `mypy` Code 1: How ca...
# python
g
I have questions about using
mypy
Code 1: How can I cast or at least tell that output is a type
Ouput[str]
and not
Output[any]
?
Copy code
r53_zone = aws.route53.get_zone(zone_id=SHARED_STACK_REF.require_output('hosted_zone_id'))
mypy output
Copy code
Argument "zone_id" to "get_zone" has incompatible type "Output[Any]"; expected "Optional[str]"
Code 2 Why do I get an error and how to prevent that? It looks like that
profile
attribute is dynamically created, correct?
Copy code
ec1_provider = aws.Provider(
    f"{PREFIX}-{ec1_region}", profile=aws.config.profile, region=ec1_region
)
mypy output:
Copy code
__main__.py:27: error: Module has no attribute "profile"
p
First, let’s talk about python-specific things. What options you have: • explicitly cast a variable using `cast`: https://docs.python.org/3/library/typing.html#typing.cast (suggested in this case) • ignoring type so
mypy
doesn’t complain using
# type: ignore
comment (I’d use it as a last resort) • fix the code so it actually returns the expected types (ideal but the hardest one)
If we were to fix the code, I’d require to either extend
pulumi.StackReference
class or create some helper methods yourself that does type assertions (
get_string_output(stack_ref: pulumi.StackReference, name: pulumi.Input[str]) -> pulumi.Output[str]
). Another problem might be AWS provider that expects
Optional[str]
instead of
Input[str]
.
Regarding your second question (about
profile
), I’d have to take a look but if the following code works, you might be right.
Although I’m not sure the mypy error is related to this part 🤔 . I’ve created a similar code in my project and it works as expected (
profile
is declared as
Optional[pulumi.Input[str]]
so it shouldn’t cause any issues).
EDIT: Ok, there is some “magic” in
aws.config
I guess.
well, it doesn’t look pretty to me - it actually overrides the modules so when you load it, you’re gonna get a class instead (kinda)
You can workaround this by declaring a helper variable like:
Copy code
aws_config: aws.config.vars._ExportableConfig = typing.cast(aws.config, aws.config.vars._ExportableConfig)
and instead of:
Copy code
aws.config.profile
you could use:
Copy code
aws_config.profile
Still, it doesn’t look good IMO 😐
If I’d like to have zero mypy warning, I’d declare helper function:
Copy code
def aws_profile() -> str:
  return aws.config.profile  # type: ignore
and use it that instead of directly accessing
aws.config
object