From 432d4f452171af84859cb22c0ad4bfd0fa79ddab Mon Sep 17 00:00:00 2001 From: Kiran Jonnalagadda Date: Wed, 3 Jan 2024 21:48:10 +0530 Subject: [PATCH] Resolve circular imports and remove union for markdown models --- funnel/cli/refresh/markdown.py | 11 +++-- funnel/models/commentset_membership.py | 6 +-- funnel/models/project.py | 5 +- funnel/models/proposal.py | 2 +- funnel/models/typing.py | 64 +++++--------------------- 5 files changed, 26 insertions(+), 62 deletions(-) diff --git a/funnel/cli/refresh/markdown.py b/funnel/cli/refresh/markdown.py index 2fa846732..544883b5e 100644 --- a/funnel/cli/refresh/markdown.py +++ b/funnel/cli/refresh/markdown.py @@ -9,16 +9,19 @@ import rich.progress from ... import models -from ...models import MarkdownModelUnion, db, sa_orm +from ...models import db, sa_orm from . import refresh -_M = TypeVar('_M', bound=MarkdownModelUnion) +_M = TypeVar('_M', bound=models.ModelIdProtocol) class MarkdownModel(Generic[_M]): """Holding class for a model that has markdown fields with custom configuration.""" + #: Dict of ``{MarkdownModel().name: MarkdownModel()}`` registry: ClassVar[dict[str, MarkdownModel]] = {} + #: Dict of ``{config_name: MarkdownModel()}``, where the fields on the model using + #: that config are enumerated in :attr:`config_fields` config_registry: ClassVar[dict[str, set[MarkdownModel]]] = {} def __init__(self, model: type[_M], fields: set[str]) -> None: @@ -54,12 +57,12 @@ def reparse(self, config: str | None = None, obj: _M | None = None) -> None: iter_total = 1 else: load_columns = ( - [self.model.id] + [self.model.id_] + [getattr(self.model, f'{field}_text'.lstrip('_')) for field in fields] + [getattr(self.model, f'{field}_html'.lstrip('_')) for field in fields] ) iter_list = ( - self.model.query.order_by(self.model.id) + self.model.query.order_by(self.model.id_) .options(sa_orm.load_only(*load_columns)) .yield_per(10) ) diff --git a/funnel/models/commentset_membership.py b/funnel/models/commentset_membership.py index c4b8683d1..5565fc1ac 100644 --- a/funnel/models/commentset_membership.py +++ b/funnel/models/commentset_membership.py @@ -10,9 +10,6 @@ from . import Mapped, Model, Query, relationship, sa, sa_orm from .account import Account from .membership_mixin import ImmutableMembershipMixin -from .project import Project -from .proposal import Proposal -from .update import Update __all__ = ['CommentsetMembership'] @@ -100,6 +97,9 @@ def for_user(cls, account: Account) -> Query[Self]: # Tail imports from .comment import Comment, Commentset +from .project import Project +from .proposal import Proposal +from .update import Update CommentsetMembership.new_comment_count = sa_orm.column_property( sa.select(sa.func.count(Comment.id)) diff --git a/funnel/models/project.py b/funnel/models/project.py index d0b6d3b03..1549420ae 100644 --- a/funnel/models/project.py +++ b/funnel/models/project.py @@ -45,7 +45,6 @@ types, ) from .account import Account -from .comment import SET_TYPE, Commentset from .helpers import ( RESERVED_NAMES, ImgeeType, @@ -1641,3 +1640,7 @@ def __repr__(self) -> str: # joined model, not the first grants_via={Rsvp.participant: {'participant', 'project_participant'}}, ) + + +# Tail imports +from .comment import SET_TYPE, Commentset diff --git a/funnel/models/proposal.py b/funnel/models/proposal.py index 6ba4d64db..eaa0fe07d 100644 --- a/funnel/models/proposal.py +++ b/funnel/models/proposal.py @@ -33,7 +33,6 @@ sa_orm, ) from .account import Account -from .comment import SET_TYPE, Commentset from .helpers import ( MarkdownCompositeDocument, add_search_trigger, @@ -582,6 +581,7 @@ class ProposalSuuidRedirect(BaseMixin[int, Account], Model): # Tail imports +from .comment import SET_TYPE, Commentset from .proposal_membership import ProposalMembership from .sponsor_membership import ProposalSponsorMembership diff --git a/funnel/models/typing.py b/funnel/models/typing.py index c2e13abbe..ca09f3d1a 100644 --- a/funnel/models/typing.py +++ b/funnel/models/typing.py @@ -1,17 +1,10 @@ """Union types for models with shared functionality.""" +from __future__ import annotations + from collections.abc import Iterable, Iterator, Sequence from datetime import datetime -from typing import ( - Any, - ClassVar, - Literal, - Protocol, - TypeAlias, - Union, - overload, - runtime_checkable, -) +from typing import Any, ClassVar, Literal, Protocol, overload, runtime_checkable from uuid import UUID from sqlalchemy import Table @@ -20,55 +13,16 @@ from coaster.sqlalchemy import LazyRoleSet, QueryProperty from coaster.utils import InspectableSet -from .account import Account, AccountOldId, Team -from .auth_client import AuthClient -from .comment import Comment, Commentset -from .login_session import LoginSession -from .membership_mixin import ImmutableMembershipMixin -from .moderation import CommentModeratorReport -from .project import Project -from .proposal import Proposal -from .rsvp import Rsvp -from .session import Session -from .sync_ticket import TicketParticipant -from .update import Update -from .venue import Venue, VenueRoom - __all__ = [ - 'UuidModelUnion', - 'MarkdownModelUnion', + 'ModelProtocol', + 'ModelTimestampProtocol', + 'ModelUrlProtocol', + 'ModelRoleProtocol', 'ModelIdProtocol', 'ModelUuidProtocol', 'ModelSearchProtocol', ] -# All models with a `uuid` attr -UuidModelUnion: TypeAlias = Union[ - Account, - AccountOldId, - AuthClient, - Comment, - CommentModeratorReport, - Commentset, - ImmutableMembershipMixin, - LoginSession, - Project, - Proposal, - Rsvp, - Session, - Team, - TicketParticipant, - Update, - Venue, - VenueRoom, -] - - -# All models with one or more markdown composite columns -MarkdownModelUnion: TypeAlias = Union[ - Account, Comment, Project, Proposal, Session, Update, Venue, VenueRoom -] - class ModelProtocol(Protocol): __tablename__: str @@ -135,3 +89,7 @@ class ModelSearchProtocol(ModelUuidProtocol, Protocol): @property def title(self) -> Mapped[str] | declared_attr[str]: ... + + +# Tail imports +from .account import Account