#dev-contrib
1 messages Β· Page 24 of 1
snekbox allows to ls, users are expected to define a custom layer to add their executables somewhere, users are expected to have their snekbox API clients know where that's going to be
I think we either have an ls API, or we have a ListExecutables API which is basically like ls but hard-coded to look in a specific directory.
i like ls or just /glob or something
that way users can load executables into anywhere they want
I'm open to the idea. My initial feeling is that exposing ls as an API feels really weird.
Then again we are effectivly exposing exec as an API already so might not be much of a stretch
It's just that ls feels very broad
Like, I don't see a use case where someone would want to ls a directory that isn't the one containing their executables
But we would allow that anyway for the sake of not hard-coding an executable dir.
I don't think we need to expose the binary
I'd just take a glob in and return everything that matches the glob with +x set
Wait wait wait
We already allow executing arbitrary binaries
And ls should be in the image already
So... isn't this already possible?
Ah no it's not cause it runs in a jail
Sure but even that feels broad - the fact that any path can be searched
Anyway I'm not totally against the idea
It may make more sense in the context of a larger reorganisation of snekbox i.e. splitting it into the three components I mentioned above
yeah
I particularly dislike the coupling of our specific versions and libraries and snekbox itself
and do agree with reorganising
I'd prioritise that, splitting the execution and http API is an easier task
I wonder if we limit it to PATH + a custom directory for any extras that's better?
like PATH + /executables/
At that point why not restrict the prefix instead? I don't think it's unreasonably restrictive to require executable to be under /snekbin/ if you want them to be discoverable by the API.
And with such name it's unlikely to conflict with anything else they might put in the image
ya true
What I like about that is the caller of the API doesn't need to know what the path is.
yeah
true
okay so we make /snekbin/ or whatever exposed over the API, return everything with +x in there and people don't need to worry about paths.
do we still allow for arbitrary paths to be passed in and executed?
do we still allow for arbitrary paths to be passed in and executed?
Good question. Multiple facets to this:
-
Do consumers directly expose the API endpoint / with a thin wrapper/proxy? Or do they have a more sophisticated wrapper like our bot? In the former, I can see how restricting the path would be useful, since that is effectively end-user input. In the latter, it's not as useful since the path is either not controlled by end-users, or can be validated/filtered before reaching snekbox.
-
If a consumer exposes a binary that can execute arbitrary code (namely, the
execsyscall and its friends), then such restriction would be moot. That is indeed the case for our use case.
That said I do see how it's a bit confusing to only expose binaries in a certain directory, but still allow any path to be executed.
re: 2, is it moot? we don't mount additional binaries so the risk of exec(3) into a different executable is mitigated right?
ahh true
Anyway if you can execute arbitrary code like with Python, you can effectivelly implement whatever binary you'd want to execute anyway?
true lol
i suppose we don't overcomplicate it, stick to one directory & expose that, and if we get a surprise feature request from the White House in 4 years because they want to run /usr/bin/fortune then we add a flag for allowing arbitrary paths
Well currently we allow arbitrary paths, so changing the default behaviour would be a breaking change.
Though I don't know how many other users of snekbox we have
Especially cause we don't really have proper versioning
oh yeah so we do
I thought we constrained to /snekbin/ already
hmmmm
i'd change it to a flag then and it's still breaking but purposefully is just an opt-in
we do need to consider how we pass in all those env vars for python that we currently have in the nsjail config
Yeah...
we can obv easily dynamically add those like we dynamically amend the nsjail config already
but just need to decide where they come from
it's getting towards config file but i'm not sure if that's clean or something we want
config file to specify those env vars as well as other tweakable attributes doesn't seem a terrible idea
What makes this tricky is that there are some things in the config that someone would likely never want or need to touch, but other things that they would almost certainly need to change
like our limits on threads and whatnot is again something we shouldn't build into the image
yeah
i think it's reasonable to expose the simple things like max threads, max memory, additional mount dirs & env vars
everything else seems like it'd be heading towards compromising the integrity of the sandboxing
Ehh well I don't want to have to maintain our own config system and translate it to nsjail. Not that it's super difficult, but it just adds complexity
It might be sufficient to provide a template and have folks copy it to customise things
hmmm yeah
And we can move some things out of the config and into command-line nsjail args
just annotate the heck out of things where removing them will compromise it
yea
true
We already have some hard-coded nsjail args which override the config. But currently we only do that out of necessity, since some config values are dynamic
yea
I suppose first steps here is open an issue and figure what the line is and what goes on the downstream user side
i am glad to say goodbye to the init container to install deps lol
"customer experience" as they call it in the business
We do need to flesh out a design
Hi, @patent pivot and @tawdry vapor
Nice to meet you all
if you have some problem, let me know
i wanna friend π
How do I run the bot locally to test?
the contributing guides should cover it with docker
?
Open the likely spammer thing and see the images
there aren't any messages there
wdym?
probably got picked up and banned
I see images
reload your discord?
finally got it running locally. my computer is kinda bad btw
It's so laggy
Where do you guys host the bot?
we host with Linode
Akamai is the parent right?
they are but we've been using them since before akamai took over
@patent pivot What is this link in the issue https://sentry.io/organizations/python-discord/issues/?query=BOT-commands ?? It is asking me to sign in.
which issue are you seeing thay
Sentry is our error tracker so only core team members can log in
Issue #3376 You provided a link when I click # bot-commands
ahhh
the link is for core devs but the issue should have all the relevant details
that's a mistake
oh
our sentry tickets are in the format BOT-ABC123
but it's seen bot-commands and assumed that's a sentry ticket
so has tried to add a link to sentry
don't worry about the link, it's a mistake that GitHub added thay
that*
oh, ok It was asking me to login via github and I don't want to login to random websites
the website is safe it'll just reject you lol
Just making sure
I found lookatmybeard.com in test_snekbox.py line 352. What is it and what does it do?
Probably just made up test data
I can't seem to find a connection between the redirects and snekbox commands.
I found the connection between redirects and non-snekbox commands
look at the redirect decorator on the !eval command
Big Brother
!bigbrother
Monitors users by relaying their messages to the Big Brother watch channel.
!bigbrother unwatch <user> <reason>
Stop relaying messages by the given user.
!bigbrother watch <user> <reason>
Relay messages sent by the given user to the #big-brother channel.
Bot
!echo [channel] <text>
Repeat the given message in either a specified channel or the current channel.
!embed [channel] <text>
Send the input within an embed to either a specified channel or the current channel.
BotSource
!source [source_item]
Display information and a GitHub link to the source code of a command, tag, or cog.
Branding
!branding
Control the branding cog.
!src echo
Repeat the given message in either a specified channel or the current channel.
as an example
I mean in the code
Yah, use the !src command to get a link to that command in the code
@patent pivot , I just finished the !eval function to send the original message with the output here is an example:
@toxic wren, here's the output of your command:
Command:
!eval
print("hello")
Output:
β
Your 3.13 eval job has completed with return code 0.
hello
the issue I specified suggests we put the original message on the paste service
have a look at https://bot-core.pythondiscord.com/main/output/pydis_core.utils.paste_service.html#pydis_core.utils.paste_service.send_to_paste_service and other uses of send_to_paste_service from the code
Will do, I just need to specify the link right?
yeah you just need to take the original message content, create a PasteFile based on that and use that method
Ok π
I see that the !eval function has a way of splitting the code from the command, How do I do the same thing here?
I wouldn't do that -- just make this a generic change to that decorator
paste the code verbatim with markdown formatting and the rest should be handled by the pastebin
literally just needs to be the original message content
with the command because when I do ctx.message.content returns evrything inclusding the command should I remove that?
no, include with the command so people can just copy paste straight out of the paste
but as mentioned use markdown/md formatting instead of python/py
so the lexer arg should be md?
yea
ok
maybe markdown i'm not sure exactly whether it wants the extension or lexer name
ill try both and see what works
looks like markdown looking at how the web UI does it
Thanksπ
btw Im adding a fallback for when The pastebin fails it sends the code in the message directly
@patent pivot I just got everything working, Ill commit and open a PR and ref the issue. Sound good?
honestly just raise an error -- you're going to have more problems from long code blocks and long responess going over the character limit
Should I log it or just return the code and say error with the pastebin?
raise a warning log and return the current response we have with no link
ok will do and commit
What is the difference between log.trace and log.info ?
and which should I use?
trace is for development
info is the base level shown in production
if you're talking about the log for the paste service being down, use log.warning
Will do shortly π
Take your time
hang on I'm confused why you've done it here
updating the decorator would've been the clean way that then works for all redirected commands
the decorator code is linked in the original issue
I thought I was only doing the !eval
bot%2Fdecorators.py line 112
def redirect_output(```
the bot#3376 issue I wrote I left generic to cover commands including !eval
yeah, its not your fault my english is kinda bad so I thought it was for !eval
Ill make the changes
This needs updating https://github.com/python-discord/bot/blob/main/bot%2Fdecorators.py#L158 basically to include a markdown link
bot%2Fdecorators.py line 158
await ctx.send(f"Here's the output of your command, {ctx.author.mention}")```
you can do [your command]({paste_response.link}) or whatever and it'll embed a link
and an else claude will be needed to carry the context for when we don't ping the user
Ok
claude?
else clause*
oh I thought you were talking about the model
yeah I'm too claude-addicted
I don't really have any paid subscriptions for any of the Ai stuff
The redirect output dec is:
@redirect_output(
destination_channel=Channels.bot_commands,
bypass_roles=SNEKBOX_ROLES,
categories=NO_SNEKBOX_CATEGORIES,
channels=NO_SNEKBOX_CHANNELS,
ping_user=False
)
ping_user=False
but the user gets pinged when redirected
for the eval command btw
uhhhh
bot/exts/utils/snekbox/_cog.py line 596
@redirect_output(```
no the eval command pings with the response, I suggest you remove that ping from inside eval and enable the ping user (by just removing that argument from the decorator so the default is used)
it isn't the decorator pinging
it only pings when in non-snekbox channels, it does not ping when you do in snekbox channels
yeah, but we should just have it reply in snekbox channels, and not do anything in non-snekbox then enable ping_user
so, this is what I make from what you said:
- In non-snekbox channels it should not ping and just give the message
- It should not say anything in non-snekbox channels and just ping in #bot-commands
I'm on mobile right now so can't validate everything 100%
it might not need changing at all
but we do need to have the redirect decorator send a message because that's where the paste link will be created
So the message should be like:Hey, @Dragon, you can find the output of your command here: β #bot-commands
it already does that right?
either way it's probably out of scope for this issue
these things don't need changing
This is still my question why does it ping when ping is set to false?
basically all this needs to be (in pseudocode) is:
content = original_message.content
paste_link = send_to_paste_service(...)
if ping_user:
await ctx.send(f"Hey @user! Your output from [your command]({paste_link})")
else:
await ctx.send(f"The output from [your command]({paste_link})")
that's very rough but that's literally all that this needs
the new else clause and the pasting of the code
because snekbox !eval itself does a ping
so we disabled the redirect doing the ping
it does not ping when in snekbox channels though
bot%2Fexts%2Futils%2Fsnekbox%2F_cog.py line 441
if ctx.message.channel == ctx.channel:```
in theory you don't need to touch that file at all though
it literally just needs this in the decorator
The reason I am asking this is because the !eval command overrides what the decorators commands says and says something else so I need to change commands that do this like eval and timeit
where do they override decorator behaviour?
I don't know what you mean by that
the pinging and handling should remain as is and you really shouldn't need to touch _cog.py in snekbox
as far as I can tell it really should just be this -- the new else clause will be handled when ping_user is disabled (as it is with snekbox)
https://github.com/python-discord/bot/blob/main/bot%2Fdecorators.py#L158
says, Here is the output of your command @mention but when eval does this it says β
Your 3.13 eval job has completed with return code 0.
bot%2Fdecorators.py line 158
await ctx.send(f"Here's the output of your command, {ctx.author.mention}")```
so it essentially overrides what the decrators says
yes but that's only when ping user is true
oh so it does not override, but then why does it ping me?
because that's done inside the !eval command
ping_user is in case there's a chance a command would be redirected and the command wouldn't ping the user to show that it's been redirected
!src eval
Run Python code and get the results.
but we know for snekbox it will always be pinged
trust me this will do it π
and you just need that additional else clause which can be a non-pinging version for snekbox
Ok
pinging: f"Here's the output of [your command]({paste_link}), {ctx.author.mention}"
non-pinging: f"Here's the output of [your command]({paste_link})"
and that's what you need in your if-else
For the paste service the arg http_session I am passing in self.bot.http_session, which worked in /-cog.py but does not in decorators. What should I pass in
I think you can probably safely just create your own client session with a context manager
I can't remember if we decided there were or weren't risks of doing that
It worked in the _cog.py beautifully but now i get a AttributeError: 'CustomHelpCommand' object has no attribute 'bot'
yeah there's no access to the bot object there
create a new client session
look elsewhere in the code for aiohttp.ClientSession
ok
from aiohttp import ClientSession
async with ClientSession() as session:
# pass "session" in here to paste method
# do rest of processing
something like that
but obviously in the method
and only the actual pasting inside that with block so that the session closes afterwards
You don't need to pass in the Base URL or import the baseurls, it has a default
commiting he change
also because it's probably going to annoy me (I know it's nitpicky) can you add colons to the end of both the message lines?
after Here's ?
or the tottal end
after the end of the line
pinging: f"Here's the output of [your command]({paste_link}), {ctx.author.mention}:"
non-pinging: f"Here's the output of [your command]({paste_link}):"
@patent pivot Updated
@toxic wren are you able to add this behaviour? fine if not I don't mind coming in afterwards and adding it
ill add an try exept statement gimme a few minutes
yeah, then just needs a bit of nice conditional logic to handle the message in the following situations:
- ping, with link
- no ping, with link
- ping, no link
- no ping, no link
so instead of the if/else it might be best to build a message gradually
msg = ""
if ping_user:
msg += f"{ctx.author.mention}, "
msg += "Here's the output of "
if paste_link:
msg += f"[your command]({paste_link}):"
else:
msg += "your command:"
same place you import send_to_paste_service from
from pydis_core.utils.paste_service import PasteUploadError, send_to_paste_service
except PasteUploadError:
log.warning("Pastebin Upload Error")
this is the except statement.
I'd update to use log.exception
captures the exception info
also I'd do a bit more of a descriptive line
"Failed to upload original command to paste service when redirecting output"
Example?
maybe throw the original message ID in as well
is it ctx.message_id or something?
log.exception("Failed to upload message %d in channel %d to paste service when redirecting output", ctx.message.channel.id, ctx.message.id)
I think that should do it without being messed by the redirection
wdym?
definitely test it though, you can just set the base URL to something random like https://notreal.pythondiscord.com
ok
Doing something like this.
try:
paste_link = None
async with ClientSession() as session:
paste_response = await send_to_paste_service(
files=[PasteFile(content=ctx.message.content, lexer="markdown")],
http_session=session,
)
paste_link = paste_response.link
msg="Here's the output of [your command]({paste_link}),"
if ping_user:
await ctx.send(f"{msg} {ctx.author.mention}:")
else:
await ctx.send(f"{msg}:")
scheduling.create_task(func(self, ctx, *args, **kwargs))
except PasteUploadError:
log.exception("Failed to upload message %d in channel %d to paste service when redirecting output", ctx.message.channel.id, ctx.message.id)
your try except is too big there
the only line that can raise PasteUploadError is the send_to_paste_service, so it's not worth putting everything inside it
paste_link = None
async with ClientSession() as session:
try:
paste_link = ...
except ...:
log.exception(...)
# put my block from above here
await ctx.send(msg)
it'll end up looking way cleaner
your proposal there still doesn't send when it can't get a paste link which we want it to do
yeah just fixed it, looks like this now:
try:
paste_link = None
async with ClientSession() as session:
paste_response = await send_to_paste_service(
files=[PasteFile(content=ctx.message.content, lexer="markdown")],
http_session=session,
)
paste_link = paste_response.link
except PasteUploadError:
log.exception("Failed to upload message %d in channel %d to paste service when redirecting output", ctx.message.channel.id, ctx.message.id)
if ping_user:
await ctx.send(f"Here's the output of [your command]({paste_link}), {ctx.author.mention}:")
else:
await ctx.send(f"Here's the output of [your command]({paste_link}):")
scheduling.create_task(func(self, ctx, *args, **kwargs))
that still won't do it
I didn''t add the blocks yet
the try except needs to be inside the async with
the try except needs to literally have 1 line inside it
The try has this:
paste_response = await send_to_paste_service(files=[PasteFile(content=ctx.message.content,lexer="markdown")],http_session=session,)
paste_link = paste_response.link
paste_link = None
async with ClientSession() as session:
try:
paste_response = await send_to_paste_service(...)
paste_link = paste_response.link
except ...:
log.exception(...)
msg = ""
if ping_user:
msg += f"{ctx.author.mention}, "
msg += "Here's the output of "
if paste_link:
msg += f"[your command]({paste_link}):"
else:
msg += "your command:"
await ctx.send(msg)
this will do it
exactly that with no changes
you'll need to fill in the exception and the arguments to send_to_paste_service
but don't add any more into the try except or move around where paste_link is defined
you've also got some lifting failures for your last commits so you'll need to check those
but using the structure I sent above might fix some of them
I have 6 lint errors in the decorator file. Fixing βοΈ
This line is too long log.exception("Failed to upload message %d in channel %d to paste service when redirecting output", ctx.message.channel.id, ctx.message.id)
you can split it into multiple lines
log.exception(
"... message ...",
ctx.message.channel.id, ctx.message.id
)
@patent pivot Done.
the message block is not what I put above
you need to remove that first ctx.send from the ping_user block
right now it's going to send two messages when ping_user is true
my phone was rendering diff wrong ignore me
bot#3377 ready for staff review for any staff members who read this chat
@patent pivot I am mentioning you in the Accessibility section in GitHub in the issues, for Issues I can fix, Please take a look at them and see If you can Assign them to me.
Ill take some for now and take a look at others later.
@patent pivot Merging is disabled, Does another member need to review before merging?
What does the PR page say? It gives you a bunch of info of the checks we run and the requirements we have before something can be merged
bot#3377
I know what it says. I'm asking you what you're seeing
Review requirements: mainWaiting for status to be reported β 0/1 rules approved
and joe approved the changes hours ago
You can click in on that for more details about the rules required.
You can see we require 2 approvals. One must be from a core dev, the second can be from anyone on staff.
When I click on it I go to a 404 page on GitHub
oh ok
I thought 1 approval like normal should be enough
We require 2 for a lot of our projects, especially for one as critical as our Python bot.
Makes sense, though I don't understand why 2 are needed, this can delay the approval process if staff don't see the Pr
Is there like a staff channel where this is posted?
Well generally if something is time sensitive we have core devs aware and working on it. I don't believe your PR is time sensitive, so there's no harm in waiting.
2 are needed for anything in our bot repo because of how critical it is to this server and what it does.
ok, thanks for the info.
you opened the PR a few hours ago, things can sit in approval queues for weeks π , this is all volunteer time for everyone, no one is paid to do pydis
yeah jimj9 explained the process to me. Can you assign some of the accessibility issues. I also made a meta post for changing the contributor role gradient [here](#community-meta message)
I will when at a laptop in the next few days, there's no rush and no reason you can't work on them without formal assignment, no one is going to start when your comments are there
Well, you told me not to start until assigned. But, I can start working on them now.
π
i saw the contributor discussion internally and have put my thoughts there, i have thoughts that go with it about ensuring the PRs received remain high quality
for other issues I said to wait because a core dev will decide if they're still relevant, for accessibility ones I explicitly listed them as ones that anyone can take and make inroads to
okπ
also important to mention with all this: the contributor role is a reward that is voted on based on longer term contribution quality, and the things I mentioned were more things to achieve over a longer term rather than trying to speedrun.
there is still a vote that has to be passed and you shouldn't be trying to get as much done expectedly for this, moreso longer contribution will be rewarded with it.
I understand and know this. Thanks for the info though. I reason I am trying to get suff done fast Is because I am busy next week and I wanted to get it done instead waiting.
cc @thorny obsidian https://github.com/python-discord/branding/issues/212
I do like the colors
Joe, I do not see your commens on GitHub, but I see them in my email. Is this some kinds of issue or have you not commented on the issue yet?
I see. them now, some kind of browser issue on my side.
Firefox.
is there a !src command for the discord site?
there is not a !src command for site no, but just searching through with ctrl+f (project wide) generally finds things well on site
@patent pivot I have completed changing the accessibility issues site#1382 , site#1381 and site#1406. Should I create a PR?
yep create a PR whenever -- however also bear in mind that Mark and Stelercus have left feedback for you on bot#3376
yeah, thats how I did it π
or bot#3377 rather
yes I have made some changes and resolved them. I got 31 emailsπ
there is still the comment about allowing users to delete the pastes
some
I don't know how to make a ternary condition. And deleting the paste can be done.
msg += f"[your command]({paste_link})" if paste_link else "your command"
with mark's comment about switching the ordering back it's gonna be like uhhh
I don't really understand why we need a ternary condition. For future contibutors the if statement will be easier.
it'll end up being neater
msg = "Here's the output of "
msg += f"[your command]({paste_link})" if paste_link else "your command"
msg += f", {ctx.author.mention}:" if ping_user else ":"
replacing lines x-y?
175 to 183
This resolves Mark's comment right?
yeah
generally i'd comment that something is resolved and let the original commenter mark it as resolved so they can acknowledge you have made the changes in the way they're thinking
Will, do
what about Mark's second comment?
about the empty message
resolved by using the ternaries as above
so just comment that it's resolved through the later changes and leave it to be marked as resolved
not sure if this is like a known issue but i am pretty sure that date is wrong
the oct 10th, 2022
what should it be?
i mean 3.13 was only released in oct 2024 so probably just the year is wrong
itβs probably a simple fix
yes, it was streamed on oct 9 the 2024
yea looks like a copy paste error somewhere lol
lmao
can be changed when someone looks at accessibility or redoes the timeline next
not urgent
should I bundle this with my changes?
all good
your PR isn't currently touching those files so probably not
i remember doing a fair bit of work on the timeline a long time ago
somehwere deep in git history
there's already issues about alt text on that page & staff look at the timeline semi-regularly
It is touching the timeline and one of the md files. The change is to add alt-text to an image of the logo.
btw site#1562
ah, then maybe fine to add in a separate commit
commiting now.
though if we're not squashing this one you might want to get familiar with git rebasing and force pushing instead of adding loads of commits to git history
also your change to that file currently seems to be removing alt text
I mean I learnt the basics of git but have no idea what a rebase is.
where?
ah
timeline.html
I haven't fully reviewed it yet and it might make sense for that to be removed
so don't take this as a review
I was because in one of the issues it said the word "Logo" is generic and the logo provides no value to the person so no alt-text needed
you might want to check out github desktop, it'll allow for things like squashing and rewording commits so you can change things without having to add a new commit https://docs.github.com/en/desktop/managing-commits/squashing-commits-in-github-desktop
I have it installed but never found a useful use for it.
but will check it out
yea, this will be that use, you can change the wording of old commits and include new changes in old commits
then you force push that to github and it's a new history instead of adding new commits to the old history
hmm.. ok. but wont the commit message be long?
no you can change the commit message
yes but if I want to explain the commit it needs to be long
not really
for example your bot PR
it's changing one block of code
so it doesn't need 11 commits
it needs 1 commit
yeah
so when we merge that we'll squash it down into 1 commit titled something like "Preserve invocation context when redirecting command output"
ok , I understand now
Oh file name says' 2024 but the inside says 2022
interesting
pushed site#1562
btw can you assign the issues site#1382 , site#1381 and site#1406 to me? If you are on your laptop.
assigned -- but it's really not necessary now you've got a PR and dropped the comments
if not assigned the issues will not close right?
no, the issues close if you write the correct thing in the PR body
I'm just editing it in now
Oh, I am learning something new everyday.
it's this thing
assigning the issues doesn't really do anything other than putting your name in the side
i wouldn't worry -- we'll just squash that one down when we merge it
it's literally going to change 1 block of code and isn't worth a force push
the only thing left on that is the removal links
then stel & mark just need to have a look again
Should I do the removal link?
that's what the review says yea
nvm I will
you might need to do a bit of changing about what you store from the paste response
huh?
worth changing paste_link into just paste_response and instead of using paste_link use paste_response.link
ok
because then you can use paste_response.removal
Person who made the command
ok
So it's just:await message.author.send(content=f"[Click here](<{paste_response.removal}>) to delete your recent paste.")?
yes but change the message to fit this context
so like "Click here to delete paste made by the bot from your code"
not really good at english
So if you find any mistakes let me know
f"Your command output was redirected to <#{Channels.bot_commands}>. [Click here](<{paste_response.removal}>) to delete the automatically uploaded copy of your original command."
will need splitting across multiple lines
Will do
message.author.send give me undefined name 'message'
doe it need an import
is it ctx?
ctx.message
you can probably just do ctx.author.send though
Errors:
The bot does not send a paste link anymore and goes to the else statement and the removal link does not exist.
π
Debug session complete β
:
The bot goes to the else statement even though the generation of the link is successful and it works(added print in the code). Ternary issue?
show your code?
paste_link = None
async with ClientSession() as session:
try:
paste_response = await send_to_paste_service(
files=[PasteFile(content=ctx.message.content, lexer="markdown")],
http_session=session,
)
except PasteUploadError:
log.exception(
"Failed to upload message %d in channel %d to paste service when redirecting output",
ctx.message.channel.id, ctx.message.id
)
msg = ""
msg = "Here's the output of "
print(paste_response.link)
msg += f"[your command]({paste_response.link})" if paste_link else "your command"
msg += f", {ctx.author.mention}:" if ping_user else ":"
await ctx.send(msg)
#Send a DM to the user about the redirect and pastebin removal
await ctx.author.send(
content=
f"Your command output was redirected to <#{Channels.bot_commands}>. [Click here](<{paste_response.removal}>) to delete the automatically uploaded copy of your original command."
)
yeah because now you're not setting paste_link
all references to paste_link need to be paste_response
oh, my bad. Im so stupid
paste_response = None
async with ClientSession() as session:
...
msg += f"[your command]({paste_response.link})" if paste_response else "your command"
etc.
Yup all good.
bot#3377
site#1562
review left on formatting
Will check tommarow evening EST
Fixed
@patent pivot
try:
# Send a DM to the user about the redirect and paste removal
await ctx.author.send(
f"Your command output was redirected to <#{Channels.bot_commands}>."
f" [Click here](<{paste_response.removal}>) to delete the pasted"
" copy of your original command."
)
except Forbidden:
log.warning("Redirect output: Failed to send DM to user. Forbidden.")
and from discord import Forbidden
Is this right and the way you want be to do?
I would do discord.Forbidden for clarify where that exception comes from
but otherwise yeah, if that's the only error we risk raising for non-error scenarios that's fine
#community-meta message
I'm guessing this is because #1035199133436354600 isn't actually the channel the command is sent in? Should we check for the category instead? Or should this really work?
Yeah we don't properly support forum posts/threads in the whitelist check
https://github.com/python-discord/bot-core/pull/305
I am trying to test DM behavior.
I am testing uploading a .py file directly so the bot will ask me to make a paste bin and DM me the removal link.
It works differently locally and in the server is this a config change?
The server send me removal link but the local bot only send me this
"Hey @toxic wren!
It looks like you tried to attach a Python file - please use a code-pasting service such as https://paste.pythondiscord.com/"
Where as the server one sends
"Click here to delete your recent paste."
And when I block the bot the server bot still send me a message but it is hidden I can choose to see it.
whereas the local one does not send anything
Why is the behavior different?
@patent pivot
I'm confused -- I'm not sure why you're uploading a py file at all? this isn't part of the funcitonality you are changing
I was testing the already there DM functionality to see how it responds and instead of using the changed commands I am trying other commands
ahh
i'm not entirely sure what you have tried to do here -- but it sounds like you maybe ignored instead of blocked?
I blocked for sure I tested it agin a few minutes ago
then i'm not sure -- if you have truly blocked the bot and it attempts to send a DM to you then it will raise Forbidden
It does I think but the server bot send a message either way and I see it when I unbock by local bot has no message?
the behaviour you are describing is not possible
the bot cannot send a message "either way", it tries to send a message and gets "Forbidden" back and that's that, no message is sent
hmm. ok ill just make the changes and push
changes made. pushed.
you need to import discord
rookie mistake, changed. pushed
linting errors fix in progress
@patent pivot done. ready for review
applied arg changes
@toxic wren it was not my suggestion, my suggestion was catching the error because it's not actually an error.
When you log things as warning or error in our projects it creates a new Sentry ticket because it assumes that the behaviour should never happen, so catching the error here is good, but I purposefully did not say warning because we don't want to stop it from causing an error and then raise an error ticket anyway
oh ,ok
site#1562
hi folks, I'd love to contribute to python/cpython with performance improvements... Is there a place where this is discussed and I could learn more?
#internals-and-peps is the channel in this server where cpython related things are discussed
thanks
Hello everyone,
I'm seeking assistance and feedback on my new open-source package, fastjson-db. It's a lightweight NoSQL database designed for speed and simplicity.
I would greatly appreciate any help with testing, code review, or general feedback on its functionality and usability. Your insights would be invaluable!
This is my first open-source package, so mistakes are expected. Feel free to open issues or pull requests.
Check it out here: https://github.com/MauricioReisdoefer/fastjson-db
Thank you in advance for your time and support!
This channel is for Python Discord's projects like the bots and the website. If you want feedback for a library, you should rather post in the r/Python subreddit or ask in #databases
Ok
Sorry
I love this emote

<@&831776746206265384>
!compban 755318700357451836
discord actually lets you delete the last 24 hours of activity when banning
ah right right
@celest charm the reason I picked at what you said π https://github.com/python-discord/bot/pull/3371/files#diff-d82a54c450ea031f87210217bd9b41f10344938751efefdf015f27d9404a9a06R254-R255
Yeah this is totally fine
I probably should've been more clear/nuanced, there are two kinds of except clauses:
- The first one is when you're catching an exception that's part of the function's interface (usually it's a library function), where it's functioning more as a return value. Usually the
exceptclause is aimed at a very specific exception that's a leaf in the exception hierarchy or close to that. - The second one is when you're catching when "something goes wrong" but you're not sure what, when or where in the call stack it happens. Usually the
exceptclause hasExceptionor a broad base class likeIOErroror e.gaiohttp.exceptions.ClientError
Do you think a tag for reporting exceptions properly is worth it? I'm seeing someone doing f"Something wrong: {e}" every week or so here for some reason
yeah it can be useful, just need to figure out how to word it so it's not used in the wrong cases
something like !exc-logging
I'm thinking of something like:
When reporting or logging an exception, you might be tempted to call
stron the exception or put the exception directly into an f-string like so:
try:
quack()
except DuckError as exc:
print("Quacking failed:", exc) # or: + str(exc)
logger.error(f"Quacking failed: {exc}")
This is often a bad idea because it removes much of the useful information, including the traceback and even the class of the exception.
>>> fruits = {"apple": "a", "cherry": "c"}
>>> try:
... print(fruits["banana"])
... except Exception as e:
... print(f"Something went wrong: {e}")
Something went wrong: 'banana'
When using
logging, use theexc_infoargument to log the exception with its traceback
>>> try:
... print(fruits["banana"])
... except Exception as e:
... logger.error("Bananas out of stock:", exc_info=e)
ERROR:root:Bananas out of stock:
Traceback (most recent call last):
File "<python-input-19>", line 2, in <module>
print(fruits["banana"])
~~~~~~^^^^^^^^^^
KeyError: 'banana'
If you cannot use
logging, you can use thetracebackmodule to format the exception using theprint_exceptionorformat_exceptionfunctions:
>>> try:
... print(fruits["banana"])
... except Exception as exc:
... print("".join(traceback.format_exception(exc)))
Traceback (most recent call last):
File "<python-input-40>", line 2, in <module>
print(fruits["banana"])
~~~~~~^^^^^^^^^^
KeyError: 'banana'
wow this is long
unacceptably long even
Does discord still not have collapsible embeds?
don't think so
understandable, they are carrying out other important tasks like moving the search bar
lol
they actually did improve embeds recently
apparently "recently" was in April what the fuck #core-dev-announcements message
Isn't it better to recommend logger.exception(β¦) instead of logger.error(β¦, exc_info=True) as it already does that?
/nitpick
I wanted to include both, but it's already too long
the exc_info parameter is more flexible, you can e.g. include a traceback in a warning (which would be the appropriate level for a retry function, I think)
Yeah, and there seem to be no solutions for long tags that don't feel like over-engineering
-# At least to me
We had some articles on our website, not sure what happened to them
We could have a very condensed tag with more nuance, and link to a larger article
Sounds like a good middle solution
the tag would be something like:
When logging an exception, don't pass it to
str()or place it inside an f-string placeholder. That removes valuable information from the exception:
>>> fruits = {"apple": "a", "cherry": "c"}
... try:
... print(fruits["banana"])
... except Exception as exc:
... print(f"Something went wrong: {exc}")
Something went wrong: 'banana'
Instead, use the
exc_infoparameter when usinglogging, or thetracebackmodule to print the exception type, message and its traceback:
>>> try:
... print(fruits["banana"])
... except Exception as exc:
... logger.error("Something went wrong: ", exc_info=exc)
... # or: traceback.print_exception(exc) when not using `logging`
ERROR:root:Something went wrong:
Traceback (most recent call last):
File "<python-input-47>", line 2, in <module>
print(fruits["banana"])
~~~~~~^^^^^^^^^^
KeyError: 'banana'
actually, that's probably good enough for a tag on its own
!embed
When logging an exception, don't pass it to str() or place it inside an f-string placeholder. This removes the traceback and the class from the exception, making it very hard to investigate what happened and debug the problem. ```
try:
... print(fruits["banana"])
... except Exception as exc:
... print(f"Something went wrong: {exc}")
Something went wrong: 'banana'
Instead, use the exc_info parameter when using logging, or the traceback module to print the exception type, message and its traceback:
try:
... print(fruits["banana"])
... except Exception as exc:
... logger.error("Something went wrong: ", exc_info=exc)
... # or: traceback.print_exception(exc) if not usinglogging
ERROR:root:Something went wrong:
Traceback (most recent call last):
File "<python-input-47>", line 2, in <module>
print(fruits["banana"])
~~~~~~^^^^^^^^^^
KeyError: 'banana'
When logging an exception, don't pass it to str() or place it inside an f-string placeholder. This removes the traceback and the class from the exception, making it very hard to investigate what happened and debug the problem. ```
try:
... print(fruits["banana"])
... except Exception as exc:
... print(f"Something went wrong: {exc}")
Something went wrong: 'banana'
Instead, use the exc_info parameter when using logging, or the traceback module to print the exception type, message and its traceback:
try:
... print(fruits["banana"])
... except Exception as exc:
... logger.error("Something went wrong: ", exc_info=exc)
... # or: traceback.print_exception(exc) if not usinglogging
ERROR:root:Something went wrong:
Traceback (most recent call last):
File "<python-input-47>", line 2, in <module>
print(fruits["banana"])
~~~~~~^^^^^^^^^^
KeyError: 'banana'
@cold island thoughts?^
btw: if you specify a code block like this without a new line, discord doesn't add huge padding for it, as demonstrated above (compare to any other tag with a code block). Perhaps our bot could automatically perform this fixup
No newline ```py
print("hello, world!")
---
With newline
```py
print("hello, world!")
Newline after
With two newlines
print("hello, world!")
Two newlines after
"With two newlines" is how reasonable Markdown code is usually written
Oh I didn't know that (or I did and forgot). But I like the spacing with the newline better
Instead, use the
exc_infoparameter when using theloggingmodule, or thetracebackmodule, to print the exception type, message and its traceback:
Otherwise looks solid
I think I lost the `s somewhere while copypasting
That would look way better in a book or a webpage, but unfortunately compactness really trumps everything here IMO
it's just a bit more space under the first codeblock and it makes reading easier
This is what "with newline" looks like btw. Not with the extra empty space as found in markdown commonly
actually apparently our tags already follow this, i'm surprised
well, not everywhere
silences a channel for moderators to intervene
!help shh
!help silence
!silence [duration_or_channel] [duration=10] [kick=False]
Can also use: hush
Silence the current channel for duration minutes or forever.
Duration is capped at 15 minutes, passing forever makes the silence indefinite. Indefinitely silenced channels get added to a notifier which posts notices every 15 minutes from the start.
Passing a voice channel will attempt to move members out of the channel and back to force sync permissions. If kick is True, members will not be added back to the voice channel, and members will be unable to rejoin.
^
thanks, idk why I didn't get pinged for reply. Just saw now
I think I accidentally left the reply ping off
I made a PR to add python facts from the suggestion thread along with a few more to Sir Lancebot:
WHAT
YOU CAN DO THAT NOW
(highlight lines on a diff)
I don't remember when it wasn't a thing π€
it wasn't always
my PR:
bot#3377
and site#1562
Hello, just wanted to follow up again on my 2 open Lancebot PRs:
sir-lancebot#1690
sir-lancebot#1694
Would someone be able to review these soon? Thanks in advance for your time.
oh nice π
Could I get one review on https://github.com/python-discord/bot/pull/3385?
done
Pretty busy at the moment so won't make any promises but I will keep in mind that there are other PRs needing review
Guys i need review on :
bot#3377
site#1562
sheesh its been a while
well I'm just gonna assume that if the emoji text is right then it works lol
fffffun I didn't realise there wasn't a formatter
comment left on the bot PR explaining further
question on the if statement on GitHub
Please react with β
to upload your file(s) to our paste bin, which is more accessible for some users.
Sorry, for the late commit @patent pivot but in bot#3377 is this what you were talking about?
if RedirectOutput.delete_invocation:
paste_response = None
async with ClientSession() as session:
try:
paste_response = await send_to_paste_service(
files=[PasteFile(content=ctx.message.content, lexer="markdown")],
http_session=session,
)
except PasteUploadError:
log.exception(
"Failed to upload message %d in channel %d to paste service when redirecting output",
ctx.message.channel.id, ctx.message.id
)
msg = "Here's the output of "
msg += f"[your command]({paste_response.link})" if paste_response else "your command"
msg += f", {ctx.author.mention}:" if ping_user else ":"
await ctx.send(msg)
try:
# Send a DM to the user about the redirect and paste removal
await ctx.author.send(
f"Your command output was redirected to <#{Channels.bot_commands}>."
f" [Click here](<{paste_response.removal}>) to delete the pasted"
" copy of your original command."
)
except discord.Forbidden:
log.warning("Redirect output: Failed to send DM to user. Forbidden.")
scheduling.create_task(func(self, ctx, *args, **kwargs))
message = await old_channel.send(
f"Hey, {ctx.author.mention}, you can find the output of your command here: "
f"{redirect_channel.mention}"
)
No, you've put too much in the if statement there
you still need to define paste_response and you don't need any of the message stuff in the if statement
it literally needs to be the async with block
so, this?
if RedirectOutput.delete_invocation:
paste_response = None
async with ClientSession() as session:
try:
paste_response = await send_to_paste_service(
files=[PasteFile(content=ctx.message.content, lexer="markdown")],
http_session=session,
)
except PasteUploadError:
log.exception(
"Failed to upload message %d in channel %d to paste service when redirecting output",
ctx.message.channel.id, ctx.message.id
)
no, you need to define paste_response outside the if statement
I thought you said var too?
@patent pivot
that's my mistake then
it's fine. Commiting now βοΈ
oh, looks like project got updated while I PR was inactive, fetching
Oh, wait im getting errors to for git pull, can you help?
What error?
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint: git config pull.rebase false # merge
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.
hmmm
what did you try do to get here
i'd just do git config pull.rebase true and then git pull
git fetch git pull
on your branch or on main?
my branch
I did git reset --hard and still does not work
run git pull --rebase
get this
Auto-merging bot/decorators.py
CONFLICT (content): Merge conflict in bot/decorators.py
error: could not apply 1c256aac... Add if statement
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 1c256aac... Add if statement
btw add if statement is local commit
the git errors do tell you mostly what you need to do
right, and did you make this commit before pulling in the suggestions that you'd applied in the git editor?
i suspect that's what the conflict is
yes
I clicked use HEAD
yea that's where the conflict came from
follow the instructions in the error, you need to go open that file and resolve the conflict and then run git rebase --continue
the errors in git tell you what you need to do to fix things and not lose your work
you shouldn't have had to do any resetting here
ok, i just reset back to cloud version with none of the changes I made today, how do I update the branch?
as long as you have the same history that is currently on github you just need to add that change back and push your new commits
I have the history of 2 weeks ago
how do I update
pull
will that change the decorator.py file?
but, i want to keep the changes in decorator.py
which changes, your new if statement?
I will lose all my work right?
run the following ```
$ git stash
$ git pull
$ git stash apply
$ git stash drop
no the older ones, I have not put in the if statement yet, as I have stated I have the history of 2 weeks ago.
right then I'm really confused
your local decorator.py is presumably 2 weeks old right?
so you need to update it before you can add your if statement
your older changes are on github so you need to have those reflected locally
git pull will pull the newer changes from github to your local copy of decorator.py
basically I just cloned the cloud repo again
so then you don't need to do anything if you've cloned it again?
you jsut need to add the new changes and commit and then push that
I mean my fork of the repo that I forked about 3-4 weeks ago and changes were made to the actual bot repo owned by python-discord 2 weeks ago
How do I add the changes on the main repo without chaning the decorator.py file as I have the preserve invocation code there.
oh right
fyi I am on preserve-invocation-context branch
so you mean how do you update the changes from python-discord back in so your branch isn't out of date
is your local copy of main up to date?
try run git rebase main whilst you are on your preserve-invocation-context branch and then run git push --force
no
so git fetch and git pull
no because you'll need to sync the fork
oh, on github
ok, done whats next?
check out your preserve invocation context branch and run this
ok, now can I make local changes and push?
yep
and btw can you take a looka t site#1562
I think jc will have a look at that based on his comment
yeah, bu dont we need 3 approvals?
2
2 staff memebers right? Markoz is core dev and jschrist is staff I think, so I need 1 more staff
It says core dev in the screen shot approved by markoz and staff 1 approved right?
yes
trust me i wrote these rules
you need 1 more approval
mark approved as a core dev and staff, that means there is 1 more staff or core dev approval needed
all core devs are staff
ok
i miss when this wasn't behind auth, I liked looking at it
but now lol
yeah i know that
buti'm confused why you can't use the oauth login
can you not see it>?
maybe because it's an org app or something
I'm already logged in and not authenticated
if I'm logged out
it 404s for me because 404 is 403
so when you do this login it returns a 404?
huh yeah
yeah says its a private app
interesting
try do it now
policy-bot
Palantir project
gotcha
I have so many questions about how does this anagram code work because I don't think that's a word
hmmm
competing is
coempting is also a word β but going by google results primarily in scrabble lol
the source word/concept
i do feel like we could potentially try pick from a bit of an easier english dictionary for that feature though
instead of just picking a full dictionary we look for like top 10k words or something
smh why is there no type checker in CI
Idea: basedpyright has a "baseline" feature where you record the errors your codebase has right now. Basedpyright will complain about new ones, but not old ones. This allows you to add type checking to CI without fixing all the 3000 errors right now
https://docs.basedpyright.com/latest/benefits-over-pyright/baseline/
We will need to bikeshed what options we want enabled, but about 2K on sensible settings
wtf really lol
lol
On a related note, why
https://github.com/python-discord/bot-core/blob/main/pydis_core/__init__.py#L19
pydis_core/__init__.py line 19
__all__ = [module.__name__ for module in __all__]```
that'll be Chris with claude code man
Let's see if I can find any actual bugs with a type checker
lol
given the number of sentry alerts we receive on bugs that are solvable via type checking
i'm sure you will
a useless but technically valid bug: replace items in typing that were deprecated by PEP 585 (like List and Collection)
well, I found a typing bug in frontmatter...
excellent
I read this in a
voice
A lot of the errors are going to be of the form Cannot assign "X | None", X expected
yeah
see that's the problem i have had and I think chris has had with a lot of our discord.py stuff
I might have to think with the brain to resolve those ones
the typing on discord.py means that contextually we know that something can never be the case, but the type validator will want us to explicitly check a lot of things
But the good thing about baseline is, we can leave them alone and think with brain later
like we know if we put a predicate on a command to make it guild only then ctx.guild is going to exist, but the type checker obviously doesn't know that and doesn't see that
!pep 505
with how much python developers love None, it's annoying to deal with it sometimes. smh
I suppose we stop typing stuff as Context and create some sort of narrowed subtype GuildOnlyContext
because we have a type error on basically every command that uses ctx.guild because we always use a guild only decorator
can you validate signatures that get passed into decorators?
using a static type validator that is
wdym
like if I have ```py
class GuildOnlyContext(Context):
guild: Guild # redeclare as non-optional
Disallow this
@guild_only
@bot.command()
def do_something(ctx: Context) -> None:
print(ctx.guild.name)
Allow this
@guild_only
@bot.command()
def do_something(ctx: GuildOnlyContext) -> None:
print(ctx.guild.name)
basically that
it would have to be in this order ```py
@bot.command()
@guild_only
or you could override command in our bot such that, if ctx is annotated with GuildOnlyContext, it automagically makes the command guild-only
that's the way it actually is -- i got it wrong
P = ParamSpec("P")
R = TypeVar("R")
def guild_only(
func: Callable[[GuildOnlyContext, *P.args, **P.kwargs], R],
) -> Callable[[Context, *P.args, **P.kwargs], R]:
@wraps(func)
def wrapper(ctx: Context, *args: P.args, **kwargs: P.kwargs) -> R:
...
return wrapper
something like that right?
yeah
i guess there is the newer syntax for that without paramspec etc.
you also might need inspect.markcoroutinefunction
because @wraps doesn't propagate the fact that func is an async def function
but not sure if discord.py inspects that
it's annoying because yeah i think in hindsight doing something like this and being shit on it with typing would've been nice but we have so many things in bot that we figure out contextually it'd just be a pain in the ass to update it all
however, the baseline mode you sent the link to is quite cool
and absolutely could be fun to try on a repo
It's fine to add hacks or unsound things, and we could just # type: ignore like we do with ruff lints
there is even a uhh https://docs.basedpyright.com/latest/installation/pre-commit hook/
sadly it might be too slow to run in a pre-commit hook
yea this is true -- just for something like the guilds thing where 90% of our commands have that error it'd be nicer to do an actual fix
it's written in JavaScript ( 
) not a fast language π¦ π π¦ π§βπ
i think that running it only in CI is not a bad shout
this is cool actually https://docs.basedpyright.com/latest/benefits-over-pyright/improved-ci-integration/
if we use baseline then yeah i'd just add this as another non-required workflow
Here's an example of a None issue that's not related to discord: https://github.com/python-discord/bot/blob/fe2dabfc54e14ab360d7e1147dd9ce43caf31cfc/bot/exts/backend/branding/_repository.py#L206
blah blah blah
download_urlcould be None
relevant class: ```py
class RemoteObject:
sha: str # Hash helps us detect asset change.
name: str # Filename.
path: str # Path from repo root.
type: str # Either 'file' or 'dir'.
download_url: str | None # If type is 'dir', this is None!
A more static-typing-oriented approach would be making a class for a file and another for a directory (or something to that effect), and then the `fetch_directory` method would have to somehow link the `types`. For example:
```py
@overload
async def fetch_directory(self, path: str, types: Literal["file"]) -> dict[str, RemoteFile]: ...
@overload
async def fetch_directory(self, path: str, types: Literal["dir"]) -> dict[str, RemoteFile]: ...
@overload
async def fetch_directory(self, path: str, types: Literal["*"] = ...) -> dict[str, RemoteFile | RemoteDir]: ...
``` or something more complicated. It is 100% true that it will be extra work, but it will catch some bugs
bot/exts/backend/branding/_repository.py line 206
meta_bytes = await self.fetch_file(contents["meta.md"].download_url)```
so just like with tests, maybe errors could be fixed in code that's frequently edited, or is critical to our operation. And other errors can be left as is
Branding updates? Doesn't really matter if it breaks
yea
ok @patent pivot i found the first bug
https://github.com/python-discord/bot/blob/fe2dabfc54e14ab360d7e1147dd9ce43caf31cfc/bot/exts/help_channels/_channel.py#L194-L199
bot/exts/help_channels/_channel.py lines 194 to 199
try:
# Fetch the post again, to ensure we have the latest info
post = await get_or_fetch_channel(bot.instance, post_id)
except discord.HTTPException:
log.trace(f"Not closing missing post #{post} ({post.id}).")
return```
"post" is unbound
hhaahaha
yeah
looks like the log was copied from the same template a couple of lines below
small bug in discord's typing:
@_cog_special_method
def cog_check(self, ctx: Context[BotT]) -> bool:
"""A special method that registers as a :func:`~discord.ext.commands.check`
for every command and subcommand in this cog.
This function **can** be a coroutine and must take a sole parameter,
``ctx``, to represent the :class:`.Context`.
"""
return True
``` return type should've been `-> bool | Coroutine[Any, Any, bool]`
seems like we're going to encounter a lot of annoying things like this
bot/utils/messages.py lines 206 to 211
def sub_clyde(username: str | None) -> str | None:
"""
Replace "e"/"E" in any "clyde" in `βusername`β with a Cyrillic "Π΅"/"Π" and return the new string.
Discord disallows "clyde" anywhere in the username for webhooks. It will return a 400.
Return None only if `βusername`β is None.```
The cursed substitution aside, str | None -> str | None just for the convenience of when you might have none is something that won't work well with type checkers. In a statically typed language you have stuff like Option::map, but alas we don't
Man I mean I get it. I hate how tedious __all__ is.
Yeah it kinda is. But the names are already listed explicitly
I don't like how import = automatically export in Python.
At this point I'm just holding out for ty
SO. MANY. it's freaking crazy
This is why disnake is moving towards strict typing + typevar and subscriptable support for end users lol
I'm really not a fan of baseline checks, at least not for now.
As I think a lot of issues require refactoring or changes to multiple areas of code, and a baseline would make adding new code a pain before these are done.
yo
One example is converters, another is getting constants, which I made suggestions for here https://github.com/python-discord/bot/issues/1773
I think it would work fine for people to just make PRs improving typing without using a type checker in CI, as they should be improvements regardless.
yeah this is why I was thinking we add it more as a completely separate advisory check if we're going to add it
not required for merge
i mean we could even dynamically generate that baseline state for the PR if we wanted -- very clearly demonstrate exactly what's going on with typing for a subset of changes
@patent pivot @oblique cairn I have made the changes in site#1562 check it out!
yes! finally bot#3377 is merged.
already updated, very fast indeed.
huh
why did that trigger a devops review lol
oh
pahahahahahahaha
pattern is .github/*
but it's regex not a globbing pattern
very funny
where did the forward slash go π€
oooh lmao
fix was ^\.github/
I was trying to read it as both regex and glob at the same time
hahahaha
going by the other patterns in that file, it appears i wrote it as both a regex and glob at the same time
i mean you can always review it
I am having issues getting the test environment up and running, docker compose works to start everything inside docker, but it looks like the bot gets stuck waiting to acquire a lock for 'filtering.check_bad_name'
i.e. when I go to bot commands on the test server and type !help, it reacts and checks whether the channel is a help channel, but always ends on this log line and doesn't create a message on the test server
bot-1 | 2025-09-24 23:39:20 | DEBUG | bot.utils.lock | _check_bad_display_name: acquiring lock for resource 'filtering.check_bad_name':158020687850766338...
did you run the .envserver script?
Sec PC just crashed
A guide to setting up and configuring Bot.
maybe do a fresh git clone and then use the Contributing guide
I've made no changes other than string values (that don't impact logic)
unless there was a broken state on main
Umm.... I cant really help you, maybe just do a fresh git clone and I can guide you through it.
envserver is a file with all the stuff related to your server(channel id's , role id's, etc)
Just to clarify, the bot will log this when you send a message but it doesn't mean that this is where it gets stuck. Can't think of anything that would prevent it from acquiring a lock
do you want me to nuke the venv too? or only the repo stae
btw:
Is a !contrib command for showing contributing guidelines with this link a good idea?
oh it exsits
Looking to contribute to Open Source Projects for the first time? Want to add a feature or fix a bug on the bots on this server? We have on-going projects that people can contribute to, even if you've never contributed to open source before!
Projects to Contribute to
- Sir Lancebot - our fun, beginner-friendly bot
- Python - our utility & moderation bot
- Site - resources, guides, and more
Where to start
- Read our contribution guide
- Chat with us in #dev-contrib if you're ready to jump in or have any questions
- Open an issue or ask to be assigned to an issue to work on
hmmm only thing I can think for this is a permissions issue
do any other commands work? !ping etc.
have you also added the "admins" role (whatever role you have that configured to in your env file) to yourself?
I suspected this too
yes
I did no extra config other than running the config uv script
and writing the .env files
to maybe help a bit, can you do the following:
- add a new env variable
BOT_TRACE_LOGGERS=* - start the bot and attempt to run a command like !help or !ping
- quit the bot
- upload the logs to https://paste.pythondiscord.com/
you might want to read through the logs before you upload to check there's nothing sensitive in there
it'll generate a lot of noise
basically turning all the loggers to max
If he used the server template that wont be an issue right?
you still need to apply the role
fairly sure you still need to give yourself those roles
I used the template
yeah
and wont he be the owner?
I did it manually because I thought it might give me access to the /command for the voice gate message
So it looks for a role like "Admin" and not something like their permissions?
(give myself the role)
it's unlikely that's the problem because even unprivileged commands aren't working here
but yeah i'd get a trace log dump together and we can have a look what's going on in there
correct
it looks for the role you specified as the admins role
the self role assignment appears to work
Setting it up again would probably be good.
maybe an issue with being unable to create new messages?
Did you follow instuctions for creating a Discord App?
Giving it privileged gateway intents?
i think you're proposing a lot of drastic actions (fresh git clone, setting up again, etc.) for a mostly undiagnosed problem here
yes
there's no need to start afresh, we can try and debug what is going on here long before we need to suggest people reclone repos, all that does is help people lose work
doing now, sec
potentially but as long as the bot has the right roles and you have the right roles that shouldn't be an issue
and if we're assumging a permissions error you'd definitely see that logged in some way
did you give bot Admin?
is that a required manual step?
Well, bot needs permissions to do certain commands.
And it cant give itself those roles
there should be a role for bots in the template with the necessary permissions
so yeah
surely not !help though right
I'd elliminate the easy to see problems first Β―_(γ)_/Β―
can test again?
i can't remember the other permissions in that template, it's unlikely to be the problem, but ensuring that both you and the bot have roles is a godo start
For example the bot might have perms to see the channel but not write in it
Having the right role solves that
For my contrib I gave it the "Python" role and it worked
for commands such as eval, help,etc
yea
there are roles such as "Super bot"
Which I did'nt need for normal setup, so this is not a permissions error, unless the config is wrong.
bot-1 | 2025-09-24 23:39:20 | DEBUG | bot.utils.lock | _check_bad_display_name: acquiring lock for resource 'filtering.check_bad_name':158020687850766338...
was the error
it's not an error
that is not an error
I mean log
I would start with giving the bot admin perms and then continue with what joe outlined
check_bad_display_name? is that referring to the people in the server?
yes
alright, I stopped and deleted all running containers, am now running
or is it just a check
it's a check on the names of people who write in the server
who is in the server?
only you?
me and the bot
oh, interesting
the check runs anyway
(if you are asking because of that debug log I assure you it's unrelated -- it's very out of the way of the command processing logic in the bot)
it's not related to whether it succeeded or not
Just so we're on the same page here, did you give the bot the necessary role?
I just assigned it admins and superbot
but not before attempting the first message
no difference
I am trying !help in #bot-commands (on the test server obviously ^^)
asking some questions that might be obvious, but just sanity checking:
- are you using the right prefix (i know you said the bot was reacting, but just double checking)
- are any other commands working? (e.g. !ping)
same deal for !ping
how can I tell if another prefix is configured at runtime?
it's sourced from .env right?
orz, it's because vscode didn't apply my edit before my pc crashed and when it reopened it still hadn't applied the edit
fml
(usually use either nvim or pycharm)
you should turn on auto-save
no worries
is there a test hook for metricity to initialize it with given state to test voice gate behavior (or anything else relying on metrics)?
there isn't but you can generally just send a few messages and then insert a few more rows matching that format
I was thinking more of the 10 minute blocks, but I'm sure I can figure out a way to do it manually, was just making sure I wasn't manually doing something that was automated somewhere :)
ya that's what i mean β you should just be able to update the timestamps of messages
ah, gotcha
UPDATE messages SET created_at = created_at - INTERVAL '15 minutes' WHERE id = '<some message id>';
shifts the timestamps which will shift the block calculation
doing more dev env setup for redis cli and postgres but ty for the pointer
asking anyone here, is there a command/feature you wish you had in any of the bots or site(I know Github Issues exist).
