Up min versions to py3.9, Django 4

This commit is contained in:
Griatch 2022-02-04 23:24:48 +01:00
parent 89f9eaffcc
commit b76c5d2bab
15 changed files with 44 additions and 58 deletions

View file

@ -18,7 +18,7 @@ jobs:
strategy:
matrix:
python-version: [3.7]
python-version: [3.10]
steps:
- name: Checkout 0.9.5 branch

View file

@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.7, 3.8]
python-version: [3.9, 3.10]
TESTING_DB: ['sqlite3', 'postgresql', 'mysql']
steps:

View file

@ -2,7 +2,7 @@
## Evennia 1.0 (2019-) (develop branch, WIP)
Up requirements to Django 3.2+, Twisted 21+
Up requirements to Django 4.0+, Twisted 22+, Python 3.9 or 3.10
- New `drop:holds()` lock default to limit dropping nonsensical things. Access check
defaults to True for backwards-compatibility in 0.9, will be False in 1.0

View file

@ -91,10 +91,10 @@ PSTATUS = chr(18) # ping server or portal status
SRESET = chr(19) # shutdown server in reset mode
# requirements
PYTHON_MIN = "3.7"
PYTHON_MIN = "3.9"
TWISTED_MIN = "20.3.0"
DJANGO_MIN = "3.2.0"
DJANGO_LT = "4.0"
DJANGO_MIN = "4.0.2"
DJANGO_LT = "4.1"
try:
sys.path[1] = EVENNIA_ROOT
@ -375,7 +375,7 @@ ERROR_NOTWISTED = """
ERROR_DJANGO_MIN = """
ERROR: Django {dversion} found. Evennia requires at least version {django_min} (but
no higher than {django_lt}).
below version {django_lt}).
If you are using a virtualenv, use the command `pip install --upgrade -e evennia` where
`evennia` is the folder to where you cloned the Evennia library. If not

View file

@ -26,45 +26,55 @@ from django.dispatch import Signal
# Account.create() after the Account is created. Note that this will *not* fire
# if calling create.create_account alone, since going through the Account.create()
# is the most expected route.
SIGNAL_ACCOUNT_POST_CREATE = Signal(providing_args=["ip"])
# sends with kwarg 'ip'
SIGNAL_ACCOUNT_POST_CREATE = Signal()
# The Sender is the renamed Account. This is triggered by the username setter in AccountDB.
SIGNAL_ACCOUNT_POST_RENAME = Signal(providing_args=["old_name", "new_name"])
# sends with kwargs 'old_name' and 'new_name'
SIGNAL_ACCOUNT_POST_RENAME = Signal()
# The Sender is the connecting Account. This is triggered when an Account connects cold;
# that is, it had no other sessions connected.
SIGNAL_ACCOUNT_POST_FIRST_LOGIN = Signal(providing_args=["session"])
# sends with kwarg 'session'
SIGNAL_ACCOUNT_POST_FIRST_LOGIN = Signal()
# The sender is the connecting Account. This is triggered whenever a session authenticates
# to an Account regardless of existing sessions. It then firest after FIRST_LOGIN signal
SIGNAL_ACCOUNT_POST_LOGIN = Signal(providing_args=["session"])
# sends with kwarg 'session'
SIGNAL_ACCOUNT_POST_LOGIN = Signal()
# The Sender is the Account attempting to authenticate. This is triggered whenever a
# session tries to login to an Account but fails.
SIGNAL_ACCOUNT_POST_LOGIN_FAIL = Signal(providing_args=["session"])
# sends with kwarg 'session'
SIGNAL_ACCOUNT_POST_LOGIN_FAIL = Signal()
# The sender is the disconnecting Account. This is triggered whenever a session disconnects
# from the account, regardless of how many it started with or remain.
SIGNAL_ACCOUNT_POST_LOGOUT = Signal(providing_args=["session"])
# sends with kwarg 'session'
SIGNAL_ACCOUNT_POST_LOGOUT = Signal()
# The sender is the Account. This is triggered when an Account's final session disconnects.
SIGNAL_ACCOUNT_POST_LAST_LOGOUT = Signal(providing_args=["session"])
# sends with kwarg 'session'
SIGNAL_ACCOUNT_POST_LAST_LOGOUT = Signal()
# The sender is an Object. This is triggered when Object has been created, after all hooks.
SIGNAL_OBJECT_POST_CREATE = Signal()
# The sender is the Object being puppeted. This is triggered after all puppeting hooks have
# been called. The Object has already been puppeted by this point.
SIGNAL_OBJECT_POST_PUPPET = Signal(providing_args=["session", "account"])
# sends with kwargs 'session', 'account'
SIGNAL_OBJECT_POST_PUPPET = Signal()
# The sender is the Object being released. This is triggered after all hooks are called.
# The Object is no longer puppeted by this point.
SIGNAL_OBJECT_POST_UNPUPPET = Signal(providing_args=["session", "account"])
# sends with kwargs 'session', 'account'
SIGNAL_OBJECT_POST_UNPUPPET = Signal()
# The sender is the Typed Object being renamed. This isn't necessarily an Object;
# it could be a script. It fires whenever the value of the Typed object's 'key'
# changes. Will need to use isinstance() or other filtering on things that use this.
SIGNAL_TYPED_OBJECT_POST_RENAME = Signal(providing_args=["old_key", "new_key"])
# sends with kwargs 'old_key', 'new_key'
SIGNAL_TYPED_OBJECT_POST_RENAME = Signal()
# The sender is the created Script. This is called after the Script was first created,
# after all hooks.

View file

@ -278,7 +278,7 @@ class AccountAdmin(BaseUserAdmin):
return str(dbserialize.pack_dbobj(obj))
serialized_string.help_text = (
"Copy & paste this string into an Attribute's `value` field to store it there."
"Copy & paste this string into an Attribute's `value` field to store this account there."
)
def puppeted_objects(self, obj):

View file

@ -129,7 +129,8 @@ class MsgAdmin(admin.ModelAdmin):
return str(dbserialize.pack_dbobj(obj))
serialized_string.help_text = (
"Copy & paste this string into an Attribute's `value` field to store it there."
"Copy & paste this string into an Attribute's `value` field to store "
"this message-object there."
)
def get_form(self, request, obj=None, **kwargs):
@ -246,7 +247,7 @@ class ChannelAdmin(admin.ModelAdmin):
return str(dbserialize.pack_dbobj(obj))
serialized_string.help_text = (
"Copy & paste this string into an Attribute's `value` field to store it there."
"Copy & paste this string into an Attribute's `value` field to store this channel there."
)
def get_form(self, request, obj=None, **kwargs):

View file

@ -4,10 +4,9 @@
#
from django.conf import settings
from django import forms
from django.urls import reverse
from django.urls import reverse, path
from django.http import HttpResponseRedirect
from django.conf import settings
from django.conf.urls import url
from django.contrib import admin, messages
from django.contrib.admin.utils import flatten_fieldsets
from django.contrib.admin.widgets import ForeignKeyRawIdWidget
@ -227,7 +226,7 @@ class ObjectAdmin(admin.ModelAdmin):
return str(dbserialize.pack_dbobj(obj))
serialized_string.help_text = (
"Copy & paste this string into an Attribute's `value` field to store it there."
"Copy & paste this string into an Attribute's `value` field to store this object there."
)
def get_fieldsets(self, request, obj=None):
@ -266,8 +265,8 @@ class ObjectAdmin(admin.ModelAdmin):
def get_urls(self):
urls = super().get_urls()
custom_urls = [
url(
r"^account-object-link/(?P<object_id>.+)/$",
path(
"account-object-link/<int:pk>",
self.admin_site.admin_view(self.link_object_to_account),
name="object-account-link"
)

View file

@ -125,7 +125,7 @@ class ScriptAdmin(admin.ModelAdmin):
return str(dbserialize.pack_dbobj(obj))
serialized_string.help_text = (
"Copy & paste this string into an Attribute's `value` field to store it there."
"Copy & paste this string into an Attribute's `value` field to store this script there."
)

View file

@ -5,15 +5,14 @@ Tests for the REST API.
from evennia.utils.test_resources import BaseEvenniaTest
from evennia.web.api import serializers
from rest_framework.test import APIClient
from django.urls import reverse
from django.urls import reverse, path, include
from django.test import override_settings
from collections import namedtuple
from django.conf.urls import url, include
from django.core.exceptions import ObjectDoesNotExist
urlpatterns = [
url(r"^", include("evennia.web.website.urls")),
url(r"^api/", include("evennia.web.api.urls", namespace="api")),
path(r"^", include("evennia.web.website.urls")),
path(r"^api/", include("evennia.web.api.urls", namespace="api")),
]

View file

@ -199,8 +199,8 @@ class CharacterDeleteView(CharacterMixin, ObjectDeleteView):
ObjectDeleteView) can delete a character they own.
"""
pass
# using the character form fails there
form_class = forms.EvenniaForm
class CharacterCreateView(CharacterMixin, ObjectCreateView):

View file

@ -87,5 +87,3 @@ class EvenniaDeleteView(DeleteView, TypeclassMixin):
def page_title(self):
# Makes sure the page has a sensible title.
return "Delete %s" % self.typeclass._meta.verbose_name.title()

View file

@ -162,27 +162,6 @@ class ObjectDeleteView(LoginRequiredMixin, ObjectDetailView, EvenniaDeleteView):
# -- Evennia constructs --
access_type = "delete"
def delete(self, request, *args, **kwargs):
"""
Calls the delete() method on the fetched object and then
redirects to the success URL.
We extend this so we can capture the name for the sake of confirmation.
"""
# Get the object in question. ObjectDetailView.get_object() will also
# check to make sure the current user (authenticated or not) has
# permission to delete it!
obj = str(self.get_object())
# Perform the actual deletion (the parent class handles this, which will
# in turn call the delete() method on the object)
response = super().delete(request, *args, **kwargs)
# Notify the user of the deletion
messages.success(request, "Successfully deleted '%s'." % obj)
return response
class ObjectUpdateView(LoginRequiredMixin, ObjectDetailView, EvenniaUpdateView):
"""

View file

@ -2,10 +2,10 @@
# general
attrs >= 19.2.0
django >= 3.2, < 3.3
django == 4.0.2
twisted >= 21.7.0, < 22.0.0
pytz
djangorestframework >= 3.10.3, < 3.12
djangorestframework >= 3.13.1, < 3.14
pyyaml
django-filter == 2.4
django-sekizai == 2.0.0

View file

@ -21,4 +21,4 @@ ipython >= 7.19.0
django-extensions >= 3.1.0
# xyzroom contrib
scipy==1.7.1
scipy<1.9