Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/hypothesis/configuration.py: 59%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

41 statements  

1# This file is part of Hypothesis, which may be found at 

2# https://github.com/HypothesisWorks/hypothesis/ 

3# 

4# Copyright the Hypothesis Authors. 

5# Individual contributors are listed in AUTHORS.rst and the git log. 

6# 

7# This Source Code Form is subject to the terms of the Mozilla Public License, 

8# v. 2.0. If a copy of the MPL was not distributed with this file, You can 

9# obtain one at https://mozilla.org/MPL/2.0/. 

10 

11import os 

12import sys 

13import warnings 

14from pathlib import Path 

15 

16import _hypothesis_globals 

17 

18from hypothesis.errors import HypothesisSideeffectWarning 

19 

20__hypothesis_home_directory_default = Path.cwd() / ".hypothesis" 

21__hypothesis_home_directory = None 

22 

23 

24def set_hypothesis_home_dir(directory: str | Path | None) -> None: 

25 global __hypothesis_home_directory 

26 __hypothesis_home_directory = None if directory is None else Path(directory) 

27 

28 

29def storage_directory(*names: str, intent_to_write: bool = True) -> Path: 

30 if intent_to_write: 

31 check_sideeffect_during_initialization( 

32 "accessing storage for {}", "/".join(names) 

33 ) 

34 

35 global __hypothesis_home_directory 

36 if not __hypothesis_home_directory: 

37 if where := os.getenv("HYPOTHESIS_STORAGE_DIRECTORY"): 

38 __hypothesis_home_directory = Path(where) 

39 if not __hypothesis_home_directory: 

40 __hypothesis_home_directory = __hypothesis_home_directory_default 

41 return __hypothesis_home_directory.joinpath(*names) 

42 

43 

44_first_postinit_what = None 

45 

46 

47def check_sideeffect_during_initialization( 

48 what: str, *fmt_args: object, is_restart: bool = False 

49) -> None: 

50 """Called from locations that should not be executed during initialization, for example 

51 touching disk or materializing lazy/deferred strategies from plugins. If initialization 

52 is in progress, a warning is emitted. 

53 

54 Note that computing the repr can take nontrivial time or memory, so we avoid doing so 

55 unless (and until) we're actually emitting the warning. 

56 """ 

57 global _first_postinit_what 

58 # This is not a particularly hot path, but neither is it doing productive work, so we want to 

59 # minimize the cost by returning immediately. The drawback is that we require 

60 # notice_initialization_restarted() to be called if in_initialization changes away from zero. 

61 if _first_postinit_what is not None: 

62 return 

63 elif _hypothesis_globals.in_initialization > 0: 

64 msg = what.format(*fmt_args) 

65 if is_restart: 

66 when = "between importing hypothesis and loading the hypothesis plugin" 

67 elif "_hypothesis_pytestplugin" in sys.modules or os.getenv( 

68 "HYPOTHESIS_EXTEND_INITIALIZATION" 

69 ): 

70 when = "during pytest plugin or conftest initialization" 

71 else: # pragma: no cover 

72 # This can be triggered by Hypothesis plugins, but is really annoying 

73 # to test automatically - drop st.text().example() in hypothesis.run() 

74 # to manually confirm that we get the warning. 

75 when = "at import time" 

76 # Note: -Werror is insufficient under pytest, as doesn't take effect until 

77 # test session start. 

78 text = ( 

79 f"Slow code in plugin: avoid {msg} {when}! Set PYTHONWARNINGS=error " 

80 "to get a traceback and show which plugin is responsible." 

81 ) 

82 if is_restart: 

83 text += " Additionally, set HYPOTHESIS_EXTEND_INITIALIZATION=1 to pinpoint the exact location." 

84 warnings.warn( 

85 text, 

86 HypothesisSideeffectWarning, 

87 stacklevel=3, 

88 ) 

89 else: 

90 _first_postinit_what = (what, fmt_args) 

91 

92 

93def notice_initialization_restarted(*, warn: bool = True) -> None: 

94 """Reset _first_postinit_what, so that we don't think we're in post-init. Additionally, if it 

95 was set that means that there has been a sideeffect that we haven't warned about, so do that 

96 now (the warning text will be correct, and we also hint that the stacktrace can be improved). 

97 """ 

98 global _first_postinit_what 

99 if _first_postinit_what is not None: 

100 what, *fmt_args = _first_postinit_what 

101 _first_postinit_what = None 

102 if warn: 

103 check_sideeffect_during_initialization( 

104 what, 

105 *fmt_args, 

106 is_restart=True, 

107 )