Skip to content

Commit

Permalink
f-strings!
Browse files Browse the repository at this point in the history
  • Loading branch information
Zac-HD committed Mar 31, 2024
1 parent e6567e5 commit f4c983a
Show file tree
Hide file tree
Showing 13 changed files with 61 additions and 79 deletions.
7 changes: 2 additions & 5 deletions hypothesis-python/docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -389,11 +389,8 @@ The :pypi:`schemathesis` package provides an excellent example of this!
data[d] = "null"
else:
data[d] = str(v)
result = requests.post(
"https://waspfinder.example.com/api/v1/users/"
"%s/goals.json" % (waspfinder_user,),
data=data,
)
url = f"https://waspfinder.example.com/api/users/{waspfinder_user}/goals.json"
result = requests.post(url, data=data)
# Let's not hammer the API too badly. This will of course make the
# tests even slower than they otherwise would have been, but that's
Expand Down
28 changes: 12 additions & 16 deletions hypothesis-python/src/hypothesis/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -956,18 +956,15 @@ def run(data):
if k.startswith("execute:")
)
):
took_ms = exception.runtime.total_seconds() * 1000
deadline_ms = self.settings.deadline.total_seconds() * 1000
report(
"Unreliable test timings! On an initial run, this "
"test took %.2fms, which exceeded the deadline of "
"%.2fms, but on a subsequent run it took %.2f ms, "
"which did not. If you expect this sort of "
"variability in your test timings, consider turning "
f"test took {took_ms:.2f}ms, which exceeded the deadline of "
f"{deadline_ms:.2f}ms, but on a subsequent run it took "
f"{runtime_secs * 1000:.2f} ms, which did not. If you expect "
"this sort of variability in your test timings, consider turning "
"deadlines off for this test by setting deadline=None."
% (
exception.runtime.total_seconds() * 1000,
self.settings.deadline.total_seconds() * 1000,
runtime_secs * 1000,
)
)
else:
report("Failed to reproduce exception. Expected: \n" + traceback)
Expand Down Expand Up @@ -1241,10 +1238,10 @@ def run_engine(self):
# Whether or not replay actually raised the exception again, we want
# to print the reproduce_failure decorator for the failing example.
if self.settings.print_blob:
enc = encode_failure(falsifying_example.buffer)
fragments.append(
"\nYou can reproduce this example by temporarily adding "
"@reproduce_failure(%r, %r) as a decorator on your test case"
% (__version__, encode_failure(falsifying_example.buffer))
f"@reproduce_failure({__version__!r}, {enc!r}) as a decorator on your test case"
)
# Mostly useful for ``find`` and ensuring that objects that
# hold on to a reference to ``data`` know that it's now been
Expand Down Expand Up @@ -1527,11 +1524,10 @@ def wrapped_test(*arguments, **kwargs):
expected_version, failure = reproduce_failure
if expected_version != __version__:
raise InvalidArgument(
"Attempting to reproduce a failure from a different "
"version of Hypothesis. This failure is from %s, but "
"you are currently running %r. Please change your "
"Hypothesis version to a matching one."
% (expected_version, __version__)
"Attempting to reproduce a failure from a different version "
f"of Hypothesis. This failure is from {expected_version}, but "
f"you are currently running {__version__!r}. Please change "
"your Hypothesis version to a matching one."
)
try:
state.execute_once(
Expand Down
5 changes: 3 additions & 2 deletions hypothesis-python/src/hypothesis/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.


class HypothesisException(Exception):
"""Generic parent class for exceptions thrown by Hypothesis."""

Expand Down Expand Up @@ -150,8 +151,8 @@ class DeadlineExceeded(_Trimmable):

def __init__(self, runtime, deadline):
super().__init__(
"Test took %.2fms, which exceeds the deadline of %.2fms"
% (runtime.total_seconds() * 1000, deadline.total_seconds() * 1000)
f"Test took {runtime.total_seconds() * 1000:.2f}ms, which "
f"exceeds the deadline of {deadline.total_seconds() * 1000:.2f}ms"
)
self.runtime = runtime
self.deadline = deadline
Expand Down
20 changes: 10 additions & 10 deletions hypothesis-python/src/hypothesis/extra/numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,8 @@ def set_element(self, val, result, idx, *, fill=False):
# This branch only exists to help debug weird behaviour in Numpy,
# such as the string problems we had a while back.
raise HypothesisException(
"Internal error when checking element=%r of %r to array of %r"
% (val, val.dtype, result.dtype)
f"Internal error when checking element={val!r} "
f"of {val.dtype!r} for array of {result.dtype!r}"
) from err
if elem_changed:
strategy = self.fill if fill else self.element_strategy
Expand All @@ -283,11 +283,11 @@ def set_element(self, val, result, idx, *, fill=False):
"allow_subnormal=False."
)
raise InvalidArgument(
"Generated array element %r from %r cannot be represented as "
"dtype %r - instead it becomes %r (type %r). Consider using a more "
"precise strategy, for example passing the `width` argument to "
f"Generated array element {val!r} from {strategy!r} cannot be "
f"represented as dtype {self.dtype!r} - instead it becomes "
f"{result[idx]!r} (type {type(result[idx])!r}). Consider using a "
"more precise strategy, for example passing the `width` argument to "
"`floats()`."
% (val, strategy, self.dtype, result[idx], type(result[idx]))
)

def do_draw(self, data):
Expand Down Expand Up @@ -399,10 +399,10 @@ def do_draw(self, data):
mismatch = out != result
if mismatch.any():
raise InvalidArgument(
"Array elements %r cannot be represented as dtype %r - instead "
"they become %r. Use a more precise strategy, e.g. without "
"trailing null bytes, as this will be an error future versions."
% (result[mismatch], self.dtype, out[mismatch])
f"Array elements {result[mismatch]!r} cannot be represented as "
f"dtype {self.dtype!r} - instead they become {out[mismatch]!r}. "
"Use a more precise strategy, e.g. without trailing null bytes, "
"as this will be an error future versions."
)
result = out

Expand Down
8 changes: 4 additions & 4 deletions hypothesis-python/src/hypothesis/extra/pandas/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ def convert_element(value):
return np.array([value], dtype=dtype)[0]
except (TypeError, ValueError):
raise InvalidArgument(
"Cannot convert %s=%r of type %s to dtype %s"
% (name, value, type(value).__name__, dtype.str)
f"Cannot convert {name}={value!r} of type "
f"{type(value).__name__} to dtype {dtype.str}"
) from None

elements = elements.map(convert_element)
Expand Down Expand Up @@ -719,8 +719,8 @@ def assign_rows(draw):
for k in row:
if k not in column_names:
raise InvalidArgument(
"Row %r contains column %r not in columns %r)"
% (row, k, [c.name for c in rewritten_columns])
f"Row {row!r} contains column {k!r} not in columns "
f"{[c.name for c in rewritten_columns]!r})"
)
row = as_list
if any_unique:
Expand Down
6 changes: 3 additions & 3 deletions hypothesis-python/src/hypothesis/stateful.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ def _repr_step(self, rule, data, result):
output_assignment = ", ".join(output_names) + " = "
else:
output_assignment = self._last_names(1)[0] + " = "
args = ", ".join("%s=%s" % kv for kv in data.items())
args = ", ".join(f"{k}={v}" for k, v in data.items())
return f"{output_assignment}state.{rule.function.__name__}({args})"

def _add_result_to_targets(self, targets, result):
Expand Down Expand Up @@ -586,8 +586,8 @@ def _convert_targets(targets, target):
if target is not None:
if targets:
raise InvalidArgument(
"Passing both targets=%r and target=%r is redundant - pass "
"targets=%r instead." % (targets, target, (*targets, target))
f"Passing both targets={targets!r} and target={target!r} is "
f"redundant - pass targets={(*targets, target)!r} instead."
)
targets = (target,)

Expand Down
4 changes: 2 additions & 2 deletions hypothesis-python/src/hypothesis/strategies/_internal/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,8 +519,8 @@ def fixed_dictionaries(
check_strategy(v, f"optional[{k!r}]")
if type(mapping) != type(optional):
raise InvalidArgument(
"Got arguments of different types: mapping=%s, optional=%s"
% (nicerepr(type(mapping)), nicerepr(type(optional)))
f"Got arguments of different types: mapping={nicerepr(type(mapping))}, "
f"optional={nicerepr(type(optional))}"
)
if set(mapping) & set(optional):
raise InvalidArgument(
Expand Down
12 changes: 6 additions & 6 deletions hypothesis-python/src/hypothesis/strategies/_internal/numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,15 @@ def integers(
if min_value is not None:
if min_value != int(min_value):
raise InvalidArgument(
"min_value=%r of type %r cannot be exactly represented as an integer."
% (min_value, type(min_value))
f"min_value={min_value!r} of type {type(min_value)!r} "
f"cannot be exactly represented as an integer."
)
min_value = int(min_value)
if max_value is not None:
if max_value != int(max_value):
raise InvalidArgument(
"max_value=%r of type %r cannot be exactly represented as an integer."
% (max_value, type(max_value))
f"max_value={max_value!r} of type {type(max_value)!r} "
f"cannot be exactly represented as an integer."
)
max_value = int(max_value)

Expand Down Expand Up @@ -416,8 +416,8 @@ def floats(
# This is a custom alternative to check_valid_interval, because we want
# to include the bit-width and exclusion information in the message.
msg = (
"There are no %s-bit floating-point values between min_value=%r "
"and max_value=%r" % (width, min_arg, max_arg)
f"There are no {width}-bit floating-point values between "
f"min_value={min_arg!r} and max_value={max_arg!r}"
)
if exclude_min or exclude_max:
msg += f", {exclude_min=} and {exclude_max=}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ def example(self) -> Ex:
"The `.example()` method is good for exploring strategies, but should "
"only be used interactively. We recommend using `@given` for tests - "
"it performs better, saves and replays failures to avoid flakiness, "
"and reports minimal examples. (strategy: %r)" % (self,),
f"and reports minimal examples. (strategy: {self!r})",
NonInteractiveExampleWarning,
stacklevel=2,
)
Expand Down Expand Up @@ -1042,6 +1042,6 @@ def check_strategy(arg, name=""):
if name:
name += "="
raise InvalidArgument(
"Expected a SearchStrategy%s but got %s%r (type=%s)"
% (hint, name, arg, type(arg).__name__)
f"Expected a SearchStrategy{hint} but got "
f"{name}{arg!r} (type={type(arg).__name__})"
)
4 changes: 2 additions & 2 deletions hypothesis-python/tests/common/debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ def inner(x):
except Found:
return result
raise Unsatisfiable(
"Could not find any examples from %r that satisfied %s"
% (definition, get_pretty_function_description(condition))
f"Could not find any examples from {definition!r} that satisfied "
f"{get_pretty_function_description(condition)}"
)


Expand Down
30 changes: 11 additions & 19 deletions hypothesis-python/tests/cover/test_regex.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,40 +69,32 @@ def unicode_regex(pattern):
return re.compile(pattern, re.UNICODE)


def _test_matching_pattern(pattern, *, isvalidchar, is_unicode=False):
r = unicode_regex(pattern) if is_unicode else ascii_regex(pattern)

codepoints = range(sys.maxunicode + 1) if is_unicode else range(1, 128)
for c in [chr(x) for x in codepoints]:
if isvalidchar(c):
msg = "%r supposed to match %r (%r, category %r), but it doesn't"
assert r.search(c), msg % (pattern, c, c, unicodedata.category(c))
else:
assert not r.search(c), (
'"%s" supposed not to match "%s" (%r, category "%s"), '
"but it does" % (pattern, c, c, unicodedata.category(c))
)


@pytest.mark.parametrize(
"category,predicate", [(r"\w", is_word), (r"\d", is_digit), (r"\s", None)]
"pattern, predicate", [(r"\w", is_word), (r"\d", is_digit), (r"\s", None)]
)
@pytest.mark.parametrize("invert", [False, True])
@pytest.mark.parametrize("is_unicode", [False, True])
def test_matching(category, predicate, invert, is_unicode):
def test_matching(pattern, predicate, invert, is_unicode):
if predicate is None:
# Special behaviour due to \x1c, INFORMATION SEPARATOR FOUR
predicate = is_unicode_space if is_unicode else is_space
if invert:
category = category.swapcase()
pattern = pattern.swapcase()

def pred(s):
return not predicate(s)

else:
pred = predicate

_test_matching_pattern(category, isvalidchar=pred, is_unicode=is_unicode)
r = unicode_regex(pattern) if is_unicode else ascii_regex(pattern)

codepoints = range(sys.maxunicode + 1) if is_unicode else range(1, 128)
for c in [chr(x) for x in codepoints]:
if pred(c):
assert r.search(c), f"{pattern=} {c=} {unicodedata.category(c)=}"
else:
assert not r.search(c), f"{pattern=} {c=} {unicodedata.category(c)=}"


@pytest.mark.parametrize(
Expand Down
4 changes: 1 addition & 3 deletions website/content/2016-05-11-generating-the-right-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ class Project:
self.end = end

def __repr__(self):
return "Project {} from {} to {}".format(
self.name, self.start.isoformat(), self.end.isoformat()
)
return f"Project {self.name} from {self.start.isoformat()} to {self.end.isoformat()}"
```

A project has a name, a start date, and an end date.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,11 @@ that look like the following:
```python
def plurality_winner(election):
counts = Counter(vote[0] for vote in election)
alternatives = candidates_for_election(election)
winning_score = max(counts.values())
winners = [c for c, v in counts.items() if v == winning_score]
if len(winners) > 1:
return None
else:
if len(winners) == 1:
return winners[0]
return None
```

That is, they take a list of individual votes, each expressed
Expand Down

0 comments on commit f4c983a

Please sign in to comment.