microdot 2.6.0__tar.gz → 2.6.1__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 (124) hide show
  1. {microdot-2.6.0/src/microdot.egg-info → microdot-2.6.1}/PKG-INFO +1 -1
  2. microdot-2.6.1/docs/implementation/type_hints.rst +16 -0
  3. {microdot-2.6.0 → microdot-2.6.1}/docs/index.rst +2 -2
  4. {microdot-2.6.0 → microdot-2.6.1}/docs/users-guide/concurrency.rst +4 -4
  5. {microdot-2.6.0 → microdot-2.6.1}/docs/users-guide/responses.rst +1 -1
  6. {microdot-2.6.0 → microdot-2.6.1}/pyproject.toml +1 -1
  7. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/__init__.py +1 -1
  8. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/microdot.py +3 -1
  9. {microdot-2.6.0 → microdot-2.6.1/src/microdot.egg-info}/PKG-INFO +1 -1
  10. {microdot-2.6.0 → microdot-2.6.1}/src/microdot.egg-info/SOURCES.txt +1 -0
  11. {microdot-2.6.0 → microdot-2.6.1}/tests/test_response.py +7 -0
  12. {microdot-2.6.0 → microdot-2.6.1}/LICENSE +0 -0
  13. {microdot-2.6.0 → microdot-2.6.1}/MANIFEST.in +0 -0
  14. {microdot-2.6.0 → microdot-2.6.1}/README.md +0 -0
  15. {microdot-2.6.0 → microdot-2.6.1}/docs/Makefile +0 -0
  16. {microdot-2.6.0 → microdot-2.6.1}/docs/_static/css/custom.css +0 -0
  17. {microdot-2.6.0 → microdot-2.6.1}/docs/api/asgi.rst +0 -0
  18. {microdot-2.6.0 → microdot-2.6.1}/docs/api/auth.rst +0 -0
  19. {microdot-2.6.0 → microdot-2.6.1}/docs/api/cors.rst +0 -0
  20. {microdot-2.6.0 → microdot-2.6.1}/docs/api/csrf.rst +0 -0
  21. {microdot-2.6.0 → microdot-2.6.1}/docs/api/index.rst +0 -0
  22. {microdot-2.6.0 → microdot-2.6.1}/docs/api/jinja.rst +0 -0
  23. {microdot-2.6.0 → microdot-2.6.1}/docs/api/login.rst +0 -0
  24. {microdot-2.6.0 → microdot-2.6.1}/docs/api/microdot.rst +0 -0
  25. {microdot-2.6.0 → microdot-2.6.1}/docs/api/multipart.rst +0 -0
  26. {microdot-2.6.0 → microdot-2.6.1}/docs/api/sessions.rst +0 -0
  27. {microdot-2.6.0 → microdot-2.6.1}/docs/api/sse.rst +0 -0
  28. {microdot-2.6.0 → microdot-2.6.1}/docs/api/test_client.rst +0 -0
  29. {microdot-2.6.0 → microdot-2.6.1}/docs/api/utemplate.rst +0 -0
  30. {microdot-2.6.0 → microdot-2.6.1}/docs/api/websocket.rst +0 -0
  31. {microdot-2.6.0 → microdot-2.6.1}/docs/api/wsgi.rst +0 -0
  32. {microdot-2.6.0 → microdot-2.6.1}/docs/conf.py +0 -0
  33. {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/auth.rst +0 -0
  34. {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/cors.rst +0 -0
  35. {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/csrf.rst +0 -0
  36. {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/index.rst +0 -0
  37. {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/login.rst +0 -0
  38. {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/multipart.rst +0 -0
  39. {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/production.rst +0 -0
  40. {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/sessions.rst +0 -0
  41. {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/sse.rst +0 -0
  42. {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/templates.rst +0 -0
  43. {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/test_client.rst +0 -0
  44. {microdot-2.6.0 → microdot-2.6.1}/docs/extensions/websocket.rst +0 -0
  45. {microdot-2.6.0 → microdot-2.6.1}/docs/implementation/freezing.rst +0 -0
  46. {microdot-2.6.0 → microdot-2.6.1}/docs/implementation/index.rst +0 -0
  47. {microdot-2.6.0 → microdot-2.6.1}/docs/implementation/migrating.rst +0 -0
  48. {microdot-2.6.0 → microdot-2.6.1}/docs/intro.rst +0 -0
  49. {microdot-2.6.0 → microdot-2.6.1}/docs/make.bat +0 -0
  50. {microdot-2.6.0 → microdot-2.6.1}/docs/users-guide/defining-routes.rst +0 -0
  51. {microdot-2.6.0 → microdot-2.6.1}/docs/users-guide/index.rst +0 -0
  52. {microdot-2.6.0 → microdot-2.6.1}/docs/users-guide/intro.rst +0 -0
  53. {microdot-2.6.0 → microdot-2.6.1}/docs/users-guide/request-object.rst +0 -0
  54. {microdot-2.6.0 → microdot-2.6.1}/setup.cfg +0 -0
  55. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/__init__.pyi +0 -0
  56. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/asgi.py +0 -0
  57. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/asgi.pyi +0 -0
  58. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/auth.py +0 -0
  59. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/auth.pyi +0 -0
  60. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/cors.py +0 -0
  61. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/cors.pyi +0 -0
  62. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/csrf.py +0 -0
  63. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/csrf.pyi +0 -0
  64. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/helpers.py +0 -0
  65. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/helpers.pyi +0 -0
  66. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/jinja.py +0 -0
  67. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/jinja.pyi +0 -0
  68. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/login.py +0 -0
  69. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/login.pyi +0 -0
  70. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/microdot.pyi +0 -0
  71. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/multipart.py +0 -0
  72. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/multipart.pyi +0 -0
  73. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/py.typed +0 -0
  74. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/session.py +0 -0
  75. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/session.pyi +0 -0
  76. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/sse.py +0 -0
  77. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/sse.pyi +0 -0
  78. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/test_client.py +0 -0
  79. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/test_client.pyi +0 -0
  80. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/utemplate.py +0 -0
  81. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/utemplate.pyi +0 -0
  82. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/websocket.py +0 -0
  83. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/websocket.pyi +0 -0
  84. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/wsgi.py +0 -0
  85. {microdot-2.6.0 → microdot-2.6.1}/src/microdot/wsgi.pyi +0 -0
  86. {microdot-2.6.0 → microdot-2.6.1}/src/microdot.egg-info/dependency_links.txt +0 -0
  87. {microdot-2.6.0 → microdot-2.6.1}/src/microdot.egg-info/not-zip-safe +0 -0
  88. {microdot-2.6.0 → microdot-2.6.1}/src/microdot.egg-info/requires.txt +0 -0
  89. {microdot-2.6.0 → microdot-2.6.1}/src/microdot.egg-info/top_level.txt +0 -0
  90. {microdot-2.6.0 → microdot-2.6.1}/tests/__init__.py +0 -0
  91. {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.bin +0 -0
  92. {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.css +0 -0
  93. {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.gif +0 -0
  94. {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.gz +0 -0
  95. {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.html +0 -0
  96. {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.jpg +0 -0
  97. {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.js +0 -0
  98. {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.json +0 -0
  99. {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.png +0 -0
  100. {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.txt +0 -0
  101. {microdot-2.6.0 → microdot-2.6.1}/tests/files/test.txt.gz +0 -0
  102. {microdot-2.6.0 → microdot-2.6.1}/tests/mock_socket.py +0 -0
  103. {microdot-2.6.0 → microdot-2.6.1}/tests/templates/hello.jinja.txt +0 -0
  104. {microdot-2.6.0 → microdot-2.6.1}/tests/templates/hello.utemplate.txt +0 -0
  105. {microdot-2.6.0 → microdot-2.6.1}/tests/templates/hello_utemplate_txt.py +0 -0
  106. {microdot-2.6.0 → microdot-2.6.1}/tests/test_asgi.py +0 -0
  107. {microdot-2.6.0 → microdot-2.6.1}/tests/test_auth.py +0 -0
  108. {microdot-2.6.0 → microdot-2.6.1}/tests/test_cors.py +0 -0
  109. {microdot-2.6.0 → microdot-2.6.1}/tests/test_csrf.py +0 -0
  110. {microdot-2.6.0 → microdot-2.6.1}/tests/test_end2end.py +0 -0
  111. {microdot-2.6.0 → microdot-2.6.1}/tests/test_jinja.py +0 -0
  112. {microdot-2.6.0 → microdot-2.6.1}/tests/test_login.py +0 -0
  113. {microdot-2.6.0 → microdot-2.6.1}/tests/test_microdot.py +0 -0
  114. {microdot-2.6.0 → microdot-2.6.1}/tests/test_multidict.py +0 -0
  115. {microdot-2.6.0 → microdot-2.6.1}/tests/test_multipart.py +0 -0
  116. {microdot-2.6.0 → microdot-2.6.1}/tests/test_request.py +0 -0
  117. {microdot-2.6.0 → microdot-2.6.1}/tests/test_session.py +0 -0
  118. {microdot-2.6.0 → microdot-2.6.1}/tests/test_sse.py +0 -0
  119. {microdot-2.6.0 → microdot-2.6.1}/tests/test_url_pattern.py +0 -0
  120. {microdot-2.6.0 → microdot-2.6.1}/tests/test_urlencode.py +0 -0
  121. {microdot-2.6.0 → microdot-2.6.1}/tests/test_utemplate.py +0 -0
  122. {microdot-2.6.0 → microdot-2.6.1}/tests/test_websocket.py +0 -0
  123. {microdot-2.6.0 → microdot-2.6.1}/tests/test_wsgi.py +0 -0
  124. {microdot-2.6.0 → microdot-2.6.1}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microdot
3
- Version: 2.6.0
3
+ Version: 2.6.1
4
4
  Summary: The impossibly small web framework for MicroPython
5
5
  Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/miguelgrinberg/microdot
@@ -0,0 +1,16 @@
1
+ Type Hints
2
+ ~~~~~~~~~~
3
+
4
+ Since version 2.6.0, Microdot includes standard Python type hints for all
5
+ public classes, methods, attributes and functions. This allows IDEs such as
6
+ Visual Studio Code, PyCharm and Vim/Neovim to provide type information and
7
+ autocompletion functions as you type.
8
+
9
+ Type hints are provided in standard stub files with the *.pyi* extension.
10
+ Install Microdot with ``pip``, ``uv`` or your favorite installer to have these
11
+ added to your virtual environment.
12
+
13
+ .. note::
14
+ The *.pyi* stub files are only meant to be used on your computer, to help
15
+ your IDE provide better coding assistance while you type. It is not
16
+ necessary to copy these files to your MicroPython device.
@@ -9,8 +9,8 @@ Microdot
9
9
  *"The impossibly small web framework for Python and MicroPython"*
10
10
 
11
11
  Microdot is a minimalistic Python web framework inspired by
12
- `Flask <https://flask.palletsprojects.com/>`_. Given its size, it can run on
13
- systems with limited resources such as microcontrollers. Both standard Python
12
+ `Flask <https://flask.palletsprojects.com/>`_. Given its small size, it can run
13
+ on systems with limited resources such as microcontrollers. Both standard Python
14
14
  (CPython) and `MicroPython <https://micropython.org>`_ are supported.
15
15
 
16
16
  .. toctree::
@@ -8,7 +8,7 @@ that applications must be careful to prevent blocking in their handlers.
8
8
  ^^^^^^^^^^^^^^^^^^^^
9
9
 
10
10
  The recommendation for route handlers in Microdot is to use asynchronous
11
- functions, declared as ``async def``. Microdot executes these handler
11
+ functions, declared with ``async def``. Microdot executes these handler
12
12
  functions as native asynchronous tasks. The standard considerations for writing
13
13
  asynchronous code apply, and in particular blocking calls should be avoided to
14
14
  ensure the application runs smoothly and is always responsive.
@@ -24,9 +24,9 @@ When running on CPython, Microdot executes synchronous handlers in a
24
24
  `thread executor <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor>`_,
25
25
  which uses a thread pool. The use of blocking or CPU intensive code in these
26
26
  handlers does not have such a negative effect on the application, because
27
- handlers do not run on the same thread as the asynchronous loop. On the other
28
- hand, the application will be affected by threading issues such as those caused
29
- by the Global Interpreter Lock.
27
+ the handlers run on a different threads than the one running the asynchronous
28
+ loop. On the other hand, the application will be affected by threading issues
29
+ such as those caused by the Global Interpreter Lock.
30
30
 
31
31
  Under MicroPython the situation is different. Most microcontroller boards
32
32
  do not have or have very limited threading support, so Microdot executes
@@ -196,5 +196,5 @@ Another option is to create a response object directly in the route function::
196
196
  Standard cookies do not offer sufficient privacy and security controls, so
197
197
  never store sensitive information in them unless you are adding additional
198
198
  protection mechanisms such as encryption or cryptographic signing. The
199
- :ref:`session <Maintaining Secure User Sessions>` extension implements signed
199
+ :ref:`session <Secure User Sessions>` extension implements signed
200
200
  cookies that prevent tampering by malicious actors.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "microdot"
3
- version = "2.6.0"
3
+ version = "2.6.1"
4
4
  authors = [
5
5
  { name = "Miguel Grinberg", email = "miguel.grinberg@gmail.com" },
6
6
  ]
@@ -1,4 +1,4 @@
1
1
  from microdot.microdot import Microdot, Request, Response, abort, redirect, \
2
2
  send_file, URLPattern, AsyncBytesIO, iscoroutine # noqa: F401
3
3
 
4
- __version__ = '2.6.0'
4
+ __version__ = '2.6.1'
@@ -630,6 +630,8 @@ class Response:
630
630
  http_cookie += '; HttpOnly'
631
631
  if partitioned:
632
632
  http_cookie += '; Partitioned'
633
+ if '\r' in http_cookie or '\n' in http_cookie:
634
+ raise ValueError('invalid cookie')
633
635
  if 'Set-Cookie' in self.headers:
634
636
  self.headers['Set-Cookie'].append(http_cookie)
635
637
  else:
@@ -762,7 +764,7 @@ class Response:
762
764
  :param status_code: The 3xx status code to use for the redirect. The
763
765
  default is 302.
764
766
  """
765
- if '\x0d' in location or '\x0a' in location:
767
+ if '\r' in location or '\n' in location:
766
768
  raise ValueError('invalid redirect URL')
767
769
  return cls(status_code=status_code, headers={'Location': location})
768
770
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microdot
3
- Version: 2.6.0
3
+ Version: 2.6.1
4
4
  Summary: The impossibly small web framework for MicroPython
5
5
  Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/miguelgrinberg/microdot
@@ -39,6 +39,7 @@ docs/extensions/websocket.rst
39
39
  docs/implementation/freezing.rst
40
40
  docs/implementation/index.rst
41
41
  docs/implementation/migrating.rst
42
+ docs/implementation/type_hints.rst
42
43
  docs/users-guide/concurrency.rst
43
44
  docs/users-guide/defining-routes.rst
44
45
  docs/users-guide/index.rst
@@ -194,6 +194,13 @@ class TestResponse(unittest.TestCase):
194
194
  secure=True, http_only=True)
195
195
  res.delete_cookie('foo8', http_only=True)
196
196
  res.delete_cookie('foo9', path='/s')
197
+ with self.assertRaises(ValueError):
198
+ res.set_cookie('foo1', 'bar1\r\nSet-Cookie: foo2=bar2')
199
+ with self.assertRaises(ValueError):
200
+ res.set_cookie('foo1', 'bar1',
201
+ domain='example.com\r\nSet-Cookie: foo2=bar2')
202
+ with self.assertRaises(ValueError):
203
+ res.set_cookie('foo1', 'bar1', path='/\r\nSet-Cookie: foo2=bar2')
197
204
  self.assertEqual(res.headers, {'Set-Cookie': [
198
205
  'foo1=bar1',
199
206
  'foo2=bar2; Path=/; Partitioned',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes