forked from CGM_Public/pretix_original
Python 3 style type hinting
This commit is contained in:
@@ -3,6 +3,8 @@ import hashlib
|
||||
|
||||
from django.core.cache import caches
|
||||
|
||||
from tixlbase.models import Event
|
||||
|
||||
|
||||
class EventRelatedCache:
|
||||
"""
|
||||
@@ -17,12 +19,12 @@ class EventRelatedCache:
|
||||
instantiate it as many times as you want.
|
||||
"""
|
||||
|
||||
def __init__(self, event, cache='default'):
|
||||
def __init__(self, event: Event, cache: str='default'):
|
||||
self.cache = caches[cache]
|
||||
self.event = event
|
||||
self.prefixkey = 'event:%d' % self.event.pk
|
||||
|
||||
def _prefix_key(self, original_key):
|
||||
def _prefix_key(self, original_key: str) -> str:
|
||||
# Race conditions can happen here, but should be very very rare.
|
||||
# We could only handle this by going _really_ lowlevel using
|
||||
# memcached's `add` keyword instead of `set`.
|
||||
@@ -39,7 +41,7 @@ class EventRelatedCache:
|
||||
return key
|
||||
|
||||
@staticmethod
|
||||
def _strip_prefix(key):
|
||||
def _strip_prefix(key: str) -> str:
|
||||
return key.split(":", 3)[-1] if 'event:' in key else key
|
||||
|
||||
def clear(self):
|
||||
@@ -49,35 +51,35 @@ class EventRelatedCache:
|
||||
prefix = int(time.time())
|
||||
self.cache.set(self.prefixkey, prefix)
|
||||
|
||||
def set(self, key, value, timeout=3600):
|
||||
def set(self, key: str, value: str, timeout: int=3600):
|
||||
return self.cache.set(self._prefix_key(key), value, timeout)
|
||||
|
||||
def get(self, key):
|
||||
def get(self, key: str) -> str:
|
||||
return self.cache.get(self._prefix_key(key))
|
||||
|
||||
def get_many(self, keys):
|
||||
def get_many(self, keys: "list[str]") -> "dict[str, str]":
|
||||
values = self.cache.get_many([self._prefix_key(key) for key in keys])
|
||||
newvalues = {}
|
||||
for k, v in values.items():
|
||||
newvalues[self._strip_prefix(k)] = v
|
||||
return newvalues
|
||||
|
||||
def set_many(self, values, timeout=3600):
|
||||
def set_many(self, values: "dict[str, str]", timeout=3600):
|
||||
newvalues = {}
|
||||
for k, v in values.items():
|
||||
newvalues[self._prefix_key(k)] = v
|
||||
return self.cache.set_many(newvalues, timeout)
|
||||
|
||||
def delete(self, key): # NOQA
|
||||
def delete(self, key: str): # NOQA
|
||||
return self.cache.delete(self._prefix_key(key))
|
||||
|
||||
def delete_many(self, keys): # NOQA
|
||||
def delete_many(self, keys: "list[str]"): # NOQA
|
||||
return self.cache.delete_many([self._prefix_key(key) for key in keys])
|
||||
|
||||
def incr(self, key, by=1): # NOQA
|
||||
def incr(self, key: str, by: int=1): # NOQA
|
||||
return self.cache.incr(self._prefix_key(key), by)
|
||||
|
||||
def decr(self, key, by=1): # NOQA
|
||||
def decr(self, key: str, by: int=1): # NOQA
|
||||
return self.cache.decr(self._prefix_key(key), by)
|
||||
|
||||
def close(self): # NOQA
|
||||
|
||||
@@ -62,7 +62,7 @@ class LocaleMiddleware(BaseLocaleMiddleware):
|
||||
return response
|
||||
|
||||
|
||||
def get_language_from_request(request):
|
||||
def get_language_from_request(request) -> str:
|
||||
"""
|
||||
Analyzes the request to find what language the user wants the system to
|
||||
show. Only languages listed in settings.LANGUAGES are taken into account.
|
||||
|
||||
@@ -119,7 +119,7 @@ class User(AbstractBaseUser, PermissionsMixin):
|
||||
self.identifier = self.identifier.lower()
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def get_short_name(self):
|
||||
def get_short_name(self) -> str:
|
||||
if self.givenname:
|
||||
return self.givenname
|
||||
elif self.familyname:
|
||||
@@ -127,7 +127,7 @@ class User(AbstractBaseUser, PermissionsMixin):
|
||||
else:
|
||||
return self.username
|
||||
|
||||
def get_full_name(self):
|
||||
def get_full_name(self) -> str:
|
||||
if self.givenname and not self.familyname:
|
||||
return self.givenname
|
||||
elif not self.givenname and self.familyname:
|
||||
@@ -295,18 +295,18 @@ class Event(models.Model):
|
||||
self.get_cache().clear()
|
||||
return obj
|
||||
|
||||
def get_plugins(self):
|
||||
def get_plugins(self) -> "list[str]":
|
||||
if self.plugins is None:
|
||||
return []
|
||||
return self.plugins.split(",")
|
||||
|
||||
def get_date_from_display(self):
|
||||
def get_date_from_display(self) -> str:
|
||||
return _date(
|
||||
self.date_from,
|
||||
"DATETIME_FORMAT" if self.show_times else "DATE_FORMAT"
|
||||
)
|
||||
|
||||
def get_date_to_display(self):
|
||||
def get_date_to_display(self) -> str:
|
||||
if not self.show_date_to:
|
||||
return ""
|
||||
return _date(
|
||||
@@ -314,7 +314,7 @@ class Event(models.Model):
|
||||
"DATETIME_FORMAT" if self.show_times else "DATE_FORMAT"
|
||||
)
|
||||
|
||||
def get_cache(self):
|
||||
def get_cache(self) -> "tixlbase.cache.EventRelatedCache":
|
||||
from tixlbase.cache import EventRelatedCache
|
||||
return EventRelatedCache(self)
|
||||
|
||||
@@ -579,7 +579,7 @@ class Item(models.Model):
|
||||
self.active = False
|
||||
return super().save()
|
||||
|
||||
def get_all_variations(self, use_cache=False):
|
||||
def get_all_variations(self, use_cache: bool=False) -> "list[VariationDict]":
|
||||
"""
|
||||
This method returns a list containing all variations of this
|
||||
item. The list contains one VariationDict per variation, where
|
||||
|
||||
@@ -10,7 +10,7 @@ class PluginType(Enum):
|
||||
RESTRICTION = 1
|
||||
|
||||
|
||||
def get_all_plugins():
|
||||
def get_all_plugins() -> "class":
|
||||
plugins = []
|
||||
for app in apps.get_app_configs():
|
||||
if hasattr(app, 'TixlPluginMeta'):
|
||||
|
||||
@@ -8,7 +8,7 @@ RUN_LOCAL = ('SAUCE_USERNAME' not in os.environ)
|
||||
|
||||
if RUN_LOCAL:
|
||||
# could add Chrome, PhantomJS etc... here
|
||||
BROWSERS = ['Chrome']
|
||||
BROWSERS = ['Chrome', 'Firefox']
|
||||
else:
|
||||
from sauceclient import SauceClient
|
||||
USERNAME = os.environ.get('SAUCE_USERNAME')
|
||||
|
||||
@@ -6,7 +6,7 @@ class VariationDict(dict):
|
||||
code calling this method.
|
||||
"""
|
||||
|
||||
def relevant_items(self):
|
||||
def relevant_items(self) -> "list[(int, PropertyValue)]":
|
||||
"""
|
||||
Iterate over all items with numeric keys.
|
||||
|
||||
@@ -17,7 +17,7 @@ class VariationDict(dict):
|
||||
if type(i[0]) is int:
|
||||
yield i
|
||||
|
||||
def relevant_values(self):
|
||||
def relevant_values(self) -> "list[PropertyValue]":
|
||||
"""
|
||||
Iterate over all values with numeric keys.
|
||||
|
||||
@@ -28,7 +28,7 @@ class VariationDict(dict):
|
||||
if type(i[0]) is int:
|
||||
yield i[1]
|
||||
|
||||
def identify(self):
|
||||
def identify(self) -> str:
|
||||
"""
|
||||
Build a simple and unique identifier for this dict. This can be any string
|
||||
used to compare one VariationDict to others.
|
||||
@@ -42,7 +42,7 @@ class VariationDict(dict):
|
||||
str(v[1].pk) for v in sorted(self.relevant_items(), key=order_key)
|
||||
))
|
||||
|
||||
def key(self):
|
||||
def key(self) -> str:
|
||||
"""
|
||||
Build an identifier for this dict which exactly specifies the combination
|
||||
for this variation without any doubt. This can be used to "talk" about a
|
||||
@@ -62,7 +62,7 @@ class VariationDict(dict):
|
||||
else:
|
||||
return super().__eq__(other)
|
||||
|
||||
def ordered_values(self):
|
||||
def ordered_values(self) -> "list[ItemVariation]":
|
||||
"""
|
||||
Returns a list of values ordered by their keys
|
||||
"""
|
||||
@@ -74,7 +74,7 @@ class VariationDict(dict):
|
||||
)
|
||||
]
|
||||
|
||||
def copy(self):
|
||||
def copy(self) -> "VariationDict":
|
||||
"""
|
||||
Return a one-level deep copy of this object (create a new
|
||||
VariationDict but make a shallow copy of the dict inside it).
|
||||
|
||||
@@ -22,6 +22,16 @@ class LoginFormBrowserTest(BrowserTest):
|
||||
self.driver.find_element_by_css_selector('button[type="submit"]').click()
|
||||
self.driver.find_element_by_class_name("navbar-right")
|
||||
|
||||
def test_login_fail(self):
|
||||
self.driver.implicitly_wait(10)
|
||||
self.driver.get('%s%s' % (self.live_server_url, '/control/login'))
|
||||
username_input = self.driver.find_element_by_name("email")
|
||||
username_input.send_keys('dummy@dummy.dummy')
|
||||
password_input = self.driver.find_element_by_name("password")
|
||||
password_input.send_keys('wrong')
|
||||
self.driver.find_element_by_css_selector('button[type="submit"]').click()
|
||||
self.driver.find_element_by_class_name("alert-danger")
|
||||
|
||||
|
||||
class LoginFormTest(TestCase):
|
||||
"""
|
||||
|
||||
@@ -52,10 +52,10 @@ class EventUpdate(EventPermissionRequiredMixin, UpdateView):
|
||||
template_name = 'tixlcontrol/event/settings.html'
|
||||
permission = 'can_change_settings'
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
def get_object(self, queryset=None) -> Event:
|
||||
return self.request.event
|
||||
|
||||
def get_success_url(self):
|
||||
def get_success_url(self) -> str:
|
||||
return reverse('control:event.settings', kwargs={
|
||||
'organizer': self.get_object().organizer.slug,
|
||||
'event': self.get_object().slug,
|
||||
@@ -72,7 +72,7 @@ class EventPlugins(EventPermissionRequiredMixin, TemplateView, SingleObjectMixin
|
||||
def get_object(self, queryset=None):
|
||||
return self.request.event
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
def get_context_data(self, *args, **kwargs) -> dict:
|
||||
from tixlbase.plugins import get_all_plugins
|
||||
context = super().get_context_data(*args, **kwargs)
|
||||
context['plugins'] = [p for p in get_all_plugins() if not p.name.startswith('.')]
|
||||
@@ -98,7 +98,7 @@ class EventPlugins(EventPermissionRequiredMixin, TemplateView, SingleObjectMixin
|
||||
self.object.save()
|
||||
return redirect(self.get_success_url())
|
||||
|
||||
def get_success_url(self):
|
||||
def get_success_url(self) -> str:
|
||||
return reverse('control:event.settings.plugins', kwargs={
|
||||
'organizer': self.get_object().organizer.slug,
|
||||
'event': self.get_object().slug,
|
||||
|
||||
@@ -12,7 +12,7 @@ from tixlbase.models import ItemVariation, PropertyValue, Item
|
||||
|
||||
|
||||
class TolerantFormsetModelForm(forms.ModelForm):
|
||||
def has_changed(self):
|
||||
def has_changed(self) -> bool:
|
||||
"""
|
||||
Returns True if data differs from initial. Contrary to the default
|
||||
implementation, the ORDER field is being ignored.
|
||||
@@ -231,11 +231,11 @@ class VariationsField(forms.ModelMultipleChoiceField):
|
||||
kwargs['widget'] = VariationsSelectMultiple
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def set_item(self, item):
|
||||
def set_item(self, item: Item):
|
||||
self.item = item
|
||||
self._set_choices(self._get_choices())
|
||||
|
||||
def _get_choices(self):
|
||||
def _get_choices(self) -> "list[(str, VariationDict)]":
|
||||
"""
|
||||
We can't use a normal QuerySet as there theoretically might be
|
||||
two types of variations: Some who already have a ItemVariation
|
||||
@@ -255,7 +255,7 @@ class VariationsField(forms.ModelMultipleChoiceField):
|
||||
) for v in variations
|
||||
)
|
||||
|
||||
def clean(self, value):
|
||||
def clean(self, value: "list[int]"):
|
||||
"""
|
||||
At cleaning time, we have to clean up the mess we produced with our
|
||||
_get_choices implementation. In the case of ItemVariation object ids
|
||||
|
||||
Reference in New Issue
Block a user