|
21 | 21 | import textwrap
|
22 | 22 | import types
|
23 | 23 | import warnings
|
24 |
| -from functools import lru_cache, partial, wraps |
| 24 | +from functools import partial, wraps |
25 | 25 | from io import StringIO
|
26 | 26 | from keyword import iskeyword
|
27 | 27 | from random import _inst as global_random_instance
|
28 | 28 | from tokenize import COMMENT, detect_encoding, generate_tokens, untokenize
|
29 | 29 | from types import ModuleType
|
30 |
| -from typing import TYPE_CHECKING, Any, Callable |
| 30 | +from typing import TYPE_CHECKING, Any, Callable, MutableMapping |
31 | 31 | from unittest.mock import _patch as PatchType
|
| 32 | +from weakref import WeakKeyDictionary |
32 | 33 |
|
33 | 34 | from hypothesis.errors import HypothesisWarning
|
34 | 35 | from hypothesis.internal.compat import PYPY, is_typed_named_tuple
|
|
39 | 40 | from hypothesis.strategies._internal.strategies import T
|
40 | 41 |
|
41 | 42 | READTHEDOCS = os.environ.get("READTHEDOCS", None) == "True"
|
| 43 | +LAMBDA_SOURCE_CACHE: MutableMapping[Callable, str] = WeakKeyDictionary() |
42 | 44 |
|
43 | 45 |
|
44 | 46 | def is_mock(obj):
|
@@ -303,8 +305,7 @@ def visit_Lambda(self, node):
|
303 | 305 | SPACE_PRECEDES_CLOSE_BRACKET = re.compile(r" \)")
|
304 | 306 |
|
305 | 307 |
|
306 |
| -@lru_cache(maxsize=1024) |
307 |
| -def extract_lambda_source(f): |
| 308 | +def _extract_lambda_source(f): |
308 | 309 | """Extracts a single lambda expression from the string source. Returns a
|
309 | 310 | string indicating an unknown body if it gets confused in any way.
|
310 | 311 |
|
@@ -440,6 +441,17 @@ def extract_lambda_source(f):
|
440 | 441 | return source.strip()
|
441 | 442 |
|
442 | 443 |
|
| 444 | +def extract_lambda_source(f): |
| 445 | + try: |
| 446 | + return LAMBDA_SOURCE_CACHE[f] |
| 447 | + except KeyError: |
| 448 | + pass |
| 449 | + |
| 450 | + source = _extract_lambda_source(f) |
| 451 | + LAMBDA_SOURCE_CACHE[f] = source |
| 452 | + return source |
| 453 | + |
| 454 | + |
443 | 455 | def get_pretty_function_description(f):
|
444 | 456 | if isinstance(f, partial):
|
445 | 457 | return pretty(f)
|
@@ -493,7 +505,7 @@ def repr_call(f, args, kwargs, *, reorder=True):
|
493 | 505 | if repr_len > 30000:
|
494 | 506 | warnings.warn(
|
495 | 507 | "Generating overly large repr. This is an expensive operation, and with "
|
496 |
| - f"a length of {repr_len//1000} kB is is unlikely to be useful. Use -Wignore " |
| 508 | + f"a length of {repr_len//1000} kB is unlikely to be useful. Use -Wignore " |
497 | 509 | "to ignore the warning, or -Werror to get a traceback.",
|
498 | 510 | HypothesisWarning,
|
499 | 511 | stacklevel=2,
|
|
0 commit comments