Skip to content

Commit 7e73d80

Browse files
committed
Merge dev into main
2 parents abdf01f + de3787c commit 7e73d80

File tree

8 files changed

+49
-18
lines changed

8 files changed

+49
-18
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# OSBot-Utils
22

3-
![Current Release](https://img.shields.io/badge/release-v3.35.0-blue)
3+
![Current Release](https://img.shields.io/badge/release-v3.35.1-blue)
44
![Python](https://img.shields.io/badge/python-3.8+-green)
55
![Type-Safe](https://img.shields.io/badge/Type--Safe-✓-brightgreen)
66
![Caching](https://img.shields.io/badge/Caching-Built--In-orange)

osbot_utils/decorators/methods/cache_on_self.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import inspect
21
from functools import wraps
3-
from typing import Any, Callable, TypeVar, Dict
4-
from weakref import WeakKeyDictionary
5-
2+
from typing import Any, Callable, TypeVar, Dict
3+
from weakref import WeakKeyDictionary
64
from osbot_utils.helpers.cache_on_self.Cache_On_Self import Cache_On_Self
75

86

osbot_utils/type_safe/Type_Safe__Base.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,15 @@ class Type_Safe__Base:
1111
def is_instance_of_type(self, item, expected_type):
1212
if expected_type is Any:
1313
return True
14-
if isinstance(expected_type, ForwardRef): # todo: add support for ForwardRef
14+
if isinstance(expected_type, str):
15+
if type(item).__name__ == expected_type: # happens in ForwardRefs
16+
return True
17+
else:
18+
raise TypeError(f"Expected type '{expected_type}' but got instance of '{type(item).__name__}'.") # Doesn't match - unresolvable forward reference
19+
20+
if isinstance(expected_type, ForwardRef): # todo: add support for ForwardRef | todo: see the side effects of this 'return true'
1521
return True
22+
1623
origin = type_safe_cache.get_origin(expected_type)
1724
args = get_args(expected_type)
1825

osbot_utils/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v3.35.0
1+
v3.35.1

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "osbot_utils"
3-
version = "v3.35.0"
3+
version = "v3.35.1"
44
description = "OWASP Security Bot - Utils"
55
authors = ["Dinis Cruz <[email protected]>"]
66
license = "MIT"

tests/unit/type_safe/type_safe_core/decorators/test__decorator__type_safe__bugs.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import re
21
import pytest
32
from typing import List, Dict, Callable
43
from unittest import TestCase
@@ -8,14 +7,6 @@
87

98
class test__decorator__type_safe__bugs(TestCase):
109

11-
def test__bug__type_safe__return_value__not_works__with_forward_refs(self):
12-
class An_Class(Type_Safe):
13-
@type_safe
14-
def return_self(self) ->'An_Class':
15-
return self
16-
error_message = "Function 'test__decorator__type_safe__bugs.test__bug__type_safe__return_value__not_works__with_forward_refs.<locals>.An_Class.return_self' return type validation failed: isinstance() arg 2 must be a type, a tuple of types, or a union"
17-
with pytest.raises(TypeError, match=re.escape(error_message)):
18-
An_Class().return_self()
1910

2011
def test__bug__type_safe__list_callable_with_signatures(self):
2112

tests/unit/type_safe/type_safe_core/decorators/test__decorator__type_safe__regression.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,3 +488,38 @@ def an_method(texts : Dict[Safe_Str, Safe_UInt]):
488488
assert an_method(texts=texts_1) == texts_2
489489
assert an_method(texts=texts_1) == texts_3
490490
assert an_method(texts=texts_1) == texts_4
491+
492+
def test__regression__type_safe__return_value__not_works__with__bad__forward_refs(self):
493+
import re
494+
495+
class An_Class(Type_Safe):
496+
@type_safe
497+
def an_method(self) -> 'An_Class2':
498+
return self
499+
500+
error_message = ("Function 'test_decorator__type_safe__regression.test__regression__type_safe__return_value__not_works__with__bad__forward_refs."
501+
"<locals>.An_Class.an_method' return type validation failed: "
502+
"Expected type 'An_Class2' but got instance of 'An_Class'.")
503+
504+
with pytest.raises(TypeError, match=re.escape(error_message)):
505+
An_Class().an_method()
506+
507+
def test__regression__type_safe__return_value__not_works__with_differnt__forward_refs(self):
508+
class An_Class_2(Type_Safe):
509+
pass
510+
class An_Class_1(Type_Safe):
511+
@type_safe
512+
def an_method(self) -> 'An_Class_2':
513+
return An_Class_2()
514+
515+
assert type(An_Class_1().an_method()) is An_Class_2 # FIXED: this used to fail before fix
516+
517+
def test__regression__type_safe__return_value__not_works__with_forward_refs(self):
518+
class An_Class(Type_Safe):
519+
@type_safe
520+
def return_self(self) -> 'An_Class':
521+
return self
522+
# error_message = "Function 'test__decorator__type_safe__bugs.test__bug__type_safe__return_value__not_works__with_forward_refs.<locals>.An_Class.return_self' return type validation failed: isinstance() arg 2 must be a type, a tuple of types, or a union"
523+
# with pytest.raises(TypeError, match=re.escape(error_message)):
524+
# An_Class().return_self() # BUG
525+
assert type(An_Class().return_self()) is An_Class # FIXED

tests/unit/type_safe/type_safe_core/steps/test_perf__Type_Safe__Step__From_Json.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def deserialize_none_type(): # Test None
160160

161161
with Performance_Measure__Session() as session:
162162
session.measure(deserialize_type ).assert_time__less_than(self.time_20_kns )
163-
session.measure(deserialize_none_type).assert_time__less_than(self.time_500_ns)
163+
session.measure(deserialize_none_type).assert_time__less_than(self.time_1_kns)
164164

165165
def test_dict_key_value_annotations(self): # Test dict with annotated keys/values
166166
class AnnotatedDict(Type_Safe):

0 commit comments

Comments
 (0)