Skip to content

Commit

Permalink
strict type checking (#539)
Browse files Browse the repository at this point in the history
  • Loading branch information
ITProKyle committed Feb 25, 2021
1 parent 9b05207 commit fc75595
Show file tree
Hide file tree
Showing 532 changed files with 23,696 additions and 1,243 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Expand Up @@ -117,7 +117,7 @@
"xtrace"
],
"files.insertFinalNewline": true,
"python.analysis.typeCheckingMode": "basic",
"python.analysis.typeCheckingMode": "strict",
"python.formatting.provider": "black",
"python.linting.flake8Args": [
"--docstring-convention=all"
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -76,7 +76,7 @@ lint-isort: ## run isort

lint-pylint: ## run pylint
@echo "Running pylint..."
@find runway -name '*.py' -not -path 'runway/embedded*' -not -path 'runway/templates/stacker/*' -not -path 'runway/templates/cdk-py/*' -not -path 'runway/blueprints/*' | xargs pipenv run pylint --rcfile=pyproject.toml
@find runway -name '*.py' -not -path 'runway/templates/cdk-py/*' | xargs pipenv run pylint --rcfile=pyproject.toml
@echo ""

lint-pyright:
Expand Down
8 changes: 4 additions & 4 deletions Pipfile
Expand Up @@ -21,16 +21,16 @@ flake8-docstrings = "~=1.5.0"
pep8-naming = "~=0.11"
pydocstyle = "~=5.0.2"
# Typing
boto3-stubs = {extras = ["acm", "awslambda", "cloudformation", "cognito-idp", "dynamodb", "ec2", "ecr", "ecs", "iam", "kms", "route53", "s3", "ssm", "sts"],version = "*"}
boto3-stubs = {extras = ["acm", "awslambda", "cloudformation", "cloudfront", "cognito-idp", "dynamodb", "ec2", "ecr", "ecs", "iam", "kms", "route53", "s3", "ssm", "sts"],version = "*"}
mypy-boto3 = "*"
# Test
coverage = {extras = ["toml"],version = "~=5.2.1"}
mock = "~=4.0.2"
moto = "~=1.3"
pytest = "~=6.0.1"
pytest-cov = "~=2.10.1"
pytest = "~=6.2"
pytest-cov = "~=2.10"
pytest-mock = "~=3.5"
pytest-subprocess = "~=1.0.0"
pytest-subprocess = "~=1.0"
pytest-sugar = "*"
testfixtures = "~=4.10.0"
# Build
Expand Down
535 changes: 283 additions & 252 deletions Pipfile.lock

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -59,6 +59,6 @@
"access": "public"
},
"devDependencies": {
"pyright": "^1.1.99"
"pyright": "1.1.112"
}
}
12 changes: 5 additions & 7 deletions pyrightconfig.json
Expand Up @@ -10,28 +10,26 @@
"**/docs",
"**/node_modules",
"**/typings",
"**/infrastructure",
"**/integration_test_infrastructure",
"**/integration_tests",
"**/npm",
"**/runway/aws_sso_botocore",
"**/runway/cfngin/commands",
"**/runway/hooks/staticsite/auth_at_edge/templates",
"**/runway/templates",
"**/runway/templates/cdk-py",
"**/scripts"
],
"pythonVersion": "3.8",
"reportDuplicateImport": "none",
"reportImportCycles": "none",
"reportIncompatibleMethodOverride": "warning",
"reportMissingTypeStubs": "none",
"reportPrivateUsage": "none",
"reportUnknownMemberType": "none",
"reportUntypedClassDecorator": "none",
"reportUntypedFunctionDecorator": "none",
"reportUnnecessaryIsInstance": "warning",
"reportUnusedImport": "none",
"reportUnusedVariable": "none",
"reportWildcardImportFromLibrary": "none",
"typeCheckingMode": "basic",
"strictParameterNoneValue": false,
"typeCheckingMode": "strict",
"useLibraryCodeForTypes": true,
"venv": ".venv"
}
4 changes: 2 additions & 2 deletions runway/_cli/commands/_run_aws.py
@@ -1,7 +1,7 @@
"""``runway run-aws`` command."""
# docs: file://./../../../docs/source/commands.rst
import logging
from typing import Any, Tuple
from typing import Any, Tuple, cast

import click
from awscli.clidriver import create_clidriver
Expand Down Expand Up @@ -36,4 +36,4 @@ def run_aws(ctx: click.Context, args: Tuple[str, ...], **_: Any) -> None:
if name.startswith("awscli.") and isinstance(logger, logging.Logger):
logger.setLevel(logging.ERROR)
with SafeHaven(environ={"LC_CTYPE": "en_US.UTF"}):
ctx.exit(create_clidriver().main(list(args)))
ctx.exit(cast(int, create_clidriver().main(list(args))))
5 changes: 4 additions & 1 deletion runway/_cli/main.py
Expand Up @@ -14,7 +14,10 @@

LOGGER = logging.getLogger("runway.cli")

CLICK_CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"], max_content_width=999)
CLICK_CONTEXT_SETTINGS: Dict[str, Any] = {
"help_option_names": ["-h", "--help"],
"max_content_width": 999,
}


class _CliGroup(click.Group):
Expand Down
3 changes: 1 addition & 2 deletions runway/_cli/utils.py
Expand Up @@ -4,7 +4,6 @@
import logging
import os
import sys
from collections.abc import MutableMapping
from pathlib import Path
from typing import Any, Iterator, List, Optional, Tuple

Expand All @@ -24,7 +23,7 @@
LOGGER = logging.getLogger(__name__)


class CliContext(MutableMapping):
class CliContext:
"""CLI context object."""

def __init__(
Expand Down
6 changes: 3 additions & 3 deletions runway/_logging.py
@@ -1,7 +1,7 @@
"""Runway logging."""
import logging
from enum import IntEnum
from typing import Any, Dict, Text, Tuple, Union
from typing import Any, MutableMapping, Text, Tuple, Union


class LogLevels(IntEnum):
Expand Down Expand Up @@ -62,8 +62,8 @@ def notice(self, msg: Union[Exception, str], *args: Any, **kwargs: Any) -> None:
self.log(LogLevels.NOTICE, msg, *args, **kwargs)

def process(
self, msg: Union[Exception, str], kwargs: Dict[str, Any]
) -> Tuple[str, Dict[str, Any]]:
self, msg: Union[Exception, str], kwargs: MutableMapping[str, Any]
) -> Tuple[str, MutableMapping[str, Any]]:
"""Process the message to append the prefix.
Args:
Expand Down
2 changes: 1 addition & 1 deletion runway/blueprints/k8s/k8s_master.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""Module with k8s cluster resources."""
import awacs.iam
from awacs.aws import StringLike # type: ignore # pylint: disable=no-name-in-module
from awacs.aws import StringLike # pylint: disable=no-name-in-module
from awacs.aws import Allow, Condition, PolicyDocument, Statement
from awacs.helpers.trust import make_simple_assume_policy
from troposphere import Export, Join, Output, Sub, ec2, eks, iam
Expand Down
7 changes: 4 additions & 3 deletions runway/blueprints/staticsite/auth_at_edge.py
Expand Up @@ -17,7 +17,7 @@
from .staticsite import StaticSite

if TYPE_CHECKING:
from ...cfngin.blueprints.base import BlueprintVariable
from ...cfngin.blueprints.type_defs import BlueprintVariableTypeDef
from ...context.cfngin import CfnginContext

LOGGER = logging.getLogger("runway")
Expand All @@ -26,7 +26,7 @@
class AuthAtEdge(StaticSite):
"""Auth@Edge Blueprint."""

AUTH_VARIABLES: Dict[str, BlueprintVariable] = {
AUTH_VARIABLES: Dict[str, BlueprintVariableTypeDef] = {
"OAuthScopes": {"type": list, "default": [], "description": "OAuth2 Scopes"},
"PriceClass": {
"type": str,
Expand Down Expand Up @@ -58,7 +58,7 @@ class AuthAtEdge(StaticSite):
},
}
IAM_ARN_PREFIX = "arn:aws:iam::aws:policy/service-role/"
VARIABLES: Dict[str, BlueprintVariable] = {}
VARIABLES: Dict[str, BlueprintVariableTypeDef] = {}

def __init__(
self,
Expand Down Expand Up @@ -378,6 +378,7 @@ def _get_error_responses(self) -> List[cloudfront.CustomErrorResponse]:
)
]

# pyright: reportIncompatibleMethodOverride=none
def _get_cloudfront_bucket_policy_statements(
self, bucket: s3.Bucket, oai: cloudfront.CloudFrontOriginAccessIdentity
) -> List[Statement]:
Expand Down
4 changes: 2 additions & 2 deletions runway/blueprints/staticsite/staticsite.py
Expand Up @@ -36,7 +36,7 @@
if TYPE_CHECKING:
from troposphere import Ref # pylint: disable=ungrouped-imports

from ...cfngin.blueprints.base import BlueprintVariable
from ...cfngin.blueprints.type_defs import BlueprintVariableTypeDef

LOGGER = logging.getLogger("runway")

Expand All @@ -53,7 +53,7 @@ class _IndexRewriteFunctionInfoTypeDef(TypedDict, total=False):
class StaticSite(Blueprint):
"""CFNgin blueprint for creating S3 bucket and CloudFront distribution."""

VARIABLES: Dict[str, BlueprintVariable] = {
VARIABLES: Dict[str, BlueprintVariableTypeDef] = {
"AcmCertificateArn": {
"type": str,
"default": "",
Expand Down
30 changes: 22 additions & 8 deletions runway/cfngin/actions/base.py
Expand Up @@ -5,7 +5,7 @@
import os
import sys
import threading
from typing import TYPE_CHECKING, Any, Callable, Optional
from typing import TYPE_CHECKING, Any, Callable, Optional, Union

import botocore.exceptions

Expand Down Expand Up @@ -143,18 +143,19 @@ def provider(self) -> Provider:
Used for running things like hooks.
"""
if not self.provider_builder:
raise ValueError("ProviderBuilder required to build a provider")
return self.provider_builder.build()

def build_provider(self, stack: Stack) -> Provider:
"""Build a :class:`runway.cfngin.providers.base.BaseProvider`.
"""Build a CFNgin provider.
Args:
stack: Stack the action will be executed on.
Returns:
Suitable for operating on the given :class:`runway.cfngin.stack.Stack`.
"""
if not self.provider_builder:
raise ValueError("ProviderBuilder required to build a provider")
return self.provider_builder.build(region=stack.region, profile=stack.profile)

def ensure_cfn_bucket(self) -> None:
Expand All @@ -172,13 +173,26 @@ def execute(self, **kwargs: Any) -> None:
LOGGER.error(str(err))
sys.exit(1)

def pre_run(self, **_: Any) -> None:
def pre_run(
self, *, dump: Union[bool, str] = False, outline: bool = False, **__kwargs: Any
) -> None:
"""Perform steps before running the action."""

def post_run(self, **_: Any) -> None:
def post_run(
self, *, dump: Union[bool, str] = False, outline: bool = False, **__kwargs: Any
) -> None:
"""Perform steps after running the action."""

def run(self, *_args: Any, **_kwargs: Any) -> None:
def run(
self,
*,
concurrency: int = 0,
dump: Union[bool, str] = False,
force: bool = False,
outline: bool = False,
tail: bool = False,
**_kwargs: Any
) -> None:
"""Abstract method for running the action."""
raise NotImplementedError('Subclass must implement "run" method')

Expand Down
7 changes: 4 additions & 3 deletions runway/cfngin/actions/build.py
Expand Up @@ -371,7 +371,7 @@ def _launch_stack( # pylint: disable=R
# a successful update.
elif provider.is_stack_failed(provider_stack):
reason = status.reason
if "rolling" in reason:
if reason and "rolling" in reason:
reason = reason.replace("rolling", "rolled")
status_reason = provider.get_rollback_status_reason(stack.fqn)
LOGGER.info("%s:roll back reason: %s", stack.fqn, status_reason)
Expand Down Expand Up @@ -534,14 +534,15 @@ def pre_run( # pylint: disable=arguments-differ
outline=outline,
)

def run( # pylint: disable=arguments-differ
def run(
self,
*,
concurrency: int = 0,
dump: Union[bool, str] = False,
force: bool = False, # pylint: disable=unused-argument
outline: bool = False,
tail: bool = False,
**_: Any
**_kwargs: Any
) -> None:
"""Kicks off the build/update of the stacks in the stack_definitions.
Expand Down
31 changes: 24 additions & 7 deletions runway/cfngin/actions/destroy.py
Expand Up @@ -2,7 +2,7 @@
from __future__ import annotations

import logging
from typing import TYPE_CHECKING, Any, Callable, Optional
from typing import TYPE_CHECKING, Any, Callable, Optional, Union

from ..exceptions import StackDoesNotExist
from ..hooks.utils import handle_hooks
Expand Down Expand Up @@ -75,19 +75,32 @@ def _destroy_stack(
provider.destroy_stack(provider_stack)
return DESTROYING_STATUS

def pre_run(self, **kwargs):
def pre_run(
self,
*,
dump: Union[bool, str] = False, # pylint: disable=unused-argument
outline: bool = False,
**__kwargs: Any
) -> None:
"""Any steps that need to be taken prior to running the action."""
pre_destroy = self.context.config.pre_destroy
if not kwargs.get("outline") and pre_destroy:
if not outline and pre_destroy:
handle_hooks(
stage="pre_destroy",
hooks=pre_destroy,
provider=self.provider,
context=self.context,
)

def run( # pylint: disable=arguments-differ
self, *, concurrency: int = 0, force: bool = False, tail: bool = False, **_: Any
def run(
self,
*,
concurrency: int = 0,
dump: Union[bool, str] = False, # pylint: disable=unused-argument
force: bool = False,
outline: bool = False, # pylint: disable=unused-argument
tail: bool = False,
**_kwargs: Any
) -> None:
"""Kicks off the destruction of the stacks in the stack_definitions."""
plan = self._generate_plan(
Expand All @@ -108,8 +121,12 @@ def run( # pylint: disable=arguments-differ
else:
plan.outline(message='To execute this plan, run with --force" flag.')

def post_run( # pylint: disable=arguments-differ
self, *, outline: bool = False, **_: Any
def post_run(
self,
*,
dump: Union[bool, str] = False, # pylint: disable=unused-argument
outline: bool = False,
**__kwargs: Any
) -> None:
"""Any steps that need to be taken after running the action."""
if not outline and self.context.config.post_destroy:
Expand Down

0 comments on commit fc75595

Please sign in to comment.