These are the breaking changes of discord.py version 2.0.
"Breaking change" includes:
- [R]emoval: a feature is removed.
- [N]ame changes: a feature is renamed.
- [B]ehavior: something does not behave the way they did in 1.x.
- [T]yping: types of arguments, attributes or return values changes in an incompatible way. (e.g. None disallowed for argument)
- [S]yntax: a syntax previously allowed for an operation is no longer allowed. (e.g. positional only arguments, new required arguments)
Overview:
- Python 3.8 or newer is required.
- Methods and attributes that returned
TextChannel
, etc can now returnThread
. - Attributes that returned
Asset
are renamed, e.g. attributes ending with_url
(i.e.avatar_url
) are changed toavatar.url
.User.avatar
returnsNone
in case the default avatar is used. on_presence_update
replaceson_member_update
for updates toMember.status
andMember.activities
.- datetime is now timezone-aware.
- Sticker changes:
StickerType
has been renamed toStickerFormatType
, and the type ofMessage.stickers
is changed.Sticker.preview_image
,Sticker.image
andSticker.tags
are removed. - Webhooks are changed significantly:
WebhookAdapter
is removed, and synchronous requests usingrequests
is now insideSyncWebhook
. edit
method no longer updates cache and instead returns modified instance.- User accounts (userbots) are no longer supported.
Client.logout
is removed; useClient.close
instead.on_private_channel_create/delete
events are removed.User.permissions_in
is removed; useabc.GuildChannel.permissions_in
instead.Message.type
for replies are nowMessageType.reply
.Reaction.custom_emoji
property is changed toReaction.is_custom_emoji
method.missing_perms
attributes and arguments are renamed tomissing_permissions
.- Many method arguments now reject
None
. - Many arguments are now specified as positional-only or keyword-only; e.g.
oauth_url
now takes keyword-only arguments, and methods starting withget_
orfetch_
take positional-only arguments.
Changes are ordered by the date it was introduced.
Python 3.8 is now required.
User account ("userbot") is no longer supported. Thus, these features that were only applicable to them are removed:
bot
argument ofClient.start
/run
afk
argument ofClient.change_presence
- Classes:
Profile
,Relationship
,CallMessage
,GroupCall
RelationshipType
,HypeSquadHouse
,PremiumType
,UserContentFilter
,FriendFlags
,Theme
GroupChannel.add_recipients
,remove_recipients
,edit
(NOTE:GroupChannel
itself still remains)Guild.ack
Client.fetch_user_profile
Message.call
andack
ClientUser.email
,premium
,premium_type
,get_relationship
,relationships
,friends
,blocked
,create_group
,edit_settings
ClientUser.edit
'spassword
,new_password
,email
,house
argumentsUser.relationship
,mutual_friends
,is_friend
,is_blocked
,block
,unblock
,remove_friend
,send_friend_request
,profile
- Events:
on_relationship_add
andon_relationship_update
This means that detection of Nitro is no longer possible.
TL;DR: utcnow
becomes now(datetime.timezone.utc)
. If you are constructing datetime
yourself, pass tzinfo=datetime.timezone.utc
.
embed = discord.Embed(
title = "Pi Day 2021 in UTC",
timestamp = datetime(2021, 3, 14, 15, 9, 2, tzinfo=timezone.utc)
)
Note that newly-added discord.utils.utcnow()
can be used as an alias of datetime.datetime.now(datetime.timezone.utc)
.
Deprecated since 1.5.
This method was an alias of Client.close
, which remains.
Embed
that has a value is always considered truthy. Previously it only considered text fields.
Bot.add_cog
now raises when a cog with the same name is already registered. override
argument can be used to bring back the 1.x behavior.
This always returned None
for compatibility.
Due to Discord changes, this cache flag is no longer available. MemberCacheFlags
's online
argument is removed for similar reasons.
Message.type
now returns MessageType.reply
for replies, instead of default
.
These events will no longer be dispatched due to Discord changes.
Command.clean_params
is now a dict
, not OrderedDict
.
DMChannel.recipient
is now optional, and will return None
in many cases.
Use abc.GuildChannel.permissions_for
instead.
permissions_for
method's first argument is now positional only.
guild_subscriptions
argument of Client
is replaced with intents system.
This argument of Client
was an alias of chunk_guilds_at_startup
since 1.5.
Webhook was overhauled.
Webhook
andWebhookMessage
are now always asynchronouns. For synchronouns use (requests
), useSyncWebhook
andSyncWebhookMessage
.WebhookAdapter
,AsyncWebhookAdapter
, andRequestsWebhookAdapter
are removed, since they are unnecessary.adapter
arguments ofWebhook.partial
andWebhook.from_url
are removed. Sessions are now passed directly topartial
/from_url
.
webhook = discord.SyncWebhook.from_url(
f"https://discord.com/api/webhooks/{id}/{token}"
)
webhook.send("Hello from discord.py 2.0")
async with aiohttp.ClientSession() as session:
webhook = discord.Webhook.partial(
id,
token,
session=session
)
await webhook.send("Hello from discord.py 2.0")
This was moved to Context.clean_prefix
.
This was removed as Discord no longer provides the data.
Assets have been changed.
- Asset-related attributes that previously returned hash strings (e.g.
User.avatar
) now returnsAsset
.Asset.key
returns the hash from now on. Class.x_url
andClass.x_url_as
are removed.Asset.replace
orAsset.with_x
methods can be used to get specific asset sizes or types.Emoji.url
andPartialEmoji.url
are nowstr
.Emoji.save
andEmoji.read
are added to save or read emojis.Emoji.url_as
andPartialEmoji.url_as
are removed.- Some
AuditLogDiff
attributes now returnAsset
instead ofstr
:splash
,icon
,avatar
User.avatar
returnsNone
if the avatar is not set and is instead the default avatar; useUser.display_avatar
for pre-2.0 behavior.
avatar_url = user.display_avatar.url # previously str(avatar_url)
avatar_128x128_url = user.display_avatar.with_size(128).url # previously str(avatar_url_as(size=128))
avatar_128x128_png_url = user.display_avatar.replace(size=128, static_format="png").url
# previously str(avatar_url_as(size=128, static_format="png"))
# The code above can also be written as:
avatar_128x128_png_url = user.display_avatar.with_size(128).with_static_format("png").url
avatar_bytes = await user.display_avatar.read() # previously avatar_url.read
# Emoji and Sticker are special case:
emoji_url = emoji.url # previously str(emoji.url)
emoji_32x32_url = emoji.with_size(32).url # previously str(emoji.url_as(size=32))
emoji_32x32_png_url = emoji.replace(size=32, static_format="png").url
# previously str(url_as(size=128, static_format="png"))
emoji_bytes = await emoji.read() # previously emoji.url.read
# Same applies to Sticker and PartialEmoji.
Colour.blurple
is renamed to Colour.og_blurple
, and Colour.blurple
now returns the different color.
Bot
's self_bot
argument was removed, since userbots are no longer supported.
VerificationLevel.table_flip
(alias of high
) was removed. extreme
, very_high
, and double_table_flip
attributes were removed and replaced with highest
.
oauth_url
's permissions
, guild
, redirect_uri
, and scopes
arguments are now keyword only.
Due to the introduction of StageInstance
representing the current session of a StageChannel
,
StageChannel.edit
can no longer edittopic
. UseStageInstance.edit
instead.StageChannel.clone
no longer clones its topic.
Message.channel
can now return Thread
.
Guild.get_channel
, get_role
, get_member_named
, fetch_member
, and fetch_emoji
methods' first arguments are now positional only.
Guild.create_text_channel
's topic
argument no longer accepts None
.
Reaction.custom_emoji
is now a method called Reaction.is_custom_emoji
for consistency.
Arguments of Reaction.users
are now keyword only.
IntegrationAccount.id
is now str
, instead of int
, due to Discord changes.
BadInviteArgument
now requires one argument, argument
.
missing_perms
arguments and attributes of MissingPermissions
and BotMissingPermissions
are renamed to missing_permissions
.
Guild.vanity_invite
can now return None
.
Its first argument is now positional only.
Its first argument is now positional only.
Template.edit
's name
argument no longer accepts None
.
Member.edit
's roles
argument no longer accepts None
.
CommandOnCooldown
now requires an additional argument, type
.
Client.fetch_channel
and Guild.fetch_channel
can now return Thread
.
member_update
event is no longer dispatched for status/activity changes. Use presence_update
instead.
StickerType
, an enum of sticker formats, is renamed to StickerFormatType
. Old name is used for a new enum with different purpose (checking if the sticker is guild sticker or Nitro sticker).
Message.stickers
is now List[StickerItem]
instead of List[Sticker]
. While StickerItem
supports some operations of previous Sticker
, description
and pack_id
attributes do not exist. Sticker
can be fetched via StickerItem.fetch
method.
Sticker.image
is removed. Sticker
can still be fetched via Sticker.read
or Sticker.save
and its URL can be accessed via Sticker.url
, just like new Emoji
.
Due to the introduction of GuildSticker
, Sticker.tags
is removed from the parent class Sticker
and moved to StandardSticker.tags
.
AuditLogDiff.type
is now Union[ChannelType, StickerType]
, instead of ChannelType
.
ChannelNotReadable.argument
can now return Thread
.
NSFWChannelRequired.channel
can now return Thread
.
Bot.add_listener
and Bot.remove_listener
's name
arguments no longer accept None
.
The following Context
attributes can now be None
: prefix
, command
, invoked_with
, invoked_subcommand
. Note that while the documentation change suggests potentially breaking change, the code indicates that this was always the case.
Command.help
can now be None
.
Client.get_channel
can now return Thread
.
Client.get_guild
, get_user
, and get_emoji
methods' first arguments are now positional only.
edit
methods of most classes no longer update the cache in-place, and instead returns the modified object.
on_socket_raw_receive
is no longer dispatched for incomplete data, and the value passed is always decompressed and decoded to str
. Previously, when received a multi-part zlib-compressed binary message, on_socket_raw_receive
was dispatched on all messages with the compressed, encoded bytes
.
Guild.get_member
method's first argument is now positional only.
Yoooooooooo