diff --git a/.vscode/settings.json b/.vscode/settings.json index a08bb8f..213bbf3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "python.testing.pytestArgs": [ - "pyrox", + "test", + "pyrox" ], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true, diff --git a/README.md b/README.md index a6d0ce2..0caf31e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Python Version](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/downloads/) [![License](https://img.shields.io/badge/license-GPL--3.0-green.svg)](LICENSE) ![Development Status](https://img.shields.io/badge/status-beta-orange.svg) -![Version](https://img.shields.io/badge/version-3.6.9-blue.svg) +![Version](https://img.shields.io/badge/version-3.6.10-blue.svg) **Pyrox** is a Python back-end engine and application framework built on **PyQt6**. It provides a rich set of interfaces, models, services, and abstractions for building industrial automation and desktop applications. Pyrox is designed to be used as a foundation — downstream projects like [ControlRox](https://github.com/iroxusux/ControlRox) build their entire application layer on top of it. diff --git a/pyproject.toml b/pyproject.toml index 9ea7e34..13dab4c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pyrox" -version = "3.6.9" +version = "3.6.10" authors = [{ name = "Brian LaFond", email = "Brian.L.LaFond@gmail.com" }] description = "Python based irox engine." readme = "README.md" diff --git a/pyrox/core/__init__.py b/pyrox/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pyrox/core/validators.py b/pyrox/core/validators.py new file mode 100644 index 0000000..baf08ab --- /dev/null +++ b/pyrox/core/validators.py @@ -0,0 +1,17 @@ +from typing import Any + + +def unsafe_assert_is_type(value: Any, type_check: type) -> None: + """Common use type check assertion. + Useful for single line, compact type checking to raise a common message to the user. + Doesn't return anything, as it is unsafe and will stop execution in place. + + Args: + value (Any): Value object to check. + type_check (type): Type that the 'value' must be, otherwise a value is raised + + Raises: + ValueError: If value is not type(type_check) + """ + if not isinstance(value, type_check): + raise ValueError(f'Expected type {str(type_check)}, but got {str(type(value))}!') diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/core/__init__.py b/test/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/core/test_validators.py b/test/core/test_validators.py new file mode 100644 index 0000000..5b6412a --- /dev/null +++ b/test/core/test_validators.py @@ -0,0 +1,35 @@ +import pytest +from pyrox.core.validators import unsafe_assert_is_type + + +class TestUnsafeAssertIsType: + + def test_expected_values_pass(self): + unsafe_assert_is_type('string', str) + unsafe_assert_is_type(0, int) + unsafe_assert_is_type(0.0, float) + unsafe_assert_is_type(object(), object) + + def test_custom_classes_pass(self): + class TestClass: + def __init__(self) -> None: + self.a = 1 + + unsafe_assert_is_type(TestClass(), TestClass) + + def test_child_classes_all_pass(self): + class TestClass: + def __init__(self) -> None: + self.a = 1 + + class ChildClass(TestClass): + pass + + unsafe_assert_is_type(TestClass(), TestClass) + unsafe_assert_is_type(ChildClass(), ChildClass) + unsafe_assert_is_type(ChildClass(), TestClass) + + def test_incorrect_value_raises_value_error_with_message(self): + with pytest.raises(ValueError) as context: + unsafe_assert_is_type('string', int) + assert context.exconly() == f'ValueError: Expected type {str(int)}, but got {str(str)}!'