diff --git a/requirements/common.in b/requirements/common.in index 246f115762..cb8577d558 100644 --- a/requirements/common.in +++ b/requirements/common.in @@ -8,6 +8,9 @@ Django==2.2.* # needed for Literal, TypedDict typing-extensions +# Backport of @dataclass +dataclasses;python_version<"3.7" + # Needed for rendering backend templates Jinja2 diff --git a/requirements/dev.txt b/requirements/dev.txt index 5a97547a93..bcdabd715b 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -243,6 +243,10 @@ cssutils==1.0.2 \ --hash=sha256:a2fcf06467553038e98fea9cfe36af2bf14063eb147a70958cfcaa8f5786acaf \ --hash=sha256:c74dbe19c92f5052774eadb15136263548dd013250f1ed1027988e7fef125c8d \ # via premailer +dataclasses==0.7 ; python_version < "3.7" \ + --hash=sha256:3459118f7ede7c8bea0fe795bff7c6c2ce287d01dd226202f7c9ebc0610a7836 \ + --hash=sha256:494a6dcae3b8bcf80848eea2ef64c0cc5cd307ffc263e17cdf42f3e5420808e6 \ + # via -r requirements/common.in decorator==4.4.2 \ --hash=sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760 \ --hash=sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7 \ diff --git a/requirements/prod.txt b/requirements/prod.txt index 83583d949b..09c503217b 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -154,6 +154,10 @@ cssutils==1.0.2 \ --hash=sha256:a2fcf06467553038e98fea9cfe36af2bf14063eb147a70958cfcaa8f5786acaf \ --hash=sha256:c74dbe19c92f5052774eadb15136263548dd013250f1ed1027988e7fef125c8d \ # via premailer +dataclasses==0.7 ; python_version < "3.7" \ + --hash=sha256:3459118f7ede7c8bea0fe795bff7c6c2ce287d01dd226202f7c9ebc0610a7836 \ + --hash=sha256:494a6dcae3b8bcf80848eea2ef64c0cc5cd307ffc263e17cdf42f3e5420808e6 \ + # via -r requirements/common.in decorator==4.4.2 \ --hash=sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760 \ --hash=sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7 \ diff --git a/version.py b/version.py index 0406c95296..4d5255fd12 100644 --- a/version.py +++ b/version.py @@ -44,4 +44,4 @@ API_FEATURE_LEVEL = 12 # historical commits sharing the same major version, in which case a # minor version bump suffices. -PROVISION_VERSION = '86.3' +PROVISION_VERSION = '86.4' diff --git a/zerver/lib/bugdown/__init__.py b/zerver/lib/bugdown/__init__.py index 423545c815..afbb152deb 100644 --- a/zerver/lib/bugdown/__init__.py +++ b/zerver/lib/bugdown/__init__.py @@ -1,6 +1,6 @@ # Zulip's main markdown implementation. See docs/subsystems/markdown.md for # detailed documentation on our markdown syntax. -from typing import (Any, Callable, Dict, Generic, Iterable, List, NamedTuple, +from typing import (Any, Callable, Dict, Generic, Iterable, List, Optional, Set, Tuple, TypeVar, Union) from typing.re import Match, Pattern from typing_extensions import TypedDict @@ -15,6 +15,7 @@ import os import html import time import functools +from dataclasses import dataclass from io import StringIO import dateutil.parser import dateutil.tz @@ -291,12 +292,12 @@ def walk_tree(root: Element, return results -ElementFamily = NamedTuple('ElementFamily', [ - ('grandparent', Optional[Element]), - ('parent', Element), - ('child', Element), - ('in_blockquote', bool), -]) +@dataclass +class ElementFamily: + grandparent: Optional[Element] + parent: Element + child: Element + in_blockquote: bool T = TypeVar("T") @@ -1517,6 +1518,11 @@ class BlockQuoteProcessor(markdown.blockprocessors.BlockQuoteProcessor): # And then run the upstream processor's code for removing the '>' return super().clean(line) +@dataclass +class Fence: + fence_str: str + is_code: bool + class BugdownListPreprocessor(markdown.preprocessors.Preprocessor): """ Allows list blocks that come directly after another block to be rendered as a list. @@ -1529,11 +1535,6 @@ class BugdownListPreprocessor(markdown.preprocessors.Preprocessor): def run(self, lines: List[str]) -> List[str]: """ Insert a newline between a paragraph and ulist if missing """ - Fence = NamedTuple('Fence', [ - ('fence_str', str), - ('is_code', bool), - ]) - inserts = 0 in_code_fence: bool = False open_fences: List[Fence] = [] diff --git a/zerver/lib/integrations.py b/zerver/lib/integrations.py index 4d8fe32a7e..9d05b920a4 100644 --- a/zerver/lib/integrations.py +++ b/zerver/lib/integrations.py @@ -1,5 +1,6 @@ import os +from dataclasses import dataclass from typing import Dict, List, Optional, Any, Tuple from django.conf.urls import url from django.contrib.staticfiles.storage import staticfiles_storage @@ -201,22 +202,17 @@ def split_fixture_path(path: str) -> Tuple[str, str]: integration_name = os.path.split(os.path.dirname(path))[-1] return integration_name, fixture_name -# FIXME: Change to namedtuple if we drop Python3.6: No default values support on namedtuples (or dataclass) +@dataclass class ScreenshotConfig: - def __init__(self, fixture_name: str, image_name: str='001.png', - image_dir: Optional[str]=None, bot_name: Optional[str]=None, - payload_as_query_param: bool=False, payload_param_name: str='payload', - extra_params: Optional[Dict[str, str]]=None, - use_basic_auth: bool=False, custom_headers: Optional[Dict[str, str]]=None): - self.fixture_name = fixture_name - self.image_name = image_name - self.image_dir = image_dir - self.bot_name = bot_name - self.payload_as_query_param = payload_as_query_param - self.payload_param_name = payload_param_name - self.extra_params = extra_params - self.use_basic_auth = use_basic_auth - self.custom_headers = custom_headers + fixture_name: str + image_name: str = '001.png' + image_dir: Optional[str] = None + bot_name: Optional[str] = None + payload_as_query_param: bool = False + payload_param_name: str = 'payload' + extra_params: Optional[Dict[str, str]] = None + use_basic_auth: bool = False + custom_headers: Optional[Dict[str, str]] = None def get_fixture_and_image_paths(integration: WebhookIntegration, screenshot_config: ScreenshotConfig) -> Tuple[str, str]: