Skip to content

Commit 93c7ef8

Browse files
authored
fix: actually fix weird behavior with msgs and embeds (#854)
* fix: actually fix weird behavior with msgs and embeds * feat: polish up deepcopy variable * refactor: move deepcopying to embeds * docs: add notes about deepcopy variable
1 parent a83ddf4 commit 93c7ef8

File tree

3 files changed

+35
-14
lines changed

3 files changed

+35
-14
lines changed

interactions/api/models/attrs_utils.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from copy import deepcopy
12
from functools import wraps
23
from typing import Dict, Mapping, Optional, Tuple
34

@@ -18,9 +19,16 @@ class DictSerializerMixin:
1819
_extras: dict = attrs.field(init=False, repr=False)
1920
"""A dict containing values that were not serialized from Discord."""
2021

22+
__deepcopy__ = False
23+
"""Should the kwargs be deepcopied or not?"""
24+
2125
def __init__(self, kwargs_dict: dict = None, /, **other_kwargs):
2226
kwargs = kwargs_dict or other_kwargs
2327
client = kwargs.pop("_client", None)
28+
29+
if self.__deepcopy__:
30+
kwargs = deepcopy(kwargs)
31+
2432
self._json = kwargs.copy()
2533
passed_kwargs = {}
2634

@@ -169,6 +177,23 @@ def inner_convert_object(value):
169177
return inner_convert_object
170178

171179

180+
def deepcopy_kwargs(cls: Optional[type] = None):
181+
"""
182+
A decorator to make the DictSerializerMixin deepcopy the kwargs before processing them.
183+
This can help avoid weird bugs with some objects, though will error out in others.
184+
"""
185+
186+
def decorator(cls: type):
187+
cls.__deepcopy__ = True # type: ignore
188+
return cls
189+
190+
if cls is not None:
191+
cls.__deepcopy__ = True # type: ignore
192+
return cls
193+
194+
return decorator
195+
196+
172197
define_defaults = dict(kw_only=True, eq=False, init=False, on_setattr=attrs.setters.NO_OP)
173198

174199

interactions/api/models/attrs_utils.pyi

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ class DictSerializerMixin:
1818
_json: dict = attrs.field(init=False)
1919
_extras: dict = attrs.field(init=False)
2020
"""A dict containing values that were not serialized from Discord."""
21+
__deepcopy__: bool = attrs.field(init=False)
22+
"""Should the kwargs be deepcopied or not?"""
2123
def __init__(self, kwargs_dict: dict = None, /, **other_kwargs): ...
2224

2325
@attrs.define(eq=False, init=False, on_setattr=attrs.setters.NO_OP)
@@ -63,3 +65,9 @@ def convert_dict(
6365
value_converter: Optional[Callable[[Any], _P]] = None,
6466
) -> Callable[[Dict[Any, Any]], Dict[_T, _P]]:
6567
"""A helper function to convert the keys and values of a dictionary with the specified converters"""
68+
69+
def deepcopy_kwargs(cls: Optional[Type[_T]] = None) -> Callable[[Any], _T]:
70+
"""
71+
A decorator to make the DictSerializerMixin deepcopy the kwargs before processing them.
72+
This can help avoid weird bugs with some objects, though will error out in others.
73+
"""

interactions/api/models/message.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
DictSerializerMixin,
1212
convert_list,
1313
convert_type,
14+
deepcopy_kwargs,
1415
define,
1516
field,
1617
)
@@ -457,6 +458,7 @@ def __setattr__(self, key, value) -> None:
457458

458459

459460
@define()
461+
@deepcopy_kwargs()
460462
class Embed(DictSerializerMixin):
461463
"""
462464
A class object representing an embed.
@@ -877,20 +879,6 @@ class Message(ClientSerializerMixin):
877879
converter=convert_list(Sticker), default=None
878880
) # deprecated
879881

880-
def __attrs_post_init__(self):
881-
if self.embeds:
882-
# note from astrea49: this dumb fix is necessary to make sure the _json
883-
# is correct when using a dict for the embeds when initializing
884-
# otherwise, attributes like the footer will be missing or incorrect
885-
# i have no idea why this is necessary and i've have tried debugging for hours
886-
# to find why it's necessary, but i've came up with nothing
887-
# by all means, the converters and json should be correct, but it isn't
888-
# this also happens nowhere else as far as i can tell
889-
890-
# this line should NOT be touched unless you somehow find a solution to
891-
# this, or end up modifying how _json works altogether
892-
self._json["embeds"] = [e._json for e in self.embeds]
893-
894882
async def get_channel(self) -> Channel:
895883
"""
896884
Gets the channel where the message was sent.

0 commit comments

Comments
 (0)