[python] enable strict typechecking

This commit is contained in:
Dmytro Meleshko 2021-06-04 13:51:03 +03:00
parent 20c3f3b524
commit d466b3ce30
6 changed files with 21 additions and 30 deletions

View file

@ -3,7 +3,7 @@
import json import json
import os import os
from abc import abstractmethod from abc import abstractmethod
from typing import Dict, Iterator, List, Protocol, TextIO, runtime_checkable from typing import Dict, Iterator, List, Protocol, TextIO
__dir__ = os.path.dirname(__file__) __dir__ = os.path.dirname(__file__)
@ -60,23 +60,10 @@ BASE16_TO_ANSI_MAPPING: List[int] = [
ANSI_TO_BASE16_MAPPING: List[int] = [BASE16_TO_ANSI_MAPPING.index(i) for i in range(16)] ANSI_TO_BASE16_MAPPING: List[int] = [BASE16_TO_ANSI_MAPPING.index(i) for i in range(16)]
@runtime_checkable
class Theme(Protocol): class Theme(Protocol):
base16_name: str
@property is_dark: bool
@abstractmethod base16_colors: List[Color]
def base16_name(self) -> str:
raise NotImplementedError()
@property
@abstractmethod
def is_dark(self) -> bool:
raise NotImplementedError()
@property
@abstractmethod
def base16_colors(self) -> List[Color]:
raise NotImplementedError()
@property @property
def name(self) -> str: def name(self) -> str:
@ -152,7 +139,6 @@ class MyTheme(Theme):
] ]
@runtime_checkable
class ThemeGenerator(Protocol): class ThemeGenerator(Protocol):
@abstractmethod @abstractmethod
@ -248,7 +234,7 @@ class ThemeGeneratorVim(ThemeGenerator):
output.write("let {}base16_colors = [\n".format(namespace)) output.write("let {}base16_colors = [\n".format(namespace))
for gui_color, cterm_color in zip(theme.base16_colors, ANSI_TO_BASE16_MAPPING): for gui_color, cterm_color in zip(theme.base16_colors, ANSI_TO_BASE16_MAPPING):
output.write( output.write(
"\\ {{'gui': '{}', 'cterm': '{:02}'}},\n".format(gui_color.css_hex, cterm_color) "\\ {{'gui': '{}', 'cterm': '{:02}'}},\n".format(gui_color.css_hex, cterm_color),
) )
output.write("\\ ]\n") output.write("\\ ]\n")
@ -293,7 +279,7 @@ class ThemeGeneratorXfceTerminal(ThemeGenerator):
output.write("TabActivityColor={}\n".format(theme.base16_colors[0x8].css_hex)) output.write("TabActivityColor={}\n".format(theme.base16_colors[0x8].css_hex))
output.write("ColorBoldUseDefault=TRUE\n") output.write("ColorBoldUseDefault=TRUE\n")
output.write( output.write(
"ColorPalette={}\n".format(";".join(color.css_hex for color in theme.ansi_colors)) "ColorPalette={}\n".format(";".join(color.css_hex for color in theme.ansi_colors)),
) )
@ -340,7 +326,7 @@ class ThemeGeneratorIterm(ThemeGenerator):
def generate(self, theme: Theme, output: TextIO) -> None: def generate(self, theme: Theme, output: TextIO) -> None:
output.write('<?xml version="1.0" encoding="UTF-8"?>\n') output.write('<?xml version="1.0" encoding="UTF-8"?>\n')
output.write( output.write(
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n' '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n',
) )
output.write('<plist version="1.0">\n') output.write('<plist version="1.0">\n')
output.write("<dict>\n") output.write("<dict>\n")

View file

@ -1,15 +1,17 @@
let g:coc_global_extensions += ['coc-pyright'] let g:coc_global_extensions += ['coc-pyright']
let g:coc_filetypes += ['python'] let g:coc_filetypes += ['python']
" let g:coc_user_config['python.autocomplete.showAdvancedMembers'] = v:false
let g:coc_user_config['python'] = { let g:coc_user_config['python'] = {
\ 'formatting': { \ 'formatting': {
\ 'provider': 'yapf', \ 'provider': 'yapf',
\ 'yapfArgs': ['--style=' . simplify(g:dotfiles_dir.'/python/yapf.ini')] \ 'yapfArgs': ['--style=' . simplify(g:dotfiles_dir.'/python/yapf.ini')],
\ }, \ },
\ 'linting': { \ 'linting': {
\ 'pylintEnabled': v:false, \ 'pylintEnabled': v:false,
\ 'flake8Enabled': v:true, \ 'flake8Enabled': v:true,
\ 'flake8Args': ['--config=' . simplify(g:dotfiles_dir.'/python/flake8.ini')], \ 'flake8Args': ['--config=' . simplify(g:dotfiles_dir.'/python/flake8.ini')],
\ }, \ },
\ 'analysis': {
\ 'typeCheckingMode': 'strict',
\ },
\ } \ }

View file

@ -2,7 +2,7 @@ import os
import subprocess import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
from typing import Iterable, NoReturn from typing import Iterable, NoReturn, Optional
if os.name == "posix": if os.name == "posix":
DOTFILES_CONFIG_DIR: Path = Path.home() / ".config" / "dotfiles" DOTFILES_CONFIG_DIR: Path = Path.home() / ".config" / "dotfiles"
@ -13,7 +13,7 @@ def platform_not_supported_error() -> NoReturn:
raise Exception("platform '{}' is not supported!".format(sys.platform)) raise Exception("platform '{}' is not supported!".format(sys.platform))
def run_chooser(choices: Iterable[str], prompt: str = None, async_read: bool = False) -> int: def run_chooser(choices: Iterable[str], prompt: Optional[str] = None, async_read: bool = False) -> int:
supports_result_index = True supports_result_index = True
if os.isatty(sys.stderr.fileno()): if os.isatty(sys.stderr.fileno()):
process_args = [ process_args = [
@ -36,10 +36,13 @@ def run_chooser(choices: Iterable[str], prompt: str = None, async_read: bool = F
platform_not_supported_error() platform_not_supported_error()
chooser_process = subprocess.Popen(process_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE) chooser_process = subprocess.Popen(process_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
assert chooser_process.stdin is not None
assert chooser_process.stdout is not None
with chooser_process.stdin as pipe: with chooser_process.stdin as pipe:
for index, choice in enumerate(choices): for index, choice in enumerate(choices):
assert "\n" not in choice if "\n" not in choice:
raise Exception("choices can only span a single line")
if not supports_result_index: if not supports_result_index:
pipe.write(str(index).encode()) pipe.write(str(index).encode())
pipe.write(b" ") pipe.write(b" ")
@ -54,7 +57,7 @@ def run_chooser(choices: Iterable[str], prompt: str = None, async_read: bool = F
return chosen_index return chosen_index
def send_notification(title: str, message: str, url: str = None) -> None: def send_notification(title: str, message: str, url: Optional[str] = None) -> None:
if sys.platform == "darwin": if sys.platform == "darwin":
process_args = [ process_args = [
"terminal-notifier", "terminal-notifier",

View file

@ -3,7 +3,7 @@ from fractions import Fraction
def factors(n: int) -> "set[int]": def factors(n: int) -> "set[int]":
result = set() result: "set[int]" = set()
for i in range(1, int(sqrt(n)) + 1): for i in range(1, int(sqrt(n)) + 1):
if n % i == 0: if n % i == 0:
result.add(i) result.add(i)

View file

@ -14,7 +14,7 @@ def bright_colored(string: str, *colors: str) -> str:
def colorize_percent( def colorize_percent(
percent: float, warning: float, critical: float, inverse: bool = False percent: float, warning: float, critical: float, inverse: bool = False,
) -> str: ) -> str:
colors = [Fore.GREEN, Fore.YELLOW, Fore.RED] colors = [Fore.GREEN, Fore.YELLOW, Fore.RED]

View file

@ -13,7 +13,7 @@ from humanize import humanize_bytes, humanize_timedelta
def get_system_info() -> Tuple[List[str], List[str]]: def get_system_info() -> Tuple[List[str], List[str]]:
info_lines: List[str] = [] info_lines: List[str] = []
def info(name: str, value: str, *format_args) -> None: def info(name: str, value: str, *format_args: object) -> None:
line = bright_colored(name + ":", Fore.YELLOW) + " " + value line = bright_colored(name + ":", Fore.YELLOW) + " " + value
if format_args: if format_args:
line = line % format_args line = line % format_args