Skip to content

Commit 8d194f2

Browse files
Merge pull request #127 from ZeroIntensity/fix-sync-routes
Fix Synchronous Routes
2 parents d92d26c + 96746e1 commit 8d194f2

9 files changed

Lines changed: 217 additions & 107 deletions

File tree

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
run: pip install --upgrade --pre ward
4040

4141
- name: Install project
42-
run: pip install .[templates]
42+
run: pip install .[full]
4343

4444
- name: Run tests
4545
run: ward

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111
- Added environment prefixes for database configuration
1212
- Added `templates` and `TemplatesConfig` to config
1313
- Added the `templates` function
14-
- Added support for `attrs` in type validation.
14+
- Added support for `attrs` in type validation
15+
- Removed `psutil` and `plotext` as a global dependency
16+
- Added `fancy` optional dependencies
17+
- Fixed route inputs with synchronous routes
18+
- **Breaking Change:** Route inputs are now applied in the order of the decorator call as it appears in code
1519

1620
## [1.0.0-alpha7] - 2023-12-7
1721

pyproject.toml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,8 @@ dependencies = [
2626
"typing_extensions",
2727
"ujson",
2828
"configzen",
29-
"psutil",
30-
"plotext",
3129
"uvicorn",
3230
"aiofiles",
33-
"aiohttp",
3431
]
3532
dynamic = ["version", "license"]
3633

@@ -46,6 +43,21 @@ databases = [
4643
"aiosqlite"
4744
]
4845
templates = ["beautifulsoup4", "jinja2", "mako", "django", "chameleon"]
46+
fancy = ["psutil", "plotext"]
47+
full = [
48+
"psutil",
49+
"plotext",
50+
"beautifulsoup4",
51+
"jinja2",
52+
"mako",
53+
"django",
54+
"chameleon",
55+
"attrs",
56+
"psycopg2-binary",
57+
"mysql-connector-python",
58+
"pymongo",
59+
"aiosqlite"
60+
]
4961

5062
[project.urls]
5163
Documentation = "https://view.zintensity.dev"

src/_view/app.c

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,7 @@ static int handle_route_impl(
18991899
ViewApp* self;
19001900
Py_ssize_t* size;
19011901
PyObject** path_params;
1902+
19021903
if (PyAwaitable_UnpackValues(
19031904
awaitable,
19041905
&self,
@@ -1933,14 +1934,14 @@ static int handle_route_impl(
19331934
NULL
19341935
);
19351936
}
1937+
19361938
PyObject** params = json_parser(
19371939
&self->parsers,
19381940
body,
19391941
query_obj,
19401942
r->inputs,
19411943
r->inputs_size
19421944
);
1943-
19441945
Py_DECREF(query_obj);
19451946

19461947
if (!params) {
@@ -1977,7 +1978,6 @@ static int handle_route_impl(
19771978
NULL
19781979
);
19791980

1980-
19811981
for (int i = 0; i < r->inputs_size + *size; i++)
19821982
Py_DECREF(merged[i]);
19831983

@@ -1992,22 +1992,33 @@ static int handle_route_impl(
19921992
NULL
19931993
);
19941994

1995-
for (int i = 0; i < r->inputs_size; i++) {
1995+
for (int i = 0; i < r->inputs_size; i++)
19961996
Py_DECREF(params[i]);
1997-
}
19981997
}
19991998

2000-
if (!coro) {
1999+
if (!coro)
20012000
return -1;
2002-
}
20032001

2004-
if (PyAwaitable_AddAwait(
2005-
awaitable,
2006-
coro,
2007-
handle_route_callback,
2008-
route_error
2009-
) < 0) {
2010-
return -1;
2002+
if (!Py_IS_TYPE(coro, &PyCoro_Type)) {
2003+
if (handle_route_callback(awaitable, coro) < 0) {
2004+
if (fire_error(
2005+
self,
2006+
awaitable,
2007+
500,
2008+
r,
2009+
NULL
2010+
) < 0)
2011+
return -1;
2012+
}
2013+
} else {
2014+
if (PyAwaitable_AddAwait(
2015+
awaitable,
2016+
coro,
2017+
handle_route_callback,
2018+
route_error
2019+
) < 0) {
2020+
return -1;
2021+
}
20112022
}
20122023

20132024
return 0;
@@ -2045,7 +2056,6 @@ static int body_inc_buf(PyObject* awaitable, PyObject* result) {
20452056
return -1;
20462057
}
20472058

2048-
20492059
char* buf;
20502060
Py_ssize_t* size;
20512061
char* query;
@@ -2226,9 +2236,8 @@ static int handle_route_query(PyObject* awaitable, char* query) {
22262236
);
22272237
if (!parsed_item) {
22282238
PyErr_Clear();
2229-
for (int i = 0; i < r->inputs_size; i++) {
2239+
for (int i = 0; i < r->inputs_size; i++)
22302240
Py_XDECREF(params[i]);
2231-
}
22322241

22332242
free(params);
22342243
Py_DECREF(query_obj);
@@ -2274,18 +2283,30 @@ static int handle_route_query(PyObject* awaitable, char* query) {
22742283
free(params);
22752284
Py_DECREF(query_obj);
22762285

2277-
22782286
if (!coro)
22792287
return -1;
22802288

2281-
if (PyAwaitable_AddAwait(
2282-
awaitable,
2283-
coro,
2284-
handle_route_callback,
2285-
route_error
2286-
) < 0) {
2287-
Py_DECREF(coro);
2288-
return -1;
2289+
if (!Py_IS_TYPE(coro, &PyCoro_Type)) {
2290+
if (handle_route_callback(awaitable, coro) < 0) {
2291+
if (fire_error(
2292+
self,
2293+
awaitable,
2294+
500,
2295+
r,
2296+
NULL
2297+
) < 0)
2298+
return -1;
2299+
}
2300+
} else {
2301+
if (PyAwaitable_AddAwait(
2302+
awaitable,
2303+
coro,
2304+
handle_route_callback,
2305+
route_error
2306+
) < 0) {
2307+
Py_DECREF(coro);
2308+
return -1;
2309+
}
22892310
}
22902311

22912312
Py_DECREF(coro);
@@ -2880,6 +2901,7 @@ static PyObject* app(
28802901
} else {
28812902
res_coro = PyObject_CallNoArgs(r->callable);
28822903
}
2904+
28832905
if (!res_coro) {
28842906
Py_DECREF(awaitable);
28852907
free(path);
@@ -2898,9 +2920,9 @@ static PyObject* app(
28982920
return awaitable;
28992921
}
29002922

2901-
if (!PyObject_IsInstance(
2923+
if (!Py_IS_TYPE(
29022924
res_coro,
2903-
(PyObject*) &PyCoro_Type
2925+
&PyCoro_Type
29042926
)) {
29052927
if (handle_route_callback(
29062928
awaitable,

src/view/_loader.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def _format_body(
141141
default=default,
142142
)
143143
vbody_defaults[k] = default
144-
144+
145145
return [
146146
(TYPECODE_CLASSTYPES, k, v, vbody_defaults[k])
147147
for k, v in vbody_final.items()
@@ -421,6 +421,7 @@ def finalize(routes: list[Route], app: ViewApp):
421421
virtual_routes[route.path or ""] = [route]
422422

423423
sig = inspect.signature(route.func)
424+
route.inputs = [i for i in reversed(route.inputs)]
424425
if len(sig.parameters) != len(route.inputs):
425426
names = [i.name for i in route.inputs]
426427
for k, v in sig.parameters.items():

0 commit comments

Comments
 (0)