| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 049965d commit 0de8d7a
18 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,99 @@ | |||
| 1 | + name: CI | ||
| 2 | + | ||
| 3 | + on: | ||
| 4 | + push: | ||
| 5 | + branches: | ||
| 6 | + - master | ||
| 7 | + tags: | ||
| 8 | + - '**' | ||
| 9 | + pull_request: {} | ||
| 10 | + | ||
| 11 | + jobs: | ||
| 12 | + test: | ||
| 13 | + name: test py${{ matrix.python-version }} on ${{ matrix.os }} | ||
| 14 | + strategy: | ||
| 15 | + fail-fast: false | ||
| 16 | + matrix: | ||
| 17 | + os: [ubuntu, macos] | ||
| 18 | + python-version: ['3.6', '3.7', '3.8'] | ||
| 19 | + | ||
| 20 | + env: | ||
| 21 | + PYTHON: ${{ matrix.python-version }} | ||
| 22 | + OS: ${{ matrix.os }} | ||
| 23 | + EXTRAS: yes | ||
| 24 | + | ||
| 25 | + runs-on: ${{ matrix.os }}-latest | ||
| 26 | + | ||
| 27 | + steps: | ||
| 28 | + - uses: actions/checkout@v2 | ||
| 29 | + | ||
| 30 | + - name: set up python | ||
| 31 | + uses: actions/setup-python@v1 | ||
| 32 | + with: | ||
| 33 | + python-version: ${{ matrix.python-version }} | ||
| 34 | + | ||
| 35 | + - name: install dependencies | ||
| 36 | + run: | | ||
| 37 | + make install | ||
| 38 | + pip freeze | ||
| 39 | + | ||
| 40 | + - name: lint | ||
| 41 | + run: | | ||
| 42 | + make lint | ||
| 43 | + make check-dist | ||
| 44 | + | ||
| 45 | + - name: test with extras | ||
| 46 | + run: make test | ||
| 47 | + | ||
| 48 | + - uses: codecov/codecov-action@v1 | ||
| 49 | + with: | ||
| 50 | + file: ./coverage.xml | ||
| 51 | + env_vars: EXTRAS,PYTHON,OS | ||
| 52 | + | ||
| 53 | + - name: uninstall extras | ||
| 54 | + run: pip uninstall -y multidict numpy | ||
| 55 | + | ||
| 56 | + - name: test without extras | ||
| 57 | + run: | | ||
| 58 | + make test | ||
| 59 | + coverage xml | ||
| 60 | + | ||
| 61 | + - uses: codecov/codecov-action@v1 | ||
| 62 | + with: | ||
| 63 | + file: ./coverage.xml | ||
| 64 | + env_vars: DEPS,PYTHON,OS | ||
| 65 | + env: | ||
| 66 | + EXTRAS: no | ||
| 67 | + | ||
| 68 | + deploy: | ||
| 69 | + name: Deploy | ||
| 70 | + needs: test | ||
| 71 | + if: "success() && startsWith(github.ref, 'refs/tags/')" | ||
| 72 | + runs-on: ubuntu-latest | ||
| 73 | + | ||
| 74 | + steps: | ||
| 75 | + - uses: actions/checkout@v2 | ||
| 76 | + | ||
| 77 | + - name: set up python | ||
| 78 | + uses: actions/setup-python@v1 | ||
| 79 | + with: | ||
| 80 | + python-version: '3.8' | ||
| 81 | + | ||
| 82 | + - name: install | ||
| 83 | + run: | | ||
| 84 | + make install | ||
| 85 | + pip install -U wheel | ||
| 86 | + | ||
| 87 | + - name: build | ||
| 88 | + run: python setup.py sdist bdist_wheel | ||
| 89 | + | ||
| 90 | + - run: twine check dist/* | ||
| 91 | + | ||
| 92 | + - name: check tag | ||
| 93 | + run: PACKAGE=devtools python <(curl -Ls https://git.io/JvQsH) | ||
| 94 | + | ||
| 95 | + - name: upload to pypi | ||
| 96 | + run: twine upload dist/* | ||
| 97 | + env: | ||
| 98 | + TWINE_USERNAME: __token__ | ||
| 99 | + TWINE_PASSWORD: ${{ secrets.pypi_token }} | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,27 +1,29 @@ | |||
| 1 | 1 | .DEFAULT_GOAL := all | |
| 2 | + isort = isort -rc devtools tests | ||
| 3 | + black = black -S -l 120 --target-version py37 devtools | ||
| 2 | 4 | ||
| 3 | - .PHONY: install-dev | ||
| 4 | - install-dev: | ||
| 5 | + .PHONY: install | ||
| 6 | + install: | ||
| 5 | 7 | pip install -U setuptools pip | |
| 6 | - pip install -r dev-requirements.txt | ||
| 8 | + pip install -U -r requirements.txt | ||
| 9 | + pip install -e . | ||
| 7 | 10 | ||
| 8 | - .PHONY: install-test | ||
| 9 | - install-test: | ||
| 10 | - pip install -U setuptools pip | ||
| 11 | - pip install -r tests/requirements.txt | ||
| 12 | - pip install -r docs/requirements.txt | ||
| 13 | - pip install -U . | ||
| 14 | - | ||
| 15 | - .PHONY: isort | ||
| 16 | - isort: | ||
| 17 | - isort -rc -w 120 devtools | ||
| 18 | - isort -rc -w 120 tests | ||
| 11 | + .PHONY: format | ||
| 12 | + format: | ||
| 13 | + $(isort) | ||
| 14 | + $(black) | ||
| 19 | 15 | ||
| 20 | 16 | .PHONY: lint | |
| 21 | 17 | lint: | |
| 22 | - python setup.py check -rms | ||
| 23 | 18 | flake8 devtools/ tests/ | |
| 24 | - pytest devtools -p no:sugar -q | ||
| 19 | + $(isort) --check-only -df | ||
| 20 | + $(black) --check | ||
| 21 | + | ||
| 22 | + .PHONY: check-dist | ||
| 23 | + check-dist: | ||
| 24 | + python setup.py check -ms | ||
| 25 | + python setup.py sdist | ||
| 26 | + twine check dist/* | ||
| 25 | 27 | ||
| 26 | 28 | .PHONY: test | |
| 27 | 29 | test: | |
@@ -34,7 +36,7 @@ testcov: | |||
| 34 | 36 | @coverage html | |
| 35 | 37 | ||
| 36 | 38 | .PHONY: all | |
| 37 | - all: testcov lint | ||
| 39 | + all: lint testcov | ||
| 38 | 40 | ||
| 39 | 41 | .PHONY: clean | |
| 40 | 42 | clean: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -133,6 +133,7 @@ class StylePrint: | |||
| 133 | 133 | Annoyingly enums do not allow inheritance, a lazy design mistake, this is an ugly work around | |
| 134 | 134 | for that mistake. | |
| 135 | 135 | """ | |
| 136 | + | ||
| 136 | 137 | def __call__(self, input, *styles, reset=True, flush=True, file=None, **print_kwargs): | |
| 137 | 138 | text = sformat(input, *styles, reset=reset, apply=isatty(file)) | |
| 138 | 139 | print(text, flush=flush, file=file, **print_kwargs) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -46,7 +46,7 @@ def str(self, highlight=False) -> str: | |||
| 46 | 46 | suffix = sformat( | |
| 47 | 47 | ' ({.value.__class__.__name__}){}'.format(self, ''.join(' {}={}'.format(k, v) for k, v in self.extra)), | |
| 48 | 48 | sformat.dim, | |
| 49 | - apply=highlight | ||
| 49 | + apply=highlight, | ||
| 50 | 50 | ) | |
| 51 | 51 | try: | |
| 52 | 52 | s += pformat(self.value, indent=4, highlight=highlight) | |
@@ -68,6 +68,7 @@ class DebugOutput: | |||
| 68 | 68 | """ | |
| 69 | 69 | Represents the output of a debug command. | |
| 70 | 70 | """ | |
| 71 | + | ||
| 71 | 72 | arg_class = DebugArgument | |
| 72 | 73 | __slots__ = 'filename', 'lineno', 'frame', 'arguments', 'warning' | |
| 73 | 74 | ||
@@ -83,7 +84,7 @@ def str(self, highlight=False) -> str: | |||
| 83 | 84 | prefix = '{}:{} {}'.format( | |
| 84 | 85 | sformat(self.filename, sformat.magenta), | |
| 85 | 86 | sformat(self.lineno, sformat.green), | |
| 86 | - sformat(self.frame, sformat.green, sformat.italic) | ||
| 87 | + sformat(self.frame, sformat.green, sformat.italic), | ||
| 87 | 88 | ) | |
| 88 | 89 | if self.warning: | |
| 89 | 90 | prefix += sformat(' ({})'.format(self.warning), sformat.dim) | |
@@ -104,15 +105,22 @@ def __repr__(self) -> str: | |||
| 104 | 105 | class Debug: | |
| 105 | 106 | output_class = DebugOutput | |
| 106 | 107 | complex_nodes = ( | |
| 107 | - ast.Call, ast.Attribute, ast.Subscript, | ||
| 108 | - ast.IfExp, ast.BoolOp, ast.BinOp, ast.Compare, | ||
| 109 | - ast.DictComp, ast.ListComp, ast.SetComp, ast.GeneratorExp | ||
| 108 | + ast.Call, | ||
| 109 | + ast.Attribute, | ||
| 110 | + ast.Subscript, | ||
| 111 | + ast.IfExp, | ||
| 112 | + ast.BoolOp, | ||
| 113 | + ast.BinOp, | ||
| 114 | + ast.Compare, | ||
| 115 | + ast.DictComp, | ||
| 116 | + ast.ListComp, | ||
| 117 | + ast.SetComp, | ||
| 118 | + ast.GeneratorExp, | ||
| 110 | 119 | ) | |
| 111 | 120 | ||
| 112 | - def __init__(self, *, | ||
| 113 | - warnings: Optional[bool] = None, | ||
| 114 | - highlight: Optional[bool] = None, | ||
| 115 | - frame_context_length: int = 50): | ||
| 121 | + def __init__( | ||
| 122 | + self, *, warnings: Optional[bool] = None, highlight: Optional[bool] = None, frame_context_length: int = 50 | ||
| 123 | + ): | ||
| 116 | 124 | self._show_warnings = self._env_bool(warnings, 'PY_DEVTOOLS_WARNINGS', True) | |
| 117 | 125 | self._highlight = self._env_bool(highlight, 'PY_DEVTOOLS_HIGHLIGHT', None) | |
| 118 | 126 | # 50 lines should be enough to make sure we always get the entire function definition | |
@@ -217,9 +225,7 @@ def _process_args(self, func_ast, code_lines, args, kwargs) -> Generator[DebugAr | |||
| 217 | 225 | for l_ in range(start_line, end_line + 1): | |
| 218 | 226 | start_ = start_col if l_ == start_line else 0 | |
| 219 | 227 | end_ = end_col if l_ == end_line else None | |
| 220 | - name_lines.append( | ||
| 221 | - code_lines[l_][start_:end_].strip(' ') | ||
| 222 | - ) | ||
| 228 | + name_lines.append(code_lines[l_][start_:end_].strip(' ')) | ||
| 223 | 229 | yield self.output_class.arg_class(arg, name=' '.join(name_lines).strip(' ,')) | |
| 224 | 230 | else: | |
| 225 | 231 | yield self.output_class.arg_class(arg) | |
@@ -239,7 +245,7 @@ def _parse_code( | |||
| 239 | 245 | try: | |
| 240 | 246 | new_line = call_frame.code_context[line] | |
| 241 | 247 | except IndexError: # pragma: no cover | |
| 242 | - return None, None, line, 'error passing code. line not found' | ||
| 248 | + return None, None, line, 'error parsing code. line not found' | ||
| 243 | 249 | call_lines.append(new_line) | |
| 244 | 250 | if re.search(func_regex, new_line): | |
| 245 | 251 | break | |
@@ -258,7 +264,7 @@ def _parse_code( | |||
| 258 | 264 | # ) | |
| 259 | 265 | # inspect ignores it when setting index and we have to add it back | |
| 260 | 266 | for extra in range(2, 6): | |
| 261 | - extra_lines = call_frame.code_context[tail_index + 1:tail_index + extra] | ||
| 267 | + extra_lines = call_frame.code_context[tail_index + 1 : tail_index + extra] | ||
| 262 | 268 | code = dedent(''.join(call_lines + extra_lines)) | |
| 263 | 269 | try: | |
| 264 | 270 | func_ast = self._wrap_parse(code, filename) | |
@@ -268,12 +274,12 @@ def _parse_code( | |||
| 268 | 274 | break | |
| 269 | 275 | ||
| 270 | 276 | if not func_ast: | |
| 271 | - return None, None, lineno, 'error passing code, {0.__class__.__name__}: {0}'.format(e1) | ||
| 277 | + return None, None, lineno, 'error parsing code, {0.__class__.__name__}: {0}'.format(e1) | ||
| 272 | 278 | ||
| 273 | 279 | if not isinstance(func_ast, ast.Call): | |
| 274 | - return None, None, lineno, 'error passing code, found {} not Call'.format(func_ast.__class__) | ||
| 280 | + return None, None, lineno, 'error parsing code, found {} not Call'.format(func_ast.__class__) | ||
| 275 | 281 | ||
| 276 | - code_lines = [l for l in code.split('\n') if l] | ||
| 282 | + code_lines = [line for line in code.split('\n') if line] | ||
| 277 | 283 | # this removes the trailing bracket from the lines of code meaning it doesn't appear in the | |
| 278 | 284 | # representation of the last argument | |
| 279 | 285 | code_lines[-1] = code_lines[-1][:-1] | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,7 +1,6 @@ | |||
| 1 | 1 | import io | |
| 2 | 2 | import os | |
| 3 | 3 | import textwrap | |
| 4 | - import warnings | ||
| 5 | 4 | from collections import OrderedDict | |
| 6 | 5 | from collections.abc import Generator | |
| 7 | 6 | from typing import Any, Union | |
@@ -52,13 +51,15 @@ class SkipPretty(Exception): | |||
| 52 | 51 | ||
| 53 | 52 | ||
| 54 | 53 | class PrettyFormat: | |
| 55 | - def __init__(self, | ||
| 56 | - indent_step=4, | ||
| 57 | - indent_char=' ', | ||
| 58 | - repr_strings=False, | ||
| 59 | - simple_cutoff=10, | ||
| 60 | - width=120, | ||
| 61 | - yield_from_generators=True): | ||
| 54 | + def __init__( | ||
| 55 | + self, | ||
| 56 | + indent_step=4, | ||
| 57 | + indent_char=' ', | ||
| 58 | + repr_strings=False, | ||
| 59 | + simple_cutoff=10, | ||
| 60 | + width=120, | ||
| 61 | + yield_from_generators=True, | ||
| 62 | + ): | ||
| 62 | 63 | self._indent_step = indent_step | |
| 63 | 64 | self._c = indent_char | |
| 64 | 65 | self._repr_strings = repr_strings | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,7 +1,7 @@ | |||
| 1 | 1 | from statistics import mean, stdev | |
| 2 | 2 | from time import time | |
| 3 | 3 | ||
| 4 | - __all__ = 'Timer', | ||
| 4 | + __all__ = ('Timer',) | ||
| 5 | 5 | ||
| 6 | 6 | ||
| 7 | 7 | class TimerResult: | |
@@ -49,9 +49,7 @@ def __call__(self, name=None, verbose=None): | |||
| 49 | 49 | return self | |
| 50 | 50 | ||
| 51 | 51 | def start(self, name=None, verbose=None): | |
| 52 | - self.results.append( | ||
| 53 | - TimerResult(name or self._name, self._verbose if verbose is None else verbose) | ||
| 54 | - ) | ||
| 52 | + self.results.append(TimerResult(name or self._name, self._verbose if verbose is None else verbose)) | ||
| 55 | 53 | return self | |
| 56 | 54 | ||
| 57 | 55 | def capture(self, verbose=None): | |
@@ -72,14 +70,18 @@ def summary(self, verbose=False): | |||
| 72 | 70 | times.add(r.elapsed()) | |
| 73 | 71 | ||
| 74 | 72 | if times: | |
| 75 | - print(_SUMMARY_TEMPLATE.format( | ||
| 76 | - count=len(times), | ||
| 77 | - mean=mean(times), | ||
| 78 | - stddev=stdev(times) if len(times) > 1 else 0, | ||
| 79 | - min=min(times), | ||
| 80 | - max=max(times), | ||
| 81 | - dp=self.dp, | ||
| 82 | - ), file=self.file, flush=True) | ||
| 73 | + print( | ||
| 74 | + _SUMMARY_TEMPLATE.format( | ||
| 75 | + count=len(times), | ||
| 76 | + mean=mean(times), | ||
| 77 | + stddev=stdev(times) if len(times) > 1 else 0, | ||
| 78 | + min=min(times), | ||
| 79 | + max=max(times), | ||
| 80 | + dp=self.dp, | ||
| 81 | + ), | ||
| 82 | + file=self.file, | ||
| 83 | + flush=True, | ||
| 84 | + ) | ||
| 83 | 85 | else: | |
| 84 | 86 | raise RuntimeError('timer not started') | |
| 85 | 87 | return times | |
| Back | FazBrowse Home | New Git URL |
0 commit comments