Skip to content

Commit b35e82c

Browse files
committed
better user API
1 parent dce3804 commit b35e82c

File tree

4 files changed

+28
-21
lines changed

4 files changed

+28
-21
lines changed

docs/examples/python/custom_router_easy_resolver.py

+9-11
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33

44
# Create a custom resolver that uses the following pattern: "{name:type}"
55
class CustomResolver(ReactPyResolver):
6-
def __init__(
7-
self,
8-
route,
9-
param_pattern=r"{(?P<name>\w+)(?P<type>:\w+)?}", # Match parameters that use the "{name:type}" format
10-
converters={ # Enable matching for the following types: int, str, any
11-
"int": ConversionInfo(regex=r"\d+", func=int),
12-
"str": ConversionInfo(regex=r"[^/]+", func=str),
13-
"any": ConversionInfo(regex=r".*", func=str),
14-
},
15-
) -> None:
16-
super().__init__(route, param_pattern, converters)
6+
# Match parameters that use the "<name:type>" format
7+
param_pattern = r"<(?P<name>\w+)(?P<type>:\w+)?>"
8+
9+
# Enable matching for the following types: int, str, any
10+
converters = {
11+
"int": ConversionInfo(regex=r"\d+", func=int),
12+
"str": ConversionInfo(regex=r"[^/]+", func=str),
13+
"any": ConversionInfo(regex=r".*", func=str),
14+
}

docs/examples/python/example/__init__.py

Whitespace-only changes.

src/reactpy_router/resolvers.py

+7-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22

33
import re
4-
from typing import TYPE_CHECKING
4+
from typing import TYPE_CHECKING, ClassVar
55

66
from reactpy_router.converters import CONVERTERS
77
from reactpy_router.types import MatchedRoute
@@ -17,16 +17,13 @@ class ReactPyResolver:
1717
1818
URL routing syntax for this resolver is based on Starlette, and supports a mixture of Starlette and Django parameter types."""
1919

20-
def __init__(
21-
self,
22-
route: Route,
23-
param_pattern: str = r"{(?P<name>\w+)(?P<type>:\w+)?}",
24-
converters: dict[str, ConversionInfo] | None = None,
25-
) -> None:
20+
param_pattern: str = r"{(?P<name>\w+)(?P<type>:\w+)?}"
21+
converters: ClassVar[dict[str, ConversionInfo]] = CONVERTERS
22+
23+
def __init__(self, route: Route) -> None:
2624
self.element = route.element
27-
self.registered_converters = converters or CONVERTERS
2825
self.converter_mapping: ConverterMapping = {}
29-
self.param_regex = re.compile(param_pattern)
26+
self.param_regex = re.compile(self.param_pattern)
3027
self.pattern = self.parse_path(route.path)
3128
self.key = self.pattern.pattern # Unique identifier for ReactPy rendering
3229

@@ -49,7 +46,7 @@ def parse_path(self, path: str) -> re.Pattern[str]:
4946

5047
# Check if a converter exists for the type
5148
try:
52-
conversion_info = self.registered_converters[param_type]
49+
conversion_info = self.converters[param_type]
5350
except KeyError as e:
5451
msg = f"Unknown conversion type {param_type!r} in {path!r}"
5552
raise ValueError(msg) from e

tests/test_resolver.py

+12
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ def test_resolve_any():
1717
)
1818

1919

20+
def test_custom_resolver():
21+
class CustomResolver(ReactPyResolver):
22+
param_pattern = r"<(?P<name>\w+)(?P<type>:\w+)?>"
23+
24+
resolver = CustomResolver(route("<404:any>", "Hello World"))
25+
assert resolver.parse_path("<404:any>") == re.compile("^(?P<_numeric_404>.*)$")
26+
assert resolver.converter_mapping == {"_numeric_404": str}
27+
assert resolver.resolve("/hello/world") == MatchedRoute(
28+
element="Hello World", params={"404": "/hello/world"}, path="/hello/world"
29+
)
30+
31+
2032
def test_parse_path():
2133
resolver = ReactPyResolver(route("/", None))
2234
assert resolver.parse_path("/a/b/c") == re.compile("^/a/b/c$")

0 commit comments

Comments
 (0)