Skip to content

Commit cd5d511

Browse files
authored
Moving to pyproject.toml and complete type hints (#107)
* moving to pyproject.toml * fixing mkdocs * tweak pyproject.toml * switch to hatch/hatchling * linting * revert removal of editable builds * bump * fix docs build * lint plugins.py * add history file * complete type hints * fix tests * revert "str->as_str" name change * tweak HISTORY * tweak pyproject.toml
1 parent 3838cc8 commit cd5d511

25 files changed

+327
-249
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,10 @@ jobs:
9494
python-version: '3.10'
9595

9696
- name: install
97-
run: make install
98-
99-
- name: set version
100-
run: VERSION_PATH='devtools/version.py' python <(curl -Ls https://git.io/JT3rm)
97+
run: pip install -U build twine setuptools
10198

10299
- name: build
103-
run: python setup.py sdist bdist_wheel
100+
run: python -m build
104101

105102
- run: twine check dist/*
106103

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ old-version/
1919
*.swp
2020
/site/
2121
/site.zip
22+
/build/

HISTORY.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## v0.8.0 (2021-09-29)
2+
3+
* test with python 3.10 #91
4+
* display `SQLAlchemy` objects nicely #94
5+
* fix tests on windows #93
6+
* show function `qualname` #95
7+
* cache pygments loading (significant speedup) #96
8+
19
## v0.7.0 (2021-09-03)
210

311
* switch to [`executing`](https://pypi.org/project/executing/) and [`asttokens`](https://pypi.org/project/asttokens/)
@@ -9,6 +17,10 @@
917
* display `dataclasses` properly, #88
1018
* uprev test dependencies, #81, #83, #90
1119

20+
## v0.6.1 (2020-10-22)
21+
22+
compatibility with python 3.8.6
23+
1224
## v0.6.0 (2020-07-29)
1325

1426
* improve `__pretty__` to work better with pydantic classes, #52

MANIFEST.in

Lines changed: 0 additions & 3 deletions
This file was deleted.

Makefile

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.DEFAULT_GOAL := all
2-
isort = isort devtools tests
3-
black = black -S -l 120 --target-version py37 devtools
2+
isort = isort devtools tests docs/plugins.py
3+
black = black -S -l 120 --target-version py37 devtools docs/plugins.py
44

55
.PHONY: install
66
install:
@@ -15,9 +15,10 @@ format:
1515

1616
.PHONY: lint
1717
lint:
18-
flake8 devtools/ tests/
18+
flake8 --max-complexity 10 --max-line-length 120 --ignore E203,W503 devtools tests docs/plugins.py
1919
$(isort) --check-only --df
2020
$(black) --check --diff
21+
mypy devtools
2122

2223
.PHONY: test
2324
test:
@@ -50,12 +51,10 @@ clean:
5051
.PHONY: docs
5152
docs:
5253
flake8 --max-line-length=80 docs/examples/
53-
python docs/build/main.py
5454
mkdocs build
5555

5656
.PHONY: docs-serve
5757
docs-serve:
58-
python docs/build/main.py
5958
mkdocs serve
6059

6160
.PHONY: publish-docs

devtools/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@
44
from .prettier import *
55
from .timer import *
66
from .version import VERSION
7+
8+
__version__ = VERSION

devtools/ansi.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66

77
MYPY = False
88
if MYPY:
9-
from typing import Any, Union
9+
from typing import Any, Mapping, Union
1010

1111

12-
def strip_ansi(value):
12+
def strip_ansi(value: str) -> str:
1313
import re
1414

1515
return re.sub('\033\\[((?:\\d|;)*)([a-zA-Z])', '', value)
@@ -62,7 +62,7 @@ class Style(IntEnum):
6262
# this is a meta value used for the "Style" instance which is the "style" function
6363
function = -1
6464

65-
def __call__(self, input: 'Any', *styles: 'Style', reset: bool = True, apply: bool = True) -> str:
65+
def __call__(self, input: 'Any', *styles: 'Union[Style, int, str]', reset: bool = True, apply: bool = True) -> str:
6666
"""
6767
Styles text with ANSI styles and returns the new string.
6868
@@ -91,7 +91,7 @@ def __call__(self, input: 'Any', *styles: 'Style', reset: bool = True, apply: bo
9191
s = self.styles[s]
9292
except KeyError:
9393
raise ValueError(f'invalid style "{s}"')
94-
codes.append(_style_as_int(s.value))
94+
codes.append(_style_as_int(s.value)) # type: ignore
9595

9696
if codes:
9797
r = _as_ansi(';'.join(codes)) + text
@@ -103,16 +103,16 @@ def __call__(self, input: 'Any', *styles: 'Style', reset: bool = True, apply: bo
103103
return r
104104

105105
@property
106-
def styles(self):
106+
def styles(self) -> 'Mapping[str, Style]':
107107
return self.__class__.__members__
108108

109-
def __repr__(self):
109+
def __repr__(self) -> str:
110110
if self == self.function:
111111
return '<pseudo function sformat(text, *styles)>'
112112
else:
113113
return super().__repr__()
114114

115-
def __str__(self):
115+
def __str__(self) -> str:
116116
if self == self.function:
117117
return repr(self)
118118
else:
@@ -139,14 +139,22 @@ class StylePrint:
139139
for that mistake.
140140
"""
141141

142-
def __call__(self, input, *styles, reset=True, flush=True, file=None, **print_kwargs):
142+
def __call__(
143+
self,
144+
input: str,
145+
*styles: 'Union[Style, int, str]',
146+
reset: bool = True,
147+
flush: bool = True,
148+
file: 'Any' = None,
149+
**print_kwargs: 'Any',
150+
) -> None:
143151
text = sformat(input, *styles, reset=reset, apply=isatty(file))
144152
print(text, flush=flush, file=file, **print_kwargs)
145153

146-
def __getattr__(self, item):
154+
def __getattr__(self, item: str) -> str:
147155
return getattr(sformat, item)
148156

149-
def __repr__(self):
157+
def __repr__(self) -> str:
150158
return '<pseudo function sprint(text, *styles)>'
151159

152160

devtools/debug.py

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,22 @@
1010
MYPY = False
1111
if MYPY:
1212
from types import FrameType
13-
from typing import Any, Generator, List, Optional
13+
from typing import Any, Generator, List, Optional, Union
1414

1515
pformat = PrettyFormat(
1616
indent_step=int(os.getenv('PY_DEVTOOLS_INDENT', 4)),
1717
simple_cutoff=int(os.getenv('PY_DEVTOOLS_SIMPLE_CUTOFF', 10)),
1818
width=int(os.getenv('PY_DEVTOOLS_WIDTH', 120)),
1919
yield_from_generators=env_true('PY_DEVTOOLS_YIELD_FROM_GEN', True),
2020
)
21+
# required for type hinting because I (stupidly) added methods called `str`
22+
StrType = str
2123

2224

2325
class DebugArgument:
2426
__slots__ = 'value', 'name', 'extra'
2527

26-
def __init__(self, value, *, name=None, **extra):
28+
def __init__(self, value: 'Any', *, name: 'Optional[str]' = None, **extra: 'Any') -> None:
2729
self.value = value
2830
self.name = name
2931
self.extra = []
@@ -35,7 +37,7 @@ def __init__(self, value, *, name=None, **extra):
3537
self.extra.append(('len', length))
3638
self.extra += [(k, v) for k, v in extra.items() if v is not None]
3739

38-
def str(self, highlight=False) -> str:
40+
def str(self, highlight: bool = False) -> StrType:
3941
s = ''
4042
if self.name and not is_literal(self.name):
4143
s = f'{sformat(self.name, sformat.blue, apply=highlight)}: '
@@ -54,7 +56,7 @@ def str(self, highlight=False) -> str:
5456
s += suffix
5557
return s
5658

57-
def __str__(self) -> str:
59+
def __str__(self) -> StrType:
5860
return self.str()
5961

6062

@@ -66,14 +68,22 @@ class DebugOutput:
6668
arg_class = DebugArgument
6769
__slots__ = 'filename', 'lineno', 'frame', 'arguments', 'warning'
6870

69-
def __init__(self, *, filename: str, lineno: int, frame: str, arguments: 'List[DebugArgument]', warning=None):
71+
def __init__(
72+
self,
73+
*,
74+
filename: str,
75+
lineno: int,
76+
frame: str,
77+
arguments: 'List[DebugArgument]',
78+
warning: 'Union[None, str, bool]' = None,
79+
) -> None:
7080
self.filename = filename
7181
self.lineno = lineno
7282
self.frame = frame
7383
self.arguments = arguments
7484
self.warning = warning
7585

76-
def str(self, highlight=False) -> str:
86+
def str(self, highlight: bool = False) -> StrType:
7787
if highlight:
7888
prefix = (
7989
f'{sformat(self.filename, sformat.magenta)}:{sformat(self.lineno, sformat.green)} '
@@ -87,10 +97,10 @@ def str(self, highlight=False) -> str:
8797
prefix += f' ({self.warning})'
8898
return f'{prefix}\n ' + '\n '.join(a.str(highlight) for a in self.arguments)
8999

90-
def __str__(self) -> str:
100+
def __str__(self) -> StrType:
91101
return self.str()
92102

93-
def __repr__(self) -> str:
103+
def __repr__(self) -> StrType:
94104
arguments = ' '.join(str(a) for a in self.arguments)
95105
return f'<DebugOutput {self.filename}:{self.lineno} {self.frame} arguments: {arguments}>'
96106

@@ -102,7 +112,7 @@ def __init__(self, *, warnings: 'Optional[bool]' = None, highlight: 'Optional[bo
102112
self._show_warnings = env_bool(warnings, 'PY_DEVTOOLS_WARNINGS', True)
103113
self._highlight = highlight
104114

105-
def __call__(self, *args, file_=None, flush_=True, **kwargs) -> 'Any':
115+
def __call__(self, *args: 'Any', file_: 'Any' = None, flush_: bool = True, **kwargs: 'Any') -> 'Any':
106116
d_out = self._process(args, kwargs)
107117
s = d_out.str(use_highlight(self._highlight, file_))
108118
print(s, file=file_, flush=flush_)
@@ -113,18 +123,18 @@ def __call__(self, *args, file_=None, flush_=True, **kwargs) -> 'Any':
113123
else:
114124
return args
115125

116-
def format(self, *args, **kwargs) -> DebugOutput:
126+
def format(self, *args: 'Any', **kwargs: 'Any') -> DebugOutput:
117127
return self._process(args, kwargs)
118128

119-
def breakpoint(self):
129+
def breakpoint(self) -> None:
120130
import pdb
121131

122132
pdb.Pdb(skip=['devtools.*']).set_trace()
123133

124-
def timer(self, name=None, *, verbose=True, file=None, dp=3) -> Timer:
134+
def timer(self, name: 'Optional[str]' = None, *, verbose: bool = True, file: 'Any' = None, dp: int = 3) -> Timer:
125135
return Timer(name=name, verbose=verbose, file=file, dp=dp)
126136

127-
def _process(self, args, kwargs) -> DebugOutput:
137+
def _process(self, args: 'Any', kwargs: 'Any') -> DebugOutput:
128138
"""
129139
BEWARE: this must be called from a function exactly 2 levels below the top of the stack.
130140
"""
@@ -181,13 +191,13 @@ def _process(self, args, kwargs) -> DebugOutput:
181191
warning=self._show_warnings and warning,
182192
)
183193

184-
def _args_inspection_failed(self, args, kwargs):
194+
def _args_inspection_failed(self, args: 'Any', kwargs: 'Any') -> 'Generator[DebugArgument, None, None]':
185195
for arg in args:
186196
yield self.output_class.arg_class(arg)
187197
for name, value in kwargs.items():
188198
yield self.output_class.arg_class(value, name=name)
189199

190-
def _process_args(self, ex, args, kwargs) -> 'Generator[DebugArgument, None, None]':
200+
def _process_args(self, ex: 'Any', args: 'Any', kwargs: 'Any') -> 'Generator[DebugArgument, None, None]':
191201
import ast
192202

193203
func_ast = ex.node

0 commit comments

Comments
 (0)