Browse Source

Use prebuilt Python 3.11 instead of building Python 3.9

Closes tildes-community/tildes-cf#14

See merge request tildes-community/tildes-cf!8
develop
talklittle 1 month ago
committed by Andrew Shu
parent
commit
c0be1a8403
  1. 2
      ansible/roles/postgresql_tildes_dbs/tasks/main.yml
  2. 58
      ansible/roles/python/tasks/main.yml
  3. 3
      ansible/vars.yml
  4. 6
      tildes/consumers/site_icon_downloader.py
  5. 2
      tildes/consumers/topic_metadata_generator.py
  6. 4
      tildes/prospector.yaml
  7. 1
      tildes/pytest.ini
  8. 2
      tildes/requirements-dev.in
  9. 56
      tildes/requirements-dev.txt
  10. 22
      tildes/requirements.txt
  11. 2
      tildes/scripts/backup_database.py
  12. 2
      tildes/tildes/lib/database.py
  13. 2
      tildes/tildes/lib/datetime.py
  14. 13
      tildes/tildes/models/group/group_wiki_page.py
  15. 1
      tildes/tildes/models/model_query.py
  16. 3
      tildes/tildes/models/pagination.py
  17. 18
      tildes/tildes/schemas/fields.py
  18. 2
      tildes/tildes/views/bookmarks.py
  19. 4
      tildes/tildes/views/decorators.py
  20. 2
      tildes/tildes/views/votes.py

2
ansible/roles/postgresql_tildes_dbs/tasks/main.yml

@ -4,7 +4,7 @@
name: name:
- gcc - gcc
- libpq-dev - libpq-dev
- python3-dev
- python{{ python_version }}-dev
- name: Install packages needed by Ansible community plugins - name: Install packages needed by Ansible community plugins
pip: pip:

58
ansible/roles/python/tasks/main.yml

@ -1,56 +1,10 @@
--- ---
- name: Check if the correct version of Python is already installed
stat:
path: /usr/local/bin/python{{ python_version }}
register: python_binary
- name: Download and install Python
when: not python_binary.stat.exists
block:
- name: Download Python source code
get_url:
dest: /tmp/python.tar.gz
url: https://www.python.org/ftp/python/{{ python_full_version }}/Python-{{ python_full_version }}.tgz
checksum: sha256:1e71f006222666e0a39f5a47be8221415c22c4dd8f25334cc41aee260b3d379e
- name: Create temp directory to extract Python to
file:
path: /tmp/python
state: directory
- name: Extract Python
unarchive:
remote_src: true
src: /tmp/python.tar.gz
dest: /tmp/python
extra_opts:
- --strip-components=1
- name: Install build dependencies for Python
apt:
name:
- make
- build-essential
- libssl-dev
- zlib1g-dev
- libbz2-dev
- libreadline-dev
- libsqlite3-dev
- wget
- curl
- llvm
- libncurses5-dev
- libncursesw5-dev
- xz-utils
- tk-dev
- name: Build and install Python (this can take a long time)
shell:
chdir: /tmp/python
cmd: |
./configure --enable-optimizations --with-ensurepip=install
make
make altinstall
- name: Install Python and dependencies needed by packages
apt:
name:
- python{{ python_version }}
- python{{ python_version }}-venv
- libgit2-dev
- name: Create dir for venvs - name: Create dir for venvs
file: file:

3
ansible/vars.yml

@ -5,7 +5,6 @@ bin_dir: "{{ venv_dir }}/bin"
static_sites_dir: /opt/tildes-static-sites static_sites_dir: /opt/tildes-static-sites
python_full_version: 3.9.20
python_version: "{{ python_full_version.rpartition('.')[0] }}"
python_version: "3.11"
is_docker: "{{ ansible_facts['virtualization_type'] == 'container' }}" is_docker: "{{ ansible_facts['virtualization_type'] == 'container' }}"

6
tildes/consumers/site_icon_downloader.py

@ -10,7 +10,7 @@ from typing import Optional
import publicsuffix import publicsuffix
import requests import requests
from PIL import Image
from PIL import Image, IcoImagePlugin
from tildes.enums import ScraperType from tildes.enums import ScraperType
from tildes.lib.event_stream import EventStreamConsumer, Message from tildes.lib.event_stream import EventStreamConsumer, Message
@ -80,6 +80,10 @@ class SiteIconDownloader(EventStreamConsumer):
return None return None
if favicon.format == "ICO": if favicon.format == "ICO":
assert isinstance(
favicon, IcoImagePlugin.IcoImageFile
) # tell mypy the type is more restricted now
# get the 32x32 size if it's present, otherwise resize the largest one # get the 32x32 size if it's present, otherwise resize the largest one
if (32, 32) in favicon.ico.sizes(): if (32, 32) in favicon.ico.sizes():
return favicon.ico.getimage((32, 32)) return favicon.ico.getimage((32, 32))

2
tildes/consumers/topic_metadata_generator.py

@ -45,6 +45,8 @@ class TopicMetadataGenerator(EventStreamConsumer):
new_metadata = self._generate_text_metadata(topic) new_metadata = self._generate_text_metadata(topic)
elif topic.is_link_type: elif topic.is_link_type:
new_metadata = self._generate_link_metadata(topic) new_metadata = self._generate_link_metadata(topic)
else:
new_metadata = {}
# update the topic's content_metadata in a way that won't wipe out any existing # update the topic's content_metadata in a way that won't wipe out any existing
# values, and can handle the column being null # values, and can handle the column being null

4
tildes/prospector.yaml

@ -29,6 +29,8 @@ pylint:
disable: disable:
- bad-continuation # let Black handle line-wrapping - bad-continuation # let Black handle line-wrapping
- comparison-with-callable # seems to have a lot of false positives - comparison-with-callable # seems to have a lot of false positives
- consider-using-f-string # TBD if helpful [2025-01-16]
- consider-using-generator # TBD if helpful [2025-01-16]
- cyclic-import # not sure what's triggering this, doesn't seem to work correctly - cyclic-import # not sure what's triggering this, doesn't seem to work correctly
- logging-fstring-interpolation # rather use f-strings than worry about this - logging-fstring-interpolation # rather use f-strings than worry about this
- no-else-return # elif after return - could refactor to enable this check - no-else-return # elif after return - could refactor to enable this check
@ -39,8 +41,10 @@ pylint:
- too-many-branches # almost never helpful - too-many-branches # almost never helpful
- too-many-instance-attributes # models have many instance attributes - too-many-instance-attributes # models have many instance attributes
- too-many-locals # almost never helpful - too-many-locals # almost never helpful
- too-many-positional-arguments # TBD if helpful [2025-01-16]
- too-many-public-methods # almost never helpful - too-many-public-methods # almost never helpful
- too-many-return-statements # almost never helpful - too-many-return-statements # almost never helpful
- too-many-statements # almost never helpful - too-many-statements # almost never helpful
- ungrouped-imports # let isort handle this - ungrouped-imports # let isort handle this
- unnecessary-pass # I prefer using pass, even when it's not technically necessary - unnecessary-pass # I prefer using pass, even when it's not technically necessary
- use-yield-from # TBD if helpful [2025-01-16]

1
tildes/pytest.ini

@ -4,7 +4,6 @@ addopts = -p no:cacheprovider --strict-markers
filterwarnings = filterwarnings =
ignore::DeprecationWarning ignore::DeprecationWarning
ignore::PendingDeprecationWarning ignore::PendingDeprecationWarning
ignore::yaml.YAMLLoadWarning
markers = markers =
html_validation: mark a test as one that validates HTML using the Nu HTML Checker (very slow) html_validation: mark a test as one that validates HTML using the Nu HTML Checker (very slow)
webtest: mark a test as one that uses the WebTest library, which goes through the actual WSGI app and involves using HTTP/HTML (more of a "functional test" than "unit test") webtest: mark a test as one that uses the WebTest library, which goes through the actual WSGI app and involves using HTTP/HTML (more of a "functional test" than "unit test")

2
tildes/requirements-dev.in

@ -3,7 +3,7 @@ black
freezegun freezegun
html5validator html5validator
mypy mypy
prospector @ git+https://github.com/Deimos/prospector.git#egg=prospector
prospector
pyramid-debugtoolbar pyramid-debugtoolbar
pytest pytest
pytest-mock pytest-mock

56
tildes/requirements-dev.txt

@ -2,20 +2,20 @@ ago==0.0.93
alembic==1.6.5 alembic==1.6.5
appdirs==1.4.4 appdirs==1.4.4
argon2-cffi==20.1.0 argon2-cffi==20.1.0
astroid==2.6.5
attrs==21.2.0
astroid==3.3.8
attrs==24.3.0
backcall==0.2.0 backcall==0.2.0
beautifulsoup4==4.9.3 beautifulsoup4==4.9.3
black==21.7b0 black==21.7b0
bleach==3.3.1 bleach==3.3.1
certifi==2021.5.30 certifi==2021.5.30
cffi==1.14.6
cffi==1.17.1
charset-normalizer==2.0.3 charset-normalizer==2.0.3
click==8.0.1 click==8.0.1
cornice==5.2.0 cornice==5.2.0
decorator==5.0.9 decorator==5.0.9
dodgy==0.2.1 dodgy==0.2.1
flake8==3.9.2
flake8==7.1.1
flake8-polyfill==1.0.2 flake8-polyfill==1.0.2
freezegun==1.1.0 freezegun==1.1.0
gunicorn==20.1.0 gunicorn==20.1.0
@ -23,52 +23,52 @@ html5lib==1.1
html5validator==0.4.0 html5validator==0.4.0
hupper==1.10.3 hupper==1.10.3
idna==3.2 idna==3.2
iniconfig==1.1.1
invoke==1.6.0
iniconfig==2.0.0
invoke==2.2.0
ipython==7.25.0 ipython==7.25.0
ipython-genutils==0.2.0 ipython-genutils==0.2.0
isort==5.9.2 isort==5.9.2
jedi==0.18.0 jedi==0.18.0
jinja2==3.0.1 jinja2==3.0.1
lazy-object-proxy==1.6.0 lazy-object-proxy==1.6.0
lupa==1.9
lupa==2.4
mako==1.1.4 mako==1.1.4
markupsafe==2.0.1 markupsafe==2.0.1
marshmallow==3.13.0
marshmallow==3.25.1
matplotlib-inline==0.1.2 matplotlib-inline==0.1.2
mccabe==0.6.1
mypy==1.13.0
mccabe==0.7.0
mypy==1.14.1
mypy-extensions==1.0.0 mypy-extensions==1.0.0
packaging==23.2
packaging==24.2
parso==0.8.2 parso==0.8.2
pastedeploy==2.1.1 pastedeploy==2.1.1
pathspec==0.9.0 pathspec==0.9.0
pep517==0.11.0 pep517==0.11.0
pep8-naming==0.12.0
pep8-naming==0.10.0
pexpect==4.8.0 pexpect==4.8.0
pickleshare==0.7.5 pickleshare==0.7.5
pillow==8.3.1
pillow==11.1.0
pip-tools==6.2.0 pip-tools==6.2.0
plaster==1.0 plaster==1.0
plaster-pastedeploy==0.7 plaster-pastedeploy==0.7
pluggy==0.13.1
pluggy==1.5.0
prometheus-client==0.11.0 prometheus-client==0.11.0
prompt-toolkit==3.0.19 prompt-toolkit==3.0.19
git+https://github.com/Deimos/prospector.git#egg=prospector
psycopg2==2.9.1
prospector==1.13.3
psycopg2==2.9.10
ptyprocess==0.7.0 ptyprocess==0.7.0
publicsuffix2==2.20160818 publicsuffix2==2.20160818
py==1.10.0
pycodestyle==2.7.0
py==1.11.0
pycodestyle==2.12.1
pycparser==2.20 pycparser==2.20
pydocstyle==6.1.1 pydocstyle==6.1.1
pyflakes==2.3.1
pygit2==1.6.1
pyflakes==3.2.0
pygit2==1.17.0
pygments==2.9.0 pygments==2.9.0
pylint==2.9.5
pylint-plugin-utils==0.6
pylint==3.3.3
pylint-plugin-utils==0.8.2
pyotp==2.6.0 pyotp==2.6.0
pyparsing==2.4.7
pyparsing==3.2.1
pyramid==1.10.8 pyramid==1.10.8
pyramid-debugtoolbar==4.9 pyramid-debugtoolbar==4.9
pyramid-ipython==0.2 pyramid-ipython==0.2
@ -77,17 +77,17 @@ pyramid-mako==1.1.0
pyramid-session-redis==1.5.0 pyramid-session-redis==1.5.0
pyramid-tm==2.4 pyramid-tm==2.4
pyramid-webassets==0.10 pyramid-webassets==0.10
pytest==6.2.4
pytest-mock==3.6.1
pytest==8.3.4
pytest-mock==3.14.0
python-dateutil==2.8.2 python-dateutil==2.8.2
python-editor==1.0.4 python-editor==1.0.4
pyyaml==5.4.1
pyyaml==6.0.2
qrcode==7.2 qrcode==7.2
redis==3.5.3 redis==3.5.3
regex==2021.7.6 regex==2021.7.6
repoze.lru==0.7 repoze.lru==0.7
requests==2.26.0 requests==2.26.0
requirements-detector==0.7
requirements-detector==1.3.2
sentry-sdk==1.3.0 sentry-sdk==1.3.0
setoptconf==0.3.0 setoptconf==0.3.0
six==1.16.0 six==1.16.0
@ -119,7 +119,7 @@ webencodings==0.5.1
webob==1.8.7 webob==1.8.7
webtest==2.0.35 webtest==2.0.35
wheel==0.36.2 wheel==0.36.2
wrapt==1.12.1
wrapt==1.17.2
zope.deprecation==4.4.0 zope.deprecation==4.4.0
zope.interface==5.4.0 zope.interface==5.4.0
zope.sqlalchemy==1.5 zope.sqlalchemy==1.5

22
tildes/requirements.txt

@ -5,7 +5,7 @@ backcall==0.2.0
beautifulsoup4==4.9.3 beautifulsoup4==4.9.3
bleach==3.3.1 bleach==3.3.1
certifi==2021.5.30 certifi==2021.5.30
cffi==1.14.6
cffi==1.17.1
charset-normalizer==2.0.3 charset-normalizer==2.0.3
click==8.0.1 click==8.0.1
cornice==5.2.0 cornice==5.2.0
@ -14,36 +14,36 @@ gunicorn==20.1.0
html5lib==1.1 html5lib==1.1
hupper==1.10.3 hupper==1.10.3
idna==3.2 idna==3.2
invoke==1.6.0
invoke==2.2.0
ipython==7.25.0 ipython==7.25.0
ipython-genutils==0.2.0 ipython-genutils==0.2.0
jedi==0.18.0 jedi==0.18.0
jinja2==3.0.1 jinja2==3.0.1
lupa==1.9
lupa==2.4
mako==1.1.4 mako==1.1.4
markupsafe==2.0.1 markupsafe==2.0.1
marshmallow==3.13.0
marshmallow==3.25.1
matplotlib-inline==0.1.2 matplotlib-inline==0.1.2
packaging==23.2
packaging==24.2
parso==0.8.2 parso==0.8.2
pastedeploy==2.1.1 pastedeploy==2.1.1
pep517==0.11.0 pep517==0.11.0
pexpect==4.8.0 pexpect==4.8.0
pickleshare==0.7.5 pickleshare==0.7.5
pillow==8.3.1
pillow==11.1.0
pip-tools==6.2.0 pip-tools==6.2.0
plaster==1.0 plaster==1.0
plaster-pastedeploy==0.7 plaster-pastedeploy==0.7
prometheus-client==0.11.0 prometheus-client==0.11.0
prompt-toolkit==3.0.19 prompt-toolkit==3.0.19
psycopg2==2.9.1
psycopg2==2.9.10
ptyprocess==0.7.0 ptyprocess==0.7.0
publicsuffix2==2.20160818 publicsuffix2==2.20160818
pycparser==2.20 pycparser==2.20
pygit2==1.6.1
pygit2==1.17.0
pygments==2.9.0 pygments==2.9.0
pyotp==2.6.0 pyotp==2.6.0
pyparsing==2.4.7
pyparsing==3.2.1
pyramid==1.10.8 pyramid==1.10.8
pyramid-ipython==0.2 pyramid-ipython==0.2
pyramid-jinja2==2.8 pyramid-jinja2==2.8
@ -52,7 +52,7 @@ pyramid-tm==2.4
pyramid-webassets==0.10 pyramid-webassets==0.10
python-dateutil==2.8.2 python-dateutil==2.8.2
python-editor==1.0.4 python-editor==1.0.4
pyyaml==5.4.1
pyyaml==6.0.2
qrcode==7.2 qrcode==7.2
redis==3.5.3 redis==3.5.3
requests==2.26.0 requests==2.26.0
@ -75,7 +75,7 @@ webassets==2.0
webencodings==0.5.1 webencodings==0.5.1
webob==1.8.7 webob==1.8.7
wheel==0.36.2 wheel==0.36.2
wrapt==1.12.1
wrapt==1.17.2
zope.deprecation==4.4.0 zope.deprecation==4.4.0
zope.interface==5.4.0 zope.interface==5.4.0
zope.sqlalchemy==1.5 zope.sqlalchemy==1.5

2
tildes/scripts/backup_database.py

@ -34,7 +34,7 @@ def create_encrypted_backup(gpg_recipient: str) -> str:
filename = datetime.now().strftime(FILENAME_FORMAT) filename = datetime.now().strftime(FILENAME_FORMAT)
# dump the database to a file # dump the database to a file
with open(f"{filename}.sql", "w") as dump_file:
with open(f"{filename}.sql", "w", encoding="utf-8") as dump_file:
subprocess.run( subprocess.run(
["pg_dump", "-U", "tildes", "tildes"], ["pg_dump", "-U", "tildes", "tildes"],
stdout=dump_file, stdout=dump_file,

2
tildes/tildes/lib/database.py

@ -68,7 +68,7 @@ class CIText(UserDefinedType):
def get_col_spec(self, **kw: Any) -> str: def get_col_spec(self, **kw: Any) -> str:
"""Return the type name (for creating columns and so on).""" """Return the type name (for creating columns and so on)."""
# pylint: disable=no-self-use,unused-argument
# pylint: disable=unused-argument
return "CITEXT" return "CITEXT"
def bind_processor(self, dialect: Dialect) -> Callable: def bind_processor(self, dialect: Dialect) -> Callable:

2
tildes/tildes/lib/datetime.py

@ -43,6 +43,8 @@ class SimpleHoursPeriod:
hours = count hours = count
elif unit == "d": elif unit == "d":
hours = count * 24 hours = count * 24
else:
raise ValueError("Invalid time period")
return cls(hours=hours) return cls(hours=hours)

13
tildes/tildes/models/group/group_wiki_page.py

@ -130,7 +130,7 @@ class GroupWikiPage(DatabaseModel):
def markdown(self) -> Optional[str]: def markdown(self) -> Optional[str]:
"""Return the wiki page's markdown.""" """Return the wiki page's markdown."""
try: try:
return self.file_path.read_text().rstrip("\r\n")
return self.file_path.read_text(encoding="utf-8").rstrip("\r\n")
except FileNotFoundError: except FileNotFoundError:
return None return None
@ -141,7 +141,7 @@ class GroupWikiPage(DatabaseModel):
if not new_markdown.endswith("\n"): if not new_markdown.endswith("\n"):
new_markdown = new_markdown + "\n" new_markdown = new_markdown + "\n"
self.file_path.write_text(new_markdown)
self.file_path.write_text(new_markdown, encoding="utf-8")
def edit(self, new_markdown: str, user: User, edit_message: str) -> None: def edit(self, new_markdown: str, user: User, edit_message: str) -> None:
"""Set the page's markdown, render its HTML, and commit the repo.""" """Set the page's markdown, render its HTML, and commit the repo."""
@ -156,9 +156,10 @@ class GroupWikiPage(DatabaseModel):
repo = Repository(self.BASE_PATH) repo = Repository(self.BASE_PATH)
author = Signature(user.username, user.username) author = Signature(user.username, user.username)
repo.index.read()
repo.index.add(str(self.file_path.relative_to(self.BASE_PATH)))
repo.index.write()
index = repo.index # type: ignore
index.read()
index.add(str(self.file_path.relative_to(self.BASE_PATH)))
index.write()
# Prepend the group name and page path to the edit message - if you change the # Prepend the group name and page path to the edit message - if you change the
# format of this, make sure to also change the page-editing template to match # format of this, make sure to also change the page-editing template to match
@ -169,6 +170,6 @@ class GroupWikiPage(DatabaseModel):
author, author,
author, author,
edit_message, edit_message,
repo.index.write_tree(),
index.write_tree(),
[repo.head.target], [repo.head.target],
) )

1
tildes/tildes/models/model_query.py

@ -14,6 +14,7 @@ from sqlalchemy.orm import Load, undefer
from sqlalchemy.orm.query import Query from sqlalchemy.orm.query import Query
# pylint: disable=invalid-name
ModelType = TypeVar("ModelType") ModelType = TypeVar("ModelType")

3
tildes/tildes/models/pagination.py

@ -16,6 +16,7 @@ from tildes.lib.id import id36_to_id, id_to_id36
from .model_query import ModelQuery from .model_query import ModelQuery
# pylint: disable=invalid-name
ModelType = TypeVar("ModelType") ModelType = TypeVar("ModelType")
@ -136,9 +137,11 @@ class PaginatedQuery(ModelQuery):
# an upper bound if the sort order is *ascending* # an upper bound if the sort order is *ascending*
is_anchor_upper_bound = not self.sort_desc is_anchor_upper_bound = not self.sort_desc
# pylint: disable=possibly-used-before-assignment
subquery = self._anchor_subquery(anchor_id) subquery = self._anchor_subquery(anchor_id)
# restrict the results to items on the right "side" of the anchor item # restrict the results to items on the right "side" of the anchor item
# pylint: disable=possibly-used-before-assignment
if is_anchor_upper_bound: if is_anchor_upper_bound:
query = query.filter(func.row(*self.sorting_columns) < subquery) query = query.filter(func.row(*self.sorting_columns) < subquery)
else: else:

18
tildes/tildes/schemas/fields.py

@ -34,7 +34,7 @@ class Enum(Field):
self._enum_class = enum_class self._enum_class = enum_class
def _serialize( def _serialize(
self, value: enum.Enum, attr: str, obj: object, **kwargs: Any
self, value: enum.Enum, attr: str | None, obj: object, **kwargs: Any
) -> str: ) -> str:
"""Serialize the enum value - lowercase version of its name.""" """Serialize the enum value - lowercase version of its name."""
return value.name.lower() return value.name.lower()
@ -89,7 +89,7 @@ class ShortTimePeriod(Field):
def _serialize( def _serialize(
self, self,
value: Optional[SimpleHoursPeriod], value: Optional[SimpleHoursPeriod],
attr: str,
attr: str | None,
obj: object, obj: object,
**kwargs: Any, **kwargs: Any,
) -> Optional[str]: ) -> Optional[str]:
@ -131,7 +131,9 @@ class Markdown(Field):
return value return value
def _serialize(self, value: str, attr: str, obj: object, **kwargs: Any) -> str:
def _serialize(
self, value: str, attr: str | None, obj: object, **kwargs: Any
) -> str:
"""Serialize the value (no-op in this case).""" """Serialize the value (no-op in this case)."""
return value return value
@ -166,7 +168,9 @@ class SimpleString(Field):
"""Deserialize the string, removing/replacing as necessary.""" """Deserialize the string, removing/replacing as necessary."""
return simplify_string(value) return simplify_string(value)
def _serialize(self, value: str, attr: str, obj: object, **kwargs: Any) -> str:
def _serialize(
self, value: str, attr: str | None, obj: object, **kwargs: Any
) -> str:
"""Serialize the value (no-op in this case).""" """Serialize the value (no-op in this case)."""
return value return value
@ -179,7 +183,11 @@ class Ltree(Field):
VALID_CHARS_REGEX = re.compile("^[A-Za-z0-9_.]+$") VALID_CHARS_REGEX = re.compile("^[A-Za-z0-9_.]+$")
def _serialize( def _serialize(
self, value: sqlalchemy_utils.Ltree, attr: str, obj: object, **kwargs: Any
self,
value: sqlalchemy_utils.Ltree,
attr: str | None,
obj: object,
**kwargs: Any,
) -> str: ) -> str:
"""Serialize the Ltree value - use the (string) path.""" """Serialize the Ltree value - use the (string) path."""
return value.path return value.path

2
tildes/tildes/views/bookmarks.py

@ -32,7 +32,7 @@ def get_bookmarks(
if post_type == "comment": if post_type == "comment":
post_cls = Comment post_cls = Comment
bookmark_cls = CommentBookmark bookmark_cls = CommentBookmark
elif post_type == "topic":
else:
post_cls = Topic post_cls = Topic
bookmark_cls = TopicBookmark bookmark_cls = TopicBookmark

4
tildes/tildes/views/decorators.py

@ -16,9 +16,7 @@ from webargs import pyramidparser
def use_kwargs( def use_kwargs(
argmap: Union[Schema, dict[str, Union[Field, type]]],
location: str = "query",
**kwargs: Any
argmap: Union[Schema, dict[str, Field]], location: str = "query", **kwargs: Any
) -> Callable: ) -> Callable:
"""Wrap the webargs @use_kwargs decorator with preferred default modifications. """Wrap the webargs @use_kwargs decorator with preferred default modifications.

2
tildes/tildes/views/votes.py

@ -32,7 +32,7 @@ def get_voted_posts(
if post_type == "comment": if post_type == "comment":
post_cls = Comment post_cls = Comment
vote_cls = CommentVote vote_cls = CommentVote
elif post_type == "topic":
else:
post_cls = Topic post_cls = Topic
vote_cls = TopicVote vote_cls = TopicVote

Loading…
Cancel
Save