Skip to content

Commit eff1930

Browse files
authored
Release 0.0.6. (#24)
1 parent 856f0de commit eff1930

16 files changed

+122
-105
lines changed

.conda/meta.yaml

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ build:
1313
noarch: python
1414
number: 0
1515
entry_points:
16-
- pytask = _pytask.cli:pytask
16+
- pytask = _pytask.cli:cli
1717

1818
requirements:
1919
host:
@@ -42,8 +42,9 @@ test:
4242
- tests
4343
commands:
4444
- pytask --help
45-
- pytask --markers
4645
- pytask --version
46+
- pytask clean
47+
- pytask markers
4748

4849
- pytest tests
4950

.pre-commit-config.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ repos:
2020
hooks:
2121
- id: reorder-python-imports
2222
- repo: https://github.com/psf/black
23-
rev: 19.10b0
23+
rev: 20.8b1
2424
hooks:
2525
- id: black
2626
- repo: https://github.com/asottile/blacken-docs
27-
rev: v1.7.0
27+
rev: v1.8.0
2828
hooks:
2929
- id: blacken-docs
3030
additional_dependencies: [black]
@@ -48,11 +48,11 @@ repos:
4848
Pygments,
4949
]
5050
- repo: https://github.com/PyCQA/doc8
51-
rev: 0.8.1rc3
51+
rev: 0.9.0a1
5252
hooks:
5353
- id: doc8
5454
- repo: https://github.com/econchick/interrogate
55-
rev: 1.2.0
55+
rev: 1.3.1
5656
hooks:
5757
- id: interrogate
5858
args: [-v, --fail-under=40, src, tests]

docs/conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
author = "Tobias Raabe"
2222

2323
# The full version, including alpha/beta/rc tags
24-
release = "0.0.5"
24+
release = "0.0.6"
2525

2626

2727
# -- General configuration -------------------------------------------------------------

setup.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.0.5
2+
current_version = 0.0.6
33
parse = (?P<major>\d+)\.(?P<minor>\d+)(\.(?P<patch>\d+))(\-?((dev)?(?P<dev>\d+))?)
44
serialize =
55
{major}.{minor}.{patch}dev{dev}

setup.py

+1-10
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
setup(
1717
name="pytask",
18-
version="0.0.5",
18+
version="0.0.6",
1919
description=DESCRIPTION,
2020
long_description=DESCRIPTION + "\n\n" + README,
2121
long_description_content_type="text/x-rst",
@@ -37,15 +37,6 @@
3737
],
3838
platforms="any",
3939
entry_points={"console_scripts": ["pytask=_pytask.cli:cli"]},
40-
install_requires=[
41-
"attrs>=17.4.0",
42-
"click",
43-
"click-default-group",
44-
"networkx",
45-
"pluggy",
46-
"pony>=0.7.13",
47-
],
48-
tests_require=["pexpect", "pytest"],
4940
packages=find_packages(where="src"),
5041
package_dir={"": "src"},
5142
)

src/_pytask/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.0.5"
1+
__version__ = "0.0.6"

src/_pytask/config.py

+18-10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Configure pytask."""
12
import configparser
23
import itertools
34
import os
@@ -32,10 +33,12 @@
3233
"build/*",
3334
"dist/*",
3435
]
36+
"""List[str]: List of expressions to ignore folders."""
3537

3638

3739
@hookimpl
3840
def pytask_configure(pm, config_from_cli):
41+
"""Configure pytask."""
3942
config = {"pm": pm, "terminal_width": _get_terminal_width()}
4043

4144
# Either the path to the configuration is passed via the CLI or it needs to be
@@ -88,17 +91,19 @@ def pytask_configure(pm, config_from_cli):
8891

8992
@hookimpl
9093
def pytask_parse_config(config, config_from_cli, config_from_file):
94+
"""Parse the configuration."""
9195
config_from_file["ignore"] = parse_value_or_multiline_option(
9296
config_from_file.get("ignore")
9397
)
9498

9599
config["ignore"] = (
96-
get_first_non_none_value(
97-
config_from_cli,
98-
config_from_file,
99-
key="ignore",
100-
default=[],
101-
callback=to_list,
100+
to_list(
101+
get_first_non_none_value(
102+
config_from_cli,
103+
config_from_file,
104+
key="ignore",
105+
default=[],
106+
)
102107
)
103108
+ IGNORED_FOLDERS
104109
)
@@ -117,7 +122,7 @@ def pytask_parse_config(config, config_from_cli, config_from_file):
117122

118123
@hookimpl
119124
def pytask_post_parse(config):
120-
# Sort markers alphabetically.
125+
"""Sort markers alphabetically."""
121126
config["markers"] = {k: config["markers"][k] for k in sorted(config["markers"])}
122127

123128

@@ -144,9 +149,11 @@ def _find_project_root_and_ini(paths: List[Path]):
144149
path = parent.joinpath(config_name)
145150

146151
if path.exists():
147-
config = configparser.ConfigParser()
148-
config.read(path)
149-
if "pytask" in config.sections():
152+
try:
153+
_read_config(path)
154+
except Exception:
155+
pass
156+
else:
150157
config_path = path
151158
break
152159

@@ -159,6 +166,7 @@ def _find_project_root_and_ini(paths: List[Path]):
159166

160167

161168
def _read_config(path):
169+
"""Read the configuration from a file with a [pytask] section."""
162170
config = configparser.ConfigParser()
163171
config.read(path)
164172
return dict(config["pytask"])

src/_pytask/mark/expression.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ def lex(self, input_: str) -> Iterator[Token]:
101101
pos += len(value)
102102
else:
103103
raise ParseError(
104-
pos + 1, 'unexpected character "{}"'.format(input_[pos]),
104+
pos + 1,
105+
'unexpected character "{}"'.format(input_[pos]),
105106
)
106107
yield Token(TokenType.EOF, "", pos)
107108

@@ -205,7 +206,9 @@ def compile_(cls, input_: str) -> "Expression":
205206
"""
206207
astexpr = expression(Scanner(input_))
207208
code = compile(
208-
astexpr, filename="<pytest match expression>", mode="eval",
209+
astexpr,
210+
filename="<pytest match expression>",
211+
mode="eval",
209212
) # type: types.CodeType
210213
return cls(code)
211214

src/_pytask/report.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import attr
66
import click
77
from _pytask.enums import ColorCode
8-
from _pytask.shared import remove_internal_traceback_frames_from_exc_info
8+
from _pytask.traceback import remove_internal_traceback_frames_from_exc_info
99

1010

1111
@attr.s

src/_pytask/resolve_dependencies.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from _pytask.exceptions import ResolvingDependenciesError
1414
from _pytask.mark import Mark
1515
from _pytask.report import ResolvingDependenciesReport
16-
from _pytask.shared import remove_traceback_from_exc_info
16+
from _pytask.traceback import remove_traceback_from_exc_info
1717
from pony import orm
1818

1919

src/_pytask/shared.py

+5-64
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,6 @@
22
from collections.abc import Iterable
33
from pathlib import Path
44

5-
import _pytask
6-
import pluggy
7-
8-
9-
_PLUGGY_DIRECTORY = Path(pluggy.__file__).parent
10-
_PYTASK_DIRECTORY = Path(_pytask.__file__).parent
11-
125

136
def to_list(scalar_or_iter):
147
"""Convert scalars and iterables to list.
@@ -85,23 +78,13 @@ def get_first_non_none_value(*configs, key, default=None, callback=None):
8578
>>> get_first_non_none_value({}, {}, key="a", default="default")
8679
'default'
8780
88-
>>> get_first_non_none_value({"a": None}, {"a": "b"}, key="a", callback=to_list)
89-
['b']
81+
>>> get_first_non_none_value({"a": None}, {"a": "b"}, key="a")
82+
'b'
9083
9184
"""
92-
return next(
93-
(
94-
config[key] if callback is None else callback(config[key])
95-
for config in configs
96-
if config.get(key) is not None
97-
),
98-
default,
99-
)
100-
101-
102-
def remove_traceback_from_exc_info(exc_info):
103-
"""Remove traceback from exception."""
104-
return (*exc_info[:2], None)
85+
callback = (lambda x: x) if callback is None else callback # noqa: E731
86+
processed_values = (callback(config.get(key)) for config in configs)
87+
return next((value for value in processed_values if value is not None), default)
10588

10689

10790
def parse_value_or_multiline_option(value):
@@ -110,48 +93,6 @@ def parse_value_or_multiline_option(value):
11093
return value
11194

11295

113-
def is_internal_traceback_frame(frame):
114-
"""Returns ``True`` if traceback frame belongs to internal packages.
115-
116-
Internal packages are ``_pytask`` and ``pluggy``.
117-
118-
"""
119-
path = Path(frame.tb_frame.f_code.co_filename)
120-
return any(root in path.parents for root in [_PLUGGY_DIRECTORY, _PYTASK_DIRECTORY])
121-
122-
123-
def filter_internal_traceback_frames(frame):
124-
"""Filter internal traceback frames from traceback.
125-
126-
If the first external frame is visited, return the frame. Else return ``None``.
127-
128-
"""
129-
for frame in yield_traceback_frames(frame):
130-
if frame is None or not is_internal_traceback_frame(frame):
131-
return frame
132-
133-
134-
def remove_internal_traceback_frames_from_exc_info(exc_info):
135-
"""Remove internal traceback frames from exception info.
136-
137-
If a non-internal traceback frame is found, return the traceback from the first
138-
occurrence downwards. Otherwise, return the whole traceback.
139-
140-
"""
141-
if exc_info is not None:
142-
filtered_traceback = filter_internal_traceback_frames(exc_info[2])
143-
if filtered_traceback is not None:
144-
exc_info = (*exc_info[:2], filtered_traceback)
145-
146-
return exc_info
147-
148-
149-
def yield_traceback_frames(frame):
150-
"""Yield traceback frames."""
151-
yield frame
152-
yield from yield_traceback_frames(frame.tb_next)
153-
154-
15596
def convert_truthy_or_falsy_to_bool(x):
15697
"""Convert truthy or falsy value in .ini to Python boolean."""
15798
if x in [True, "True", "true", "1"]:

src/_pytask/skipping.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from _pytask.outcomes import Skipped
88
from _pytask.outcomes import SkippedAncestorFailed
99
from _pytask.outcomes import SkippedUnchanged
10-
from _pytask.shared import remove_traceback_from_exc_info
10+
from _pytask.traceback import remove_traceback_from_exc_info
1111

1212

1313
def skip_ancestor_failed(reason: str = "No reason provided.") -> str:

src/_pytask/traceback.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"""Process tracebacks."""
2+
from pathlib import Path
3+
4+
import _pytask
5+
import pluggy
6+
7+
_PLUGGY_DIRECTORY = Path(pluggy.__file__).parent
8+
_PYTASK_DIRECTORY = Path(_pytask.__file__).parent
9+
10+
11+
def remove_traceback_from_exc_info(exc_info):
12+
"""Remove traceback from exception."""
13+
return (*exc_info[:2], None)
14+
15+
16+
def remove_internal_traceback_frames_from_exc_info(exc_info):
17+
"""Remove internal traceback frames from exception info.
18+
19+
If a non-internal traceback frame is found, return the traceback from the first
20+
occurrence downwards. Otherwise, return the whole traceback.
21+
22+
"""
23+
if exc_info is not None:
24+
filtered_traceback = _filter_internal_traceback_frames(exc_info[2])
25+
if filtered_traceback is not None:
26+
exc_info = (*exc_info[:2], filtered_traceback)
27+
28+
return exc_info
29+
30+
31+
def _is_internal_traceback_frame(frame):
32+
"""Returns ``True`` if traceback frame belongs to internal packages.
33+
34+
Internal packages are ``_pytask`` and ``pluggy``.
35+
36+
"""
37+
path = Path(frame.tb_frame.f_code.co_filename)
38+
return any(root in path.parents for root in [_PLUGGY_DIRECTORY, _PYTASK_DIRECTORY])
39+
40+
41+
def _filter_internal_traceback_frames(frame):
42+
"""Filter internal traceback frames from traceback.
43+
44+
If the first external frame is visited, return the frame. Else return ``None``.
45+
46+
"""
47+
for frame in _yield_traceback_frames(frame):
48+
if frame is None or not _is_internal_traceback_frame(frame):
49+
return frame
50+
51+
52+
def _yield_traceback_frames(frame):
53+
"""Yield traceback frames."""
54+
yield frame
55+
yield from _yield_traceback_frames(frame.tb_next)

src/pytask/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
from _pytask.config import hookimpl
44
from _pytask.mark import MARK_GEN as mark # noqa: N811
55

6-
__all__ = ["cli", "hookimpl", "main", "mark", "pytask"]
7-
__version__ = "0.0.5"
6+
__all__ = ["cli", "hookimpl", "main", "mark"]
7+
__version__ = "0.0.6"

tests/test_mark.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,14 @@ def task_func(arg):
237237
"foo or or",
238238
"at column 8: expected not OR left parenthesis OR identifier; got or",
239239
),
240-
("(foo", "at column 5: expected right parenthesis; got end of input",),
241-
("foo bar", "at column 5: expected end of input; got identifier",),
240+
(
241+
"(foo",
242+
"at column 5: expected right parenthesis; got end of input",
243+
),
244+
(
245+
"foo bar",
246+
"at column 5: expected end of input; got identifier",
247+
),
242248
(
243249
"or or",
244250
"at column 1: expected not OR left parenthesis OR identifier; got or",

0 commit comments

Comments
 (0)