Allow color parameters to accept multiple formats (#25)
This commit is contained in:
parent
534b5b3980
commit
9df06868a4
@ -48,3 +48,29 @@ class Color:
|
||||
|
||||
def to_rgb(self) -> tuple[int, int, int]:
|
||||
return ((self.value >> 16) & 0xFF, (self.value >> 8) & 0xFF, self.value & 0xFF)
|
||||
|
||||
@classmethod
|
||||
def parse(cls, value: "Color | int | str | None") -> "Color | None":
|
||||
"""Convert ``value`` to a :class:`Color` instance.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
value:
|
||||
The value to convert. May be ``None``, an existing ``Color``, an
|
||||
integer in the ``0xRRGGBB`` format, or a hex string like ``"#RRGGBB"``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Optional[Color]
|
||||
A ``Color`` object if ``value`` is not ``None``.
|
||||
"""
|
||||
|
||||
if value is None:
|
||||
return None
|
||||
if isinstance(value, cls):
|
||||
return value
|
||||
if isinstance(value, int):
|
||||
return cls(value)
|
||||
if isinstance(value, str):
|
||||
return cls.from_hex(value)
|
||||
raise TypeError("Color value must be Color, int, str, or None")
|
||||
|
@ -503,9 +503,7 @@ class InteractionCallbackData:
|
||||
self.tts: Optional[bool] = data.get("tts")
|
||||
self.content: Optional[str] = data.get("content")
|
||||
self.embeds: Optional[List[Embed]] = (
|
||||
[Embed(e) for e in data.get("embeds", [])]
|
||||
if data.get("embeds")
|
||||
else None
|
||||
[Embed(e) for e in data.get("embeds", [])] if data.get("embeds") else None
|
||||
)
|
||||
self.allowed_mentions: Optional[AllowedMentions] = (
|
||||
AllowedMentions(data["allowed_mentions"])
|
||||
@ -572,3 +570,6 @@ class InteractionResponsePayload:
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<InteractionResponsePayload type={self.type!r}>"
|
||||
|
||||
def __getitem__(self, item: str) -> Any:
|
||||
return self.to_dict()[item]
|
||||
|
@ -25,6 +25,7 @@ from .enums import ( # These enums will need to be defined in disagreement/enum
|
||||
# SelectMenuType will be part of ComponentType or a new enum if needed
|
||||
)
|
||||
from .permissions import Permissions
|
||||
from .color import Color
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -312,7 +313,7 @@ class Embed:
|
||||
self.description: Optional[str] = data.get("description")
|
||||
self.url: Optional[str] = data.get("url")
|
||||
self.timestamp: Optional[str] = data.get("timestamp") # ISO8601 timestamp
|
||||
self.color: Optional[int] = data.get("color")
|
||||
self.color = Color.parse(data.get("color"))
|
||||
|
||||
self.footer: Optional[EmbedFooter] = (
|
||||
EmbedFooter(data["footer"]) if data.get("footer") else None
|
||||
@ -342,7 +343,7 @@ class Embed:
|
||||
if self.timestamp:
|
||||
payload["timestamp"] = self.timestamp
|
||||
if self.color is not None:
|
||||
payload["color"] = self.color
|
||||
payload["color"] = self.color.value
|
||||
if self.footer:
|
||||
payload["footer"] = self.footer.to_dict()
|
||||
if self.image:
|
||||
@ -1708,13 +1709,13 @@ class Container(Component):
|
||||
def __init__(
|
||||
self,
|
||||
components: List[Component],
|
||||
accent_color: Optional[int] = None,
|
||||
accent_color: Color | int | str | None = None,
|
||||
spoiler: bool = False,
|
||||
id: Optional[int] = None,
|
||||
):
|
||||
super().__init__(ComponentType.CONTAINER)
|
||||
self.components = components
|
||||
self.accent_color = accent_color
|
||||
self.accent_color = Color.parse(accent_color)
|
||||
self.spoiler = spoiler
|
||||
self.id = id
|
||||
|
||||
@ -1722,7 +1723,7 @@ class Container(Component):
|
||||
payload = super().to_dict()
|
||||
payload["components"] = [c.to_dict() for c in self.components]
|
||||
if self.accent_color:
|
||||
payload["accent_color"] = self.accent_color
|
||||
payload["accent_color"] = self.accent_color.value
|
||||
if self.spoiler:
|
||||
payload["spoiler"] = self.spoiler
|
||||
if self.id is not None:
|
||||
|
@ -152,7 +152,7 @@ from disagreement.models import Container, TextDisplay
|
||||
|
||||
container = Container(
|
||||
components=[TextDisplay(content="Inside a container")],
|
||||
accent_color=0xFF0000,
|
||||
accent_color="#FF0000", # int or Color() also work
|
||||
spoiler=False,
|
||||
)
|
||||
```
|
||||
|
28
tests/test_color_acceptance.py
Normal file
28
tests/test_color_acceptance.py
Normal file
@ -0,0 +1,28 @@
|
||||
from disagreement.color import Color
|
||||
from disagreement.models import Embed, Container, Component
|
||||
|
||||
|
||||
def test_color_parse():
|
||||
assert Color.parse(0x123456).value == 0x123456
|
||||
assert Color.parse("#123456").value == 0x123456
|
||||
c = Color(0xABCDEF)
|
||||
assert Color.parse(c) is c
|
||||
assert Color.parse(None) is None
|
||||
|
||||
|
||||
def test_embed_color_parsing():
|
||||
e = Embed({"color": "#FF0000"})
|
||||
assert e.color.value == 0xFF0000
|
||||
e = Embed({"color": Color(0x00FF00)})
|
||||
assert e.color.value == 0x00FF00
|
||||
e = Embed({"color": 0x0000FF})
|
||||
assert e.color.value == 0x0000FF
|
||||
|
||||
|
||||
def test_container_accent_color_parsing():
|
||||
container = Container(components=[], accent_color="#010203")
|
||||
assert container.accent_color.value == 0x010203
|
||||
container = Container(components=[], accent_color=Color(0x111111))
|
||||
assert container.accent_color.value == 0x111111
|
||||
container = Container(components=[], accent_color=0x222222)
|
||||
assert container.accent_color.value == 0x222222
|
Loading…
x
Reference in New Issue
Block a user