Skip to content
Merged

Op #33

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions doc/architecture_improvements.md
Original file line number Diff line number Diff line change
Expand Up @@ -761,14 +761,6 @@ class LazyModelCollector:
if self._steps is None:
self._steps = self._discover_steps()
return self._steps

@lru_cache(maxsize=128)
def evaluate_guard(self, step_name: str) -> bool:
"""Evaluate guard with caching."""
guard = self._guards.get(f"guard_{step_name}")
if guard is None:
return True
return guard(self.model)
```

### 6.2 Algorithm Optimizations
Expand Down
Empty file modified license_to_commit.sh
100644 → 100755
Empty file.
8 changes: 4 additions & 4 deletions pyosmo/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,21 @@ def can_process(self) -> bool:
# Inline guard - return a decorator that attaches the guard to the step
guard_func = step_name_or_func

def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
def inline_decorator(func: Callable[..., Any]) -> Callable[..., Any]:
func._osmo_guard_inline = guard_func # type: ignore[attr-defined]
func._osmo_guard_invert = invert # type: ignore[attr-defined]
return func

return decorator
return inline_decorator

# Named guard
def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
def named_decorator(func: Callable[..., Any]) -> Callable[..., Any]:
func._osmo_guard = True # type: ignore[attr-defined]
func._osmo_guard_for = step_name_or_func # type: ignore[attr-defined]
func._osmo_guard_invert = invert # type: ignore[attr-defined]
return func

return decorator
return named_decorator


def pre(step_name: str) -> Callable[[F], F]:
Expand Down
11 changes: 7 additions & 4 deletions pyosmo/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,13 @@ def _find_decorator_guard(self) -> Optional['ModelFunction']:
"""Find a guard method decorated with @guard("step_name") for this step."""
for attr_name in dir(self.object_instance):
method = getattr(self.object_instance, attr_name)
if callable(method) and hasattr(method, '_osmo_guard') and hasattr(method, '_osmo_guard_for'):
# Check if this guard is for our step
if method._osmo_guard_for == self.name:
return ModelFunction(attr_name, self.object_instance)
if (
callable(method)
and hasattr(method, '_osmo_guard')
and hasattr(method, '_osmo_guard_for')
and method._osmo_guard_for == self.name
):
return ModelFunction(attr_name, self.object_instance)
return None

@property
Expand Down
13 changes: 7 additions & 6 deletions pyosmo/tests/test_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def __init__(self):
def process(self):
self.process_called = True

@guard("process")
@guard('process')
def can_process(self) -> bool:
return self.ready

Expand Down Expand Up @@ -207,7 +207,8 @@ def other_action(self):

model = InlineGuardModel()
osmo = Osmo(model)
osmo.test_end_condition = Length(10)
osmo.seed = 42
osmo.test_end_condition = Length(20)

osmo.run()

Expand All @@ -227,7 +228,7 @@ def __init__(self):
def action(self):
self.action_called = True

@guard("action", invert=True)
@guard('action', invert=True)
def is_blocked(self) -> bool:
return self.blocked

Expand Down Expand Up @@ -262,11 +263,11 @@ def login(self):
def checkout(self):
pass

@guard("login")
@guard('login')
def can_login(self) -> bool:
return not self.logged_in

@guard("checkout")
@guard('checkout')
def can_checkout(self) -> bool:
return self.logged_in and self.has_items

Expand Down Expand Up @@ -305,7 +306,7 @@ def __init__(self):
def action_a(self):
pass

@guard("action_a")
@guard('action_a')
def guard_for_a(self) -> bool:
return self.flag_a

Expand Down
9 changes: 4 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build-system]
requires = ["setuptools>=45", "wheel", "setuptools-scm[toml]>=6.2"]
requires = ["setuptools>=77.0.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
Expand All @@ -8,7 +8,7 @@ version = "0.2.2"
description = "pyosmo - a model-based testing tool"
readme = "README.md"
requires-python = ">=3.11"
license = {text = "MIT"}
license = "MIT"
authors = [
{name = "Olli-Pekka Puolitaival", email = "oopee1@gmail.com"},
]
Expand All @@ -18,7 +18,6 @@ maintainers = [
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand All @@ -27,13 +26,13 @@ classifiers = [
]
dependencies = [
"click",
"mypy>=1.18.2",
"pytest>=9.0.0",
]

[project.optional-dependencies]
dev = [
"pytest>=7.0",
"mypy>=1.18.2",
"pytest>=9.0.0",
"hypothesis>=6.0",
"ruff>=0.1.0",
"mypy>=1.0",
Expand Down
8 changes: 3 additions & 5 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.