diff --git a/bases/__init__.py b/bases/__init__.py
index 55d1fc6..3c7ffe2 100644
--- a/bases/__init__.py
+++ b/bases/__init__.py
@@ -57,7 +57,7 @@
"""
-__version__ = "0.1.1"
+__version__ = "0.2.0"
from . import encoding as encoding
from . import alphabet as alphabet
diff --git a/bases/alphabet/__init__.py b/bases/alphabet/__init__.py
index 80efd8a..38275cd 100644
--- a/bases/alphabet/__init__.py
+++ b/bases/alphabet/__init__.py
@@ -45,6 +45,7 @@
import re
from typing import Collection, Dict, Iterator, Optional, overload, Tuple, Union
from typing_extensions import Literal
+from typing_validation import validate
from .abstract import Alphabet as Alphabet
from .string_alphabet import StringAlphabet as StringAlphabet
@@ -63,6 +64,7 @@ def get(name: str) -> Alphabet:
StringAlphabet('0123456789ABCDEF')
```
"""
+ validate(name, str)
if name not in _alphabets:
raise KeyError(f"Alphabet named {repr(name)} does not exist.")
return _alphabets[name]
@@ -79,6 +81,7 @@ def has(name: str) -> bool:
True
```
"""
+ validate(name, str)
return name in _alphabets
def register(**kwargs: Alphabet) -> None:
@@ -101,6 +104,8 @@ def register(**kwargs: Alphabet) -> None:
re.match(r"^base[0-9][a-zA-Z0-9_]*$", name)
```
"""
+ for arg in kwargs.values():
+ validate(arg, Alphabet)
for name, alphabet in kwargs.items():
if not re.match(r"^base[0-9][a-zA-Z0-9_]*$", name):
raise ValueError(f"Invalid alphabet name {repr(name)}")
@@ -133,6 +138,8 @@ def unregister(*names: str) -> None:
StringAlphabet('0123456789ABCDEF')
```
"""
+ for name in names:
+ validate(name, str)
for name in names:
if name not in _alphabets:
raise KeyError(f"Alphabet named {repr(name)} does not exist.")
@@ -153,6 +160,7 @@ def table(*, prefix: str = "") -> Iterator[Tuple[str, Alphabet]]:
```
"""
+ validate(prefix, str)
alphabets = [(name, alphabet) for name, alphabet in _alphabets.items()
if name.startswith(prefix)]
alphabets = sorted(alphabets, key=lambda pair: pair[0])
@@ -188,6 +196,9 @@ def make(chars: Union[str, range], *, case_sensitive: bool = True, name: Optiona
If the optional keyword argument `name` is specified, the alphabet is automatically registered using `register`.
"""
+ validate(chars, Union[str, range])
+ validate(case_sensitive, bool)
+ validate(name, Optional[str])
if isinstance(chars, str):
string_alphabet = StringAlphabet(chars, case_sensitive=case_sensitive)
if name is not None:
diff --git a/bases/alphabet/abstract.py b/bases/alphabet/abstract.py
index cdff1d8..97f92f3 100644
--- a/bases/alphabet/abstract.py
+++ b/bases/alphabet/abstract.py
@@ -4,6 +4,7 @@
from abc import ABC, abstractmethod
from typing import Any, Mapping, Optional, overload, Sequence, TypeVar, Union
+from typing_validation import validate
Self = TypeVar("Self", bound="Alphabet")
@@ -26,6 +27,7 @@ class Alphabet(ABC, Sequence[str]):
_case_sensitive: bool
def __init__(self, case_sensitive: bool = True):
+ validate(case_sensitive, bool)
self._case_sensitive = case_sensitive
@property
@@ -68,6 +70,9 @@ def index(self, char: str, start: int = 0, stop: Optional[int] = None) -> int:
```
"""
# pylint: disable = arguments-renamed
+ validate(char, str)
+ validate(start, int)
+ validate(stop, Optional[int])
if start < 0:
start = max(len(self) + start, 0)
if stop is None:
@@ -87,6 +92,7 @@ def count(self, char: str) -> int:
Returns 1 if `char` is in the alphabet and 0 otherwise.
"""
# pylint: disable = arguments-renamed
+ validate(char, str)
return 1 if char in self else 0
def __contains__(self, char: Any) -> bool:
diff --git a/bases/alphabet/range_alphabet.py b/bases/alphabet/range_alphabet.py
index 5db7b31..728622c 100644
--- a/bases/alphabet/range_alphabet.py
+++ b/bases/alphabet/range_alphabet.py
@@ -3,6 +3,7 @@
"""
from typing import Any, Iterator, Mapping, overload, Union
+from typing_validation import validate
from .abstract import Alphabet
from .string_alphabet import StringAlphabet
@@ -28,6 +29,7 @@ class RangeAlphabet(Alphabet):
def __init__(self, codepoints: range, *,
case_sensitive: bool = True):
super().__init__(case_sensitive)
+ validate(codepoints, range)
self._codepoints = codepoints
self._revdir = _RangeAlphabetRevdir(self)
self.__validate_init()
@@ -75,12 +77,14 @@ def __getitem__(self, idx: slice) -> "RangeAlphabet":
...
def __getitem__(self, idx: Union[int, slice]) -> Union[str, "RangeAlphabet"]:
+ validate(idx, Union[int, slice])
if isinstance(idx, slice):
new_codepoints = self._codepoints[idx]
return RangeAlphabet(new_codepoints, case_sensitive=self.case_sensitive)
return chr(self._codepoints[idx])
def with_case_sensitivity(self, case_sensitive: bool) -> "RangeAlphabet":
+ validate(case_sensitive, bool)
if case_sensitive == self.case_sensitive:
return self
return RangeAlphabet(self.codepoints, case_sensitive=case_sensitive)
@@ -146,6 +150,7 @@ def __contains__(self, char: Any) -> bool:
return ord(char.upper()) in alphabet.codepoints or ord(char.lower()) in alphabet.codepoints
def __getitem__(self, char: str) -> int:
+ validate(char, str)
alphabet = self._alphabet
if ord(char) in alphabet.codepoints:
return ord(char)-alphabet.codepoints.start
diff --git a/bases/alphabet/string_alphabet.py b/bases/alphabet/string_alphabet.py
index 4ab06f2..4501e0e 100644
--- a/bases/alphabet/string_alphabet.py
+++ b/bases/alphabet/string_alphabet.py
@@ -4,6 +4,7 @@
from types import MappingProxyType
from typing import Any, Mapping, overload, Union
+from typing_validation import validate
from .abstract import Alphabet
@@ -30,6 +31,7 @@ class StringAlphabet(Alphabet):
def __init__(self, chars: str, *,
case_sensitive: bool = True):
super().__init__(case_sensitive)
+ validate(chars, str)
self._chars = chars
revdir = {
c: idx for idx, c in enumerate(chars)
@@ -88,12 +90,14 @@ def __getitem__(self, idx: slice) -> "StringAlphabet":
...
def __getitem__(self, idx: Union[int, slice]) -> Union[str, "StringAlphabet"]:
+ validate(idx, Union[int, slice])
if isinstance(idx, slice):
new_chars = self._chars[idx]
return StringAlphabet(new_chars, case_sensitive=self.case_sensitive)
return self._chars[idx]
def with_case_sensitivity(self, case_sensitive: bool) -> "StringAlphabet":
+ validate(case_sensitive, bool)
if case_sensitive == self.case_sensitive:
return self
return StringAlphabet(self.chars, case_sensitive=case_sensitive)
diff --git a/bases/encoding/__init__.py b/bases/encoding/__init__.py
index 92e0f09..c8ef7c4 100644
--- a/bases/encoding/__init__.py
+++ b/bases/encoding/__init__.py
@@ -63,6 +63,7 @@
import re
from typing import Any, cast, Collection, Dict, Iterator, Mapping, Optional, overload, Tuple, Type, Union
from typing_extensions import Literal
+from typing_validation import validate
from bases import alphabet
from bases.alphabet import Alphabet
@@ -89,6 +90,7 @@ def get(name: str) -> BaseEncoding:
block_nchars=2)
```
"""
+ validate(name, str)
if name not in _base_encodings:
raise KeyError(f"Encoding named {repr(name)} does not exist.")
return _base_encodings[name]
@@ -101,6 +103,7 @@ def has(name: str) -> bool:
True
```
"""
+ validate(name, str)
return name in _base_encodings
def register(**kwargs: BaseEncoding) -> None:
@@ -126,6 +129,8 @@ def register(**kwargs: BaseEncoding) -> None:
re.match(r"^base[0-9][a-zA-Z0-9_]*$", name)
```
"""
+ for arg in kwargs.values():
+ validate(arg, BaseEncoding)
for name, encoding in kwargs.items():
if not re.match(r"^base[0-9][a-zA-Z0-9_]*$", name):
raise ValueError(f"Invalid encoding name {repr(name)}")
@@ -161,6 +166,8 @@ def unregister(*names: str) -> None:
block_nchars=2)
```
"""
+ for name in names:
+ validate(name, str)
for name in names:
if name not in _base_encodings:
raise KeyError(f"Encoding named {repr(name)} does not exist.")
@@ -190,6 +197,7 @@ def table(*, prefix: str = "") -> Iterator[Tuple[str, BaseEncoding]]:
```
"""
+ validate(prefix, str)
encodings = [(name, encoding) for name, encoding in _base_encodings.items()
if name.startswith(prefix)]
encodings = sorted(encodings, key=lambda pair: pair[0])
@@ -248,6 +256,10 @@ def make(chars: Union[str, range, Alphabet, BaseEncoding], *, kind: str, name: O
```
"""
+ validate(chars, Union[str, range, Alphabet, BaseEncoding])
+ validate(kind, str)
+ validate(name, Optional[str])
+ validate(case_sensitive, Optional[bool])
kwargs["case_sensitive"] = case_sensitive
if kind == "simple-enc":
if isinstance(chars, BaseEncoding):
diff --git a/bases/encoding/base.py b/bases/encoding/base.py
index b475d18..01f96af 100644
--- a/bases/encoding/base.py
+++ b/bases/encoding/base.py
@@ -4,6 +4,7 @@
from abc import ABC, abstractmethod
from typing import Any, Mapping, Optional, TypeVar, Union
+from typing_validation import validate
from bases import alphabet
from bases.alphabet import Alphabet
@@ -24,6 +25,8 @@ class BaseEncoding(ABC):
def __init__(self, chars: Union[str, range, Alphabet], *,
case_sensitive: Optional[bool] = None):
+ validate(chars, Union[str, range, Alphabet])
+ validate(case_sensitive, Optional[bool])
if isinstance(chars, Alphabet):
if case_sensitive is not None:
chars = chars.with_case_sensitivity(case_sensitive)
@@ -99,6 +102,8 @@ def with_alphabet(self: Self, chars: Union[str, range, Alphabet], *,
Returns a new encoding with the same kind and options as this one,
but a different alphabet and/or case sensitivity.
"""
+ validate(chars, Union[str, range, Alphabet])
+ validate(case_sensitive, Optional[bool])
options = {**self.options()}
options["case_sensitive"] = case_sensitive
return type(self)(chars, **options)
@@ -121,6 +126,7 @@ def with_case_sensitivity(self: Self, case_sensitive: bool) -> Self:
pad_char='=', padding='include')
```
"""
+ validate(case_sensitive, bool)
return self.with_alphabet(self.alphabet.with_case_sensitivity(case_sensitive))
def upper(self: Self) -> Self:
@@ -234,13 +240,11 @@ def canonical_string(self, s: str) -> str:
def _validate_bytes(self, b: bytes) -> bytes:
# pylint: disable = no-self-use
- if not isinstance(b, bytes):
- raise TypeError()
+ validate(b, bytes)
return b
def _validate_string(self, s: str) -> str:
- if not isinstance(s, str):
- raise TypeError()
+ validate(s, str)
alphabet = self.alphabet
for c in s:
if c not in alphabet:
diff --git a/bases/encoding/block.py b/bases/encoding/block.py
index af6ca48..395ef68 100644
--- a/bases/encoding/block.py
+++ b/bases/encoding/block.py
@@ -5,6 +5,7 @@
import math
from types import MappingProxyType
from typing import Any, Dict, List, Mapping, Optional, Union
+from typing_validation import validate
from bases.alphabet import Alphabet
from .base import BaseEncoding
@@ -93,10 +94,13 @@ def __init__(self, encoding: Union[str, range, Alphabet, BaseEncoding], *,
block_size: Union[int, Mapping[int, int]],
sep_char: str = "",
reverse_blocks: bool = False):
+ validate(encoding, Union[str, range, Alphabet, BaseEncoding])
+ validate(block_size, Union[int, Mapping[int, int]])
+ validate(sep_char, str)
+ validate(reverse_blocks, bool)
self._init_encoding = encoding
self._init_case_sensitive = case_sensitive
self._init_block_size = block_size
-
if isinstance(encoding, BaseEncoding):
alphabet: Union[str, range, Alphabet] = encoding.alphabet
else:
@@ -221,6 +225,7 @@ def _validate_bytes(self, b: bytes) -> bytes:
return b
def _validate_string(self, s: str) -> str:
+ validate(s, str)
sep_char = self.sep_char
block_nchars = self.block_nchars
if sep_char:
@@ -293,6 +298,7 @@ def _decode(self, s: str) -> bytes:
return b"".join(byte_blocks)
def options(self, skip_defaults: bool = False) -> Mapping[str, Any]:
+ validate(skip_defaults, bool)
options: Dict[str, Any] = {
"block_size": self._init_block_size,
}
diff --git a/bases/encoding/errors.py b/bases/encoding/errors.py
index 09ea86b..2f803b3 100644
--- a/bases/encoding/errors.py
+++ b/bases/encoding/errors.py
@@ -3,6 +3,7 @@
"""
import binascii
+from typing_validation import validate
from bases.alphabet import Alphabet
@@ -28,6 +29,8 @@ class InvalidDigitError(EncodingError):
base: int
def __init__(self, digit: int, base: int) -> None:
+ validate(digit, int)
+ validate(base, int)
self.digit = digit
self.base = base
if 0 <= digit < base:
@@ -57,6 +60,8 @@ class NonAlphabeticCharError(DecodingError):
alphabet: Alphabet
def __init__(self, char: str, alphabet: Alphabet) -> None:
+ validate(char, str)
+ validate(alphabet, Alphabet)
self.char = char
self.alphabet = alphabet
if char in alphabet:
@@ -73,6 +78,8 @@ class PaddingError(DecodingError):
expected_padding: int
def __init__(self, padding: int, expected_padding: int) -> None:
+ validate(padding, int)
+ validate(expected_padding, int)
self.padding = padding
self.expected_padding = expected_padding
if padding < expected_padding:
diff --git a/bases/encoding/fixchar.py b/bases/encoding/fixchar.py
index d4bf4e7..fa451a1 100644
--- a/bases/encoding/fixchar.py
+++ b/bases/encoding/fixchar.py
@@ -5,6 +5,7 @@
import math
from typing import Any, Dict, List, Mapping, Optional, Union
from typing_extensions import Literal
+from typing_validation import validate
from bases.alphabet import Alphabet
from .base import BaseEncoding
@@ -95,6 +96,9 @@ def __init__(self, alphabet: Union[str, range, Alphabet], *,
char_nbits: Union[int, Literal["auto"]] = "auto",
pad_char: Optional[str] = None,
padding: PaddingOptions = "ignore"):
+ validate(char_nbits, Union[int, Literal["auto"]])
+ validate(pad_char, Optional[str])
+ validate(padding, PaddingOptions)
if padding not in ("ignore", "include", "require"):
raise TypeError("Allowed padding options are: 'ignore', 'include' and 'require'.")
super().__init__(alphabet, case_sensitive=case_sensitive)
@@ -221,6 +225,7 @@ def pad(self, require: bool = False) -> "FixcharBaseEncoding":
pad_char='=', padding='include')
```
"""
+ validate(require, bool)
options = dict(padding="require" if require else "include")
return self.with_options(**options)
@@ -248,6 +253,7 @@ def nopad(self, allow: bool = True) -> "FixcharBaseEncoding":
case_sensitive=False))
```
"""
+ validate(allow, bool)
options = dict(padding="ignore", pad_char=self.pad_char if allow else None)
return self.with_options(**options)
@@ -272,6 +278,7 @@ def with_pad_char(self, pad_char: Optional[str]) -> "FixcharBaseEncoding":
```
"""
+ validate(pad_char, Optional[str])
options: Dict[str, Any] = dict(pad_char=pad_char)
if pad_char is None:
options["padding"] = "ignore"
@@ -286,8 +293,7 @@ def pad_string(self, s: str) -> str:
The value of `FixcharBaseEncoding.padding` is irrelevant to this method.
"""
- if not isinstance(s, str):
- raise TypeError()
+ validate(s, str)
pad_char = self.pad_char
block_nchars = self._block_nchars
# no padding available for this encoding scheme
@@ -309,8 +315,7 @@ def strip_string(self, s: str) -> str:
If `FixcharBaseEncoding.padding` is set to `"require"`, checks that the correct number of
padding characters were included and raises `bases.encoding.errors.PaddingError` if not.
"""
- if not isinstance(s, str):
- raise TypeError()
+ validate(s, str)
pad_char = self.pad_char
case_sensitive = self.case_sensitive
block_nchars = self._block_nchars
@@ -337,6 +342,7 @@ def canonical_bytes(self, b: bytes) -> bytes:
return b
def canonical_string(self, s: str) -> str:
+ validate(s, str)
if self.include_padding:
return self.pad_string(s)
return self.strip_string(s)
@@ -395,6 +401,7 @@ def _decode(self, s: str) -> bytes:
return i.to_bytes(length=original_nbytes, byteorder="big")
def options(self, skip_defaults: bool = False) -> Mapping[str, Any]:
+ validate(skip_defaults, bool)
options: Dict[str, Any] = {}
if not skip_defaults or self._init_char_nbits != "auto":
options["char_nbits"] = self._init_char_nbits
diff --git a/bases/encoding/simple.py b/bases/encoding/simple.py
index 743ecff..51a07d5 100644
--- a/bases/encoding/simple.py
+++ b/bases/encoding/simple.py
@@ -3,6 +3,7 @@
"""
from typing import Any, List, Mapping, Optional, Union
+from typing_validation import validate
from bases.alphabet import Alphabet
from .base import BaseEncoding
@@ -77,4 +78,5 @@ def _decode(self, s: str) -> bytes:
return i.to_bytes(length=nbytes, byteorder="big")
def options(self, skip_defaults: bool = False) -> Mapping[str, Any]:
+ validate(skip_defaults, bool)
return {}
diff --git a/bases/encoding/zeropad.py b/bases/encoding/zeropad.py
index 0dc50cd..d1ae9ff 100644
--- a/bases/encoding/zeropad.py
+++ b/bases/encoding/zeropad.py
@@ -4,6 +4,7 @@
import math
from typing import Any, Dict, Mapping, Optional, Union
+from typing_validation import validate
from bases.alphabet import Alphabet
from .base import BaseEncoding
@@ -49,6 +50,8 @@ def __init__(self, alphabet: Union[str, range, Alphabet], *,
case_sensitive: Optional[bool] = None,
block_nbytes: int = 1,
block_nchars: int = 1):
+ validate(block_nbytes, int)
+ validate(block_nchars, int)
super().__init__(alphabet, case_sensitive=case_sensitive)
self._simple_encoding = SimpleBaseEncoding(self.alphabet)
self._block_nbytes = block_nbytes
@@ -79,6 +82,8 @@ def max_block_nchars(base: int, block_nbytes: int) -> int:
256**block_nbytes > base**(block_nchars-1)
```
"""
+ validate(base, int)
+ validate(block_nbytes, int)
if base <= 1:
raise ValueError("Base must be >= 2.")
if block_nbytes <= 0:
@@ -97,6 +102,8 @@ def max_block_nbytes(base: int, block_nchars: int) -> int:
base**block_nchars > 256**(block_nbytes-1)
```
"""
+ validate(base, int)
+ validate(block_nchars, int)
if base <= 1:
raise ValueError("Base must be >= 2.")
if block_nchars <= 0:
@@ -174,6 +181,7 @@ def _decode(self, s: str) -> bytes:
return b
def options(self, skip_defaults: bool = False) -> Mapping[str, Any]:
+ validate(skip_defaults, bool)
options: Dict[str, Any] = {}
if not skip_defaults or self.block_nbytes != 1:
options["block_nbytes"] = self.block_nbytes
diff --git a/bases/random.py b/bases/random.py
index 3bade4a..f55f349 100644
--- a/bases/random.py
+++ b/bases/random.py
@@ -52,6 +52,7 @@
from random import Random # pylint: disable = import-self
from types import MappingProxyType
from typing import Any, Dict, Iterator, Mapping, Optional
+from typing_validation import validate
from .alphabet import Alphabet
from .encoding import BaseEncoding, SimpleBaseEncoding, ZeropadBaseEncoding, BlockBaseEncoding, FixcharBaseEncoding
@@ -112,6 +113,8 @@ def options(*,
See `set_options` for a description of the options.
"""
# pylint: disable = too-many-locals
+ for arg in (seed, min_bytes, max_bytes, min_chars, max_chars):
+ validate(arg, Optional[int])
global _options
global _rand
try:
@@ -145,6 +148,8 @@ def set_options(*,
"""
# pylint: disable = too-many-branches, too-many-locals, too-many-statements
+ for arg in (seed, min_bytes, max_bytes, min_chars, max_chars):
+ validate(arg, Optional[int])
global _options
global _rand
# set newly passed options
@@ -197,6 +202,8 @@ def rand_bytes(n: Optional[int] = None, *, encoding: Optional[BaseEncoding] = No
[0, 96, 63]]
```
"""
+ validate(n, Optional[int])
+ validate(encoding, Optional[BaseEncoding])
if encoding is None:
return rand_raw_bytes(n)
if isinstance(encoding, SimpleBaseEncoding):
@@ -217,6 +224,9 @@ def rand_raw_bytes(n: Optional[int] = None, *, min_bytes: Optional[int] = None,
The optional `min_bytes` and `max_bytes` parameters can be used to set a minimum/maximum length
for the `bytes` objects: if `None`, the values are fetched from `get_options`.
"""
+ validate(n, Optional[int])
+ validate(min_bytes, Optional[int])
+ validate(max_bytes, Optional[int])
if n is not None and n < 0:
raise ValueError()
if min_bytes is None:
@@ -318,6 +328,9 @@ def rand_str(n: Optional[int] = None, *, encoding: Optional[BaseEncoding]=None,
```
"""
+ validate(n, Optional[int])
+ validate(encoding, Optional[BaseEncoding])
+ validate(alphabet, Optional[Alphabet])
if encoding is None:
if alphabet is None:
raise ValueError("One of 'encoding' or 'alphabet' must be specified.")
diff --git a/docs/bases/alphabet/abstract.html b/docs/bases/alphabet/abstract.html
index 45112a0..cf5988a 100644
--- a/docs/bases/alphabet/abstract.html
+++ b/docs/bases/alphabet/abstract.html
@@ -34,6 +34,7 @@
Module bases.alphabet.abstract
from abc import ABC, abstractmethod
from typing import Any, Mapping, Optional, overload, Sequence, TypeVar, Union
+from typing_validation import validate
Self = TypeVar("Self", bound="Alphabet")
@@ -56,6 +57,7 @@ Module bases.alphabet.abstract
_case_sensitive: bool
def __init__(self, case_sensitive: bool = True):
+ validate(case_sensitive, bool)
self._case_sensitive = case_sensitive
@property
@@ -98,6 +100,9 @@ Module bases.alphabet.abstract
```
"""
# pylint: disable = arguments-renamed
+ validate(char, str)
+ validate(start, int)
+ validate(stop, Optional[int])
if start < 0:
start = max(len(self) + start, 0)
if stop is None:
@@ -117,6 +122,7 @@ Module bases.alphabet.abstract
Returns 1 if `char` is in the alphabet and 0 otherwise.
"""
# pylint: disable = arguments-renamed
+ validate(char, str)
return 1 if char in self else 0
def __contains__(self, char: Any) -> bool:
@@ -266,6 +272,7 @@
_case_sensitive: bool
def __init__(self, case_sensitive: bool = True):
+ validate(case_sensitive, bool)
self._case_sensitive = case_sensitive
@property
@@ -308,6 +315,9 @@
```
"""
# pylint: disable = arguments-renamed
+ validate(char, str)
+ validate(start, int)
+ validate(stop, Optional[int])
if start < 0:
start = max(len(self) + start, 0)
if stop is None:
@@ -327,6 +337,7 @@
Returns 1 if `char` is in the alphabet and 0 otherwise.
"""
# pylint: disable = arguments-renamed
+ validate(char, str)
return 1 if char in self else 0
def __contains__(self, char: Any) -> bool:
@@ -548,6 +559,7 @@ Methods
Returns 1 if `char` is in the alphabet and 0 otherwise.
"""
# pylint: disable = arguments-renamed
+ validate(char, str)
return 1 if char in self else 0
@@ -594,6 +606,9 @@ Methods
```
"""
# pylint: disable = arguments-renamed
+ validate(char, str)
+ validate(start, int)
+ validate(stop, Optional[int])
if start < 0:
start = max(len(self) + start, 0)
if stop is None:
diff --git a/docs/bases/alphabet/index.html b/docs/bases/alphabet/index.html
index 12aecbb..7273ac8 100644
--- a/docs/bases/alphabet/index.html
+++ b/docs/bases/alphabet/index.html
@@ -100,6 +100,7 @@ Module bases.alphabet
import re
from typing import Collection, Dict, Iterator, Optional, overload, Tuple, Union
from typing_extensions import Literal
+from typing_validation import validate
from .abstract import Alphabet as Alphabet
from .string_alphabet import StringAlphabet as StringAlphabet
@@ -118,6 +119,7 @@ Module bases.alphabet
StringAlphabet('0123456789ABCDEF')
```
"""
+ validate(name, str)
if name not in _alphabets:
raise KeyError(f"Alphabet named {repr(name)} does not exist.")
return _alphabets[name]
@@ -134,6 +136,7 @@ Module bases.alphabet
True
```
"""
+ validate(name, str)
return name in _alphabets
def register(**kwargs: Alphabet) -> None:
@@ -156,6 +159,8 @@ Module bases.alphabet
re.match(r"^base[0-9][a-zA-Z0-9_]*$", name)
```
"""
+ for arg in kwargs.values():
+ validate(arg, Alphabet)
for name, alphabet in kwargs.items():
if not re.match(r"^base[0-9][a-zA-Z0-9_]*$", name):
raise ValueError(f"Invalid alphabet name {repr(name)}")
@@ -188,6 +193,8 @@ Module bases.alphabet
StringAlphabet('0123456789ABCDEF')
```
"""
+ for name in names:
+ validate(name, str)
for name in names:
if name not in _alphabets:
raise KeyError(f"Alphabet named {repr(name)} does not exist.")
@@ -208,6 +215,7 @@ Module bases.alphabet
```
"""
+ validate(prefix, str)
alphabets = [(name, alphabet) for name, alphabet in _alphabets.items()
if name.startswith(prefix)]
alphabets = sorted(alphabets, key=lambda pair: pair[0])
@@ -243,6 +251,9 @@ Module bases.alphabet
If the optional keyword argument `name` is specified, the alphabet is automatically registered using `register`.
"""
+ validate(chars, Union[str, range])
+ validate(case_sensitive, bool)
+ validate(name, Optional[str])
if isinstance(chars, str):
string_alphabet = StringAlphabet(chars, case_sensitive=case_sensitive)
if name is not None:
@@ -407,6 +418,7 @@
StringAlphabet('0123456789ABCDEF')
```
"""
+ validate(name, str)
if name not in _alphabets:
raise KeyError(f"Alphabet named {repr(name)} does not exist.")
return _alphabets[name]
@@ -438,6 +450,7 @@
True
```
"""
+ validate(name, str)
return name in _alphabets
@@ -483,6 +496,9 @@
If the optional keyword argument `name` is specified, the alphabet is automatically registered using `register`.
"""
+ validate(chars, Union[str, range])
+ validate(case_sensitive, bool)
+ validate(name, Optional[str])
if isinstance(chars, str):
string_alphabet = StringAlphabet(chars, case_sensitive=case_sensitive)
if name is not None:
@@ -535,6 +551,8 @@
re.match(r"^base[0-9][a-zA-Z0-9_]*$", name)
```
"""
+ for arg in kwargs.values():
+ validate(arg, Alphabet)
for name, alphabet in kwargs.items():
if not re.match(r"^base[0-9][a-zA-Z0-9_]*$", name):
raise ValueError(f"Invalid alphabet name {repr(name)}")
@@ -576,6 +594,7 @@
```
"""
+ validate(prefix, str)
alphabets = [(name, alphabet) for name, alphabet in _alphabets.items()
if name.startswith(prefix)]
alphabets = sorted(alphabets, key=lambda pair: pair[0])
@@ -627,6 +646,8 @@
StringAlphabet('0123456789ABCDEF')
```
"""
+ for name in names:
+ validate(name, str)
for name in names:
if name not in _alphabets:
raise KeyError(f"Alphabet named {repr(name)} does not exist.")
diff --git a/docs/bases/alphabet/range_alphabet.html b/docs/bases/alphabet/range_alphabet.html
index 10dfc14..fa835b6 100644
--- a/docs/bases/alphabet/range_alphabet.html
+++ b/docs/bases/alphabet/range_alphabet.html
@@ -33,6 +33,7 @@ Module bases.alphabet.range_alphabet
"""
from typing import Any, Iterator, Mapping, overload, Union
+from typing_validation import validate
from .abstract import Alphabet
from .string_alphabet import StringAlphabet
@@ -58,6 +59,7 @@ Module bases.alphabet.range_alphabet
def __init__(self, codepoints: range, *,
case_sensitive: bool = True):
super().__init__(case_sensitive)
+ validate(codepoints, range)
self._codepoints = codepoints
self._revdir = _RangeAlphabetRevdir(self)
self.__validate_init()
@@ -105,12 +107,14 @@ Module bases.alphabet.range_alphabet
...
def __getitem__(self, idx: Union[int, slice]) -> Union[str, "RangeAlphabet"]:
+ validate(idx, Union[int, slice])
if isinstance(idx, slice):
new_codepoints = self._codepoints[idx]
return RangeAlphabet(new_codepoints, case_sensitive=self.case_sensitive)
return chr(self._codepoints[idx])
def with_case_sensitivity(self, case_sensitive: bool) -> "RangeAlphabet":
+ validate(case_sensitive, bool)
if case_sensitive == self.case_sensitive:
return self
return RangeAlphabet(self.codepoints, case_sensitive=case_sensitive)
@@ -176,6 +180,7 @@ Module bases.alphabet.range_alphabet
return ord(char.upper()) in alphabet.codepoints or ord(char.lower()) in alphabet.codepoints
def __getitem__(self, char: str) -> int:
+ validate(char, str)
alphabet = self._alphabet
if ord(char) in alphabet.codepoints:
return ord(char)-alphabet.codepoints.start
@@ -233,6 +238,7 @@
def __init__(self, codepoints: range, *,
case_sensitive: bool = True):
super().__init__(case_sensitive)
+ validate(codepoints, range)
self._codepoints = codepoints
self._revdir = _RangeAlphabetRevdir(self)
self.__validate_init()
@@ -280,12 +286,14 @@
...
def __getitem__(self, idx: Union[int, slice]) -> Union[str, "RangeAlphabet"]:
+ validate(idx, Union[int, slice])
if isinstance(idx, slice):
new_codepoints = self._codepoints[idx]
return RangeAlphabet(new_codepoints, case_sensitive=self.case_sensitive)
return chr(self._codepoints[idx])
def with_case_sensitivity(self, case_sensitive: bool) -> "RangeAlphabet":
+ validate(case_sensitive, bool)
if case_sensitive == self.case_sensitive:
return self
return RangeAlphabet(self.codepoints, case_sensitive=case_sensitive)
diff --git a/docs/bases/alphabet/string_alphabet.html b/docs/bases/alphabet/string_alphabet.html
index cb1c560..11f071e 100644
--- a/docs/bases/alphabet/string_alphabet.html
+++ b/docs/bases/alphabet/string_alphabet.html
@@ -34,6 +34,7 @@ Module bases.alphabet.string_alphabet
from types import MappingProxyType
from typing import Any, Mapping, overload, Union
+from typing_validation import validate
from .abstract import Alphabet
@@ -60,6 +61,7 @@ Module bases.alphabet.string_alphabet
def __init__(self, chars: str, *,
case_sensitive: bool = True):
super().__init__(case_sensitive)
+ validate(chars, str)
self._chars = chars
revdir = {
c: idx for idx, c in enumerate(chars)
@@ -118,12 +120,14 @@ Module bases.alphabet.string_alphabet
...
def __getitem__(self, idx: Union[int, slice]) -> Union[str, "StringAlphabet"]:
+ validate(idx, Union[int, slice])
if isinstance(idx, slice):
new_chars = self._chars[idx]
return StringAlphabet(new_chars, case_sensitive=self.case_sensitive)
return self._chars[idx]
def with_case_sensitivity(self, case_sensitive: bool) -> "StringAlphabet":
+ validate(case_sensitive, bool)
if case_sensitive == self.case_sensitive:
return self
return StringAlphabet(self.chars, case_sensitive=case_sensitive)
@@ -206,6 +210,7 @@
def __init__(self, chars: str, *,
case_sensitive: bool = True):
super().__init__(case_sensitive)
+ validate(chars, str)
self._chars = chars
revdir = {
c: idx for idx, c in enumerate(chars)
@@ -264,12 +269,14 @@
...
def __getitem__(self, idx: Union[int, slice]) -> Union[str, "StringAlphabet"]:
+ validate(idx, Union[int, slice])
if isinstance(idx, slice):
new_chars = self._chars[idx]
return StringAlphabet(new_chars, case_sensitive=self.case_sensitive)
return self._chars[idx]
def with_case_sensitivity(self, case_sensitive: bool) -> "StringAlphabet":
+ validate(case_sensitive, bool)
if case_sensitive == self.case_sensitive:
return self
return StringAlphabet(self.chars, case_sensitive=case_sensitive)
diff --git a/docs/bases/encoding/base.html b/docs/bases/encoding/base.html
index 8c5ea02..48eadf5 100644
--- a/docs/bases/encoding/base.html
+++ b/docs/bases/encoding/base.html
@@ -34,6 +34,7 @@ Module bases.encoding.base
from abc import ABC, abstractmethod
from typing import Any, Mapping, Optional, TypeVar, Union
+from typing_validation import validate
from bases import alphabet
from bases.alphabet import Alphabet
@@ -54,6 +55,8 @@ Module bases.encoding.base
def __init__(self, chars: Union[str, range, Alphabet], *,
case_sensitive: Optional[bool] = None):
+ validate(chars, Union[str, range, Alphabet])
+ validate(case_sensitive, Optional[bool])
if isinstance(chars, Alphabet):
if case_sensitive is not None:
chars = chars.with_case_sensitivity(case_sensitive)
@@ -129,6 +132,8 @@ Module bases.encoding.base
Returns a new encoding with the same kind and options as this one,
but a different alphabet and/or case sensitivity.
"""
+ validate(chars, Union[str, range, Alphabet])
+ validate(case_sensitive, Optional[bool])
options = {**self.options()}
options["case_sensitive"] = case_sensitive
return type(self)(chars, **options)
@@ -151,6 +156,7 @@ Module bases.encoding.base
pad_char='=', padding='include')
```
"""
+ validate(case_sensitive, bool)
return self.with_alphabet(self.alphabet.with_case_sensitivity(case_sensitive))
def upper(self: Self) -> Self:
@@ -264,13 +270,11 @@ Module bases.encoding.base
def _validate_bytes(self, b: bytes) -> bytes:
# pylint: disable = no-self-use
- if not isinstance(b, bytes):
- raise TypeError()
+ validate(b, bytes)
return b
def _validate_string(self, s: str) -> str:
- if not isinstance(s, str):
- raise TypeError()
+ validate(s, str)
alphabet = self.alphabet
for c in s:
if c not in alphabet:
@@ -357,6 +361,8 @@
def __init__(self, chars: Union[str, range, Alphabet], *,
case_sensitive: Optional[bool] = None):
+ validate(chars, Union[str, range, Alphabet])
+ validate(case_sensitive, Optional[bool])
if isinstance(chars, Alphabet):
if case_sensitive is not None:
chars = chars.with_case_sensitivity(case_sensitive)
@@ -432,6 +438,8 @@
Returns a new encoding with the same kind and options as this one,
but a different alphabet and/or case sensitivity.
"""
+ validate(chars, Union[str, range, Alphabet])
+ validate(case_sensitive, Optional[bool])
options = {**self.options()}
options["case_sensitive"] = case_sensitive
return type(self)(chars, **options)
@@ -454,6 +462,7 @@
pad_char='=', padding='include')
```
"""
+ validate(case_sensitive, bool)
return self.with_alphabet(self.alphabet.with_case_sensitivity(case_sensitive))
def upper(self: Self) -> Self:
@@ -567,13 +576,11 @@
def _validate_bytes(self, b: bytes) -> bytes:
# pylint: disable = no-self-use
- if not isinstance(b, bytes):
- raise TypeError()
+ validate(b, bytes)
return b
def _validate_string(self, s: str) -> str:
- if not isinstance(s, str):
- raise TypeError()
+ validate(s, str)
alphabet = self.alphabet
for c in s:
if c not in alphabet:
@@ -1007,6 +1014,8 @@ Methods
Returns a new encoding with the same kind and options as this one,
but a different alphabet and/or case sensitivity.
"""
+ validate(chars, Union[str, range, Alphabet])
+ validate(case_sensitive, Optional[bool])
options = {**self.options()}
options["case_sensitive"] = case_sensitive
return type(self)(chars, **options)
@@ -1050,6 +1059,7 @@ Methods
pad_char='=', padding='include')
```
"""
+ validate(case_sensitive, bool)
return self.with_alphabet(self.alphabet.with_case_sensitivity(case_sensitive))
diff --git a/docs/bases/encoding/block.html b/docs/bases/encoding/block.html
index 87cf887..71cf89f 100644
--- a/docs/bases/encoding/block.html
+++ b/docs/bases/encoding/block.html
@@ -35,6 +35,7 @@ Module bases.encoding.block
import math
from types import MappingProxyType
from typing import Any, Dict, List, Mapping, Optional, Union
+from typing_validation import validate
from bases.alphabet import Alphabet
from .base import BaseEncoding
@@ -123,10 +124,13 @@ Module bases.encoding.block
block_size: Union[int, Mapping[int, int]],
sep_char: str = "",
reverse_blocks: bool = False):
+ validate(encoding, Union[str, range, Alphabet, BaseEncoding])
+ validate(block_size, Union[int, Mapping[int, int]])
+ validate(sep_char, str)
+ validate(reverse_blocks, bool)
self._init_encoding = encoding
self._init_case_sensitive = case_sensitive
self._init_block_size = block_size
-
if isinstance(encoding, BaseEncoding):
alphabet: Union[str, range, Alphabet] = encoding.alphabet
else:
@@ -251,6 +255,7 @@ Module bases.encoding.block
return b
def _validate_string(self, s: str) -> str:
+ validate(s, str)
sep_char = self.sep_char
block_nchars = self.block_nchars
if sep_char:
@@ -323,6 +328,7 @@ Module bases.encoding.block
return b"".join(byte_blocks)
def options(self, skip_defaults: bool = False) -> Mapping[str, Any]:
+ validate(skip_defaults, bool)
options: Dict[str, Any] = {
"block_size": self._init_block_size,
}
@@ -517,10 +523,13 @@
block_size: Union[int, Mapping[int, int]],
sep_char: str = "",
reverse_blocks: bool = False):
+ validate(encoding, Union[str, range, Alphabet, BaseEncoding])
+ validate(block_size, Union[int, Mapping[int, int]])
+ validate(sep_char, str)
+ validate(reverse_blocks, bool)
self._init_encoding = encoding
self._init_case_sensitive = case_sensitive
self._init_block_size = block_size
-
if isinstance(encoding, BaseEncoding):
alphabet: Union[str, range, Alphabet] = encoding.alphabet
else:
@@ -645,6 +654,7 @@
return b
def _validate_string(self, s: str) -> str:
+ validate(s, str)
sep_char = self.sep_char
block_nchars = self.block_nchars
if sep_char:
@@ -717,6 +727,7 @@
return b"".join(byte_blocks)
def options(self, skip_defaults: bool = False) -> Mapping[str, Any]:
+ validate(skip_defaults, bool)
options: Dict[str, Any] = {
"block_size": self._init_block_size,
}
diff --git a/docs/bases/encoding/errors.html b/docs/bases/encoding/errors.html
index 72c3aa6..d17dced 100644
--- a/docs/bases/encoding/errors.html
+++ b/docs/bases/encoding/errors.html
@@ -33,6 +33,7 @@ Module bases.encoding.errors
"""
import binascii
+from typing_validation import validate
from bases.alphabet import Alphabet
@@ -58,6 +59,8 @@ Module bases.encoding.errors
base: int
def __init__(self, digit: int, base: int) -> None:
+ validate(digit, int)
+ validate(base, int)
self.digit = digit
self.base = base
if 0 <= digit < base:
@@ -87,6 +90,8 @@ Module bases.encoding.errors
alphabet: Alphabet
def __init__(self, char: str, alphabet: Alphabet) -> None:
+ validate(char, str)
+ validate(alphabet, Alphabet)
self.char = char
self.alphabet = alphabet
if char in alphabet:
@@ -103,6 +108,8 @@ Module bases.encoding.errors
expected_padding: int
def __init__(self, padding: int, expected_padding: int) -> None:
+ validate(padding, int)
+ validate(expected_padding, int)
self.padding = padding
self.expected_padding = expected_padding
if padding < expected_padding:
@@ -292,6 +299,8 @@ Ancestors
base: int
def __init__(self, digit: int, base: int) -> None:
+ validate(digit, int)
+ validate(base, int)
self.digit = digit
self.base = base
if 0 <= digit < base:
@@ -341,6 +350,8 @@ Class variables
alphabet: Alphabet
def __init__(self, char: str, alphabet: Alphabet) -> None:
+ validate(char, str)
+ validate(alphabet, Alphabet)
self.char = char
self.alphabet = alphabet
if char in alphabet:
@@ -388,6 +399,8 @@ Class variables
expected_padding: int
def __init__(self, padding: int, expected_padding: int) -> None:
+ validate(padding, int)
+ validate(expected_padding, int)
self.padding = padding
self.expected_padding = expected_padding
if padding < expected_padding:
diff --git a/docs/bases/encoding/fixchar.html b/docs/bases/encoding/fixchar.html
index 80affb5..b6ad3b3 100644
--- a/docs/bases/encoding/fixchar.html
+++ b/docs/bases/encoding/fixchar.html
@@ -35,6 +35,7 @@ Module bases.encoding.fixchar
import math
from typing import Any, Dict, List, Mapping, Optional, Union
from typing_extensions import Literal
+from typing_validation import validate
from bases.alphabet import Alphabet
from .base import BaseEncoding
@@ -125,6 +126,9 @@ Module bases.encoding.fixchar
char_nbits: Union[int, Literal["auto"]] = "auto",
pad_char: Optional[str] = None,
padding: PaddingOptions = "ignore"):
+ validate(char_nbits, Union[int, Literal["auto"]])
+ validate(pad_char, Optional[str])
+ validate(padding, PaddingOptions)
if padding not in ("ignore", "include", "require"):
raise TypeError("Allowed padding options are: 'ignore', 'include' and 'require'.")
super().__init__(alphabet, case_sensitive=case_sensitive)
@@ -251,6 +255,7 @@ Module bases.encoding.fixchar
pad_char='=', padding='include')
```
"""
+ validate(require, bool)
options = dict(padding="require" if require else "include")
return self.with_options(**options)
@@ -278,6 +283,7 @@ Module bases.encoding.fixchar
case_sensitive=False))
```
"""
+ validate(allow, bool)
options = dict(padding="ignore", pad_char=self.pad_char if allow else None)
return self.with_options(**options)
@@ -302,6 +308,7 @@ Module bases.encoding.fixchar
```
"""
+ validate(pad_char, Optional[str])
options: Dict[str, Any] = dict(pad_char=pad_char)
if pad_char is None:
options["padding"] = "ignore"
@@ -316,8 +323,7 @@ Module bases.encoding.fixchar
The value of `FixcharBaseEncoding.padding` is irrelevant to this method.
"""
- if not isinstance(s, str):
- raise TypeError()
+ validate(s, str)
pad_char = self.pad_char
block_nchars = self._block_nchars
# no padding available for this encoding scheme
@@ -339,8 +345,7 @@ Module bases.encoding.fixchar
If `FixcharBaseEncoding.padding` is set to `"require"`, checks that the correct number of
padding characters were included and raises `bases.encoding.errors.PaddingError` if not.
"""
- if not isinstance(s, str):
- raise TypeError()
+ validate(s, str)
pad_char = self.pad_char
case_sensitive = self.case_sensitive
block_nchars = self._block_nchars
@@ -367,6 +372,7 @@ Module bases.encoding.fixchar
return b
def canonical_string(self, s: str) -> str:
+ validate(s, str)
if self.include_padding:
return self.pad_string(s)
return self.strip_string(s)
@@ -425,6 +431,7 @@ Module bases.encoding.fixchar
return i.to_bytes(length=original_nbytes, byteorder="big")
def options(self, skip_defaults: bool = False) -> Mapping[str, Any]:
+ validate(skip_defaults, bool)
options: Dict[str, Any] = {}
if not skip_defaults or self._init_char_nbits != "auto":
options["char_nbits"] = self._init_char_nbits
@@ -579,6 +586,9 @@
char_nbits: Union[int, Literal["auto"]] = "auto",
pad_char: Optional[str] = None,
padding: PaddingOptions = "ignore"):
+ validate(char_nbits, Union[int, Literal["auto"]])
+ validate(pad_char, Optional[str])
+ validate(padding, PaddingOptions)
if padding not in ("ignore", "include", "require"):
raise TypeError("Allowed padding options are: 'ignore', 'include' and 'require'.")
super().__init__(alphabet, case_sensitive=case_sensitive)
@@ -705,6 +715,7 @@
pad_char='=', padding='include')
```
"""
+ validate(require, bool)
options = dict(padding="require" if require else "include")
return self.with_options(**options)
@@ -732,6 +743,7 @@
case_sensitive=False))
```
"""
+ validate(allow, bool)
options = dict(padding="ignore", pad_char=self.pad_char if allow else None)
return self.with_options(**options)
@@ -756,6 +768,7 @@
```
"""
+ validate(pad_char, Optional[str])
options: Dict[str, Any] = dict(pad_char=pad_char)
if pad_char is None:
options["padding"] = "ignore"
@@ -770,8 +783,7 @@
The value of `FixcharBaseEncoding.padding` is irrelevant to this method.
"""
- if not isinstance(s, str):
- raise TypeError()
+ validate(s, str)
pad_char = self.pad_char
block_nchars = self._block_nchars
# no padding available for this encoding scheme
@@ -793,8 +805,7 @@
If `FixcharBaseEncoding.padding` is set to `"require"`, checks that the correct number of
padding characters were included and raises `bases.encoding.errors.PaddingError` if not.
"""
- if not isinstance(s, str):
- raise TypeError()
+ validate(s, str)
pad_char = self.pad_char
case_sensitive = self.case_sensitive
block_nchars = self._block_nchars
@@ -821,6 +832,7 @@
return b
def canonical_string(self, s: str) -> str:
+ validate(s, str)
if self.include_padding:
return self.pad_string(s)
return self.strip_string(s)
@@ -879,6 +891,7 @@
return i.to_bytes(length=original_nbytes, byteorder="big")
def options(self, skip_defaults: bool = False) -> Mapping[str, Any]:
+ validate(skip_defaults, bool)
options: Dict[str, Any] = {}
if not skip_defaults or self._init_char_nbits != "auto":
options["char_nbits"] = self._init_char_nbits
@@ -1065,6 +1078,7 @@ Methods
case_sensitive=False))
```
"""
+ validate(allow, bool)
options = dict(padding="ignore", pad_char=self.pad_char if allow else None)
return self.with_options(**options)
@@ -1144,6 +1158,7 @@ Methods
pad_char='=', padding='include')
```
"""
+ validate(require, bool)
options = dict(padding="require" if require else "include")
return self.with_options(**options)
@@ -1170,8 +1185,7 @@ Methods
The value of `FixcharBaseEncoding.padding` is irrelevant to this method.
"""
- if not isinstance(s, str):
- raise TypeError()
+ validate(s, str)
pad_char = self.pad_char
block_nchars = self._block_nchars
# no padding available for this encoding scheme
@@ -1207,8 +1221,7 @@ Methods
If `FixcharBaseEncoding.padding` is set to `"require"`, checks that the correct number of
padding characters were included and raises `bases.encoding.errors.PaddingError` if not.
"""
- if not isinstance(s, str):
- raise TypeError()
+ validate(s, str)
pad_char = self.pad_char
case_sensitive = self.case_sensitive
block_nchars = self._block_nchars
@@ -1274,6 +1287,7 @@ Methods
```
"""
+ validate(pad_char, Optional[str])
options: Dict[str, Any] = dict(pad_char=pad_char)
if pad_char is None:
options["padding"] = "ignore"
diff --git a/docs/bases/encoding/index.html b/docs/bases/encoding/index.html
index 559db31..f64c412 100644
--- a/docs/bases/encoding/index.html
+++ b/docs/bases/encoding/index.html
@@ -135,6 +135,7 @@ Module bases.encoding
import re
from typing import Any, cast, Collection, Dict, Iterator, Mapping, Optional, overload, Tuple, Type, Union
from typing_extensions import Literal
+from typing_validation import validate
from bases import alphabet
from bases.alphabet import Alphabet
@@ -161,6 +162,7 @@ Module bases.encoding
block_nchars=2)
```
"""
+ validate(name, str)
if name not in _base_encodings:
raise KeyError(f"Encoding named {repr(name)} does not exist.")
return _base_encodings[name]
@@ -173,6 +175,7 @@ Module bases.encoding
True
```
"""
+ validate(name, str)
return name in _base_encodings
def register(**kwargs: BaseEncoding) -> None:
@@ -198,6 +201,8 @@ Module bases.encoding
re.match(r"^base[0-9][a-zA-Z0-9_]*$", name)
```
"""
+ for arg in kwargs.values():
+ validate(arg, BaseEncoding)
for name, encoding in kwargs.items():
if not re.match(r"^base[0-9][a-zA-Z0-9_]*$", name):
raise ValueError(f"Invalid encoding name {repr(name)}")
@@ -233,6 +238,8 @@ Module bases.encoding
block_nchars=2)
```
"""
+ for name in names:
+ validate(name, str)
for name in names:
if name not in _base_encodings:
raise KeyError(f"Encoding named {repr(name)} does not exist.")
@@ -262,6 +269,7 @@ Module bases.encoding
```
"""
+ validate(prefix, str)
encodings = [(name, encoding) for name, encoding in _base_encodings.items()
if name.startswith(prefix)]
encodings = sorted(encodings, key=lambda pair: pair[0])
@@ -320,6 +328,10 @@ Module bases.encoding
```
"""
+ validate(chars, Union[str, range, Alphabet, BaseEncoding])
+ validate(kind, str)
+ validate(name, Optional[str])
+ validate(case_sensitive, Optional[bool])
kwargs["case_sensitive"] = case_sensitive
if kind == "simple-enc":
if isinstance(chars, BaseEncoding):
@@ -554,6 +566,7 @@
block_nchars=2)
```
"""
+ validate(name, str)
if name not in _base_encodings:
raise KeyError(f"Encoding named {repr(name)} does not exist.")
return _base_encodings[name]
@@ -579,6 +592,7 @@
True
```
"""
+ validate(name, str)
return name in _base_encodings
@@ -641,6 +655,10 @@
```
"""
+ validate(chars, Union[str, range, Alphabet, BaseEncoding])
+ validate(kind, str)
+ validate(name, Optional[str])
+ validate(case_sensitive, Optional[bool])
kwargs["case_sensitive"] = case_sensitive
if kind == "simple-enc":
if isinstance(chars, BaseEncoding):
@@ -708,6 +726,8 @@
re.match(r"^base[0-9][a-zA-Z0-9_]*$", name)
```
"""
+ for arg in kwargs.values():
+ validate(arg, BaseEncoding)
for name, encoding in kwargs.items():
if not re.match(r"^base[0-9][a-zA-Z0-9_]*$", name):
raise ValueError(f"Invalid encoding name {repr(name)}")
@@ -767,6 +787,7 @@
```
"""
+ validate(prefix, str)
encodings = [(name, encoding) for name, encoding in _base_encodings.items()
if name.startswith(prefix)]
encodings = sorted(encodings, key=lambda pair: pair[0])
@@ -824,6 +845,8 @@
block_nchars=2)
```
"""
+ for name in names:
+ validate(name, str)
for name in names:
if name not in _base_encodings:
raise KeyError(f"Encoding named {repr(name)} does not exist.")
diff --git a/docs/bases/encoding/simple.html b/docs/bases/encoding/simple.html
index bad6b97..ad8956b 100644
--- a/docs/bases/encoding/simple.html
+++ b/docs/bases/encoding/simple.html
@@ -33,6 +33,7 @@ Module bases.encoding.simple
"""
from typing import Any, List, Mapping, Optional, Union
+from typing_validation import validate
from bases.alphabet import Alphabet
from .base import BaseEncoding
@@ -107,6 +108,7 @@ Module bases.encoding.simple
return i.to_bytes(length=nbytes, byteorder="big")
def options(self, skip_defaults: bool = False) -> Mapping[str, Any]:
+ validate(skip_defaults, bool)
return {}
@@ -210,6 +212,7 @@
return i.to_bytes(length=nbytes, byteorder="big")
def options(self, skip_defaults: bool = False) -> Mapping[str, Any]:
+ validate(skip_defaults, bool)
return {}
Ancestors
diff --git a/docs/bases/encoding/zeropad.html b/docs/bases/encoding/zeropad.html
index 92a0342..db2de64 100644
--- a/docs/bases/encoding/zeropad.html
+++ b/docs/bases/encoding/zeropad.html
@@ -34,6 +34,7 @@ Module bases.encoding.zeropad
import math
from typing import Any, Dict, Mapping, Optional, Union
+from typing_validation import validate
from bases.alphabet import Alphabet
from .base import BaseEncoding
@@ -79,6 +80,8 @@ Module bases.encoding.zeropad
case_sensitive: Optional[bool] = None,
block_nbytes: int = 1,
block_nchars: int = 1):
+ validate(block_nbytes, int)
+ validate(block_nchars, int)
super().__init__(alphabet, case_sensitive=case_sensitive)
self._simple_encoding = SimpleBaseEncoding(self.alphabet)
self._block_nbytes = block_nbytes
@@ -109,6 +112,8 @@ Module bases.encoding.zeropad
256**block_nbytes > base**(block_nchars-1)
```
"""
+ validate(base, int)
+ validate(block_nbytes, int)
if base <= 1:
raise ValueError("Base must be >= 2.")
if block_nbytes <= 0:
@@ -127,6 +132,8 @@ Module bases.encoding.zeropad
base**block_nchars > 256**(block_nbytes-1)
```
"""
+ validate(base, int)
+ validate(block_nchars, int)
if base <= 1:
raise ValueError("Base must be >= 2.")
if block_nchars <= 0:
@@ -204,6 +211,7 @@ Module bases.encoding.zeropad
return b
def options(self, skip_defaults: bool = False) -> Mapping[str, Any]:
+ validate(skip_defaults, bool)
options: Dict[str, Any] = {}
if not skip_defaults or self.block_nbytes != 1:
options["block_nbytes"] = self.block_nbytes
@@ -297,6 +305,8 @@
case_sensitive: Optional[bool] = None,
block_nbytes: int = 1,
block_nchars: int = 1):
+ validate(block_nbytes, int)
+ validate(block_nchars, int)
super().__init__(alphabet, case_sensitive=case_sensitive)
self._simple_encoding = SimpleBaseEncoding(self.alphabet)
self._block_nbytes = block_nbytes
@@ -327,6 +337,8 @@
256**block_nbytes > base**(block_nchars-1)
```
"""
+ validate(base, int)
+ validate(block_nbytes, int)
if base <= 1:
raise ValueError("Base must be >= 2.")
if block_nbytes <= 0:
@@ -345,6 +357,8 @@
base**block_nchars > 256**(block_nbytes-1)
```
"""
+ validate(base, int)
+ validate(block_nchars, int)
if base <= 1:
raise ValueError("Base must be >= 2.")
if block_nchars <= 0:
@@ -422,6 +436,7 @@
return b
def options(self, skip_defaults: bool = False) -> Mapping[str, Any]:
+ validate(skip_defaults, bool)
options: Dict[str, Any] = {}
if not skip_defaults or self.block_nbytes != 1:
options["block_nbytes"] = self.block_nbytes
@@ -456,6 +471,8 @@ Static methods
base**block_nchars > 256**(block_nbytes-1)
```
"""
+ validate(base, int)
+ validate(block_nchars, int)
if base <= 1:
raise ValueError("Base must be >= 2.")
if block_nchars <= 0:
@@ -485,6 +502,8 @@ Static methods
256**block_nbytes > base**(block_nchars-1)
```
"""
+ validate(base, int)
+ validate(block_nbytes, int)
if base <= 1:
raise ValueError("Base must be >= 2.")
if block_nbytes <= 0:
diff --git a/docs/bases/index.html b/docs/bases/index.html
index 3403379..534a75f 100644
--- a/docs/bases/index.html
+++ b/docs/bases/index.html
@@ -133,6 +133,8 @@ Package bases
"""
+__version__ = "0.2.0"
+
from . import encoding as encoding
from . import alphabet as alphabet
from .encoding import (base2, base16, base8, base10, base36, base58btc, base58flickr, base58ripple,
diff --git a/docs/bases/random.html b/docs/bases/random.html
index f306017..40c82cd 100644
--- a/docs/bases/random.html
+++ b/docs/bases/random.html
@@ -119,6 +119,7 @@ Module bases.random
from random import Random # pylint: disable = import-self
from types import MappingProxyType
from typing import Any, Dict, Iterator, Mapping, Optional
+from typing_validation import validate
from .alphabet import Alphabet
from .encoding import BaseEncoding, SimpleBaseEncoding, ZeropadBaseEncoding, BlockBaseEncoding, FixcharBaseEncoding
@@ -179,6 +180,8 @@ Module bases.random
See `set_options` for a description of the options.
"""
# pylint: disable = too-many-locals
+ for arg in (seed, min_bytes, max_bytes, min_chars, max_chars):
+ validate(arg, Optional[int])
global _options
global _rand
try:
@@ -212,6 +215,8 @@ Module bases.random
"""
# pylint: disable = too-many-branches, too-many-locals, too-many-statements
+ for arg in (seed, min_bytes, max_bytes, min_chars, max_chars):
+ validate(arg, Optional[int])
global _options
global _rand
# set newly passed options
@@ -264,6 +269,8 @@ Module bases.random
[0, 96, 63]]
```
"""
+ validate(n, Optional[int])
+ validate(encoding, Optional[BaseEncoding])
if encoding is None:
return rand_raw_bytes(n)
if isinstance(encoding, SimpleBaseEncoding):
@@ -284,6 +291,9 @@ Module bases.random
The optional `min_bytes` and `max_bytes` parameters can be used to set a minimum/maximum length
for the `bytes` objects: if `None`, the values are fetched from `get_options`.
"""
+ validate(n, Optional[int])
+ validate(min_bytes, Optional[int])
+ validate(max_bytes, Optional[int])
if n is not None and n < 0:
raise ValueError()
if min_bytes is None:
@@ -385,6 +395,9 @@ Module bases.random
```
"""
+ validate(n, Optional[int])
+ validate(encoding, Optional[BaseEncoding])
+ validate(alphabet, Optional[Alphabet])
if encoding is None:
if alphabet is None:
raise ValueError("One of 'encoding' or 'alphabet' must be specified.")
@@ -646,6 +659,8 @@
See `set_options` for a description of the options.
"""
# pylint: disable = too-many-locals
+ for arg in (seed, min_bytes, max_bytes, min_chars, max_chars):
+ validate(arg, Optional[int])
global _options
global _rand
try:
@@ -731,6 +746,8 @@
[0, 96, 63]]
```
"""
+ validate(n, Optional[int])
+ validate(encoding, Optional[BaseEncoding])
if encoding is None:
return rand_raw_bytes(n)
if isinstance(encoding, SimpleBaseEncoding):
@@ -793,6 +810,9 @@
The optional `min_bytes` and `max_bytes` parameters can be used to set a minimum/maximum length
for the `bytes` objects: if `None`, the values are fetched from `get_options`.
"""
+ validate(n, Optional[int])
+ validate(min_bytes, Optional[int])
+ validate(max_bytes, Optional[int])
if n is not None and n < 0:
raise ValueError()
if min_bytes is None:
@@ -846,6 +866,9 @@
```
"""
+ validate(n, Optional[int])
+ validate(encoding, Optional[BaseEncoding])
+ validate(alphabet, Optional[Alphabet])
if encoding is None:
if alphabet is None:
raise ValueError("One of 'encoding' or 'alphabet' must be specified.")
@@ -916,6 +939,8 @@
"""
# pylint: disable = too-many-branches, too-many-locals, too-many-statements
+ for arg in (seed, min_bytes, max_bytes, min_chars, max_chars):
+ validate(arg, Optional[int])
global _options
global _rand
# set newly passed options
diff --git a/setup.cfg b/setup.cfg
index 9615180..b4f0b9f 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -19,16 +19,16 @@ classifiers =
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.7
- Programming Language :: Python :: 3.6
Operating System :: OS Independent
Natural Language :: English
Typing :: Typed
[options]
packages = find:
-python_requires = >=3.6
+python_requires = >=3.7
install_requires =
- typing_extensions
+ typing-extensions
+ typing-validation
[options.package_data]
* = py.typed
diff --git a/tox.ini b/tox.ini
index cad94b2..c0ca378 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,10 +1,11 @@
# content of: tox.ini, put in same dir as setup.py
[tox]
-envlist = py36, py37, py38, py39, py310
+envlist = py37, py38, py39, py310
isolated_build = True
[testenv]
deps =
+ -rrequirements.txt
mypy
pylint
pytest