Repository: Rapptz/discord.py
File: discord/ui/select.py (Python)

Code before:
        values = selected_values.get({})
        payload: List[PossibleValue]
        try:
            resolved = Namespace._get_resolved_items(interaction, data['resolved'])
            payload = list(resolved.values())
        except KeyError:
            payload = data.get("values", [])  # type: ignore

        self._values = values[self.custom_id] = payload
        selected_values.set(values)

    def is_dispatchable(self) -> bool:
        return True

    @classmethod
    def from_component(cls, component: SelectComponent) -> Self:
        if not isinstance(component, SelectComponent):
            raise TypeError('Excepted an instance of SelectComponent not {component.__class__.__name__}')

        kwrgs = {
            'custom_id': component.custom_id,
            'placeholder': component.placeholder,
            'min_values': component.min_values,
            'max_values': component.max_values,
            'disabled': component.disabled,
        }
        if component.type is ComponentType.select:
            return Select(**kwrgs, options=component.options)
        elif component.type is ComponentType.user_select:
            return UserSelect(**kwrgs, default_values=component.default_values)
        elif component.type is ComponentType.role_select:
            return RoleSelect(**kwrgs, default_values=component.default_values)
        elif component.type is ComponentType.channel_select:
            return ChannelSelect(**kwrgs, channel_types=component.channel_types)
        elif component.type is ComponentType.mentionable_select:
            return MentionableSelect(**kwrgs, default_values=component.default_values)
        else:
            raise TypeError(f'Unknown component type {component.type}')


class Select(BaseSelect[V]):
    """Represents a UI select menu with a list of custom options. This is represented
    to the user as a dropdown menu.

    .. versionadded:: 2.0

    Parameters
    ------------
    custom_id: :class:`str`
        The ID of the select menu that gets received during an interaction.
        If not given then one is generated for you.

Review comment (suggestion):
This is probably better off being a separate attribute, such as `__from_component_attributes__` with a tuple of attributes or something in each one similar to the old design but decoupled from the `__repr__`.

Code after:
        return self._underlying.to_dict()

    def _refresh_component(self, component: SelectMenu) -> None:
        self._underlying = component

    def _refresh_state(self, interaction: Interaction, data: SelectMessageComponentInteractionData) -> None:
        values = selected_values.get({})
        payload: List[PossibleValue]
        try:
            resolved = Namespace._get_resolved_items(interaction, data['resolved'])
            payload = list(resolved.values())
        except KeyError:
            payload = data.get("values", [])  # type: ignore

        self._values = values[self.custom_id] = payload
        selected_values.set(values)

    def is_dispatchable(self) -> bool:
        return True

    @classmethod
    def from_component(cls, component: SelectMenu) -> Self:
        type_to_cls: Dict[ComponentType, Type[BaseSelect[Any]]] = {
            ComponentType.string_select: Select,
            ComponentType.user_select: UserSelect,
            ComponentType.role_select: RoleSelect,
            ComponentType.channel_select: ChannelSelect,
            ComponentType.mentionable_select: MentionableSelect,
        }
        constructor = type_to_cls.get(component.type, Select)
        kwrgs = {key: getattr(component, key) for key in constructor.__component_attributes__}
        return constructor(**kwrgs)


class Select(BaseSelect[V]):
    """Represents a UI select menu with a list of custom options. This is represented
    to the user as a dropdown menu.

    .. versionadded:: 2.0

    Parameters
    ------------
    custom_id: :class:`str`
        The ID of the select menu that gets received during an interaction.
        If not given then one is generated for you.
    placeholder: Optional[:class:`str`]
        The placeholder text that is shown if nothing is selected, if any.
    min_values: :class:`int`
        The minimum number of items that must be chosen for this select menu.
        Defaults to 1 and must be between 0 and 25.
    max_values: :class:`int`