sain.default
The default trait for types that can have a default implementation.
Example
from sain import Default
class Generator(Default[str]):
@staticmethod
def default() -> str:
return generator.random_str()
DEFAULT_GENERATOR = Generator.default()
1# BSD 3-Clause License 2# 3# Copyright (c) 2022-Present, nxtlo 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 9# * Redistributions of source code must retain the above copyright notice, this 10# list of conditions and the following disclaimer. 11# 12# * Redistributions in binary form must reproduce the above copyright notice, 13# this list of conditions and the following disclaimer in the documentation 14# and/or other materials provided with the distribution. 15# 16# * Neither the name of the copyright holder nor the names of its 17# contributors may be used to endorse or promote products derived from 18# this software without specific prior written permission. 19# 20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30"""The default trait for types that can have a default implementation. 31 32Example 33------- 34```py 35 36from sain import Default 37 38class Generator(Default[str]): 39 @staticmethod 40 def default() -> str: 41 return generator.random_str() 42 43DEFAULT_GENERATOR = Generator.default() 44``` 45""" 46 47from __future__ import annotations 48 49__all__ = ("Default",) 50 51import typing 52 53from .macros import rustc_diagnostic_item 54 55_T_co = typing.TypeVar("_T_co", covariant=True) 56 57 58@rustc_diagnostic_item("Default") 59@typing.runtime_checkable 60class Default(typing.Protocol[_T_co]): 61 """An interface for an object that has a default value. 62 63 Example 64 ------- 65 ```py 66 from sain import Default 67 68 class Cache(Default[dict[str, Any]]): 69 70 @staticmethod 71 def default() -> dict[str, Any]: 72 return {} 73 74 cache = Cache.default() 75 print(cache) 76 assert isinstance(cache, Default) 77 # {} 78 ``` 79 """ 80 81 __slots__ = () 82 83 # FIXME: `impl Default for String` knows the type of `Self` is `String` but we can't do that. 84 # So generics is the only way to achieve the same effect. But `Default` in Rust is not generic. 85 # in the future we just swap to `Self`. 86 @rustc_diagnostic_item("default_fn") 87 @staticmethod 88 def default() -> _T_co: 89 """Return the default value of the object.""" 90 raise NotImplementedError
@rustc_diagnostic_item('Default')
@typing.runtime_checkable
class
Default59@rustc_diagnostic_item("Default") 60@typing.runtime_checkable 61class Default(typing.Protocol[_T_co]): 62 """An interface for an object that has a default value. 63 64 Example 65 ------- 66 ```py 67 from sain import Default 68 69 class Cache(Default[dict[str, Any]]): 70 71 @staticmethod 72 def default() -> dict[str, Any]: 73 return {} 74 75 cache = Cache.default() 76 print(cache) 77 assert isinstance(cache, Default) 78 # {} 79 ``` 80 """ 81 82 __slots__ = () 83 84 # FIXME: `impl Default for String` knows the type of `Self` is `String` but we can't do that. 85 # So generics is the only way to achieve the same effect. But `Default` in Rust is not generic. 86 # in the future we just swap to `Self`. 87 @rustc_diagnostic_item("default_fn") 88 @staticmethod 89 def default() -> _T_co: 90 """Return the default value of the object.""" 91 raise NotImplementedError
An interface for an object that has a default value.
Example
from sain import Default
class Cache(Default[dict[str, Any]]):
@staticmethod
def default() -> dict[str, Any]:
return {}
cache = Cache.default()
print(cache)
assert isinstance(cache, Default)
# {}
Implementations
This class implements Default in Rust.
Default(*args, **kwargs)
1941def _no_init_or_replace_init(self, *args, **kwargs): 1942 cls = type(self) 1943 1944 if cls._is_protocol: 1945 raise TypeError('Protocols cannot be instantiated') 1946 1947 # Already using a custom `__init__`. No need to calculate correct 1948 # `__init__` to call. This can lead to RecursionError. See bpo-45121. 1949 if cls.__init__ is not _no_init_or_replace_init: 1950 return 1951 1952 # Initially, `__init__` of a protocol subclass is set to `_no_init_or_replace_init`. 1953 # The first instantiation of the subclass will call `_no_init_or_replace_init` which 1954 # searches for a proper new `__init__` in the MRO. The new `__init__` 1955 # replaces the subclass' old `__init__` (ie `_no_init_or_replace_init`). Subsequent 1956 # instantiation of the protocol subclass will thus use the new 1957 # `__init__` and no longer call `_no_init_or_replace_init`. 1958 for base in cls.__mro__: 1959 init = base.__dict__.get('__init__', _no_init_or_replace_init) 1960 if init is not _no_init_or_replace_init: 1961 cls.__init__ = init 1962 break 1963 else: 1964 # should not happen 1965 cls.__init__ = object.__init__ 1966 1967 cls.__init__(self, *args, **kwargs)