Skip to content

Commit

Permalink
Merge pull request #207 from JonathonReinhart/add-typing
Browse files Browse the repository at this point in the history
Add type annotations
  • Loading branch information
JonathonReinhart authored Apr 23, 2023
2 parents 8edd4d1 + 948e7e6 commit b086413
Show file tree
Hide file tree
Showing 13 changed files with 424 additions and 290 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ jobs:
ci/test_setup.sh
- name: Lint
run: |
mypy
- name: Build
run: |
python -m build
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
### Changed
- Introduced `pyproject.toml` and moved metadata from `setup.py` (#211)
- Added type annotations to scuba package and mypy checking in CI (#207)

### Removed
- Drop support for Python 3.5 - 3.6
Expand Down
13 changes: 13 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,16 @@ requires = [
"wheel",
"setuptools >= 42.0.0",
]


# mypy
[tool.mypy]
packages = ["scuba", "tests"]
warn_unused_configs = true
warn_return_any = true

[[tool.mypy.overrides]]
module = "scuba.*"
disallow_untyped_calls = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
argcomplete >= 1.10.1
build
mypy~=1.2.0
PyYAML
pytest
pytest-cov
types-PyYAML
types-pkg-resources
coverage
black~=23.0 # Must match .github/workflows/black.yml
-r docs/requirements.txt
38 changes: 21 additions & 17 deletions scuba/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,12 @@
import shlex
import itertools
import argparse
from typing import Any, Optional, Sequence

try:
import argcomplete
import argcomplete # type: ignore
except ImportError:

class argcomplete:
@staticmethod
def autocomplete(*_, **__):
pass

from . import argcomplete_stub as argcomplete # type: ignore[no-redef]

from . import dockerutil
from .config import find_config, ScubaConfig, ConfigError, ConfigNotFoundError
Expand All @@ -26,16 +22,20 @@ def autocomplete(*_, **__):
from .utils import format_cmdline, parse_env_var
from .version import __version__

g_verbose: bool = False


def appmsg(msg):
def appmsg(msg: str) -> None:
print("scuba: " + msg, file=sys.stderr)


def parse_scuba_args(argv):
def _list_images_completer(**_):
def parse_scuba_args(argv: Optional[Sequence[str]]) -> argparse.Namespace:
def _list_images_completer(**kwargs: Any) -> Sequence[str]:
return dockerutil.get_images()

def _list_aliases_completer(parsed_args, **_):
def _list_aliases_completer(
parsed_args: argparse.Namespace, **kwargs: Any
) -> Sequence[str]:
# We don't want to try to complete any aliases if one was already given
if parsed_args.command:
return []
Expand All @@ -44,8 +44,9 @@ def _list_aliases_completer(parsed_args, **_):
_, _, config = find_config()
return sorted(config.aliases)
except (ConfigNotFoundError, ConfigError):
argcomplete.warn(
"No or invalid config found. Cannot auto-complete aliases."
print(
"\nNo or invalid config found. Cannot auto-complete aliases.",
file=sys.stderr,
)
return []

Expand Down Expand Up @@ -73,7 +74,7 @@ def _list_aliases_completer(parsed_args, **_):
ap.add_argument("--entrypoint", help="Override the default ENTRYPOINT of the image")

img_arg = ap.add_argument("--image", help="Override Docker image")
img_arg.completer = _list_images_completer
img_arg.completer = _list_images_completer # type: ignore[attr-defined]

ap.add_argument("--shell", help="Override shell used in Docker container")
ap.add_argument(
Expand All @@ -96,7 +97,7 @@ def _list_aliases_completer(parsed_args, **_):
nargs=argparse.REMAINDER,
help="Command (and arguments) to run in the container",
)
cmd_arg.completer = _list_aliases_completer
cmd_arg.completer = _list_aliases_completer # type: ignore[attr-defined]

argcomplete.autocomplete(ap, always_complete_options=False)
args = ap.parse_args(argv)
Expand All @@ -118,7 +119,7 @@ def _list_aliases_completer(parsed_args, **_):
return args


def run_scuba(scuba_args):
def run_scuba(scuba_args: argparse.Namespace) -> int:
# Locate .scuba.yml
try:
# top_path is where .scuba.yml is found, and becomes the top of our bind mount.
Expand Down Expand Up @@ -164,6 +165,9 @@ def run_scuba(scuba_args):

# Explicitly pass sys.stdin/stdout/stderr so they apply to the
# child process if overridden (by tests).
#
# TODO: This doesn't seem to work in all cases with pytest:
# _pytest.capture.DontReadFromInput doesn't have fileno()
return dockerutil.call(
args=run_args,
stdin=sys.stdin,
Expand All @@ -172,7 +176,7 @@ def run_scuba(scuba_args):
)


def main(argv=None):
def main(argv: Optional[Sequence[str]] = None) -> None:
scuba_args = parse_scuba_args(argv)

try:
Expand Down
7 changes: 7 additions & 0 deletions scuba/argcomplete_stub.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# A stub implementation of argcomplete which does nothing.
import argparse
from typing import Any


def autocomplete(parser: argparse.ArgumentParser, **kw: Any) -> None:
pass
Loading

0 comments on commit b086413

Please sign in to comment.