diff --git a/tildes/tildes/schemas/group.py b/tildes/tildes/schemas/group.py index 3d513b3..0bd674e 100644 --- a/tildes/tildes/schemas/group.py +++ b/tildes/tildes/schemas/group.py @@ -10,6 +10,7 @@ import sqlalchemy_utils from marshmallow import pre_load, Schema, validates from marshmallow.exceptions import ValidationError from marshmallow.fields import DateTime +from marshmallow.types import UnknownOption from tildes.schemas.context import TildesSchemaContext, TildesContext from tildes.schemas.fields import Ltree, Markdown, SimpleString @@ -42,7 +43,9 @@ class GroupSchema(Schema): sidebar_markdown = Markdown(allow_none=True) @pre_load - def prepare_path(self, data: dict, many: bool, partial: Any) -> dict: + def prepare_path( + self, data: dict, many: bool, partial: Any, unknown: UnknownOption + ) -> dict: """Prepare the path value before it's validated.""" # pylint: disable=unused-argument if not TildesSchemaContext.get(default=TildesContext()).get( @@ -60,8 +63,9 @@ class GroupSchema(Schema): return new_data @validates("path") - def validate_path(self, value: sqlalchemy_utils.Ltree) -> None: + def validate_path(self, value: sqlalchemy_utils.Ltree, data_key: str) -> None: """Validate the path field, raising an error if an issue exists.""" + # pylint: disable=unused-argument # check each element for length and against validity regex path_elements = value.path.split(".") for element in path_elements: @@ -72,7 +76,9 @@ class GroupSchema(Schema): raise ValidationError("Path element %s is invalid" % element) @pre_load - def prepare_sidebar_markdown(self, data: dict, many: bool, partial: Any) -> dict: + def prepare_sidebar_markdown( + self, data: dict, many: bool, partial: Any, unknown: UnknownOption + ) -> dict: """Prepare the sidebar_markdown value before it's validated.""" # pylint: disable=unused-argument if "sidebar_markdown" not in data: diff --git a/tildes/tildes/schemas/listing.py b/tildes/tildes/schemas/listing.py index 18e831a..1c2a8e7 100644 --- a/tildes/tildes/schemas/listing.py +++ b/tildes/tildes/schemas/listing.py @@ -7,6 +7,7 @@ from typing import Any from marshmallow import pre_load, Schema, validates_schema, ValidationError from marshmallow.fields import Boolean, Integer +from marshmallow.types import UnknownOption from marshmallow.validate import Range from tildes.enums import TopicSortOption @@ -21,7 +22,9 @@ class PaginatedListingSchema(Schema): per_page = Integer(validate=Range(min=1, max=100), load_default=50) @validates_schema - def either_after_or_before(self, data: dict, many: bool, partial: Any) -> None: + def either_after_or_before( + self, data: dict, many: bool, partial: Any, unknown: UnknownOption + ) -> None: """Fail validation if both after and before were specified.""" # pylint: disable=unused-argument if data.get("after") and data.get("before"): @@ -40,7 +43,7 @@ class TopicListingSchema(PaginatedListingSchema): @pre_load def reset_rank_start_on_first_page( - self, data: dict, many: bool, partial: Any + self, data: dict, many: bool, partial: Any, unknown: UnknownOption ) -> dict: """Reset rank_start to 1 if this is a first page (no before/after).""" # pylint: disable=unused-argument @@ -66,7 +69,7 @@ class MixedListingSchema(PaginatedListingSchema): @pre_load def set_anchor_type_from_before_or_after( - self, data: dict, many: bool, partial: Any + self, data: dict, many: bool, partial: Any, unknown: UnknownOption ) -> dict: """Set the anchor_type if before or after has a special value indicating type. diff --git a/tildes/tildes/schemas/topic.py b/tildes/tildes/schemas/topic.py index 41e2aae..f133fb7 100644 --- a/tildes/tildes/schemas/topic.py +++ b/tildes/tildes/schemas/topic.py @@ -9,6 +9,7 @@ from urllib.parse import urlparse from marshmallow import pre_load, Schema, validates, validates_schema, ValidationError from marshmallow.fields import DateTime, List, Nested, String, URL +from marshmallow.types import UnknownOption from tildes.lib.url_transform import apply_url_transformations from tildes.schemas.fields import Enum, ID36, Markdown, SimpleString @@ -36,7 +37,9 @@ class TopicSchema(Schema): group = Nested(GroupSchema, dump_only=True) @pre_load - def prepare_title(self, data: dict, many: bool, partial: Any) -> dict: + def prepare_title( + self, data: dict, many: bool, partial: Any, unknown: UnknownOption + ) -> dict: """Prepare the title before it's validated.""" # pylint: disable=unused-argument if "title" not in data: @@ -56,7 +59,9 @@ class TopicSchema(Schema): return new_data @pre_load - def prepare_tags(self, data: dict, many: bool, partial: Any) -> dict: + def prepare_tags( + self, data: dict, many: bool, partial: Any, unknown: UnknownOption + ) -> dict: """Prepare the tags before they're validated.""" # pylint: disable=unused-argument if "tags" not in data: @@ -98,7 +103,7 @@ class TopicSchema(Schema): return new_data @validates("tags") - def validate_tags(self, value: list[str]) -> None: + def validate_tags(self, value: list[str], data_key: str) -> None: """Validate the tags field, raising an error if an issue exists. Note that tags are validated by ensuring that each tag would be a valid group @@ -107,6 +112,7 @@ class TopicSchema(Schema): between groups and tags. For example, a popular tag in a group could be converted into a sub-group easily. """ + # pylint: disable=unused-argument group_schema = GroupSchema(partial=True) for tag in value: try: @@ -115,7 +121,9 @@ class TopicSchema(Schema): raise ValidationError("Tag %s is invalid" % tag) from exc @pre_load - def prepare_markdown(self, data: dict, many: bool, partial: Any) -> dict: + def prepare_markdown( + self, data: dict, many: bool, partial: Any, unknown: UnknownOption + ) -> dict: """Prepare the markdown value before it's validated.""" # pylint: disable=unused-argument if "markdown" not in data: @@ -130,7 +138,9 @@ class TopicSchema(Schema): return new_data @pre_load - def prepare_link(self, data: dict, many: bool, partial: Any) -> dict: + def prepare_link( + self, data: dict, many: bool, partial: Any, unknown: UnknownOption + ) -> dict: """Prepare the link value before it's validated.""" # pylint: disable=unused-argument if "link" not in data: @@ -157,7 +167,9 @@ class TopicSchema(Schema): return new_data @validates_schema - def link_or_markdown(self, data: dict, many: bool, partial: Any) -> None: + def link_or_markdown( + self, data: dict, many: bool, partial: Any, unknown: UnknownOption + ) -> None: """Fail validation unless at least one of link or markdown were set.""" # pylint: disable=unused-argument if "link" not in data and "markdown" not in data: diff --git a/tildes/tildes/schemas/user.py b/tildes/tildes/schemas/user.py index 239cd75..b1ca227 100644 --- a/tildes/tildes/schemas/user.py +++ b/tildes/tildes/schemas/user.py @@ -9,6 +9,7 @@ from typing import Any from marshmallow import post_dump, pre_load, Schema, validates, validates_schema from marshmallow.exceptions import ValidationError from marshmallow.fields import DateTime, Email, String +from marshmallow.types import UnknownOption from marshmallow.validate import Length, Regexp from tildes.lib.password import is_breached_password @@ -78,7 +79,7 @@ class UserSchema(Schema): @validates_schema def username_pass_not_substrings( - self, data: dict, many: bool, partial: Any + self, data: dict, many: bool, partial: Any, unknown: UnknownOption ) -> None: """Ensure the username isn't in the password and vice versa.""" # pylint: disable=unused-argument @@ -97,11 +98,12 @@ class UserSchema(Schema): raise ValidationError("Username cannot contain password") @validates("password") - def password_not_breached(self, value: str) -> None: + def password_not_breached(self, value: str, data_key: str) -> None: """Validate that the password is not in the breached-passwords list. Requires check_breached_passwords be True in the schema's context. """ + # pylint: disable=unused-argument if not TildesSchemaContext.get(default=TildesContext()).get( "check_breached_passwords" ): @@ -114,7 +116,9 @@ class UserSchema(Schema): ) @pre_load - def username_trim_whitespace(self, data: dict, many: bool, partial: Any) -> dict: + def username_trim_whitespace( + self, data: dict, many: bool, partial: Any, unknown: UnknownOption + ) -> dict: """Trim leading/trailing whitespace around the username. Requires username_trim_whitespace be True in the schema's context. @@ -135,7 +139,9 @@ class UserSchema(Schema): return new_data @pre_load - def prepare_email_address(self, data: dict, many: bool, partial: Any) -> dict: + def prepare_email_address( + self, data: dict, many: bool, partial: Any, unknown: UnknownOption + ) -> dict: """Prepare the email address value before it's validated.""" # pylint: disable=unused-argument if "email_address" not in data: @@ -153,7 +159,9 @@ class UserSchema(Schema): return new_data @pre_load - def prepare_bio_markdown(self, data: dict, many: bool, partial: Any) -> dict: + def prepare_bio_markdown( + self, data: dict, many: bool, partial: Any, unknown: UnknownOption + ) -> dict: """Prepare the bio_markdown value before it's validated.""" # pylint: disable=unused-argument if "bio_markdown" not in data: