25
25
26
26
from __future__ import annotations
27
27
28
- from typing import TYPE_CHECKING , Any , ClassVar , Iterator , TypeVar
28
+ from typing import TYPE_CHECKING , Any , ClassVar , Iterator , TypeVar , overload
29
29
30
30
from .asset import AssetMixin
31
31
from .colour import Colour
43
43
from .utils import MISSING , find , get_slots
44
44
45
45
if TYPE_CHECKING :
46
+ from . import abc
46
47
from .emoji import AppEmoji , GuildEmoji
47
48
from .types .components import ActionRow as ActionRowPayload
48
49
from .types .components import ButtonComponent as ButtonComponentPayload
@@ -497,21 +498,83 @@ class SelectDefaultValue:
497
498
498
499
Parameters
499
500
----------
501
+ object: :class:`abc.Snowflake`
502
+ The model type this select default value is based of.
503
+
504
+ Below, is a table defining the model instance type and the default value type it will be mapped:
505
+
506
+ +-----------------------------------+--------------------------------------------------------------------------+
507
+ | Model Type | Default Value Type |
508
+ +-----------------------------------+--------------------------------------------------------------------------+
509
+ | :class:`discord.User` | :attr:`discord.SelectDefaultValueType.user` |
510
+ +-----------------------------------+--------------------------------------------------------------------------+
511
+ | :class:`discord.Member` | :attr:`discord.SelectDefaultValueType.user` |
512
+ +-----------------------------------+--------------------------------------------------------------------------+
513
+ | :class:`discord.Role` | :attr:`discord.SelectDefaultValueType.role` |
514
+ +-----------------------------------+--------------------------------------------------------------------------+
515
+ | :class:`discord.abc.GuildChannel` | :attr:`discord.SelectDefaultValueType.channel` |
516
+ +-----------------------------------+--------------------------------------------------------------------------+
517
+ | :class:`discord.Object` | depending on :attr:`discord.Object.type`, it will be mapped to any above |
518
+ +-----------------------------------+--------------------------------------------------------------------------+
519
+
520
+ If you pass a model that is not defined in the table, ``TypeError`` will be raised.
521
+
522
+ .. note::
523
+
524
+ The :class:`discord.abc.GuildChannel` protocol includes :class:`discord.TextChannel`, :class:`discord.VoiceChannel`, :class:`discord.StageChannel`,
525
+ :class:`discord.ForumChannel`, :class:`discord.Thread`, :class:`discord.MediaChannel`. This list is not exhaustive, and is bound to change
526
+ based of the new channel types Discord adds.
527
+
500
528
id: :class:`int`
501
- The ID of the default value.
529
+ The ID of the default value. This cannot be used with ``object``.
502
530
type: :class:`SelectDefaultValueType`
503
- The default value type.
531
+ The default value type. This cannot be used with ``object``.
532
+
533
+ Raises
534
+ ------
535
+ TypeError
536
+ You did not provide any parameter, you provided all parameters, or you provided ``id`` but not ``type``.
504
537
"""
505
538
506
539
__slots__ = ("id" , "type" )
507
540
541
+ @overload
508
542
def __init__ (
509
543
self ,
544
+ object : abc .Snowflake ,
545
+ / ,
546
+ ) -> None : ...
547
+
548
+ @overload
549
+ def __init__ (
550
+ self ,
551
+ / ,
552
+ * ,
510
553
id : int ,
511
554
type : SelectDefaultValueType ,
555
+ ) -> None : ...
556
+
557
+ def __init__ (
558
+ self ,
559
+ object : abc .Snowflake = MISSING ,
560
+ / ,
561
+ * ,
562
+ id : int = MISSING ,
563
+ type : SelectDefaultValueType = MISSING ,
512
564
) -> None :
513
565
self .id : int = id
514
566
self .type : SelectDefaultValueType = type
567
+ if object is not MISSING :
568
+ if any (p is not MISSING for p in (id , type )):
569
+ raise TypeError ("you cannot pass id or type when passing object" )
570
+ self ._handle_model (object , inst = self )
571
+ elif id is not MISSING and type is not MISSING :
572
+ self .id = id
573
+ self .type = type
574
+ else :
575
+ raise TypeError (
576
+ "you must provide an object model, or an id and type"
577
+ )
515
578
516
579
@classmethod
517
580
def _from_data (
@@ -524,6 +587,62 @@ def _from_data(
524
587
for d in default_values
525
588
]
526
589
590
+ @classmethod
591
+ def _handle_model (cls , model : abc .Snowflake , select_type : ComponentType | None = None , inst : SelectDefaultValue | None = None ) -> SelectDefaultValue :
592
+ # preventing >circular imports<
593
+ from discord import abc , Role , User , Member , Object
594
+
595
+ instances_mapping : dict [
596
+ type , tuple [tuple [ComponentType , ...], SelectDefaultValueType ]
597
+ ] = {
598
+ Role : (
599
+ (ComponentType .role_select , ComponentType .mentionable_select ),
600
+ SelectDefaultValueType .role ,
601
+ ),
602
+ User : (
603
+ (ComponentType .user_select , ComponentType .mentionable_select ),
604
+ SelectDefaultValueType .user ,
605
+ ),
606
+ Member : (
607
+ (ComponentType .user_select , ComponentType .mentionable_select ),
608
+ SelectDefaultValueType .user ,
609
+ ),
610
+ abc .User : (
611
+ (ComponentType .user_select , ComponentType .mentionable_select ),
612
+ SelectDefaultValueType .user ,
613
+ ),
614
+ abc .GuildChannel : (
615
+ (ComponentType .channel_select ,),
616
+ SelectDefaultValueType .channel ,
617
+ ),
618
+ }
619
+
620
+ obj_id = model .id
621
+ obj_type = model .__class__
622
+
623
+ if isinstance (model , Object ):
624
+ obj_type = model .type
625
+
626
+ try :
627
+ sel_types , def_type = instances_mapping [obj_type ]
628
+ except KeyError :
629
+ raise TypeError (
630
+ f"{ model .__class__ .__name__ } is not a valid instance for a select default value" ,
631
+ )
632
+
633
+ # we can't actually check select types when not in a select context
634
+ if select_type is not None and select_type not in sel_types :
635
+ raise TypeError (
636
+ f"{ model .__class__ .__name__ } objects can not be set as a default value for { select_type .value } selects" ,
637
+ )
638
+
639
+ if inst is None :
640
+ return cls (id = obj_id , type = def_type )
641
+ else :
642
+ inst .id = obj_id
643
+ inst .type = def_type
644
+ return inst
645
+
527
646
def to_dict (self ) -> SelectDefaultValuePayload :
528
647
return {
529
648
"id" : self .id ,
0 commit comments