Skip to content

Commit

Permalink
Add Django 5.1 support (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
pfouque authored Jul 5, 2024
1 parent b835404 commit b5ff9e9
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 40 deletions.
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ default_language_version:

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
rev: v4.6.0
hooks:
- id: check-added-large-files
args: ["--maxkb=700"]
Expand All @@ -18,17 +18,17 @@ repos:
- id: trailing-whitespace

- repo: https://github.com/asottile/pyupgrade
rev: v3.15.2
rev: v3.16.0
hooks:
- id: pyupgrade
args:
- "--py38-plus"

- repo: https://github.com/adamchainz/django-upgrade
rev: 1.16.0
rev: 1.18.0
hooks:
- id: django-upgrade
args: [--target-version, "3.2"]
args: [--target-version, "4.2"]


- repo: https://github.com/python-poetry/poetry
Expand All @@ -43,7 +43,7 @@ repos:
- id: poetry-export

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.3.4
rev: v0.4.8
hooks:
- id: ruff-format
- id: ruff
12 changes: 11 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
Changelog
=========

django-fsm 3.0.0 2024-03-25
Unreleased
~~~~~~~~~~

- Add support for Django 5.1
- Remove support for Django 3.2
- Remove support for Django 4.0
- Remove support for Django 4.1

django-fsm-2 3.0.0 2024-03-26
~~~~~~~~~~~~~~~~~~~~~~~~~~~

First release of the forked version of django-fsm

- Drop support for Python < 3.8.
- Add support for python 3.11
- Add support for python 3.12
Expand Down
28 changes: 14 additions & 14 deletions django_fsm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,13 @@ def name(self):
def has_perm(self, instance, user):
if not self.permission:
return True
elif callable(self.permission):
if callable(self.permission):
return bool(self.permission(instance, user))
elif user.has_perm(self.permission, instance):
if user.has_perm(self.permission, instance):
return True
elif user.has_perm(self.permission):
if user.has_perm(self.permission):
return True
else:
return False
return False

def __hash__(self):
return hash(self.name)
Expand All @@ -100,7 +99,7 @@ def get_available_FIELD_transitions(instance, field):
curr_state = field.get_state(instance)
transitions = field.transitions[instance.__class__]

for name, transition in transitions.items():
for transition in transitions.values():
meta = transition._django_fsm
if meta.has_transition(curr_state) and meta.conditions_met(instance, curr_state):
yield meta.get_transition(curr_state)
Expand Down Expand Up @@ -177,18 +176,19 @@ def conditions_met(self, instance, state):

if transition is None:
return False
elif transition.conditions is None:

if transition.conditions is None:
return True
else:
return all(map(lambda condition: condition(instance), transition.conditions))

return all(condition(instance) for condition in transition.conditions)

def has_transition_perm(self, instance, state, user):
transition = self.get_transition(state)

if not transition:
return False
else:
return transition.has_perm(instance, user)

return transition.has_perm(instance, user)

def next_state(self, current_state):
transition = self.get_transition(current_state)
Expand Down Expand Up @@ -341,7 +341,7 @@ def get_all_transitions(self, instance_cls):
"""
transitions = self.transitions[instance_cls]

for name, transition in transitions.items():
for transition in transitions.values():
meta = transition._django_fsm

for transition in meta.transitions.values():
Expand Down Expand Up @@ -565,7 +565,7 @@ def can_proceed(bound_method, check_conditions=True):
conditions.
"""
if not hasattr(bound_method, "_django_fsm"):
raise TypeError("%s method is not transition" % bound_method.__func__.__name__)
raise TypeError(f"{bound_method.__func__.__name__} method is not transition")

meta = bound_method._django_fsm
self = bound_method.__self__
Expand All @@ -579,7 +579,7 @@ def has_transition_perm(bound_method, user):
Returns True if model in state allows to call bound_method and user have rights on it
"""
if not hasattr(bound_method, "_django_fsm"):
raise TypeError("%s method is not transition" % bound_method.__func__.__name__)
raise TypeError(f"{bound_method.__func__.__name__} method is not transition")

meta = bound_method._django_fsm
self = bound_method.__self__
Expand Down
7 changes: 3 additions & 4 deletions django_fsm/management/commands/graph_transitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ def node_name(field, state):
def node_label(field, state):
if isinstance(state, int) or (isinstance(state, bool) and hasattr(field, "choices")):
return force_str(dict(field.choices).get(state))
else:
return state
return state


def generate_dot(fields_data):
def generate_dot(fields_data): # noqa: C901
result = graphviz.Digraph()

for field, model in fields_data:
Expand Down Expand Up @@ -135,7 +134,7 @@ def add_arguments(self, parser):
action="store",
dest="layout",
default="dot",
help=("Layout to be used by GraphViz for visualization. " "Layouts: %s." % " ".join(get_graphviz_layouts())),
help=f"Layout to be used by GraphViz for visualization. Layouts: {get_graphviz_layouts()}.",
)
parser.add_argument("args", nargs="*", help=("[appname[.model[.field]]]"))

Expand Down
4 changes: 2 additions & 2 deletions poetry.lock

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

15 changes: 10 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
name = "django-fsm"
version = "3.0.0"
description = "Django friendly finite state machine support."
authors = ["Mikhail Podgurskiy <[email protected]>"]
authors = [
"Mikhail Podgurskiy <[email protected]>",
]
license = "MIT License"
readme = "README.md"
homepage = "http://github.com/pfouque/django-fsm-2"
Expand All @@ -15,10 +17,9 @@ classifiers = [
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
"Framework :: Django",
"Framework :: Django :: 3.2",
"Framework :: Django :: 4.1",
"Framework :: Django :: 4.2",
"Framework :: Django :: 5.0",
"Framework :: Django :: 5.1",
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.8',
Expand All @@ -32,7 +33,7 @@ packages = [{ include = "django_fsm" }]

[tool.poetry.dependencies]
python = "^3.8"
django = ">=3.2"
django = ">=4.2"

[tool.poetry.group.graphviz.dependencies]
graphviz = "*"
Expand All @@ -55,13 +56,17 @@ target-version = "py38"
fix = true

[tool.ruff.lint]

# select = ["ALL"]
extend-select = [
"F", # Pyflakes
"E", # pycodestyle
"W", # pycodestyle
"UP", # pyupgrade
"I", # isort
"PERF",
"RET",
"C",
# "B",
]
fixable = ["I"]

Expand Down
2 changes: 1 addition & 1 deletion tests/testapp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def hide(self):
permission=lambda self, u: u.has_perm("testapp.can_remove_post"),
)
def remove(self):
raise Exception("No rights to delete %s" % self)
raise Exception(f"No rights to delete {self}")

@transition(field=state, source="new", target="restored", on_error="failed", permission=can_restore)
def restore(self):
Expand Down
4 changes: 2 additions & 2 deletions tests/testapp/tests/test_custom_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ class BlogPostWithCustomData(models.Model):
def publish(self):
pass

@transition(field=state, source="published", target="destroyed", custom=dict(label="Destroy", type="manual"))
@transition(field=state, source="published", target="destroyed", custom={"label": "Destroy", "type": "manual"})
def destroy(self):
pass

@transition(field=state, source="published", target="review", custom=dict(label="Periodic review", type="automated"))
@transition(field=state, source="published", target="review", custom={"label": "Periodic review", "type": "automated"})
def review(self):
pass

Expand Down
8 changes: 2 additions & 6 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
[tox]
envlist =
py{38,39,310}-dj32
py{38,39,310}-dj40
py{38,39,310,311}-dj41
py{38,39,310,311}-dj42
py{310,311,312}-dj50
py{310,311,312}-dj51
skipsdist = True

[testenv]
deps =
dj32: Django==3.2
dj40: Django==4.0
dj41: Django==4.1
dj42: Django==4.2
dj50: Django==5.0
dj51: Django==5.1b1

django-guardian==2.4.0
graphviz==0.20.1
Expand Down

0 comments on commit b5ff9e9

Please sign in to comment.