Skip to content

Commit cc89aa6

Browse files
committed
Added type hints
1 parent e3fddea commit cc89aa6

19 files changed

Lines changed: 110 additions & 79 deletions

File tree

remove-json-keys/src/remove_json_keys/lib/data/file.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
def atomic_write(file_path, data, encoding='utf-8'): # to prevent TOCTOU
1+
2+
from pathlib import Path
3+
from typing import Union
4+
5+
def atomic_write(file_path: Union[Path, str], data: str, encoding: str ='utf-8') -> None: # to prevent TOCTOU
26
import os
3-
from pathlib import Path
47

58
file_path = Path(file_path)
69
file_path.parent.mkdir(parents=True, exist_ok=True)
@@ -14,10 +17,10 @@ def atomic_write(file_path, data, encoding='utf-8'): # to prevent TOCTOU
1417
if tmp_path.exists() : tmp_path.unlink()
1518
raise
1619

17-
def read(file_path, encoding='utf-8'):
20+
def read(file_path: Union[Path, str], encoding: str = 'utf-8') -> str:
1821
with open(file_path, 'r', encoding=encoding) as file:
1922
return file.read()
2023

21-
def write(file_path, data, encoding='utf-8'):
24+
def write(file_path: Union[Path, str], data: str, encoding: str = 'utf-8') -> None:
2225
with open(file_path, 'w', encoding=encoding) as file:
2326
file.write(data)

remove-json-keys/src/remove_json_keys/lib/data/json.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import json, re
22
from pathlib import Path
3-
from typing import Any, Dict, Union
3+
from typing import Any, Dict, List, Union
44

55
import json5
66

@@ -13,7 +13,7 @@ def flatten(json: Dict[str, Any], key: str = 'message') -> Dict[str, Any]: # eli
1313
flat_obj[json_key] = val[key] if isinstance(val, dict) and key in val else val
1414
return flat_obj
1515

16-
def is_valid(file_path, format='json'):
16+
def is_valid(file_path: Union[Path, str], format: str = 'json') -> bool:
1717
file_path = Path(file_path)
1818
if not file_path.exists():
1919
return False
@@ -29,14 +29,14 @@ def is_valid(file_path, format='json'):
2929
else:
3030
raise ValueError(f"Unsupported format {format!r}. Expected 'json' or 'json5'")
3131

32-
def read(input: Union[str, Path], encoding: str = 'utf-8') -> Any:
32+
def read(input: Union[Path, str], encoding: str = 'utf-8') -> Any:
3333
input_str = str(input)
3434
if input_str.endswith(('.json', '.json5')):
3535
with open(input_str, 'r', encoding=encoding) as file:
3636
return json5.load(file)
3737
else : return json5.loads(input_str)
3838

39-
def remove_keys(json_path, keys):
39+
def remove_keys(json_path: Path, keys: List[str]):
4040
keys_removed, keys_skipped, files_processed_cnt = [], [], 0
4141
for file_path in json_path.rglob('*.json'):
4242
json_data = file.read(file_path)
@@ -54,7 +54,8 @@ def remove_keys(json_path, keys):
5454
files_processed_cnt += 1
5555
return keys_removed, keys_skipped, files_processed_cnt
5656

57-
def write(file_path, data, encoding='utf-8', ensure_ascii=False, style='pretty', atomic=True):
57+
def write(file_path: Union[Path, str], data: Any, encoding: str = 'utf-8', ensure_ascii: bool = False,
58+
style: str = 'pretty', atomic: bool =True):
5859
Path(file_path).parent.mkdir(parents=True, exist_ok=True)
5960
if style == 'pretty': # single key/val spans multi-lines
6061
json_str = json.dumps(data, indent=2, ensure_ascii=ensure_ascii)

remove-json-keys/src/remove_json_keys/lib/data/sns.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from types import SimpleNamespace as sn
2+
from typing import Any, Dict
23

3-
def from_dict(obj):
4+
def from_dict(obj: Dict[str, Any]) -> sn:
45
for key, val in obj.items():
56
if isinstance(val, dict):
67
obj[key] = from_dict(val)

remove-json-keys/src/remove_json_keys/lib/init.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
from pathlib import Path
2+
from types import SimpleNamespace as sn
23

34
from . import data, env, jsdelivr, language, log, settings, url
45

56
data_path = Path(__file__).parent.parent / 'assets/data'
67

7-
def cli():
8+
def cli() -> sn:
89
cli = data.sns.from_dict(data.json.read(data_path / 'package_data.json'))
910
cli.msgs = language.get_msgs(cli,
1011
language.generate_random_lang(excludes=['en']) if env.is_debug_mode() else language.get_sys_lang())
1112
settings.load(cli)
1213
return cli
1314

14-
def config_file(cli): # for --init
15+
def config_file(cli: sn) -> None: # for --init
1516
target_path = Path.cwd() / f'.{cli.short_name}.config.json5'
1617
project_markers = data.json.read(data_path / 'project_markers.json')
1718
in_project_root = None
@@ -39,7 +40,7 @@ def config_file(cli): # for --init
3940
log.success(f'{cli.msgs.log_DEFAULT_CONFIG_CREATED_AT} {target_path}')
4041
if in_project_root : log.tip(f'{cli.msgs.tip_MOVE_CONFIG_TO_ROOT}.')
4142

42-
def config_filepath(cli): # for settings.load()
43+
def config_filepath(cli: sn) -> None: # for settings.load()
4344

4445
# Check --config <path>
4546
if getattr(cli.config, 'config', ''):
@@ -65,7 +66,7 @@ def config_filepath(cli): # for settings.load()
6566

6667
cli.config_filepath = None
6768

68-
def json_path(cli):
69+
def json_path(cli: sn) -> None:
6970
for path in Path.cwd().rglob(cli.config.json_dir):
7071
if path.is_dir():
7172
cli.json_path = Path(path)
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
def create_pkg_ver_url(cli, version=None):
1+
from types import SimpleNamespace as sn
2+
from typing import Optional
3+
4+
def create_pkg_ver_url(cli: sn, version: Optional[str] = None) -> str:
25
version = version or cli.version
36
return f'{cli.urls.jsdelivr}@{cli.name}-{cli.version}/{cli.name}'
47

5-
def create_commit_url(cli, hash='latest'):
8+
def create_commit_url(cli: sn, hash: str = 'latest') -> str:
69
return f'{cli.urls.jsdelivr}@{hash}/{cli.name}'

remove-json-keys/src/remove_json_keys/lib/log.py

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os, sys
22
from pathlib import Path
33
from types import SimpleNamespace as sn
4+
from typing import Dict, List, Optional
45
if sys.platform == 'win32' : import colorama ; colorama.init() # enable ANSI color support
56

67
from . import data as datalib, pkg, settings
@@ -25,22 +26,24 @@
2526
gry='\x1b[90m' # gray
2627
)
2728

28-
def data(msg, *args, **kwargs) : print(f'\n{colors.bw}{msg.format(*args, **kwargs)}{colors.nc}')
29-
def dim(msg, *args, **kwargs) : print(f'\n{colors.gry}{msg.format(*args, **kwargs)}{colors.nc}')
30-
def docs_url(cli) : tip(f'{cli.msgs.tip_FOR_MORE_HELP_VISIT}:\n{cli.urls.docs}')
31-
def error(msg, *args, **kwargs) : print(f'\n{colors.br}ERROR: {msg.format(*args, **kwargs)}{colors.nc}')
32-
def help_cmd(cli) : info(f"{cli.msgs.log_TYPE} '{cli.cmds[0]} --help' {cli.msgs.log_FOR_AVAIL_OPTIONS}\n")
33-
def info(msg, *args, end='', **kwargs) : print(f'\n{colors.by}{msg.format(*args, **kwargs)}{colors.nc}', end=end)
34-
def init_cmd(cli) : info(f"{cli.msgs.log_TYPE} '{cli.cmds[0]} --init' {cli.msgs.log_TO_CREATE_DEFAULT_CONFIG}\n")
35-
def overwrite_print(msg, *args, **kwargs):
29+
def data(msg: str, *args, **kwargs) -> None : print(f'\n{colors.bw}{msg.format(*args, **kwargs)}{colors.nc}')
30+
def dim(msg: str, *args, **kwargs) -> None : print(f'\n{colors.gry}{msg.format(*args, **kwargs)}{colors.nc}')
31+
def docs_url(cli: sn) -> None : tip(f'{cli.msgs.tip_FOR_MORE_HELP_VISIT}:\n{cli.urls.docs}')
32+
def error(msg: str, *args, **kwargs) -> None : print(f'\n{colors.br}ERROR: {msg.format(*args, **kwargs)}{colors.nc}')
33+
def help_cmd(cli: sn) -> None : info(f"{cli.msgs.log_TYPE} '{cli.cmds[0]} --help' {cli.msgs.log_FOR_AVAIL_OPTIONS}\n")
34+
def info(msg: str, *args, end: str = '', **kwargs) -> None:
35+
print(f'\n{colors.by}{msg.format(*args, **kwargs)}{colors.nc}', end=end)
36+
def init_cmd(cli: sn) -> None:
37+
info(f"{cli.msgs.log_TYPE} '{cli.cmds[0]} --init' {cli.msgs.log_TO_CREATE_DEFAULT_CONFIG}\n")
38+
def overwrite_print(msg: str, *args, **kwargs) -> None:
3639
sys.stdout.write('\r' + msg.format(*args, **kwargs).ljust(terminal_width)[:terminal_width])
37-
def success(msg, *args, **kwargs) : print(f'\n{colors.bg}{msg.format(*args, **kwargs)}{colors.nc}')
38-
def tip(msg, *args, **kwargs) : print(f'\n{colors.bc}TIP: {msg.format(*args, **kwargs)}{colors.nc}')
39-
def version(cli):
40+
def success(msg: str, *args, **kwargs) -> None : print(f'\n{colors.bg}{msg.format(*args, **kwargs)}{colors.nc}')
41+
def tip(msg: str, *args, **kwargs) -> None : print(f'\n{colors.bc}TIP: {msg.format(*args, **kwargs)}{colors.nc}')
42+
def version(cli: sn) -> None:
4043
print(f'\n{colors.by}{cli.name}\n{colors.bw}{cli.msgs.log_VERSION.lower()}: {cli.version}{colors.nc}')
41-
def warn(msg, *args, **kwargs) : print(f'\n{colors.bo}WARNING: {msg.format(*args, **kwargs)}{colors.nc}')
44+
def warn(msg: str, *args, **kwargs) -> None : print(f'\n{colors.bo}WARNING: {msg.format(*args, **kwargs)}{colors.nc}')
4245

43-
def warn_legacy_option(cli, flag: str, source: str) -> None:
46+
def warn_legacy_option(cli: sn, flag: str, source: str) -> None:
4447
warned_set = _warned_keys[source]
4548
if flag in warned_set : return
4649
canonical_key = settings.get_canonical_key(flag)
@@ -62,13 +65,13 @@ def warn_legacy_option(cli, flag: str, source: str) -> None:
6265
msg += f' {cli.msgs.warn_AND_WILL_BE_REMOVED} @ v{next_maj_ver}'
6366
warn(msg) ; warned_set.add(flag)
6467

65-
def cmd_docs_url_exit(cli, msg='', cmd='help'):
68+
def cmd_docs_url_exit(cli: sn, msg: str = '', cmd: str = 'help') -> None:
6669
if msg : error(msg)
6770
help_cmd(cli) if cmd == 'help' else init_cmd(cli)
6871
docs_url(cli)
6972
sys.exit(1)
7073

71-
def debug(msg, cli=None, *args, **kwargs):
74+
def debug(msg: str, cli: Optional[sn] = None, *args, **kwargs) -> None:
7275
if '--debug' not in sys.argv[1:]: return
7376

7477
# Init --debug [target]
@@ -89,7 +92,7 @@ def debug(msg, cli=None, *args, **kwargs):
8992

9093
print(f'\n{colors.by}DEBUG: {msg}{colors.nc}')
9194

92-
def final_summary(msgs, summary_dict):
95+
def final_summary(msgs: sn, summary_dict: Dict[str, List[str]]) -> None:
9396
success(f'{msgs.log_ALL_JSON_PROCESSED}!')
9497
for name, file_set in summary_dict.items():
9598
if file_set:
@@ -98,7 +101,7 @@ def final_summary(msgs, summary_dict):
98101
data(f'{msgs.log_KEYS} {status}: {len(file_set)}')
99102
print(f'{status_color}[\n ' + '\n '.join(file_set) + f'\n]{colors.nc}')
100103

101-
def trunc(msg, end='\n'):
104+
def trunc(msg: str, end: str = '\n') -> None:
102105
truncated_lines = [
103106
line if len(line) < terminal_width else line[:terminal_width -4] + '...' for line in msg.splitlines()]
104107
print('\n'.join(truncated_lines), end=end)

remove-json-keys/src/remove_json_keys/lib/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def get_canonical_key(key: str) -> Optional[str]:
4747
def is_neg_key(key: str) -> bool :
4848
return bool(re.match(r'^(?:no|disable|exclude)_', string.removeprefix(key, 'legacy_')))
4949

50-
def load(cli):
50+
def load(cli: sn) -> None:
5151
cli.config = sn()
5252

5353
# Assign help tips from cli.msgs

remove-json-keys/src/remove_json_keys/lib/url.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
1+
from typing import List, Optional, Tuple
12
from urllib.error import URLError
23
from urllib.parse import urlparse
34
from urllib.request import urlopen
45
import webbrowser
56

6-
def get(url, timeout=5, encoding='utf-8'):
7+
def get(url: str, timeout: int = 5, encoding: str = 'utf-8') -> str:
78
url = validate(url)
89
try:
910
with urlopen(url, timeout=timeout) as resp:
1011
return resp.read().decode(encoding)
1112
except URLError as err:
1213
raise RuntimeError(f'Failed to fetch from {url}: {err}')
1314

14-
def open(url):
15+
def open(url: str) -> None:
1516
url = validate(url)
1617
try : webbrowser.open(url)
1718
except Exception as err:
1819
raise RuntimeError(f'Failed to open {url} in browser browser: {err}')
1920

20-
def validate(url, allowed_schemes=('http', 'https'), allowed_domains=[]):
21+
def validate(url: str, allowed_schemes: Tuple[str, ...] = ('http', 'https'),
22+
allowed_domains: Optional[List[str]] = None) -> str:
2123
parsed_url = urlparse(url)
2224

2325
if parsed_url.scheme not in allowed_schemes:

remove-json-keys/src/remove_json_keys/lib/wizard.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import sys
2+
from types import SimpleNamespace as sn
23

34
from . import data, log
45

5-
def run(cli):
6+
def run(cli: sn) -> None:
67

78
while True: # prompt user for keys to remove
89

translate-messages/src/translate_messages/lib/data/file.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
def atomic_write(file_path, data, encoding='utf-8'): # to prevent TOCTOU
1+
2+
from pathlib import Path
3+
from typing import Union
4+
5+
def atomic_write(file_path: Union[Path, str], data: str, encoding: str ='utf-8') -> None: # to prevent TOCTOU
26
import os
3-
from pathlib import Path
47

58
file_path = Path(file_path)
69
file_path.parent.mkdir(parents=True, exist_ok=True)
@@ -14,10 +17,10 @@ def atomic_write(file_path, data, encoding='utf-8'): # to prevent TOCTOU
1417
if tmp_path.exists() : tmp_path.unlink()
1518
raise
1619

17-
def read(file_path, encoding='utf-8'):
20+
def read(file_path: Union[Path, str], encoding: str = 'utf-8') -> str:
1821
with open(file_path, 'r', encoding=encoding) as file:
1922
return file.read()
2023

21-
def write(file_path, data, encoding='utf-8'):
24+
def write(file_path: Union[Path, str], data: str, encoding: str = 'utf-8') -> None:
2225
with open(file_path, 'w', encoding=encoding) as file:
2326
file.write(data)

0 commit comments

Comments
 (0)