Skip to content

Add Django 5.1 support #21

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

Merged
merged 4 commits into from
Jul 5, 2024
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
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
Loading