Reputation:
I want to delete the Guild ID in a JSON file with an Command.
This is my code:
@welcome.command(pass_context=True)
@commands.has_permissions(administrator=True)
async def reset(guild):
with open('welcome.json', 'r') as f:
welcome = json.load(f)
welcome.pop(str(guild.id))
with open('welcome.json', 'w',) as f:
json.dump(welcomereset, f, indent=4)
This is the Error Message: discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'Context' object has no attribute 'id'
How can i fix this?
Upvotes: 1
Views: 1340
Reputation: 26
@welcome.command() #pass_context is deprecated, every command will always get passes Context as first param.
@commands.has_permissions(administrator=True)
async def reset(ctx: commands.Context): #Just normal typehint for you to easily understand.
with open('welcome.json', 'r') as f:
welcome = json.load(f)
welcome.pop(str(ctx.guild.id)) #ctx.guild -> discord.Guild and than .id for it's id. I would put an if statement to check if the command was even in a guild, so NoneType attribute error won't raise.
with open('welcome.json', 'w',) as f:
json.dump(welcomereset, f, indent=4)
The first parameter in each command is ctx or context the represents discord.ext.commands.Context object, which as you can see, doesn't have id. If you are trying to get the guild id of where the command was invoked, doing ctx.guild will return Optional[discord.Guild](if command was invoked in a private channel). And than if it is not None, you can do ctx.guild.id, which is probably what you want. And you no longer need pass_context(which was used to pass discord.ext.commands.Context btw). Which means the right now, guild is your Context object.
Upvotes: 1
Reputation: 1
Since you didn't mentioned your discord.py version, I assume:
- It's before version 1.0:
You have pass_context=True
, so Context will be passed as the first argument in the function.
async def reset(guild): # The word 'guild' is actually a Context object
The name guild
is defined as Context so regardless of the name, it follows the properties of Context and not a Guild. Therefore you can still use guild
and follow properties of Context but it's recommended to edit guild
to context
or ctx
to prevent confusion.
You can also just do pass_context=False
and make the guild
argument to be accepted as an input via the user.
- It's after version 1.0:
The pass_context
parameter is removed since then, so regardless if you use this or not, Context is always passed.
As above, you need to follow the properties of Context and use proper attributes. In your case, if you need to access id of the guild the command is invoked, you can do ctx.guild.id
(ctx
refers to Context object passed).
async def reset(ctx):
...
welcome.pop(str(ctx.guild.id))
...
and this will work fine.
P.S.: I'm not sure but by looking at the code, I think you have passed wrong argument (welcomereset
) in the .dump()
and want to pass welcome
instead. Ignore this if I'm wrong :P
Upvotes: 0
Reputation: 26
The first parameter in each command is ctx
or context
the represents discord.ext.commands.Context object, which as you can see, doesn't have id
. If you are trying to get the guild id of where the command was invoked, doing ctx.guild
will return Optional[discord.Guild](if command was invoked in a private channel). And than if it is not None, you can do ctx.guild.id, which is probably what you want. And you no longer need pass_context
(which was used to pass discord.ext.commands.Context btw)
Upvotes: 0