Skip to content

Commit

Permalink
Align warning frame with user input.
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewwardrop committed Jan 17, 2024
1 parent 2fe6272 commit 5995eed
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
19 changes: 15 additions & 4 deletions docsite/docs/usage/special_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,15 @@ as shown):
class MyClass:
@spec_property(
overridable=True, # Whether to allow overriding by default.
warn_on_override=False, # Whether to warn the user when the property getter
# is overridden. Can be a boolean, string, or `Warning` instance.
# If non-boolean, then it is treated as the message to present to
# the user using `warnings.warn`.
cache=False, # Whether to cache the result after first evaluation.
invalidated_by=None, # An iterable of attributes which when mutated invalidate the cache (only supported when used with spec-classes)
allow_attribute_error=True, # Whether to allow properties to raise `AttributeErrors` which are often masked during attribute lookup.
invalidated_by=None, # An iterable of attributes which when mutated
# invalidate the cache (only supported when used with spec-classes)
allow_attribute_error=True, # Whether to allow properties to raise
# `AttributeErrors` which are often masked during attribute lookup.
)
def method(self):
...
Expand All @@ -328,11 +334,16 @@ as follows:
```python
class MyClass:
@classproperty(
overridable=True, # Whether to allow overriding by default.
overridable=False, # Whether to allow overriding by default.
warn_on_override=False, # Whether to warn the user when the property getter
# is overridden. Can be a boolean, string, or `Warning` instance.
# If non-boolean, then it is treated as the message to present to
# the user using `warnings.warn`.
cache=False, # Whether to cache the result after first evaluation.
cache_per_subclass=False, # Whether cache should be stored per subclass
# rather than once for all classes.
allow_attribute_error=True, # Whether to allow properties to raise `AttributeErrors` which are often masked during attribute lookup.
allow_attribute_error=True, # Whether to allow properties to raise
# `AttributeErrors` which are often masked during attribute lookup.
)
def method(cls):
...
Expand Down
5 changes: 3 additions & 2 deletions spec_classes/types/spec_property.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from spec_classes.errors import NestedAttributeError
from spec_classes.utils.mutation import prepare_attr_value
from spec_classes.utils.stackdepth import get_spec_classes_depth
from spec_classes.utils.type_checking import check_type, type_label


Expand Down Expand Up @@ -292,7 +293,7 @@ def __set__(self, instance, value):
f"Property `{self._qualified_name}` is now overridden and will not update based on instance state."
if isinstance(self.warn_on_override, bool)
else self.warn_on_override,
stacklevel=2,
stacklevel=get_spec_classes_depth(),
)
return
raise AttributeError(
Expand Down Expand Up @@ -470,7 +471,7 @@ def __set__(self, obj, value):
f"Class property `{self._qualified_name}` is now overridden and will not update based on class state."
if isinstance(self.warn_on_override, bool)
else self.warn_on_override,
stacklevel=2,
stacklevel=get_spec_classes_depth(),
)
return
raise AttributeError(
Expand Down
20 changes: 20 additions & 0 deletions spec_classes/utils/stackdepth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import sys


def get_spec_classes_depth():
"""
The recursion depth of the caller into spec-classes from first
non-spec-classes frame.
Args:
offset: An offset to apply the calculated depth. An `offset` of 1 aligns
the depth with that of the caller.
"""
stacklevel = 0
f = sys._getframe()
while f.f_back and (
"spec_classes" in f.f_code.co_filename or f.f_code.co_filename == "<string>"
):
f = f.f_back
stacklevel += 1
return stacklevel

0 comments on commit 5995eed

Please sign in to comment.