def test_ensure_path_like(): assert TypeCheck.ensure_path_like("") is None assert TypeCheck.ensure_path_like(b"") is None from pathlib import Path assert TypeCheck.ensure_path_like(Path("hello")) is None with pytest.raises(TypeError): TypeCheck.ensure_path_like(1)
def load_app_config(config_path: PathLike) -> None: """Loads the configuration of the application. Args: config_path (PathLike): The path to config file. Returns: None Raises: SystemExit: Config file is unreadable. """ TypeCheck.ensure_path_like(config_path, "config_path") try: with open(config_path) as fp: # De-serialise JSON to Python's dict and update config = Config.from_dict(json.load(fp)) config.apply_core_patch(DefaultCoreConfig) make_config_global(config) except FileNotFoundError: logger.warning("Config file not found! Auto-configuring...", exc_info=True) make_config_global(Config()) except OSError: logger.exception("Unable to load config file due to unknown reason(s)!") sys.exit(1)
def test_ensure_custom(): class Test: pass test = Test() assert TypeCheck.ensure_custom(Test, test) is None with pytest.raises(TypeError): TypeCheck.ensure_custom(Test, object())
def test_ensure_generator(): def a(): yield 1 a = a() assert TypeCheck.ensure_generator(a) is None with pytest.raises(TypeError): TypeCheck.ensure_generator({1}) with pytest.raises(TypeError): TypeCheck.ensure_generator("string".split())
def make_fernet(key: bytes) -> Fernet: """Makes a Fernet encrypter/decrypter from the derived key. Args: key (bytes): The derived key, in bytes. Returns: A Fernet instance, which can be used to either encrypt or decrypt data. """ TypeCheck.ensure_bytes(key, "key") return Fernet(base64.urlsafe_b64encode(key))
def encode_salt(salt: bytes) -> str: """Encodes the raw salt as string. Args: salt (bytes): The raw salt, in bytes. Returns: The Base64-encoded string of the raw salt """ TypeCheck.ensure_bytes(salt, "salt") return str(base64.b64encode(salt), "utf-8")
def decode_salt(salt: str) -> bytes: """Decodes the salt string to raw salt. Args: salt (str): The Base64-encoded string of the raw salt. Returns: The raw salt """ TypeCheck.ensure_str(salt, "salt") return base64.b64decode(bytes(salt, "utf-8"))
def make_decrypter(salt: str, key: str) -> Cryptographer: """Makes a Fernet decrypter for salt and key. Args: salt (str): The Base64-encoded string of the raw salt. key (str): The authentication key. Returns: A `Cryptographer` instance, which can be used to decrypt data. """ TypeCheck.ensure_str(salt, "salt") TypeCheck.ensure_str(key, "key") return Cryptographer(Cryptographer.decode_salt(salt), key.encode(), False)
def make_kdf(salt: bytes) -> PBKDF2HMAC: """Makes a key derivation function from raw salt. Args: salt (bytes): The raw salt, in bytes. Returns: A PBKDF2HMAC instance, which can be used to derive key from the authentication key. """ TypeCheck.ensure_bytes(salt, "salt") return PBKDF2HMAC( algorithm=hashes.SHA512(), length=32, salt=salt, iterations=10000, backend=default_backend(), )
def encrypt(self, raw_data: bytes) -> bytes: """Encrypts raw data. Args: raw_data (bytes): The raw data to be encrypted. Returns: The encrypted data, in bytes, which is encrypted using the `Fernet` (created by `Cryptography.make_fernet`) Raises: ValueError: A decrypter is used to encrypt. """ TypeCheck.ensure_bytes(raw_data, "raw_data") if not self.is_encrypt: raise ValueError("Not an encrypter!") fernet = Cryptographer.make_fernet(self.key) return fernet.encrypt(raw_data)
def decrypt(self, encrypted_data: bytes) -> bytes: """Decrypts the encrypted data. Args: encrypted_data (bytes): The encrypted data to be decrypted. Returns: The decrypted data, in bytes, which is decrypted using the `Fernet` (created by `Cryptography.make_fernet`) """ TypeCheck.ensure_bytes(encrypted_data, "encrypted_data") if self.is_encrypt: raise ValueError("Not a decrypter!") fernet = Cryptographer.make_fernet(self.key) try: return fernet.decrypt(encrypted_data) except InvalidToken: raise
def test_ensure_bytes(): assert TypeCheck.ensure_bytes(b"3123") is None assert TypeCheck.ensure_bytes(bytes(132423)) is None assert TypeCheck.ensure_bytes("n".encode()) is None with pytest.raises(TypeError): TypeCheck.ensure_bytes(8) with pytest.raises(TypeError): TypeCheck.ensure_bytes(["string"])
def save_app_config(config: Config, config_path: PathLike) -> None: """Saves the configuration of the application. Args: config (Config): The global Config instance config_path (PathLike): The path to config file Returns: None Raises: SystemExit: Config file is not writable. """ TypeCheck.ensure_path_like(config_path, "config_path") try: with open(config_path, "w") as fp: json.dump(config.__dict__(), fp) except OSError: logger.exception("Unable to save config file due to unknown reason(s)!") sys.exit(1)
def test_ensure_bool(): assert TypeCheck.ensure_bool(True) is None assert TypeCheck.ensure_bool(False) is None with pytest.raises(TypeError): TypeCheck.ensure_bool(0) with pytest.raises(TypeError): TypeCheck.ensure_bool(1)
def test_ensure_int(): assert TypeCheck.ensure_int(12345) is None assert TypeCheck.ensure_int(12341234123412341234) is None with pytest.raises(TypeError): TypeCheck.ensure_int("12345") with pytest.raises(TypeError): TypeCheck.ensure_int(12345.0)
def test_ensure_bytearray(): assert TypeCheck.ensure_bytearray(bytearray(5)) is None assert TypeCheck.ensure_bytearray(bytearray("41243", "utf-8")) is None with pytest.raises(TypeError): TypeCheck.ensure_bytearray(b"1234") with pytest.raises(TypeError): TypeCheck.ensure_bytearray(["string"])
def test_ensure_str(): assert TypeCheck.ensure_str("") is None assert TypeCheck.ensure_str(r"1asm") is None with pytest.raises(TypeError): TypeCheck.ensure_str(8) with pytest.raises(TypeError): TypeCheck.ensure_str(["string"])
def test_ensure_dict(): assert TypeCheck.ensure_dict(dict()) is None assert TypeCheck.ensure_dict({1: 5, "123": -8}) is None with pytest.raises(TypeError): TypeCheck.ensure_dict({1}) with pytest.raises(TypeError): TypeCheck.ensure_dict("string".split())
def test_ensure_set(): assert TypeCheck.ensure_set(set()) is None assert TypeCheck.ensure_set({1}) is None with pytest.raises(TypeError): TypeCheck.ensure_set(8) with pytest.raises(TypeError): TypeCheck.ensure_set("string".split())
def test_ensure_tuple(): assert TypeCheck.ensure_tuple(tuple()) is None assert TypeCheck.ensure_tuple((5, )) is None with pytest.raises(TypeError): TypeCheck.ensure_tuple(8) with pytest.raises(TypeError): TypeCheck.ensure_tuple("string".split())
def test_ensure_list(): assert TypeCheck.ensure_list([]) is None assert TypeCheck.ensure_list("".split()) is None with pytest.raises(TypeError): TypeCheck.ensure_list(8) with pytest.raises(TypeError): TypeCheck.ensure_list("string")
def test_ensure_float(): assert TypeCheck.ensure_float(12345.0) is None assert TypeCheck.ensure_float( 123412341234123445.0000000000000000001) is None with pytest.raises(TypeError): TypeCheck.ensure_float(8j) with pytest.raises(TypeError): TypeCheck.ensure_float(12345)
def test_ensure_function(): assert TypeCheck.ensure_function(lambda: None) is None assert TypeCheck.ensure_function( TestTypeCheck.test_ensure_dict) is None with pytest.raises(TypeError): TypeCheck.ensure_function({1}) with pytest.raises(TypeError): TypeCheck.ensure_function("string".split())
def test_ensure_complex(): assert TypeCheck.ensure_complex(12 + 5j) is None assert TypeCheck.ensure_complex(135453123123 + 0.00000000000000000001j) is None with pytest.raises(TypeError): TypeCheck.ensure_complex(8) with pytest.raises(TypeError): TypeCheck.ensure_complex("1234s")
def test_ensure_memoryview(): assert TypeCheck.ensure_memoryview(memoryview("a".encode())) is None with pytest.raises(TypeError): TypeCheck.ensure_memoryview({1}) with pytest.raises(TypeError): TypeCheck.ensure_memoryview("string".split())
def test_ensure_frozenset(): assert TypeCheck.ensure_frozenset(frozenset(range(10))) is None with pytest.raises(TypeError): TypeCheck.ensure_frozenset({1}) with pytest.raises(TypeError): TypeCheck.ensure_frozenset("string".split())
def test_ensure_with_name(): name = "test_name" with pytest.raises(TypeError, match=name): TypeCheck.ensure_int("", name)