Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

State using ABC base class #90

Merged
merged 4 commits into from
Nov 11, 2021
Merged
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
17 changes: 15 additions & 2 deletions src/miniflask/state.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import sys
import re
from collections.abc import MutableMapping

from colored import fg, attr

from .util import get_varid_from_fuzzy, highlight_module, get_relative_id
from .exceptions import StateKeyError


class temporary_state(dict):
class temporary_state:
def __init__(self, _state, variables):
self.variables = variables
self.state = _state
Expand Down Expand Up @@ -35,14 +36,17 @@ def __exit__(self, _type, _value, _traceback):
relative_import_re = re.compile(r"(\.+)(.*)")


class state(dict):
class state(MutableMapping):
def __init__(self, module_name, internal_state_dict, state_default): # pylint: disable=super-init-not-called
r"""!... is a local dict
Global Variables, but Fancy. ;)

Every event gets called with a state-Object as its first argument.
This is the modules **local** and **persistent** variable scope.

**Local dict**:
You can use this object like a persistent dict for all events defined in the same module.

**Fuzzy matching**:
The module dict will use local variables first. If however, a variable does not exist locally, miniflask will look in the parent modules as well.
See [fuzzy matching](./02-dict operations.md).
Expand All @@ -62,6 +66,9 @@ def dosomething(state, event):
print()
state["var"] *= 500
print(state["var"])
print("This module uses", len(state), "variables.")
for key in state:
print("This module is using the variable", key)

def register(mf):
mf.register_defaults({
Expand Down Expand Up @@ -332,6 +339,12 @@ def __deepcopy__(self, memo):
del memo
return self

def __iter__(self):
return filter(lambda key: key.startswith(self.module_id), self.all)

def __len__(self):
return len(list(filter(lambda key: key.startswith(self.module_id), self.all)))


def _create_excpetion_notfound(module_id, varid, name):
varid_split = varid.split(".")
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

def register(mf):
mf.register_defaults({
"additional_variable1": 0,
"additional_variable2": 0,
"additional_variable3": 0
})
37 changes: 29 additions & 8 deletions tests/state/temporary/modules/models/dosomething/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pytest # pylint: disable=import-error
from miniflask.exceptions import StateKeyError


Expand All @@ -14,29 +15,49 @@ def main(state, event):
del state["new_variable"]

print("before event", state["variable"])

# Check if global state iterator has all variables that we expect
assert len(state.all) == 4, "Found global Variables %i" % len(state.all)

# Check if local state iterator has all variables that we expect
assert len(state) == 1, "Found lokal Variables %i" % len(state)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo lokal -> local

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx. Fix added to next release.


# Checking if variable can be temporarily overwritten
with state.temporary({
"variable": 42
"variable": 42,
}):
event.dosomething()
assert len(state) == 1, "Found Variables %i" % len(state)
print("after event", state["variable"])
assert len(state) == 1, "Found Variables %i" % len(state)

try:
# Checking if variable can be temporarily defined
with pytest.raises(StateKeyError):
_ = state["new_variable"]
print("variable 'new_variable' should not exist")
except StateKeyError:
pass
with state.temporary({
"new_variable": 12345
}):
assert len(state) == 2, "Found Variables %i" % len(state)
event.dosomething()
try:
with pytest.raises(StateKeyError):
_ = state["new_variable"]
print("variable 'new_variable' should not exist")
except StateKeyError:
pass
assert len(state) == 1, "Found Variables %i" % len(state)

# Checking if iterating keys works as well
assert ",".join(iter(state)) == "modules.models.dosomething.variable", "Found variables:" + ",".join(iter(state))
with state.temporary({
"variable2": 42,
"variable3": 42,
"variable4": 42
}):
assert ", ".join(iter(state)) == "modules.models.dosomething.variable, modules.models.dosomething.variable2, modules.models.dosomething.variable3, modules.models.dosomething.variable4", "Found variables:" + ", ".join(iter(state))
print("after event", state["variable"])
assert ",".join(iter(state)) == "modules.models.dosomething.variable", "Found variables:" + ",".join(iter(state))


def register(mf):
mf.load("addingvariables")
mf.register_defaults({
"variable": 0
})
Expand Down