pytest_httpserver 1.1.4__tar.gz → 1.1.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/CHANGES.rst +18 -0
  2. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/PKG-INFO +1 -1
  3. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/doc/api.rst +12 -0
  4. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/doc/conf.py +1 -1
  5. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/doc/howto.rst +26 -0
  6. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/pyproject.toml +1 -1
  7. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/pytest_httpserver/__init__.py +4 -0
  8. pytest_httpserver-1.1.5/pytest_httpserver/bake.py +105 -0
  9. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/pytest_httpserver/httpserver.py +42 -0
  10. pytest_httpserver-1.1.5/tests/examples/test_howto_bake.py +25 -0
  11. pytest_httpserver-1.1.5/tests/test_bake.py +162 -0
  12. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_release.py +3 -0
  13. pytest_httpserver-1.1.4/doc/_build/doctrees/api.doctree +0 -0
  14. pytest_httpserver-1.1.4/doc/_build/doctrees/background.doctree +0 -0
  15. pytest_httpserver-1.1.4/doc/_build/doctrees/changes.doctree +0 -0
  16. pytest_httpserver-1.1.4/doc/_build/doctrees/environment.pickle +0 -0
  17. pytest_httpserver-1.1.4/doc/_build/doctrees/fixtures.doctree +0 -0
  18. pytest_httpserver-1.1.4/doc/_build/doctrees/guide.doctree +0 -0
  19. pytest_httpserver-1.1.4/doc/_build/doctrees/howto.doctree +0 -0
  20. pytest_httpserver-1.1.4/doc/_build/doctrees/index.doctree +0 -0
  21. pytest_httpserver-1.1.4/doc/_build/doctrees/tutorial.doctree +0 -0
  22. pytest_httpserver-1.1.4/doc/_build/doctrees/upgrade.doctree +0 -0
  23. pytest_httpserver-1.1.4/doc/_build/html/.buildinfo +0 -4
  24. pytest_httpserver-1.1.4/doc/_build/html/_sources/api.rst.txt +0 -118
  25. pytest_httpserver-1.1.4/doc/_build/html/_sources/background.rst.txt +0 -227
  26. pytest_httpserver-1.1.4/doc/_build/html/_sources/changes.rst.txt +0 -3
  27. pytest_httpserver-1.1.4/doc/_build/html/_sources/fixtures.rst.txt +0 -96
  28. pytest_httpserver-1.1.4/doc/_build/html/_sources/guide.rst.txt +0 -5
  29. pytest_httpserver-1.1.4/doc/_build/html/_sources/howto.rst.txt +0 -705
  30. pytest_httpserver-1.1.4/doc/_build/html/_sources/index.rst.txt +0 -46
  31. pytest_httpserver-1.1.4/doc/_build/html/_sources/tutorial.rst.txt +0 -592
  32. pytest_httpserver-1.1.4/doc/_build/html/_sources/upgrade.rst.txt +0 -75
  33. pytest_httpserver-1.1.4/doc/_build/html/_static/_sphinx_javascript_frameworks_compat.js +0 -123
  34. pytest_httpserver-1.1.4/doc/_build/html/_static/basic.css +0 -906
  35. pytest_httpserver-1.1.4/doc/_build/html/_static/css/badge_only.css +0 -1
  36. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  37. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  38. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  39. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  40. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/fontawesome-webfont.eot +0 -0
  41. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/fontawesome-webfont.svg +0 -2671
  42. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  43. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/fontawesome-webfont.woff +0 -0
  44. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  45. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/lato-bold-italic.woff +0 -0
  46. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  47. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/lato-bold.woff +0 -0
  48. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/lato-bold.woff2 +0 -0
  49. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/lato-normal-italic.woff +0 -0
  50. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  51. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/lato-normal.woff +0 -0
  52. pytest_httpserver-1.1.4/doc/_build/html/_static/css/fonts/lato-normal.woff2 +0 -0
  53. pytest_httpserver-1.1.4/doc/_build/html/_static/css/theme.css +0 -4
  54. pytest_httpserver-1.1.4/doc/_build/html/_static/doctools.js +0 -149
  55. pytest_httpserver-1.1.4/doc/_build/html/_static/documentation_options.js +0 -13
  56. pytest_httpserver-1.1.4/doc/_build/html/_static/file.png +0 -0
  57. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-bold.eot +0 -0
  58. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-bold.ttf +0 -0
  59. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-bold.woff +0 -0
  60. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-bold.woff2 +0 -0
  61. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-bolditalic.eot +0 -0
  62. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
  63. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-bolditalic.woff +0 -0
  64. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
  65. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-italic.eot +0 -0
  66. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-italic.ttf +0 -0
  67. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-italic.woff +0 -0
  68. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-italic.woff2 +0 -0
  69. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-regular.eot +0 -0
  70. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-regular.ttf +0 -0
  71. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-regular.woff +0 -0
  72. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/Lato/lato-regular.woff2 +0 -0
  73. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
  74. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
  75. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
  76. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
  77. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
  78. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
  79. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
  80. pytest_httpserver-1.1.4/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
  81. pytest_httpserver-1.1.4/doc/_build/html/_static/jquery.js +0 -2
  82. pytest_httpserver-1.1.4/doc/_build/html/_static/js/badge_only.js +0 -1
  83. pytest_httpserver-1.1.4/doc/_build/html/_static/js/theme.js +0 -1
  84. pytest_httpserver-1.1.4/doc/_build/html/_static/js/versions.js +0 -228
  85. pytest_httpserver-1.1.4/doc/_build/html/_static/language_data.js +0 -192
  86. pytest_httpserver-1.1.4/doc/_build/html/_static/minus.png +0 -0
  87. pytest_httpserver-1.1.4/doc/_build/html/_static/plus.png +0 -0
  88. pytest_httpserver-1.1.4/doc/_build/html/_static/pygments.css +0 -75
  89. pytest_httpserver-1.1.4/doc/_build/html/_static/searchtools.js +0 -635
  90. pytest_httpserver-1.1.4/doc/_build/html/_static/sphinx_highlight.js +0 -154
  91. pytest_httpserver-1.1.4/doc/_build/html/api.html +0 -1585
  92. pytest_httpserver-1.1.4/doc/_build/html/background.html +0 -316
  93. pytest_httpserver-1.1.4/doc/_build/html/changes.html +0 -685
  94. pytest_httpserver-1.1.4/doc/_build/html/fixtures.html +0 -184
  95. pytest_httpserver-1.1.4/doc/_build/html/genindex.html +0 -572
  96. pytest_httpserver-1.1.4/doc/_build/html/guide.html +0 -110
  97. pytest_httpserver-1.1.4/doc/_build/html/howto.html +0 -1141
  98. pytest_httpserver-1.1.4/doc/_build/html/index.html +0 -233
  99. pytest_httpserver-1.1.4/doc/_build/html/objects.inv +0 -0
  100. pytest_httpserver-1.1.4/doc/_build/html/py-modindex.html +0 -135
  101. pytest_httpserver-1.1.4/doc/_build/html/search.html +0 -125
  102. pytest_httpserver-1.1.4/doc/_build/html/searchindex.js +0 -1
  103. pytest_httpserver-1.1.4/doc/_build/html/tutorial.html +0 -607
  104. pytest_httpserver-1.1.4/doc/_build/html/upgrade.html +0 -178
  105. pytest_httpserver-1.1.4/tests/assets/Makefile~ +0 -19
  106. pytest_httpserver-1.1.4/tests/assets/rootCA.cnf~ +0 -17
  107. pytest_httpserver-1.1.4/tests/assets/server.cnf~ +0 -22
  108. pytest_httpserver-1.1.4/tests/assets/v3.ext~ +0 -8
  109. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/CONTRIBUTION.md +0 -0
  110. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/LICENSE +0 -0
  111. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/README.md +0 -0
  112. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/doc/Makefile +0 -0
  113. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/doc/_static/.placeholder +0 -0
  114. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/doc/background.rst +0 -0
  115. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/doc/changes.rst +0 -0
  116. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/doc/fixtures.rst +0 -0
  117. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/doc/guide.rst +0 -0
  118. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/doc/index.rst +0 -0
  119. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/doc/patch.py +0 -0
  120. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/doc/tutorial.rst +0 -0
  121. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/doc/upgrade.rst +0 -0
  122. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/example.py +0 -0
  123. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/example_pytest.py +0 -0
  124. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/pytest_httpserver/blocking_httpserver.py +0 -0
  125. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/pytest_httpserver/hooks.py +0 -0
  126. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/pytest_httpserver/py.typed +0 -0
  127. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/pytest_httpserver/pytest_plugin.py +0 -0
  128. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/assets/Makefile +0 -0
  129. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/assets/README +0 -0
  130. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/assets/rootCA.cnf +0 -0
  131. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/assets/rootCA.crt +0 -0
  132. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/assets/rootCA.key +0 -0
  133. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/assets/rootCA.srl +0 -0
  134. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/assets/server.cnf +0 -0
  135. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/assets/server.crt +0 -0
  136. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/assets/server.csr +0 -0
  137. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/assets/server.key +0 -0
  138. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/assets/v3.ext +0 -0
  139. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/conftest.py +0 -0
  140. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_example_blocking_httpserver.py +0 -0
  141. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_example_query_params1.py +0 -0
  142. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_example_query_params2.py +0 -0
  143. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_authorization_headers.py +0 -0
  144. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_case_insensitive_matcher.py +0 -0
  145. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_check.py +0 -0
  146. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_check_handler_errors.py +0 -0
  147. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_custom_handler.py +0 -0
  148. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_custom_hooks.py +0 -0
  149. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_custom_request_matcher.py +0 -0
  150. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_header_value_matcher.py +0 -0
  151. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_hooks.py +0 -0
  152. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_json_matcher.py +0 -0
  153. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_log_querying.py +0 -0
  154. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_query_params_dict.py +0 -0
  155. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_query_params_never_do_this.py +0 -0
  156. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_query_params_proper_use.py +0 -0
  157. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_readiness.py +0 -0
  158. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_regexp.py +0 -0
  159. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_timeout_requests.py +0 -0
  160. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_url_matcher.py +0 -0
  161. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/examples/test_howto_wait_success.py +0 -0
  162. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_blocking_httpserver.py +0 -0
  163. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_handler_errors.py +0 -0
  164. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_headers.py +0 -0
  165. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_hooks.py +0 -0
  166. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_ip_protocols.py +0 -0
  167. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_json_matcher.py +0 -0
  168. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_log_leak.py +0 -0
  169. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_log_querying.py +0 -0
  170. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_matcher.py +0 -0
  171. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_mixed.py +0 -0
  172. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_oneshot.py +0 -0
  173. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_ordered.py +0 -0
  174. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_parse_qs.py +0 -0
  175. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_permanent.py +0 -0
  176. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_port_changing.py +0 -0
  177. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_querymatcher.py +0 -0
  178. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_querystring.py +0 -0
  179. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_readiness.py +0 -0
  180. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_ssl.py +0 -0
  181. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_thread_type.py +0 -0
  182. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_threaded.py +0 -0
  183. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_urimatch.py +0 -0
  184. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_wait.py +0 -0
  185. {pytest_httpserver-1.1.4 → pytest_httpserver-1.1.5}/tests/test_with_statement.py +0 -0
@@ -2,6 +2,24 @@
2
2
  Release Notes
3
3
  =============
4
4
 
5
+ .. _Release Notes_1.1.5:
6
+
7
+ 1.1.5
8
+ =====
9
+
10
+ .. _Release Notes_1.1.5_New Features:
11
+
12
+ New Features
13
+ ------------
14
+
15
+ - Add ``bake()`` method to ``HTTPServer`` for creating pre-configured
16
+ request expectation proxies (``BakedHTTPServer``). This allows sharing
17
+ common keyword arguments (e.g. ``method``, ``headers``) across multiple
18
+ ``expect_request()`` calls with last-wins merging semantics.
19
+ `#470 <https://github.com/csernazs/pytest-httpserver/pull/470>`_
20
+ Contributed by `@HayaoSuzuki <https://github.com/HayaoSuzuki>`_
21
+
22
+
5
23
  .. _Release Notes_1.1.4:
6
24
 
7
25
  1.1.4
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest_httpserver
3
- Version: 1.1.4
3
+ Version: 1.1.5
4
4
  Summary: pytest-httpserver is a httpserver for pytest
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -24,6 +24,12 @@ RequestHandler
24
24
  :inherited-members:
25
25
 
26
26
 
27
+ RequestMatcherKwargs
28
+ ~~~~~~~~~~~~~~~~~~~~
29
+
30
+ .. autoclass:: RequestMatcherKwargs
31
+ :members:
32
+
27
33
  RequestMatcher
28
34
  ~~~~~~~~~~~~~~
29
35
 
@@ -31,6 +37,12 @@ RequestMatcher
31
37
  :members:
32
38
 
33
39
 
40
+ BakedHTTPServer
41
+ ~~~~~~~~~~~~~~~~
42
+
43
+ .. autoclass:: BakedHTTPServer
44
+ :members:
45
+
34
46
  BlockingHTTPServer
35
47
  ~~~~~~~~~~~~~~~~~~
36
48
 
@@ -68,7 +68,7 @@ author = "Zsolt Cserna"
68
68
  # built documents.
69
69
  #
70
70
  # The short X.Y version.
71
- version = "1.1.4"
71
+ version = "1.1.5"
72
72
  # The full version, including alpha/beta/rc tags.
73
73
  release = version
74
74
 
@@ -704,3 +704,29 @@ Example:
704
704
  will register the hooks, and hooks will be called sequentially, one by one. Each
705
705
  hook will receive the response what the previous hook returned, and the last
706
706
  hook called will return the final response which will be sent back to the client.
707
+
708
+
709
+ Reducing repetition with bake
710
+ -----------------------------
711
+
712
+ When multiple expectations share common parameters (such as headers or method),
713
+ the ``bake()`` method creates a proxy with pre-configured defaults. Keyword
714
+ arguments passed to ``bake()`` become defaults that are merged with arguments
715
+ provided at call time using last-wins semantics: if the same keyword appears in
716
+ both, the call-time value is used.
717
+
718
+ .. literalinclude :: ../tests/examples/test_howto_bake.py
719
+ :language: python
720
+
721
+ The ``bake()`` method can be chained to layer additional defaults:
722
+
723
+ .. code-block:: python
724
+
725
+ json_post = httpserver.bake(method="POST").bake(
726
+ headers={"Content-Type": "application/json"}
727
+ )
728
+
729
+ All ``expect_request``, ``expect_oneshot_request``, and
730
+ ``expect_ordered_request`` methods are available on the baked object. Other
731
+ attributes such as ``url_for()`` and ``check_assertions()`` are delegated to
732
+ the underlying server transparently.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pytest_httpserver"
3
- version = "1.1.4"
3
+ version = "1.1.5"
4
4
  description = "pytest-httpserver is a httpserver for pytest"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -6,6 +6,7 @@ This is package provides the main API for the pytest_httpserver package.
6
6
  __all__ = [
7
7
  "METHOD_ALL",
8
8
  "URI_DEFAULT",
9
+ "BakedHTTPServer",
9
10
  "BlockingHTTPServer",
10
11
  "BlockingRequestHandler",
11
12
  "Error",
@@ -15,10 +16,12 @@ __all__ = [
15
16
  "NoHandlerError",
16
17
  "RequestHandler",
17
18
  "RequestMatcher",
19
+ "RequestMatcherKwargs",
18
20
  "URIPattern",
19
21
  "WaitingSettings",
20
22
  ]
21
23
 
24
+ from .bake import BakedHTTPServer
22
25
  from .blocking_httpserver import BlockingHTTPServer
23
26
  from .blocking_httpserver import BlockingRequestHandler
24
27
  from .httpserver import METHOD_ALL
@@ -30,5 +33,6 @@ from .httpserver import HTTPServerError
30
33
  from .httpserver import NoHandlerError
31
34
  from .httpserver import RequestHandler
32
35
  from .httpserver import RequestMatcher
36
+ from .httpserver import RequestMatcherKwargs
33
37
  from .httpserver import URIPattern
34
38
  from .httpserver import WaitingSettings
@@ -0,0 +1,105 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+ from typing import Any
5
+
6
+ if TYPE_CHECKING:
7
+ import sys
8
+ from re import Pattern
9
+ from types import TracebackType
10
+
11
+ if sys.version_info >= (3, 11):
12
+ from typing import Self
13
+ else:
14
+ from typing_extensions import Self
15
+
16
+ if sys.version_info >= (3, 12):
17
+ from typing import Unpack
18
+ else:
19
+ from typing_extensions import Unpack
20
+
21
+ from .httpserver import HTTPServer
22
+ from .httpserver import RequestHandler
23
+ from .httpserver import RequestMatcherKwargs
24
+ from .httpserver import URIPattern
25
+
26
+
27
+ class BakedHTTPServer:
28
+ """
29
+ A proxy for :py:class:`HTTPServer` with pre-configured defaults for
30
+ ``expect_request()`` and related methods.
31
+
32
+ Created via :py:meth:`HTTPServer.bake`. Keyword arguments stored at bake
33
+ time are merged with arguments provided at call time using last-wins
34
+ semantics: if the same keyword appears in both, the call-time value is
35
+ used.
36
+
37
+ Any attribute not explicitly defined here is delegated to the wrapped
38
+ :py:class:`HTTPServer`, so ``url_for()``, ``check_assertions()``, etc.
39
+ work transparently.
40
+ """
41
+
42
+ def __init__(self, server: HTTPServer, **kwargs: Unpack[RequestMatcherKwargs]) -> None:
43
+ self._server = server
44
+ self._defaults = kwargs
45
+ self._context_depth: int = 0
46
+ self._started_server: bool = False
47
+
48
+ def __enter__(self) -> Self:
49
+ if self._context_depth == 0:
50
+ self._started_server = not self._server.is_running()
51
+ self._server.__enter__()
52
+ self._context_depth += 1
53
+ return self
54
+
55
+ def __exit__(
56
+ self,
57
+ exc_type: type[BaseException] | None,
58
+ exc_value: BaseException | None,
59
+ traceback: TracebackType | None,
60
+ ) -> None:
61
+ self._context_depth -= 1
62
+ if self._started_server and self._context_depth == 0:
63
+ self._server.__exit__(exc_type, exc_value, traceback)
64
+ self._started_server = False
65
+
66
+ def __getattr__(self, name: str) -> Any:
67
+ return getattr(self._server, name)
68
+
69
+ def __repr__(self) -> str:
70
+ return f"<{self.__class__.__name__} defaults={self._defaults!r} server={self._server!r}>"
71
+
72
+ def _merge_kwargs(self, kwargs: RequestMatcherKwargs) -> RequestMatcherKwargs:
73
+ return self._defaults | kwargs
74
+
75
+ def bake(self, **kwargs: Unpack[RequestMatcherKwargs]) -> Self:
76
+ """
77
+ Create a new :py:class:`BakedHTTPServer` by further layering defaults.
78
+
79
+ The new proxy merges the current defaults with the new ``kwargs``.
80
+ """
81
+ return self.__class__(self._server, **self._merge_kwargs(kwargs))
82
+
83
+ def expect_request(
84
+ self,
85
+ uri: str | URIPattern | Pattern[str],
86
+ **kwargs: Unpack[RequestMatcherKwargs],
87
+ ) -> RequestHandler:
88
+ """Create and register a request handler, using baked defaults."""
89
+ return self._server.expect_request(uri, **self._merge_kwargs(kwargs))
90
+
91
+ def expect_oneshot_request(
92
+ self,
93
+ uri: str | URIPattern | Pattern[str],
94
+ **kwargs: Unpack[RequestMatcherKwargs],
95
+ ) -> RequestHandler:
96
+ """Create and register a oneshot request handler, using baked defaults."""
97
+ return self._server.expect_oneshot_request(uri, **self._merge_kwargs(kwargs))
98
+
99
+ def expect_ordered_request(
100
+ self,
101
+ uri: str | URIPattern | Pattern[str],
102
+ **kwargs: Unpack[RequestMatcherKwargs],
103
+ ) -> RequestHandler:
104
+ """Create and register an ordered request handler, using baked defaults."""
105
+ return self._server.expect_ordered_request(uri, **self._merge_kwargs(kwargs))
@@ -24,6 +24,7 @@ from re import Pattern
24
24
  from typing import TYPE_CHECKING
25
25
  from typing import Any
26
26
  from typing import ClassVar
27
+ from typing import TypedDict
27
28
 
28
29
  import werkzeug.http
29
30
  from werkzeug import Request
@@ -32,6 +33,8 @@ from werkzeug.datastructures import Authorization
32
33
  from werkzeug.datastructures import MultiDict
33
34
  from werkzeug.serving import make_server
34
35
 
36
+ from .bake import BakedHTTPServer
37
+
35
38
  if TYPE_CHECKING:
36
39
  import sys
37
40
  from ssl import SSLContext
@@ -44,6 +47,11 @@ if TYPE_CHECKING:
44
47
  else:
45
48
  from typing_extensions import Self
46
49
 
50
+ if sys.version_info >= (3, 12):
51
+ from typing import Unpack
52
+ else:
53
+ from typing_extensions import Unpack
54
+
47
55
  URI_DEFAULT = ""
48
56
  METHOD_ALL = "__ALL"
49
57
 
@@ -285,6 +293,18 @@ class URIPattern(abc.ABC):
285
293
  """
286
294
 
287
295
 
296
+ class RequestMatcherKwargs(TypedDict, total=False):
297
+ """Keyword arguments common to ``expect_request()`` and related methods."""
298
+
299
+ method: str
300
+ data: str | bytes | None
301
+ data_encoding: str
302
+ headers: Mapping[str, str] | None
303
+ query_string: None | QueryMatcher | str | bytes | Mapping[str, str]
304
+ header_value_matcher: HVMATCHER_T | None
305
+ json: Any
306
+
307
+
288
308
  class RequestMatcher:
289
309
  """
290
310
  Matcher object for the incoming request.
@@ -1495,3 +1515,25 @@ class HTTPServer(HTTPServerBase): # pylint: disable=too-many-instance-attribute
1495
1515
  assert_msg = "\n".join(assert_msg_lines) + "\n"
1496
1516
 
1497
1517
  assert matching_count == count, assert_msg
1518
+
1519
+ def bake(self, **kwargs: Unpack[RequestMatcherKwargs]) -> BakedHTTPServer:
1520
+ """
1521
+ Create a proxy with pre-configured defaults for ``expect_request()``.
1522
+
1523
+ Keyword arguments passed here become defaults for ``expect_request()``
1524
+ and related methods. When the same keyword is provided both at bake
1525
+ time and at call time, the call-time value wins (last-wins merging).
1526
+
1527
+ Accepts the same keyword arguments as ``expect_request()`` (see
1528
+ :py:class:`RequestMatcherKwargs`).
1529
+
1530
+ :return: a :py:class:`BakedHTTPServer` proxy object.
1531
+
1532
+ Example:
1533
+
1534
+ .. code-block:: python
1535
+
1536
+ json_server = httpserver.bake(headers={"content-type": "application/json"})
1537
+ json_server.expect_request("/foo").respond_with_json({"result": "ok"})
1538
+ """
1539
+ return BakedHTTPServer(self, **kwargs)
@@ -0,0 +1,25 @@
1
+ import requests
2
+
3
+ from pytest_httpserver import HTTPServer
4
+
5
+
6
+ def test_bake_json_api(httpserver: HTTPServer) -> None:
7
+ # bake common defaults so you don't repeat them for every expect_request
8
+ json_api = httpserver.bake(method="POST", headers={"Content-Type": "application/json"})
9
+
10
+ json_api.expect_request("/users").respond_with_json({"id": 1, "name": "Alice"}, status=201)
11
+ json_api.expect_request("/items").respond_with_json({"id": 42, "name": "Widget"}, status=201)
12
+
13
+ resp = requests.post(
14
+ httpserver.url_for("/users"),
15
+ json={"name": "Alice"},
16
+ )
17
+ assert resp.status_code == 201
18
+ assert resp.json() == {"id": 1, "name": "Alice"}
19
+
20
+ resp = requests.post(
21
+ httpserver.url_for("/items"),
22
+ json={"name": "Widget"},
23
+ )
24
+ assert resp.status_code == 201
25
+ assert resp.json() == {"id": 42, "name": "Widget"}
@@ -0,0 +1,162 @@
1
+ from collections.abc import Callable
2
+
3
+ import pytest
4
+ import requests
5
+
6
+ from pytest_httpserver import BakedHTTPServer
7
+ from pytest_httpserver import HTTPServer
8
+ from pytest_httpserver import RequestMatcherKwargs
9
+
10
+
11
+ def test_bake_with_headers(httpserver: HTTPServer) -> None:
12
+ server = httpserver.bake(headers={"Content-Type": "application/json"})
13
+ server.expect_request("/foo").respond_with_json({"result": "ok"})
14
+
15
+ response = requests.get(
16
+ httpserver.url_for("/foo"),
17
+ headers={"Content-Type": "application/json"},
18
+ )
19
+ assert response.status_code == 200
20
+ assert response.json() == {"result": "ok"}
21
+
22
+
23
+ @pytest.mark.parametrize(
24
+ ("bake_chain", "expect_kwargs", "request_method"),
25
+ [
26
+ pytest.param(
27
+ lambda s: s.bake(method="POST"),
28
+ {},
29
+ "POST",
30
+ id="bake-default",
31
+ ),
32
+ pytest.param(
33
+ lambda s: s.bake(method="GET"),
34
+ {"method": "POST"},
35
+ "POST",
36
+ id="call-time-override",
37
+ ),
38
+ pytest.param(
39
+ lambda s: s.bake(method="GET").bake(method="POST"),
40
+ {},
41
+ "POST",
42
+ id="chained-override",
43
+ ),
44
+ ],
45
+ )
46
+ def test_bake_method_resolution(
47
+ httpserver: HTTPServer,
48
+ bake_chain: Callable[[HTTPServer], BakedHTTPServer],
49
+ expect_kwargs: RequestMatcherKwargs,
50
+ request_method: str,
51
+ ) -> None:
52
+ server = bake_chain(httpserver)
53
+ server.expect_request("/endpoint", **expect_kwargs).respond_with_data("ok")
54
+
55
+ response = requests.request(request_method, httpserver.url_for("/endpoint"))
56
+ assert response.status_code == 200
57
+ assert response.text == "ok"
58
+
59
+
60
+ def test_bake_chained(httpserver: HTTPServer) -> None:
61
+ server = httpserver.bake(method="POST").bake(headers={"X-Custom": "value"})
62
+ server.expect_request("/chain").respond_with_data("chained")
63
+
64
+ response = requests.post(
65
+ httpserver.url_for("/chain"),
66
+ headers={"X-Custom": "value"},
67
+ )
68
+ assert response.status_code == 200
69
+ assert response.text == "chained"
70
+
71
+
72
+ def test_bake_oneshot(httpserver: HTTPServer) -> None:
73
+ server = httpserver.bake(method="PUT")
74
+ server.expect_oneshot_request("/once").respond_with_data("once")
75
+
76
+ response = requests.put(httpserver.url_for("/once"))
77
+ assert response.status_code == 200
78
+ assert response.text == "once"
79
+
80
+ response = requests.put(httpserver.url_for("/once"))
81
+ assert response.status_code == 500
82
+
83
+
84
+ def test_bake_ordered(httpserver: HTTPServer) -> None:
85
+ server = httpserver.bake(method="GET")
86
+ server.expect_ordered_request("/first").respond_with_data("1")
87
+ server.expect_ordered_request("/second").respond_with_data("2")
88
+
89
+ response = requests.get(httpserver.url_for("/first"))
90
+ assert response.status_code == 200
91
+ assert response.text == "1"
92
+
93
+ response = requests.get(httpserver.url_for("/second"))
94
+ assert response.status_code == 200
95
+ assert response.text == "2"
96
+
97
+
98
+ def test_bake_delegates_url_for(httpserver: HTTPServer) -> None:
99
+ server = httpserver.bake(method="GET")
100
+ assert server.url_for("/path") == httpserver.url_for("/path")
101
+
102
+
103
+ def test_bake_context_manager() -> None:
104
+ server = HTTPServer()
105
+ baked = server.bake(method="GET")
106
+ with baked:
107
+ assert server.is_running()
108
+ baked.expect_request("/ctx").respond_with_data("ok")
109
+ response = requests.get(baked.url_for("/ctx"))
110
+ assert response.status_code == 200
111
+ assert response.text == "ok"
112
+ assert not server.is_running()
113
+
114
+
115
+ def test_bake_nested_context_manager() -> None:
116
+ server = HTTPServer()
117
+ with server:
118
+ with server.bake(method="GET"):
119
+ assert server.is_running()
120
+ assert server.is_running() # inner exit must not stop the server
121
+ assert not server.is_running()
122
+
123
+
124
+ def test_bake_reentrant_context_manager() -> None:
125
+ server = HTTPServer()
126
+ baked = server.bake(method="GET")
127
+ with baked:
128
+ assert server.is_running()
129
+ with baked:
130
+ assert server.is_running()
131
+ assert server.is_running() # inner exit must not stop the server
132
+ assert not server.is_running() # outer exit must stop the server
133
+
134
+
135
+ def test_bake_from_server_returns_new_object(httpserver: HTTPServer) -> None:
136
+ assert httpserver.bake(method="GET") is not httpserver.bake(method="GET")
137
+
138
+
139
+ def test_bake_from_baked_returns_new_object(httpserver: HTTPServer) -> None:
140
+ baked = httpserver.bake(method="GET")
141
+ assert baked.bake(headers={"X": "1"}) is not baked
142
+
143
+
144
+ def test_bake_repr() -> None:
145
+ server = HTTPServer(host="localhost", port=12345)
146
+ baked = server.bake(method="GET")
147
+ assert repr(baked) == "<BakedHTTPServer defaults={'method': 'GET'} server=<HTTPServer host=localhost port=12345>>"
148
+
149
+
150
+ @pytest.mark.parametrize(
151
+ "bake_chain",
152
+ [
153
+ pytest.param(lambda s: s.bake(method="GET"), id="single"),
154
+ pytest.param(lambda s: s.bake(method="GET").bake(headers={"X-Foo": "bar"}), id="chained"),
155
+ ],
156
+ )
157
+ def test_bake_returns_baked_type(
158
+ httpserver: HTTPServer,
159
+ bake_chain: Callable[[HTTPServer], BakedHTTPServer],
160
+ ) -> None:
161
+ server = bake_chain(httpserver)
162
+ assert isinstance(server, BakedHTTPServer)
@@ -163,6 +163,7 @@ def test_wheel_no_extra_contents(build: Build, version: str):
163
163
  package_contents = {path.name for path in wheel_dir.joinpath(NAME_UNDERSCORE).iterdir()}
164
164
  assert package_contents == {
165
165
  "__init__.py",
166
+ "bake.py",
166
167
  "blocking_httpserver.py",
167
168
  "hooks.py",
168
169
  "httpserver.py",
@@ -205,6 +206,7 @@ def test_sdist_contents(build: Build, version: str):
205
206
  },
206
207
  "pytest_httpserver": {
207
208
  "__init__.py",
209
+ "bake.py",
208
210
  "blocking_httpserver.py",
209
211
  "hooks.py",
210
212
  "httpserver.py",
@@ -215,6 +217,7 @@ def test_sdist_contents(build: Build, version: str):
215
217
  "assets",
216
218
  "conftest.py",
217
219
  "examples",
220
+ "test_bake.py",
218
221
  "test_blocking_httpserver.py",
219
222
  "test_handler_errors.py",
220
223
  "test_headers.py",
@@ -1,4 +0,0 @@
1
- # Sphinx build info version 1
2
- # This file records the configuration used when building these files. When it is not found, a full rebuild will be done.
3
- config: 94839d66317b50436b62af161e657c65
4
- tags: 645f666f9bcd5a90fca523b33c5a78b7
@@ -1,118 +0,0 @@
1
-
2
- .. _api-documentation:
3
-
4
- API documentation
5
- =================
6
-
7
- pytest_httpserver
8
- -----------------
9
-
10
- .. automodule:: pytest_httpserver
11
-
12
- HTTPServer
13
- ~~~~~~~~~~
14
-
15
- .. autoclass:: HTTPServer
16
- :members:
17
- :inherited-members:
18
-
19
- RequestHandler
20
- ~~~~~~~~~~~~~~
21
-
22
- .. autoclass:: RequestHandler
23
- :members:
24
- :inherited-members:
25
-
26
-
27
- RequestMatcher
28
- ~~~~~~~~~~~~~~
29
-
30
- .. autoclass:: RequestMatcher
31
- :members:
32
-
33
-
34
- BlockingHTTPServer
35
- ~~~~~~~~~~~~~~~~~~
36
-
37
- .. autoclass:: BlockingHTTPServer
38
- :members:
39
- :inherited-members:
40
-
41
- BlockingRequestHandler
42
- ~~~~~~~~~~~~~~~~~~~~~~
43
-
44
- .. autoclass:: BlockingRequestHandler
45
- :members:
46
- :inherited-members:
47
-
48
- WaitingSettings
49
- ~~~~~~~~~~~~~~~
50
-
51
- .. autoclass:: WaitingSettings
52
- :members:
53
-
54
- HeaderValueMatcher
55
- ~~~~~~~~~~~~~~~~~~
56
-
57
- .. autoclass:: HeaderValueMatcher
58
- :members:
59
-
60
- URIPattern
61
- ~~~~~~~~~~
62
-
63
- .. autoclass:: URIPattern
64
- :members:
65
-
66
- HTTPServerError
67
- ~~~~~~~~~~~~~~~
68
-
69
- .. autoclass:: HTTPServerError
70
- :members:
71
-
72
- NoHandlerError
73
- ~~~~~~~~~~~~~~
74
-
75
- .. autoclass:: NoHandlerError
76
- :members:
77
-
78
-
79
- pytest_httpserver.httpserver
80
- ----------------------------
81
- This module contains some internal classes which are normally not instantiated
82
- by the user.
83
-
84
- .. automodule:: pytest_httpserver.httpserver
85
-
86
- .. autoclass:: RequestMatcher
87
- :members:
88
-
89
- .. autoclass:: pytest_httpserver.httpserver.HTTPServerBase
90
- :members:
91
-
92
- .. autoclass:: pytest_httpserver.httpserver.Error
93
- :members:
94
-
95
- .. autoclass:: pytest_httpserver.httpserver.NoHandlerError
96
- :members:
97
-
98
- .. autoclass:: pytest_httpserver.httpserver.HTTPServerError
99
- :members:
100
-
101
- .. autoclass:: pytest_httpserver.httpserver.RequestHandlerList
102
- :members:
103
-
104
-
105
- pytest_httpserver.hooks
106
- -----------------------
107
-
108
- .. automodule:: pytest_httpserver.hooks
109
-
110
-
111
- .. autoclass:: pytest_httpserver.hooks.Chain
112
- :members:
113
-
114
- .. autoclass:: pytest_httpserver.hooks.Delay
115
- :members:
116
-
117
- .. autoclass:: pytest_httpserver.hooks.Garbage
118
- :members: