Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

Breaking Changes of discord.py 2.0

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 return Thread.
  • Attributes that returned Asset are renamed, e.g. attributes ending with _url (i.e. avatar_url) are changed to avatar.url. User.avatar returns None in case the default avatar is used.
  • on_presence_update replaces on_member_update for updates to Member.status and Member.activities.
  • datetime is now timezone-aware.
  • Sticker changes: StickerType has been renamed to StickerFormatType, and the type of Message.stickers is changed. Sticker.preview_image, Sticker.image and Sticker.tags are removed.
  • Webhooks are changed significantly: WebhookAdapter is removed, and synchronous requests using requests is now inside SyncWebhook.
  • edit method no longer updates cache and instead returns modified instance.
  • User accounts (userbots) are no longer supported.
  • Client.logout is removed; use Client.close instead.
  • on_private_channel_create/delete events are removed.
  • User.permissions_in is removed; use abc.GuildChannel.permissions_in instead.
  • Message.type for replies are now MessageType.reply.
  • Reaction.custom_emoji property is changed to Reaction.is_custom_emoji method.
  • missing_perms attributes and arguments are renamed to missing_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 with get_ or fetch_ take positional-only arguments.

Changes are ordered by the date it was introduced.

[B] Minimum Python version bumped

Python 3.8 is now required.

[R] User account support

User account ("userbot") is no longer supported. Thus, these features that were only applicable to them are removed:

  • bot argument of Client.start/run
  • afk argument of Client.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 and ack
  • ClientUser.email, premium, premium_type, get_relationship, relationships, friends, blocked, create_group, edit_settings
  • ClientUser.edit's password, new_password, email, house arguments
  • User.relationship, mutual_friends, is_friend, is_blocked, block, unblock, remove_friend, send_friend_request, profile
  • Events: on_relationship_add and on_relationship_update

This means that detection of Nitro is no longer possible.

[B] Use of timezone-aware time

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).

[R] Client.request_offline_members

Deprecated since 1.5.

[R] Client.logout

This method was an alias of Client.close, which remains.

[B] Embed.__bool__ change

Embed that has a value is always considered truthy. Previously it only considered text fields.

[B] Duplicate registration of cogs

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.

[R] ExtensionNotFound.original

This always returned None for compatibility.

[R] MemberCacheFlags.online

Due to Discord changes, this cache flag is no longer available. MemberCacheFlags's online argument is removed for similar reasons.

[B] Message.type for replies

Message.type now returns MessageType.reply for replies, instead of default.

[R] on_private_channel_create/delete

These events will no longer be dispatched due to Discord changes.

[T] Command.clean_params

Command.clean_params is now a dict, not OrderedDict.

[T] DMChannel.recipient

DMChannel.recipient is now optional, and will return None in many cases.

[R] User.permissions_in, Member.permissions_in

Use abc.GuildChannel.permissions_for instead.

[S] permissions_for positional only argument

permissions_for method's first argument is now positional only.

[R] guild_subscriptions argument

guild_subscriptions argument of Client is replaced with intents system.

[R] fetch_offline_members argument

This argument of Client was an alias of chunk_guilds_at_startup since 1.5.

[RNB] Webhook changes

Webhook was overhauled.

  • Webhook and WebhookMessage are now always asynchronouns. For synchronouns use (requests), use SyncWebhook and SyncWebhookMessage.
  • WebhookAdapter, AsyncWebhookAdapter, and RequestsWebhookAdapter are removed, since they are unnecessary.
  • adapter arguments of Webhook.partial and Webhook.from_url are removed. Sessions are now passed directly to partial/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")

[R] HelpCommand.clean_prefix

This was moved to Context.clean_prefix.

[R] Sticker.preview_image

This was removed as Discord no longer provides the data.

[RT] Asset changes

Assets have been changed.

  • Asset-related attributes that previously returned hash strings (e.g. User.avatar) now returns Asset. Asset.key returns the hash from now on.
  • Class.x_url and Class.x_url_as are removed. Asset.replace or Asset.with_x methods can be used to get specific asset sizes or types.
  • Emoji.url and PartialEmoji.url are now str. Emoji.save and Emoji.read are added to save or read emojis.
  • Emoji.url_as and PartialEmoji.url_as are removed.
  • Some AuditLogDiff attributes now return Asset instead of str: splash, icon, avatar
  • User.avatar returns None if the avatar is not set and is instead the default avatar; use User.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.

[N] Colour.blurple

Colour.blurple is renamed to Colour.og_blurple, and Colour.blurple now returns the different color.

[R] self_bot argument

Bot's self_bot argument was removed, since userbots are no longer supported.

[R] VerificationLevel attributes

VerificationLevel.table_flip (alias of high) was removed. extreme, very_high, and double_table_flip attributes were removed and replaced with highest.

[S] oauth_url taking keyword only arguments

oauth_url's permissions, guild, redirect_uri, and scopes arguments are now keyword only.

[B] StageChannel changes

Due to the introduction of StageInstance representing the current session of a StageChannel,

  • StageChannel.edit can no longer edit topic. Use StageInstance.edit instead.
  • StageChannel.clone no longer clones its topic.

[T] Message.channel

Message.channel can now return Thread.

[S] Guild methods taking positional only arguments

Guild.get_channel, get_role, get_member_named, fetch_member, and fetch_emoji methods' first arguments are now positional only.

[T] Guild.create_text_channel topic argument

Guild.create_text_channel's topic argument no longer accepts None.

[RT] Reaction.custom_emoji

Reaction.custom_emoji is now a method called Reaction.is_custom_emoji for consistency.

[S] Reaction.users arguments keyword only

Arguments of Reaction.users are now keyword only.

[T] IntegrationAccount.id

IntegrationAccount.id is now str, instead of int, due to Discord changes.

[S] BadInviteArgument new required argument

BadInviteArgument now requires one argument, argument.

[N] missing_perms

missing_perms arguments and attributes of MissingPermissions and BotMissingPermissions are renamed to missing_permissions.

[T] Guild.vanity_invite

Guild.vanity_invite can now return None.

[S] abc.Messageable.fetch_message positional only

Its first argument is now positional only.

[S] get_partial_message positional only

Its first argument is now positional only.

[T] Template.edit name argument

Template.edit's name argument no longer accepts None.

[T] Member.edit roles argument

Member.edit's roles argument no longer accepts None.

[S] CommandOnCooldown new required argument

CommandOnCooldown now requires an additional argument, type.

[T] fetch_channel

Client.fetch_channel and Guild.fetch_channel can now return Thread.

[B] on_member_update and on_presence_update separation

member_update event is no longer dispatched for status/activity changes. Use presence_update instead.

[R] StickerType

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).

[T] Message.stickers

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.

[R] Sticker.image

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.

[R] Sticker.tags

Due to the introduction of GuildSticker, Sticker.tags is removed from the parent class Sticker and moved to StandardSticker.tags.

[T] AuditLogDiff.type

AuditLogDiff.type is now Union[ChannelType, StickerType], instead of ChannelType.

[T] ChannelNotReadable.argument

ChannelNotReadable.argument can now return Thread.

[T] NSFWChannelRequired.channel

NSFWChannelRequired.channel can now return Thread.

[T] Bot.add_listener and Bot.remove_listener

Bot.add_listener and Bot.remove_listener's name arguments no longer accept None.

[T] Context attributes

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.

[T] Command.help

Command.help can now be None.

[T] Client.get_channel

Client.get_channel can now return Thread.

[S] Client methods taking positional only arguments

Client.get_guild, get_user, and get_emoji methods' first arguments are now positional only.

[B] edit method behavior

edit methods of most classes no longer update the cache in-place, and instead returns the modified object.

[B] on_socket_raw_receive behavior

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.

[S] Guild.get_member taking positional only argument

Guild.get_member method's first argument is now positional only.

@MrArkon
Copy link

MrArkon commented Jul 29, 2021

Thanks for this

@Div-100
Copy link

Div-100 commented Aug 1, 2021

Thanks @apple502j <3

@aheze
Copy link

aheze commented Aug 6, 2021

Thanks!

@AzaanRais
Copy link

AzaanRais commented Sep 1, 2021

yoo thanks this is poggg!!

@Neilisop
Copy link

Neilisop commented Sep 1, 2021

Thanks!

@itsflorent
Copy link

itsflorent commented Sep 1, 2021

Thanks, great job!

@TierGamerpy
Copy link

TierGamerpy commented Sep 2, 2021

Thanks

@nav-github01001
Copy link

nav-github01001 commented Sep 2, 2021

noice

@DevInfinix
Copy link

DevInfinix commented Sep 2, 2021

Thank you :D

@VetlixDev
Copy link

VetlixDev commented Sep 2, 2021

Pog! Thanks for the update!

@TheWever
Copy link

TheWever commented Sep 2, 2021

Why did user.Profile got removed?

@JelNiSlaw
Copy link

JelNiSlaw commented Sep 3, 2021

Why did user.Profile got removed?

Bots can't see user profiles

@Zukunftsmusik
Copy link

Zukunftsmusik commented Oct 4, 2021

Great! I especially like the removal of user bots. No idea why this was still a thing :D

@BruceCodesGithub
Copy link

BruceCodesGithub commented Oct 8, 2021

Yoooooooooo

@MarzaElise
Copy link

MarzaElise commented Oct 22, 2021

Yoooooooooo

no

@AlexisBG06
Copy link

AlexisBG06 commented Nov 14, 2021

is_avatar_animated() got removed!
it's not in the list^^

@leestarb
Copy link

leestarb commented Dec 14, 2021

Role.is_assignable is a cool thing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment