I am trying to program a discord bot that links to google sheets but have been encountering countless errors with my code. The error I get is as followed:
Traceback (most recent call last):
File "/home/runner/Bundeswehr-Bot/venv/lib/python3.8/site-packages/discord/ui/modal.py", line 186, in _scheduled_task
await self.on_submit(interaction)
File "/home/runner/Bundeswehr-Bot/modals.py", line 45, in on_submit
if sheet.find(self.host.value) == None:
File "/home/runner/Bundeswehr-Bot/venv/lib/python3.8/site-packages/gspread/cell.py", line 44, in __eq__
same_row = self.row == other.row
AttributeError: 'NoneType' object has no attribute 'row'
And my code is:
class bct_modal(discord.ui.Modal, title="BCT Logging"):
host = discord.ui.TextInput(
label='Host ID',
placeholder='The hosts discord ID here...',
required=True
)
async def on_submit(self, interaction: discord.Interaction):
ids = []
ids.append(self.host.value)
print(ids)
if sheet.find(self.host.value) == None:
sheet.append_row([self.host.value, 0, 0, 0, 0, 0, 0, 0, 0])
for id in ids:
bct_host_col = sheet.find("Hosted BCT").col
cell_row = sheet.find(id).row
sheet.update_cell(cell_row, bct_host_col, int(sheet.cell(cell_row, bct_host_col).value) + 1)
elif sheet.find(self.host.value) != None:
print("This ID is already in the sheet.")
Any help would be greatly appreciated.
NOTE: When I input an ID that isn't yet in the google spreadsheet, it appends it perfectly and just the way I want it, but if I try enter an ID that's already in the spreadsheet, it throws me this error.
In your script, I thought that if sheet.find(self.host.value) == None:
might be required to be modified. So, ==
is is
. I thought that this might be the reason for your issue of 'NoneType' object has no attribute 'row'
.
I thought that in this case, this thread might be useful.
So, how about the following modification?
if sheet.find(self.host.value) == None:
if sheet.find(self.host.value) is None:
The reason this is important in this case is that Python translates x == y
to x.__eq__(y)
if an __eq__
method exists for x
's class, and the gspread Cell
class implements a custom __eq__
method that attempts unguarded attribute access on the other
object (other.row
), which can have unexpected results if other
is not a Cell
(in this case, it throws an error, but passing in another class that does have a row
attribute might behave differently).
While this is very bad practice on the part of the gspread developers, it is avoided if you use is
as a rule for comparisons against None
.