fresco 3.3.3__py3-none-any.whl → 3.4.0__py3-none-any.whl

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.

Potentially problematic release.


This version of fresco might be problematic. Click here for more details.

fresco/__init__.py CHANGED
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  #
15
- __version__ = "3.3.3"
15
+ __version__ = "3.4.0"
16
16
 
17
17
  DEFAULT_CHARSET = "UTF-8"
18
18
 
fresco/options.py CHANGED
@@ -127,6 +127,12 @@ class Options(dict):
127
127
  Where filename contain multiple tags, all tags must match for the file
128
128
  to be loaded.
129
129
 
130
+ Files are processed in the order that tags are specified in the
131
+ ``tags`` parameter, and then in lexicographical order.
132
+ For example, calling ``options.load(..., tags=["dev", "local"])`` would
133
+ cause a file named "settings.dev" to be loaded before one named
134
+ "settings.local".
135
+
130
136
  Tag names may contain the names of environment variable surrounded by
131
137
  braces, for example ``{USER}``. These will be substituted for the
132
138
  environment variable's value, with any dots or path separators replaced
@@ -210,9 +216,13 @@ class Options(dict):
210
216
  ts[1]
211
217
  for ts in sorted(
212
218
  tagged_sources,
213
- key=lambda ts: -1
214
- if len(ts[0]) == 0
215
- else min(tags.index(t) for t in ts[0]),
219
+ key=(
220
+ lambda ts: (
221
+ ([], ts[1])
222
+ if len(ts[0]) == 0 else
223
+ (sorted(tags.index(t) for t in ts[0]), ts[1])
224
+ )
225
+ )
216
226
  )
217
227
  ]
218
228
  else:
fresco/routing.py CHANGED
@@ -107,6 +107,9 @@ ALL_METHODS = HTTP_METHODS = set(
107
107
  + RFC5789_METHODS
108
108
  )
109
109
 
110
+ #: Shortcut for specifying all methods as a kwarg
111
+ ALL = "ALL"
112
+
110
113
  __all__ = [
111
114
  "ALL_METHODS",
112
115
  "Pattern",
@@ -803,10 +806,16 @@ class Route(object):
803
806
  "HTTP methods must be specified as a string or iterable"
804
807
  )
805
808
  for m in methods:
809
+ if m == ALL:
810
+ methods = ALL_METHODS
811
+ break
806
812
  if m not in ALL_METHODS:
807
813
  raise ValueError("{!r} is not a valid HTTP method".format(m))
808
814
  method_view_map.update((m, view) for m in methods)
809
815
 
816
+ if view := _kwargs.pop("ALL", None):
817
+ method_view_map |= {m: view for m in ALL_METHODS}
818
+
810
819
  for method in ALL_METHODS:
811
820
  if method in _kwargs:
812
821
  method_view_map[method] = _kwargs.pop(method)
@@ -1386,7 +1395,7 @@ class RouteCollection(MutableSequence):
1386
1395
 
1387
1396
  def _get_routes(
1388
1397
  self, key: Tuple[t.Optional[str], str]
1389
- ) -> t.Sequence[t.Tuple[Route, t.Optional[PathMatch]]]:
1398
+ ) -> t.Sequence[t.Tuple[Route, PathMatch]]:
1390
1399
  method, path = key
1391
1400
  routes = ((r, r.match(path, method)) for r in self.__routes__)
1392
1401
  return [(r, t) for (r, t) in routes if t is not None]
@@ -216,10 +216,15 @@ class TestLoadOptions:
216
216
  def test_it_loads_in_tag_order(self, tmpdir):
217
217
  with self.check_loadoptions(
218
218
  tmpdir,
219
- {"a.dev.txt": "a = dev", "a.local.txt": "a = local"},
219
+ {
220
+ "a": "a = 0",
221
+ "a.dev.txt": "a = ${a}-1",
222
+ "a.local.txt": "a = ${a}-2",
223
+ "b.dev.txt": "a = ${a}-3",
224
+ },
220
225
  ) as loadopts:
221
- assert loadopts("*", ["dev", "local"]) == {"a": "local"}
222
- assert loadopts("*", ["local", "dev"]) == {"a": "dev"}
226
+ assert loadopts("*", ["dev", "local"]) == {"a": "0-1-3-2"}
227
+ assert loadopts("*", ["local", "dev"]) == {"a": "0-2-1-3"}
223
228
 
224
229
  def test_it_loads_from_os_environ(self, tmpdir):
225
230
  with setenv(a="2"):
@@ -27,7 +27,9 @@ from fresco.core import urlfor
27
27
  from fresco.exceptions import NotFound
28
28
  from fresco.response import Response
29
29
  from fresco.routing import ALL_METHODS
30
+ from fresco.routing import ALL
30
31
  from fresco.routing import GET
32
+ from fresco.routing import OPTIONS
31
33
  from fresco.routing import POST
32
34
  from fresco.routing import (
33
35
  Route,
@@ -114,6 +116,21 @@ class TestRouteConstructor(object):
114
116
  with pytest.raises(ValueError):
115
117
  Route("/", ["GET", "FOO"], lambda: None)
116
118
 
119
+ def test_ALL_kwarg_routes_all_methods(self):
120
+ def view():
121
+ return Response()
122
+
123
+ app = FrescoApp()
124
+ app.route("/x", ALL, view)
125
+ assert len(list(app.get_route_traversals("/x", GET))) == 1
126
+ assert len(list(app.get_route_traversals("/x", POST))) == 1
127
+ assert len(list(app.get_route_traversals("/x", OPTIONS))) == 1
128
+
129
+ app.route("/y", ALL=view)
130
+ assert len(list(app.get_route_traversals("/y", GET))) == 1
131
+ assert len(list(app.get_route_traversals("/y", POST))) == 1
132
+ assert len(list(app.get_route_traversals("/y", OPTIONS))) == 1
133
+
117
134
 
118
135
  class TestRouteBeforeHooks(object):
119
136
  def test_hook_is_called(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fresco
3
- Version: 3.3.3
3
+ Version: 3.4.0
4
4
  Summary: A Web/WSGI micro-framework
5
5
  Author-email: Oliver Cope <oliver@redgecko.org>
6
6
  License: Apache
@@ -1,16 +1,16 @@
1
- fresco/__init__.py,sha256=q7o1b5uoXjD0qXFnnM2oLCJDwUgJvkcrnL785B9wl3I,3520
1
+ fresco/__init__.py,sha256=rteQgLzbeRKgdSkiDL_0ey72k3neyI5FtDIG8LR9vxA,3520
2
2
  fresco/cookie.py,sha256=Qnx8yOjU4LUJ1fqi7YvqbhAA01rCsclJGl_fxI68slw,7055
3
3
  fresco/core.py,sha256=mwYR6UP0zRSjcFlNZf51-otX9EcmvgjEZ7GDVQoQexg,26615
4
4
  fresco/decorators.py,sha256=84NUpRJ-M7GK6wDl42bmCRSvgoWzCsy1huyvGnSAPPw,3232
5
5
  fresco/exceptions.py,sha256=KE-LoYUGnho6KltzkU6cnm9vUiUhAiDIjPqn5ba-YCA,4410
6
6
  fresco/middleware.py,sha256=uCAuOtBnvaVBJGrQa8ecvLkSZ6aSKmWaJqxB8Rv4SsQ,4173
7
7
  fresco/multidict.py,sha256=0CaNNIcFnZ1hLk3NExhNvjc_BtK4zVB26L9gP_7MeNM,13362
8
- fresco/options.py,sha256=JneUzO1Ep4c3UbX-1icBZ9cZGheVmZAXdvegrbI39mw,13614
8
+ fresco/options.py,sha256=Z1EZPRoEAqYHm2hg7gRmLtMWMKWjNgGVehPtCU66mBE,14068
9
9
  fresco/request.py,sha256=dC7pMg-4Kxa6PcqaaWFL4JviANQotuBjoKwlxZYywRY,27048
10
10
  fresco/requestcontext.py,sha256=P-SkKJkKLYVqNiR2zwooRROnSnE2VMj2P2-eD5DW5Qg,3504
11
11
  fresco/response.py,sha256=ADKHbtAGyhwtaUJxB7m_1nqVdZRKUryebmG4FDUjZVY,37072
12
12
  fresco/routeargs.py,sha256=dxNlqbQ1FrgIY6OCFzcEMdZ0OVyjlMQdQGLmUJgdPYU,10176
13
- fresco/routing.py,sha256=NxWPuVI3_zSSuAgNMeQY-3DPfb1FtAUmG7oRtotPoMM,58721
13
+ fresco/routing.py,sha256=S33ysM6BJEKxWZh7mdPO6-Eep2t1s0Q_qlrev84iNIY,58977
14
14
  fresco/static.py,sha256=9SKQ3P1YFTP45Qiic-ycvkpKRvqIURp1XSzPazTmYLI,2513
15
15
  fresco/subrequests.py,sha256=wFJWLuhVAcei5imYc5NBSCBaHBEm-X4_XswPtK3O4Zw,11081
16
16
  fresco/types.py,sha256=UHITRMDoS90s2zV2wNpqLFhRWESfaBAMuQnL4c21mqY,106
@@ -23,12 +23,12 @@ fresco/tests/test_decorators.py,sha256=VFXHo1gm2jldQXeaEF3NNo5fnpdJ-LXc8-vNymPJK
23
23
  fresco/tests/test_exceptions.py,sha256=R0Tn86m33iTKecZ69TgH4CqY9XSFP0FsLMH10O5Jth8,973
24
24
  fresco/tests/test_middleware.py,sha256=D_sWfX-w3bhItOm54nB_cuYPGoWopISvZCFIuMX68cU,3137
25
25
  fresco/tests/test_multidict.py,sha256=uDwDYII0dvVxaEyDO85zRTWlIWw3LO3StzYemJVm0E0,7565
26
- fresco/tests/test_options.py,sha256=3h62x2ZgKavQ0qmpkKxQ2kbnEb50AgrTvG-PMOqs428,10868
26
+ fresco/tests/test_options.py,sha256=Zx1tLVLeok8tO3dWua2PyTPZgeWbXFMXtN3FnorBmC8,10998
27
27
  fresco/tests/test_request.py,sha256=hoANrergrohlAeTbQufDMfIbvYURsPyPjCxOVKz7bVo,16389
28
28
  fresco/tests/test_requestcontext.py,sha256=t8hm-lzIk85ryb3sdlpVoPQyLDWpCjB86dg8nVG1yRw,3115
29
29
  fresco/tests/test_response.py,sha256=MrhHIDg81pJlTeEcn2rGtU-i59s1KzEccF81u4Up6xs,8934
30
30
  fresco/tests/test_routeargs.py,sha256=VMWUbrXegTLN9Tx2AcrpbjAAEaxAANzkcy02SmpFOmY,8162
31
- fresco/tests/test_routing.py,sha256=yfZGon6vKwszFp3pCP2Mtnf3W3u4WdELdvVcgIKHOVU,37890
31
+ fresco/tests/test_routing.py,sha256=nOg3daHL8UigPEykHzgLKmlTOYtD4n_VjoBVfMsQcYo,38565
32
32
  fresco/tests/test_static.py,sha256=y73dqzE2flpACQ_dvNhDzk_WlvNQfkhYF_8YY4MMGDo,4686
33
33
  fresco/tests/test_subrequests.py,sha256=7rluJnw-elXRXfrzvAQvGBHRBU93zwnL827mTxBGd3Y,7909
34
34
  fresco/tests/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -50,8 +50,8 @@ fresco/util/security.py,sha256=nXEdoCak_2c4OA1L1wGwhZygS22s2fzwR0Kp-DdwKZg,1058
50
50
  fresco/util/textproc.py,sha256=e5jLTofKCqdm6_Fy8XOyR43AJr5APtL59Kd8cNA9PrQ,2309
51
51
  fresco/util/urls.py,sha256=aaVovLyXNlVoGviiLN94ImqXf-LTQs_xooEIyi3LBc4,9195
52
52
  fresco/util/wsgi.py,sha256=2cr2b92RpvPSgS_P46X2mlYepoFg9Qji-V-fzxpSNzw,12971
53
- fresco-3.3.3.dist-info/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
54
- fresco-3.3.3.dist-info/METADATA,sha256=Yze5uNMocy7RORadQyMAjKAm5W2FMkN3DYaqc7cA470,1549
55
- fresco-3.3.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
56
- fresco-3.3.3.dist-info/top_level.txt,sha256=p_1aMce5Shjq9fIfdbB-aN8wCDhjF_iYnn98bUebbII,7
57
- fresco-3.3.3.dist-info/RECORD,,
53
+ fresco-3.4.0.dist-info/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
54
+ fresco-3.4.0.dist-info/METADATA,sha256=Kk7LvAhriUF3HHAIb0ZFoTyADsgD_Czx3arDrYQCVoU,1549
55
+ fresco-3.4.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
56
+ fresco-3.4.0.dist-info/top_level.txt,sha256=p_1aMce5Shjq9fIfdbB-aN8wCDhjF_iYnn98bUebbII,7
57
+ fresco-3.4.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (75.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5