diff --git a/sockpuppet/consumer.py b/sockpuppet/consumer.py index 0799549..f2ef9b1 100644 --- a/sockpuppet/consumer.py +++ b/sockpuppet/consumer.py @@ -235,6 +235,14 @@ def render_page(self, reflex): reflex_context = {key: getattr(reflex, key) for key in instance_variables} reflex_context["stimulus_reflex"] = True + if not reflex.context._attr_data: + msg = ( + "Setting context through instance variables is deprecated, " + 'please use reflex.context.context_variable = "my_data"' + ) + logger.warning(msg) + reflex_context.update(reflex.context) + original_context_data = view.view_class.get_context_data reflex.get_context_data(**reflex_context) # monkey patch context method diff --git a/sockpuppet/reflex.py b/sockpuppet/reflex.py index a6f1da0..751e9f7 100644 --- a/sockpuppet/reflex.py +++ b/sockpuppet/reflex.py @@ -1,3 +1,4 @@ +from collections import UserDict from django.urls import resolve from urllib.parse import urlparse @@ -5,26 +6,61 @@ PROTECTED_VARIABLES = [ "consumer", + "context", "element", + "params", "selectors", "session", "url", ] +class Context(UserDict): + """ + A dictionary that keeps track of whether it's been used as dictionary + or if values has been set with dot notation. We expect things to be set + in dot notation so a warning is issued until next major version (1.0) + """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._attr_data = {} + + def _getitem(self, key): + if not self.data.get(key) and not self._attr_data.get(key): + raise KeyError(key) + return self.data.get(key) or self._attr_data.get(key) + + def __getitem__(self, key): + return self._getitem(key) + + def __getattr__(self, key): + return self._getitem(key) + + def __setattr__(self, key, value): + self._attr_data[key] = value + + class Reflex: def __init__(self, consumer, url, element, selectors, params): self.consumer = consumer - self.url = url + self.context = Context() self.element = element + self.params = params self.selectors = selectors self.session = consumer.scope["session"] - self.params = params - self.context = {} + self.url = url + + self._init_run = True def __repr__(self): return f"" + def __setattr__(self, name, value): + if name in PROTECTED_VARIABLES and getattr(self, "_init_run", None): + raise ValueError("This instance variable is used by the reflex.") + super().__setattr__(name, value) + def get_context_data(self, *args, **kwargs): if self.context: self.context.update(**kwargs) @@ -45,7 +81,7 @@ def get_context_data(self, *args, **kwargs): context = view.get_context_data(**{"stimulus_reflex": True}) - self.context = context + self.context.update(context) self.context.update(**kwargs) return self.context