diff --git a/pyconstants.py b/pyconstants.py index d532e9d..3071da7 100644 --- a/pyconstants.py +++ b/pyconstants.py @@ -1,8 +1,9 @@ import sys from collections import defaultdict -from typing import Dict, Callable, List, Final from dataclasses import dataclass from types import FrameType +from typing import Callable, Dict, Final, List + @dataclass class ConstantValue: @@ -10,23 +11,28 @@ class ConstantValue: name: str value: object + def _traceFun(frame: FrameType, event: str, arg: object) -> None: for constant in constMap[frame]: - if constant.name in frame.f_locals and frame.f_locals[constant.name] != constant.value: - frame.f_locals[constant.name] = constant.value + if ( + constant.name in frame.f_locals + and frame.f_locals[constant.name] != constant.value + ): + frame.f_locals[constant.name] = constant.value raise SyntaxError(f"Cannot assign value to constant {repr(constant.name)}") + class _ConstClass: def __setattr__(self, name, value): """This is the method called when a new constant is created""" targetFrame = sys._getframe(1) targetFrame.f_trace_lines = False targetFrame.f_trace_opcodes = True - targetFrame.f_trace = _traceFun + targetFrame.f_trace = _traceFun targetFrame.f_locals[name] = value constMap[targetFrame].append(ConstantValue(targetFrame, name, value)) -constMap: Dict[FrameType, List[ConstantValue]] = defaultdict(list) # FIXME +constMap: Dict[FrameType, List[ConstantValue]] = defaultdict(list) # FIXME sys.settrace(lambda frame, event, arg: None) const = _ConstClass() diff --git a/test.py b/test.py index d9e2bbd..2ff1561 100644 --- a/test.py +++ b/test.py @@ -1,9 +1,11 @@ import pytest + from pyconstants import const + def test_costant(): # It's not that complex, why am I even writing tests? - const .myvar = 5 + const.myvar = 5 with pytest.raises(SyntaxError): myvar = 7 assert myvar == 5