Skip to content

Commit

Permalink
fix typing
Browse files Browse the repository at this point in the history
  • Loading branch information
blink1073 committed Sep 9, 2023
1 parent f7dc09f commit 689ee86
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 93 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
- name: Run Linters
run: |
- name: Run Linters
run: |
hatch run typing:test
hatch run lint:style
pipx run interrogate -v .
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ python:
build:
os: ubuntu-22.04
tools:
python: "3.11"
python: "3.11"
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ closed.
[on GitHub](https://github.com/jupyter/jupyter_core/releases/tag/4.6.2)

- Add ability to allow insecure writes with
JUPYTER_ALLOW_INSECURE_WRITES environement variable
JUPYTER_ALLOW_INSECURE_WRITES environment variable
([#182](https://github.com/jupyter/jupyter_core/pull/182)).
- Docs typo and build fixes
- Added python 3.7 and 3.8 builds to testing
Expand Down
79 changes: 39 additions & 40 deletions jupyter_core/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
from __future__ import annotations

import logging
import os
Expand All @@ -29,23 +30,25 @@
)
from .utils import ensure_dir_exists

# mypy: disable-error-code="no-untyped-call"

# aliases and flags

base_aliases: dict = {}
base_aliases: dict[str, t.Any] = {}
if isinstance(Application.aliases, dict):
# traitlets 5
base_aliases.update(Application.aliases)
base_aliases.update(Application.aliases) # type:ignore[arg-type]
_jupyter_aliases = {
"log-level": "Application.log_level",
"config": "JupyterApp.config_file",
}
base_aliases.update(_jupyter_aliases)

base_flags: dict = {}
base_flags: dict[str, t.Any] = {}
if isinstance(Application.flags, dict):
# traitlets 5
base_flags.update(Application.flags)
_jupyter_flags: dict = {
base_flags.update(Application.flags) # type:ignore[arg-type]
_jupyter_flags: dict[str, t.Any] = {
"debug": (
{"Application": {"log_level": logging.DEBUG}},
"set log level to logging.DEBUG (maximize logging output)",
Expand All @@ -69,71 +72,67 @@ class JupyterApp(Application):
name = "jupyter" # override in subclasses
description = "A Jupyter Application"

aliases = base_aliases
flags = base_flags
aliases = base_aliases # type:ignore[assignment]
flags = base_flags # type:ignore[assignment]

def _log_level_default(self):
def _log_level_default(self) -> int:
return logging.INFO

jupyter_path: t.Union[t.List[str], List] = List(Unicode())
jupyter_path: list[str] | List = List(Unicode())

def _jupyter_path_default(self):
def _jupyter_path_default(self) -> list[str]:
return jupyter_path()

config_dir: t.Union[str, Unicode] = Unicode()
config_dir: str | Unicode = Unicode()

def _config_dir_default(self):
def _config_dir_default(self) -> str:
return jupyter_config_dir()

@property
def config_file_paths(self):
def config_file_paths(self) -> list[str]:
path = jupyter_config_path()
if self.config_dir not in path:
# Insert config dir as first item.
path.insert(0, self.config_dir)
return path

data_dir: t.Union[str, Unicode] = Unicode()
data_dir: str | Unicode = Unicode()

def _data_dir_default(self):
def _data_dir_default(self) -> str:
d = jupyter_data_dir()
ensure_dir_exists(d, mode=0o700)
return d

runtime_dir: t.Union[str, Unicode] = Unicode()
runtime_dir: str | Unicode = Unicode()

def _runtime_dir_default(self):
def _runtime_dir_default(self) -> str:
rd = jupyter_runtime_dir()
ensure_dir_exists(rd, mode=0o700)
return rd

@observe("runtime_dir")
def _runtime_dir_changed(self, change):
@observe("runtime_dir") # type:ignore[misc]
def _runtime_dir_changed(self, change: t.Any) -> None:
ensure_dir_exists(change["new"], mode=0o700)

generate_config: t.Union[bool, Bool] = Bool(
generate_config: bool | Bool = Bool(
False, config=True, help="""Generate default config file."""
)

config_file_name: t.Union[str, Unicode] = Unicode(
config=True, help="Specify a config file to load."
)
config_file_name: str | Unicode = Unicode(config=True, help="Specify a config file to load.")

def _config_file_name_default(self):
def _config_file_name_default(self) -> str:
if not self.name:
return ""
return self.name.replace("-", "_") + "_config"

config_file: t.Union[str, Unicode] = Unicode(
config_file: str | Unicode = Unicode(
config=True,
help="""Full path of a config file.""",
)

answer_yes: t.Union[bool, Bool] = Bool(
False, config=True, help="""Answer yes to any prompts."""
)
answer_yes: bool | Bool = Bool(False, config=True, help="""Answer yes to any prompts.""")

def write_default_config(self):
def write_default_config(self) -> None:
"""Write our default config to a .py config file"""
if self.config_file:
config_file = self.config_file
Expand All @@ -143,7 +142,7 @@ def write_default_config(self):
if os.path.exists(config_file) and not self.answer_yes:
answer = ""

def ask():
def ask() -> str:
prompt = "Overwrite %s with default config? [y/N]" % config_file
try:
return input(prompt).lower() or "n"
Expand All @@ -166,7 +165,7 @@ def ask():
with open(config_file, mode="w", encoding="utf-8") as f:
f.write(config_text)

def migrate_config(self):
def migrate_config(self) -> None:
"""Migrate config/data from IPython 3"""
try: # let's see if we can open the marker file
# for reading and updating (writing)
Expand All @@ -188,7 +187,7 @@ def migrate_config(self):

migrate()

def load_config_file(self, suppress_errors=True):
def load_config_file(self, suppress_errors: bool = True) -> None: # type:ignore[override]
"""Load the config file.
By default, errors in loading config are handled, and a warning
Expand All @@ -209,7 +208,7 @@ def load_config_file(self, suppress_errors=True):
if self.config_file:
path, config_file_name = os.path.split(self.config_file)
else:
path = self.config_file_paths
path = self.config_file_paths # type:ignore[assignment]
config_file_name = self.config_file_name

if not config_file_name or (config_file_name == base_config):
Expand All @@ -227,12 +226,12 @@ def load_config_file(self, suppress_errors=True):
self.log.warning("Error loading config file: %s", config_file_name, exc_info=True)

# subcommand-related
def _find_subcommand(self, name):
def _find_subcommand(self, name: str) -> str:
name = f"{self.name}-{name}"
return which(name)
return which(name) or ""

@property
def _dispatching(self):
def _dispatching(self) -> bool:
"""Return whether we are dispatching to another command
or running ourselves.
Expand All @@ -242,7 +241,7 @@ def _dispatching(self):
subcommand = Unicode()

@catch_config_error
def initialize(self, argv=None):
def initialize(self, argv: t.Any = None) -> None:
"""Initialize the application."""
# don't hook up crash handler before parsing command-line
if argv is None:
Expand All @@ -264,7 +263,7 @@ def initialize(self, argv=None):
if allow_insecure_writes:
issue_insecure_write_warning()

def start(self):
def start(self) -> None:
"""Start the whole thing"""
if self.subcommand:
os.execv(self.subcommand, [self.subcommand] + self.argv[1:]) # noqa
Expand All @@ -279,10 +278,10 @@ def start(self):
raise NoStart()

@classmethod
def launch_instance(cls, argv=None, **kwargs):
def launch_instance(cls, argv: t.Any = None, **kwargs: t.Any) -> None:
"""Launch an instance of a Jupyter Application"""
try:
return super().launch_instance(argv=argv, **kwargs)
super().launch_instance(argv=argv, **kwargs)
except NoStart:
return

Expand Down
23 changes: 12 additions & 11 deletions jupyter_core/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
from __future__ import annotations

import argparse
import errno
Expand All @@ -16,7 +17,7 @@
import sysconfig
from shutil import which
from subprocess import Popen
from typing import List
from typing import Any

from . import paths
from .version import __version__
Expand All @@ -26,19 +27,19 @@ class JupyterParser(argparse.ArgumentParser):
"""A Jupyter argument parser."""

@property
def epilog(self):
def epilog(self) -> str | None:
"""Add subcommands to epilog on request
Avoids searching PATH for subcommands unless help output is requested.
"""
return "Available subcommands: %s" % " ".join(list_subcommands())

@epilog.setter
def epilog(self, x):
def epilog(self, x: Any) -> None:
"""Ignore epilog set in Parser.__init__"""
pass

def argcomplete(self):
def argcomplete(self) -> None:
"""Trigger auto-completion, if enabled"""
try:
import argcomplete # type: ignore[import]
Expand Down Expand Up @@ -78,7 +79,7 @@ def jupyter_parser() -> JupyterParser:
return parser


def list_subcommands() -> List[str]:
def list_subcommands() -> list[str]:
"""List all jupyter subcommands
searches PATH for `jupyter-name`
Expand Down Expand Up @@ -108,7 +109,7 @@ def list_subcommands() -> List[str]:
return sorted(subcommands)


def _execvp(cmd, argv):
def _execvp(cmd: str, argv: list[str]) -> None:
"""execvp, except on Windows where it uses Popen
Python provides execvp on Windows, but its behavior is problematic (Python bug#9148).
Expand All @@ -131,7 +132,7 @@ def _execvp(cmd, argv):
os.execvp(cmd, argv) # noqa


def _jupyter_abspath(subcommand):
def _jupyter_abspath(subcommand: str) -> str:
"""This method get the abspath of a specified jupyter-subcommand with no
changes on ENV.
"""
Expand All @@ -151,7 +152,7 @@ def _jupyter_abspath(subcommand):
return abs_path


def _path_with_self():
def _path_with_self() -> list[str]:
"""Put `jupyter`'s dir at the front of PATH
Ensures that /path/to/jupyter subcommand
Expand Down Expand Up @@ -189,7 +190,7 @@ def _path_with_self():
return path_list


def _evaluate_argcomplete(parser: JupyterParser) -> List[str]:
def _evaluate_argcomplete(parser: JupyterParser) -> list[str]:
"""If argcomplete is enabled, trigger autocomplete or return current words
If the first word looks like a subcommand, return the current command
Expand All @@ -199,7 +200,7 @@ def _evaluate_argcomplete(parser: JupyterParser) -> List[str]:
try:
# traitlets >= 5.8 provides some argcomplete support,
# use helper methods to jump to argcomplete
from traitlets.config.argcomplete_config import (
from traitlets.config.argcomplete_config import ( # type:ignore[import]
get_argcomplete_cwords,
increment_argcomplete_index,
)
Expand All @@ -209,7 +210,7 @@ def _evaluate_argcomplete(parser: JupyterParser) -> List[str]:
# If first completion word looks like a subcommand,
# increment word from which to start handling arguments
increment_argcomplete_index()
return cwords
return cwords # type:ignore[no-any-return]
else:
# Otherwise no subcommand, directly autocomplete and exit
parser.argcomplete()
Expand Down
Loading

0 comments on commit 689ee86

Please sign in to comment.