Skip to content

Commit

Permalink
Changes sync
Browse files Browse the repository at this point in the history
  • Loading branch information
kmmbvnr committed Feb 17, 2024
1 parent d0f78c9 commit 8de4748
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 46 deletions.
44 changes: 20 additions & 24 deletions viewflow/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ class CompositeKey(models.AutoField):

class Key(dict):
"""Dictionary with json-compatible string conversion."""

def __str__(self):
return json.dumps(self)

def __hash__(self):
return hash(
tuple(self[key] for key in sorted(self.keys()))
)
return hash(tuple(self[key] for key in sorted(self.keys())))

def __init__(self, columns: List[str], **kwargs):
self.columns = columns
Expand All @@ -39,29 +38,25 @@ def contribute_to_class(self, cls, name, private_only=False):
self.model = cls
self.concrete = False
self.editable = False
self.column = self.columns[0] # for default order_by
self.column = self.columns[0] # for default order_by
cls._meta.add_field(self, private=True) # virtual field
cls._meta.setup_pk(self) # acts as pk
cls._meta.setup_pk(self) # acts as pk

if not getattr(cls, self.attname, None):
setattr(cls, self.attname, self)

def delete(inst, using=None, keep_parents=False):
using = using or router.db_for_write(self.model, instance=inst)

signals.pre_delete.send(
sender=cls, instance=inst, using=using
)
signals.pre_delete.send(sender=cls, instance=inst, using=using)

query = cls._default_manager.filter(**self.__get__(inst))
query._raw_delete(using)

for column in self.columns:
setattr(inst, column, None)

signals.post_delete.send(
sender=cls, instance=inst, using=using
)
signals.post_delete.send(sender=cls, instance=inst, using=using)

cls.delete = delete

Expand All @@ -71,15 +66,17 @@ def get_prep_value(self, value):
def to_python(self, value):
if value is None or isinstance(value, CompositeKey.Key):
return value
if isinstance(value, dict):
return value
return CompositeKey.Key(json.loads(value))

def to_json(self, value):
if isinstance(value, datetime.datetime):
result = value.isoformat()
if value.microsecond:
result = result[:23] + result[26:]
if result.endswith('+00:00'):
result = result[:-6] + 'Z'
if result.endswith("+00:00"):
result = result[:-6] + "Z"
return result
elif isinstance(value, datetime.date):
return value.isoformat()
Expand All @@ -103,12 +100,14 @@ def __get__(self, instance, cls=None):
if instance is None:
return self

return CompositeKey.Key({
column: self.to_json(
self.model._meta.get_field(column).value_from_object(instance)
)
for column in self.columns
})
return CompositeKey.Key(
{
column: self.to_json(
self.model._meta.get_field(column).value_from_object(instance)
)
for column in self.columns
}
)

def __set__(self, instance, value):
"""
Expand All @@ -119,18 +118,15 @@ def __set__(self, instance, value):

@CompositeKey.register_lookup
class Exact(models.Lookup):
lookup_name = 'exact'
lookup_name = "exact"

def as_sql(self, compiler, connection):
fields = [
self.lhs.field.model._meta.get_field(column)
for column in self.lhs.field.columns
]

lookup_classes = [
field.get_lookup('exact')
for field in fields
]
lookup_classes = [field.get_lookup("exact") for field in fields]

lookups = [
lookup_class(field.get_col(self.lhs.alias), self.rhs[column])
Expand Down
38 changes: 20 additions & 18 deletions viewflow/fsm/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@


class TransitionNotAllowed(Exception):
"""Raised when a transition is not allowed."""
"""Exception raised when a state transition is not permitted."""


class Transition(object):
class Transition:
"""
A state transition definition.
Represents a state transition with associated conditions and permissions.
"""

def __init__(
Expand Down Expand Up @@ -71,19 +71,21 @@ def slug(self) -> str:
return self.func.__name__

def conditions_met(self, instance: object) -> bool:
"""Check if all associated conditions are met for the transition."""
"""Checks if all conditions are met for this transition."""
conditions = [
condition.resolve(instance.__class__)
if isinstance(condition, ThisObject)
else condition
(
condition.resolve(instance.__class__)
if isinstance(condition, ThisObject)
else condition
)
for condition in self.conditions
]
return all(map(lambda condition: condition(instance), conditions))

def has_perm(self, instance: object, user: UserModel) -> bool:
"""Check if the user has the required permission to execute the transition."""
"""Checks if the given user has permission to perform this transition."""
if self.permission is None:
return False
return False # No permission required
elif callable(self.permission):
return self.permission(instance, user)
elif isinstance(self.permission, ThisObject):
Expand All @@ -93,7 +95,7 @@ def has_perm(self, instance: object, user: UserModel) -> bool:
raise ValueError(f"Unknown permission type {type(self.permission)}")


class TransitionMethod(object):
class TransitionMethod:
"""Unbound transition method wrapper.
Provides shortcut to enumerate all method transitions, ex::
Expand Down Expand Up @@ -126,12 +128,12 @@ def slug(self) -> str:
return self._func.__name__


class TransitionBoundMethod(object):
class TransitionBoundMethod:
"""Instance method wrapper that performs the transition."""

do_not_call_in_templates = True

class Wrapper(object):
class Wrapper:
"""Wrapper context object, to simplify __call__ method debug"""

def __init__(self, parent: "TransitionBoundMethod", kwargs: Mapping[str, Any]):
Expand Down Expand Up @@ -227,7 +229,7 @@ def get_transitions(self) -> Iterable[Transition]:
return self._descriptor.get_transitions()


class TransitionDescriptor(object):
class TransitionDescriptor:
"""Base transition definition descriptor."""

do_not_call_in_templates = True
Expand Down Expand Up @@ -264,7 +266,7 @@ def get_transition(self, source_state: StateValue) -> Optional[Transition]:
return transition


class SuperTransitionDescriptor(object):
class SuperTransitionDescriptor:
do_not_call_in_templates = True

def __init__(self, state: State, func: TransitionFunction): # noqa D102
Expand Down Expand Up @@ -300,7 +302,7 @@ def get_descriptor(self, owner: Type[object]) -> TransitionDescriptor:
return super_method._descriptor


class StateDescriptor(object):
class StateDescriptor:
"""Class-bound value for a state descriptor.
Provides shortcut to enumerate all class transitions, ex::
Expand Down Expand Up @@ -347,7 +349,7 @@ def get_available_transitions(self, flow, state: State, user):
]


class State(object):
class State:
"""State slot field."""

ANY = MARKER("ANY")
Expand Down Expand Up @@ -408,7 +410,7 @@ def transition(
conditions: Optional[List[Condition]] = None,
permission: Optional[Permission] = None,
) -> Any:
"""Transition method decorator."""
"""Decorator to mark a method as a state transition."""

def _wrapper(func: Any) -> Any:
if isinstance(func, TransitionDescriptor):
Expand Down Expand Up @@ -462,7 +464,7 @@ def _wrapper(func: Any) -> Any:

return _wrapper

class CONDITION(object):
class CONDITION:
"""Boolean-like object to return value accompanied with a message from fsm conditions."""

def __init__(self, is_true: bool, unmet: str = ""):
Expand Down
8 changes: 4 additions & 4 deletions viewflow/workflow/nodes/join.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.utils.timezone import now
from viewflow.this_object import this
from ..activation import Activation, leading_tasks_canceled
from ..activation import Activation
from ..base import Node
from ..exceptions import FlowRuntimeError
from ..status import STATUS
Expand All @@ -12,7 +12,7 @@ class JoinActivation(mixins.NextNodeActivationMixin, Activation):

def __init__(self, *args, **kwargs): # noqa D102
self.next_task = None
super(JoinActivation, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

@classmethod
def create(cls, flow_task, prev_activation, token):
Expand Down Expand Up @@ -87,7 +87,7 @@ def cancel_active_tasks(self, active_tasks):

def is_done(self):
"""
Check that process can be continued futher.
Check that process can be continued further.
Join check the all task state in db with the common token prefix.
Expand Down Expand Up @@ -147,7 +147,7 @@ class Join(
bpmn_element = "parallelGateway"

def __init__(self, continue_on_condition=None, **kwargs): # noqa D102
super(Join, self).__init__(**kwargs)
super().__init__(**kwargs)
self._continue_on_condition = continue_on_condition

def _resolve(self, cls):
Expand Down

0 comments on commit 8de4748

Please sign in to comment.