Skip to content

Commit

Permalink
Simplify converter registration
Browse files Browse the repository at this point in the history
  • Loading branch information
ahopkins committed Dec 20, 2021
1 parent 5eab29a commit f21abf6
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 19 deletions.
29 changes: 12 additions & 17 deletions sanic/config.py
@@ -1,6 +1,5 @@
from __future__ import annotations

from collections import deque
from inspect import getmembers, isclass, isdatadescriptor
from os import environ
from pathlib import Path
Expand Down Expand Up @@ -49,16 +48,6 @@
DEPRECATED_CONFIG = ("SERVER_RUNNING", "RELOADER_PROCESS", "RELOADED_FILES")


class CastRegistry(deque):
def add(self, cast: Callable[[str], Any]) -> None:
if cast in self:
error_logger.warning(
f"Type cast '{cast.__name__}' has already been registered"
)
return None
self.appendleft(cast)


class DescriptorMeta(type):
def __init__(cls, *_):
cls.__setters__ = {name for name, _ in getmembers(cls, cls._is_setter)}
Expand Down Expand Up @@ -106,11 +95,12 @@ def __init__(
defaults = defaults or {}
super().__init__({**DEFAULT_CONFIG, **defaults})

self._cast_registry = CastRegistry((int, float, str_to_bool, str))
self._converters = [str, str_to_bool, float, int]
self._LOGO = ""

if converters:
self.register_type(*converters)
for converter in converters:
self.register_type(converter)

if keep_alive is not None:
self.KEEP_ALIVE = keep_alive
Expand Down Expand Up @@ -244,7 +234,7 @@ def __init__(self, name) -> None:

_, config_key = key.split(prefix, 1)

for converter in self._cast_registry:
for converter in reversed(self._converters):
try:
self[config_key] = converter(value)
break
Expand Down Expand Up @@ -320,11 +310,16 @@ class C:

load = update_config

def register_type(self, *cast: Callable[[str], Any]) -> None:
def register_type(self, converter: Callable[[str], Any]) -> None:
"""
Allows for adding custom function to cast from a string value to any
other type. The function should raise ValueError if it is not the
correct type.
"""
for item in cast:
self._cast_registry.add(item)
if converter in self._converters:
error_logger.warning(
f"Configuration value converter '{converter.__name__}' has "
"already been registered"
)
return
self._converters.append(converter)
6 changes: 4 additions & 2 deletions tests/test_config.py
Expand Up @@ -158,14 +158,16 @@ def test_add_converter_multiple_times(caplog):
def converter():
...

message = "Type cast 'converter' has already been registered"
message = (
"Configuration value converter 'converter' has already been registered"
)
config = Config()
config.register_type(converter)
with caplog.at_level(logging.WARNING):
config.register_type(converter)

assert ("sanic.error", logging.WARNING, message) in caplog.record_tuples
assert len(config._cast_registry) == 5
assert len(config._converters) == 5


def test_load_from_file(app):
Expand Down

0 comments on commit f21abf6

Please sign in to comment.