#dev-contrib

1 messages ยท Page 127 of 1

vale ibex
#

yea

fallen patrol
#

that sounds even more problematic

static canyon
#

Not quite sure why you'd want to remind on a role though

fallen patrol
brazen charm
#

I think going stricter to only accept mentions/ids like you said would be best here

static canyon
#

Or at least it's never happened in the 2ish years I've been a helper+

fallen patrol
#

I think it was for staff meetings, or maybe admins/owners use it in their channels

#

idk

#

kutie has said they use it

static canyon
#

Staff meeting pings are manual

fallen patrol
#

Regardless, that Role should probably be restricted to the internal roles, or even removed depending on internal usage probably

static canyon
#

Yeah

fallen patrol
#

That makes me wonder if the people with the partner role who can mention others could mention voice verified ๐Ÿ‘€

static canyon
#

I suppose we just need to make this Greedy[t.Union[UserMentionOrID, discord.Role]] then?

vale ibex
fallen patrol
#

Given the nature of how a reminder works, if a bug in that case is ever introduced later, or functionality is changed, the reminder would still have the old role attached ยฏ_(ใƒ„)_/ยฏ

vale ibex
fallen patrol
#

true

#

my opinion is don't let the user set a role if they aren't in the allowed roles

static canyon
#

So it's probably fine (since already restricted to staff)

fallen patrol
#

Partners can.

#

otherwise I wouldn't have spotted this bug

#

๐Ÿ˜›

static canyon
#

Oh right

#

They can't mention people but it will still convert

#

Same as if you do it

#

That's just how dpy's parsing works

fallen patrol
#

er, it doesn't convert for me, but it converts for them

brazen charm
#

!remind 3d m

stable mountainBOT
#
Bad argument

m is not a valid duration string.

brazen charm
#

still fails in the same way

thorny obsidian
static canyon
#

Partners won't change anything

static canyon
thorny obsidian
#

Sure? I'm new to this convo. I just wanted to clear up what I have and have not said.

brazen charm
static canyon
#

Yeah

#

I'll open up an issue

cold island
#

We did use it a couple of times

#

Why do we want to remove it?

static canyon
#

It's just whether it's needed or not

#

It's not a case of "we have to remove it"

#

!remind 3d fix this

stable mountainBOT
#
Bad argument

fix is not a valid duration string.

#
Command Help

!remind [mentions]... <expiration> <content>
Can also use: reminder, reminders, remindme

Commands for managing your reminders.

Subcommands:

!remind delete <id_>
Delete one of your active reminders.
!remind edit
Commands for modifying your current reminders.
!remind list
View a paginated embed of all reminders for your user.
!remind new [mentions]... <expiration> <content>
Set yourself a simple reminder.

cold island
#

Just don't see a reason to remove something that works perfectly well

static canyon
#

It's the greediness of discord.Member that needs to be changed here

thorny obsidian
#

The issue now is that you can unintentionally ping a user because it converts the string to a user if it matches. To fix that we just need it to take a user ID or a mention, right?

The question is to whether you want to limit it to only take an ID/mention for a member and not a role?

static canyon
#

So changing Greedy[discord.Member] to Greedy[UserMentionOrID] basically

#

The question is to whether you want to limit it to only take an ID/mention for a member and not a role?
Basically yeah. Do we want Greedy[t.Union[UserMentionOrID, discord.Role]] or Greedy[UserMentionOrID]?

cold island
#

If that's the only difference and we're already handling roles then I think we should keep the roles

thorny obsidian
#

I really dislike a reminder for an entire role, but maybe it has use for like DevOps or something?
But if this is only a fix then I agree with Zig.

cold island
#

I used a couple of times to ping mods and admins to do something when I knew I might not be available to look into it

brazen charm
static canyon
brazen charm
#

Probably not? Some role could come up though, not sure on all the formats the converter it uses for the expiration accepts

static canyon
#

That converter doesn't currently exist so would mean adding it

cold island
#

!src remind

stable mountainBOT
#
Command: remind

Commands for managing your reminders.

Source Code
static canyon
#

@cold island if we do keep the discord.Role conversion (which I think we will), should we make it only support id/mention like users?

#

Or do we still want name support?

cold island
#

Not having name support is fine probably

#

So what exactly is the bug?

thorny obsidian
#

If you try to do a time like 3d it converts to a user first since it's a bit too greedy

#

The issue there being the conversion of a plain str to a member

cold island
#

Because it tries to match by name?

thorny obsidian
#

mhm

cold island
#

icic

static canyon
cold island
#

So what is easier and still works? lol

#

If there's a greediness issue then it doesn't seem we want it

#

But you don't need to support a role mention when creating a reminder

static canyon
cold island
#

Because that would be really silly if we pinged the role while creating the reminder

static canyon
#

There isn't a greediness issue with roles afaik, but there could be in the future

#

So it's whether we want to put the effort into something that may or may not be needed at some point

cold island
#

So the question is whether we might try to remind a user who has the name of a role?

#

Let's just go with discord.Role for now, the ones who can use role reminders are admins and we don't use names to refer to members in commands

static canyon
#

Whether the reminder itself would start with a role name

cold island
#

That wouldn't work though

#

You need a duration beforehand

static canyon
#

The reminder text

#

So like !remind 1d Moderators are still here?

cold island
#

That won't mention mods

#

Because you have 1d beforehand

static canyon
#

Right yeah

#

You're right

cold island
#

The 1d becomes a duration, and then you move to the text

static canyon
#

It would be !remind {role} {duration} {msg} which I'm guessing is never gonna happen

cold island
#

yeah

static canyon
#

!remind test

stable mountainBOT
#
Missing required argument

expiration

#
Command Help

!remind [mentions]... <expiration> <content>
Can also use: reminder, reminders, remindme

Commands for managing your reminders.

Subcommands:

!remind delete <id_>
Delete one of your active reminders.
!remind edit
Commands for modifying your current reminders.
!remind list
View a paginated embed of all reminders for your user.
!remind new [mentions]... <expiration> <content>
Set yourself a simple reminder.

static canyon
#

Yeah, I think it's absolutely fine to keep using discord.Role

cold island
#

!remind 1d Moderators are still here?

stable mountainBOT
#
ROGER THAT

Your reminder will arrive <t:1629757000:R>!

cold island
#

No mentions

#

versus

#

!remind 831776746206265384 1d are still here?

stable mountainBOT
#
Okay.

Your reminder will arrive <t:1629757025:R> and will mention 1 other(s)!

cold island
#

!remind delete 2860

stable mountainBOT
#
Aye aye, cap'n!

That reminder has been deleted successfully!

cold island
#

!remind delete 2861

stable mountainBOT
#
Can do!

That reminder has been deleted successfully!

molten perch
#

(I'd like to apologise for interrupting your conversation)
Hey I was browsing the decorators (in particular the in_whitelist check) and then found this function: https://github.com/pythondiscord/bot/blob/d375a66e3cd67832f93af29f37ec8d31e3254ef3/bot/utils/checks.py#L43
I might be very well wrong, but in case you define your whitelist context as for example: channel: bot-commands, and role: staff roles
The check will return True just by invoking the command in bot-commands, because it's the first if statement in the code and it'll immediately return with True, while not takin the Role parameter into account. Good example for this: https://github.com/python-discord/bot/blob/d375a66e3cd67832f93af29f37ec8d31e3254ef3/bot/utils/checks.py#L43
where there was an additional check added, besides the decorator. Fortunately I did not find any other examples for this.
(Again I might be very well wrong, but it seems strange for me)
Update: It seems like I can also invoke ping, whereas it seems like it was meant for roles=STAFF_ROLES

stable mountainBOT
#

bot/utils/checks.py line 43

def in_whitelist_check(```
static canyon
#

I'll open an issue and PR for this ๐Ÿ‘ @cold island

tawdry vapor
molten perch
#

Oh, okay. Makes sense ๐Ÿ˜„ Totally forgot about the nature of how STAFFs can invoke commands ๐Ÿ˜… I would've totally misused it though.

static canyon
#

If a function declaration goes over the 120 char limitpy async def remind_group( self, ctx: Context, mentions: Greedy[t.Union[UserMentionOrID, discord.Role]], expiration: Duration, *, content: str ) -> None: is this the correct formatting to get around that?```py
async def remind_group(
self,
ctx: Context,
mentions: Greedy[t.Union[UserMentionOrID, discord.Role]],
expiration: Duration,
*,
content: str
) -> None:

tawdry vapor
#

Yes

#

Or make an alias for that annoration if it would shorten the length enough to avoid chopping the signature

static canyon
tawdry vapor
#

Sure

static canyon
#

Where should I define it? Where Mentionable is defined? (towards top of file)

tawdry vapor
#

Yes

static canyon
#

๐Ÿ‘

#

bot#1766 and bot#1768 are now ready for reviews ๐Ÿ‘

static canyon
#

Actually could be interesting merging those because they both edit the same file (assume it's gonna cause a conflict)

cold island
#

Unless they edit the same line I don't they they will

static canyon
#

Ah okay, should be fine then

fallen patrol
green oriole
#

Good morning folks! I will give a virtual cookie to anyone who can please please please review bot#1760. We are in dire needs for this feature, it would help us combat spam bots tremendously. Thank you!

dusky shoreBOT
vocal wolf
green oriole
#

I currently don't have time for smartconfig. I could try to have a look later this year.

fallen patrol
#

is there a repo for smartconfig?

vocal wolf
#

ye

fallen patrol
#

public?

#

smartconfig#1

dusky shoreBOT
vocal wolf
fallen patrol
#

yea

vocal wolf
#

ye

fallen patrol
#

what's its purpose again?

vocal wolf
#

uhhhhhh

#

I think it's our own parser for config files?

fallen patrol
#

sounds similar to configurave lol

green oriole
#

Configuration, easy override and server generation

static canyon
#

@brisk brook going back to our mypy discussion a few days ago, there's a lot of errors. 959 to be precise.

A lot of them are things like where we have Union[int, None] instead of Optional[int] or where we have a Union[discord.Member, discord.User] then do .joined_at or something (when it's discord.User will error) but there's lots of other things too

#

Not sure how much we really want to fix because I know joe (and probs others too) are rather against the idea of a "clean-up PR" because of the review cost

#

This is the file if you're interested (has .bash extension since that seems to be the best syntax highlighting)

cold island
#

If you're modifying code and you see something that doesn't make sense I don't mind if you fix it, but otherwise I don't think it's worth the effort

static canyon
#

It sourced from me noticing that the typehint for our pagination lines parameter is list[str] but there's multiple (iirc 5) instances where it's not

#

^^

#

So Sequence[str] would make more sense

#

Then Bluenix said about running mypy to see if there's any other easy-fix and do a PR

#

A kinda "fix annotations" PR

brisk brook
#

Yeah, if there's any obvious errors similar to the one you want to fix

brisk brook
static canyon
#

We're discussing this internally a bit at the moment. An issue we have is with dpy using typehints for converters. This could possibly be helped bot bot#1730 but also we can do two commits, one for non-command typehints, and for command typehints (that way they could be reviewed per-commit instead of the entire PR)

static canyon
#

So one review would be just "is this the correct typehint" and the other would be "is this correct and does it convert as expected"

brisk brook
#

Well I mean I view this PR you're currently making as just uniforming types.

Changing List[X] to Sequence[X] and Union[X, None] to Optional[X] to make it uniform are somewhat trivial changed to review

static canyon
brisk brook
static canyon
#

Right yeah

#

Just got to be careful with attrs

#

E.g. List[x] to Sequence[x] when you have a .append()

brisk brook
#

Easy, insignificant change with little consequence

brisk brook
# static canyon Yeah, I guess

You're just changing the annotations, not the actual type it returns. So there really will be no runtime disadvantage to making the types more ambiguous

static canyon
#

The cases I'm thinking of would be causing an error already

#

So like if a tuple was passed but there's a .append

vale ibex
#

That's odd, I just merged main into bot#1731 and now it's failing tests ๐Ÿค”

dusky shoreBOT
static canyon
#

Circular imports ^^

vale ibex
#

Ah right, sorry Numerlor ๐Ÿ˜ฆ

#

Merged main into your PR before I was about to approve and it's causing a bunch of circular imports

gritty wind
#

Youโ€™re just imagining things

vocal wolf
#

sshhhhh

#

you saw nothing

short snow
#

xith how about we add support for both, like if the bot doesn't side quackstack api env var then it would generate the ducks itself?

vocal wolf
#

wait when did lance get redis

#

am I dumb how long has this been here

short snow
#

very long

vocal wolf
#

heck

vale ibex
#

unless we're planning to make breaking changes to the public API, which I don't think we should

short snow
#

yeah he didn't know that earlier cuz of me/or got confused

#

i totally forgot quackstack has public api

vocal wolf
#

What I meant was the quackstack running alongside the bot, that would probably require maintenance. A public API would probably be the least of all 3.

vale ibex
#

ahh right yea

#

๐Ÿ‘Œ

vocal wolf
#

what's the endpoint?

#

actually, where are the docs

#

I must find them

vale ibex
#

quack.quack.jb3.dev

vocal wolf
#

wack

vale ibex
#

lmfao

short snow
short snow
vale ibex
vocal wolf
#

lol

vale ibex
#

it's jb3.dev facePalm

vocal wolf
#

welp

#

I'm done with going through all the issues in sir lance

#

I've distracted myself from my classes for long enough, I shall now go poof

vale ibex
#

๐Ÿ‘‹

#

isn't it like 3am?

vocal wolf
patent pivot
#

lmfao

vale ibex
#

goto /docs

patent pivot
#

my proposals for quackstack btw:

  • drop the idea of a pypi package, it just is going to end up being a pain to maintain
  • use the api, make it use s3 for storage
#

cc @fervent sage for thoughts on it, but imo at least the best way to get this onto lance is to use the API, if we want to do a CLI down the line we can write a CLI that calls out to our public instance

static canyon
#

This is now fixed ๐Ÿ‘

#

!remind 3D maybe look into the viability of switching to poetry

stable mountainBOT
#
Of course!

Your reminder will arrive on <t:1629973625:F>!

static canyon
#

!remind delete 2867

stable mountainBOT
#
Of course!

That reminder has been deleted successfully!

patent pivot
#

okay solid, cc @vocal wolf @vale ibex @short snow we're not going to proceed with packaging quackstack for now

#

we'll build it as an API, if we want to add a CLI at a later time it will just call our API

vale ibex
#

sounds good

patent pivot
#

okay repo issues updated accordingly

fervent sage
#

cause it was weirdโ„ข๏ธ in structure

patent pivot
#

oo, might still be worth merging in that case okay

fervent sage
#

also it would be nice to have a package anyway just not for lance kek

#

then again for a cli i can just shove api requests at what we already have

patent pivot
#

if we host a public API there is no urgent need for a package

#

yea

#

down the line we can but packaging something just makes things hurt for projects getting off the ground like this

#

we can totally throw a CLI/api wrapper to pypi that just calls our API or allows you to point it at your own instance

#

I'll reopen that PR and it can be updated to align with the fact that we're not shipping a package short term

fervent sage
#

yup

#

pain

#

git cli thinks everything is fine, github thinks there are merge conflicts

patent pivot
#

lol

fervent sage
#

why are github's instructions "git push origin main"

#

that doesnt help me resolve the conflicts for a pr

#

ok it should be good to go, I tested it yonks ago when I first made it and the api still works exactly the same, just cleaned up the indentation issue and merge conflict now

dense bear
#

this is not related directly to PyDis, but it is related to open source.
let's say I want to fix a small issue in the docs of a project. in that case, should i open an issue first or should i open an issue and a pr at the same time?

gritty wind
#

Depends on the policies of the project youโ€™re contributing to. Here for instance, we adopt a โ€œdonโ€™t PR until you get approvalโ€, so you donโ€™t waste your time, and that of reviewers if the changes you made arenโ€™t desired

dense bear
#

got it, thanks!

static canyon
#

I'm adding a quick-fix to the !user command so that the name get's escaped. Not quite sure where to put the escape_markdown but think it's best to just do it at the end?```py
name = str(user)
if on_server and user.nick:
name = f"{user.nick} ({name})"

    if user.public_flags.verified_bot:
        name += f" {constants.Emojis.verified_bot}"
    elif user.bot:
        name += f" {constants.Emojis.bot}"
    name = escape_markdown(name)```
#

Perhaps before adding the emojis actually

green oriole
#

We don't want to be escaping the emojis, yeah

static canyon
#
        name = str(user)
        if on_server and user.nick:
            name = f"{user.nick} ({name})"
        name = escape_markdown(name)

        if user.public_flags.verified_bot:
            name += f" {constants.Emojis.verified_bot}"
        elif user.bot:
            name += f" {constants.Emojis.bot}"
```like this?
green oriole
#

Yep, this looks good

static canyon
#

๐Ÿ‘

#

Damn, straight in with the review Akarys lol

#

Not even 10s lol

timid sentinel
#

woops forgot the bot had tests ๐Ÿ˜ณ

green oriole
#

fwiw you could have left the auto merge, it wouldn't have merged until tests are passing

timid sentinel
#

oh cool

#

that makes sense

dusky shoreBOT
brazen charm
#

@vale ibex Were you planning anything with the merge on the converter typehint pr or can I overwrite it

cold island
#

I don't think he was planning anything

vale ibex
#

Nah, I went to approve it earlier so merged in main, but it caused some issues with the tests

#

I posted here about it, but I suppose I should have said on the PR too

cold island
#

@brisk brook do you have any remaining concerns about bot#1760 or can it be merged?

dusky shoreBOT
brisk brook
#

I'll take another look and approve if it looks good

cold island
#

@green oriole wait wait

green oriole
#

I'm not merging

#

Haha

#

I saw blue's message

left flume
#

@vocal wolf Sorry for the ping but I'm InvisibleOS on GitHub
I initially opened this issue (coin flip command) thinking that it would be a simple command (just how I coded it on my bot during those days) but then I was introduced to more complex types of things in Lancebot's code and the PR would need to be made according to Sir-LanceBot's coding style, which I currently am not aware of.
And since I have had a pretty busy schedule for the past few months and will also be having the same at least until October, I cannot guarantee that I will be able to create the command in the specific style (However, if I'm given more time until October or so then I can create it for sure).
That is why I would like someone else to do it for now - I have changed it on GitHub as well.
Once again, sorry for the delay in response.

stable mountainBOT
#

bot/utils/message_cache.py lines 57 to 58

self._end = (self._end - 1) % self.maxlen
del self._message_id_mapping[self._messages[self._end].id]```
`bot/utils/message_cache.py` lines 47 to 48
```py
del self._message_id_mapping[self._messages[self._start].id]
self._start = (self._start + 1) % self.maxlen```
brisk brook
#

Do you want to change that or should I just approve?

cold island
#

It's on purpose. I need the old value of _start in the second del

#

And the new value of _end in the first one

#

Hmm I guess it would look nicer if I used pop on the dict

cold island
#

Although I don't need the value of the pop so I guess it's fine

brisk brook
brisk brook
static canyon
# left flume <@!196664644113268736> Sorry for the ping but I'm InvisibleOS on GitHub I initia...
class CoinSide(Converter):
    HEADS: t.Tuple[str] = ("h", "head", "heads")
    TAILS: t.Tuple[str] = ("t", "tail", "tails")

    async def convert(ctx: Context, side: str) -> str:
        if side in CoinSide.HEADS:
            return "heads"

        elif side in CoinSide.TAILS:
            return "tails"

        else:
            raise BadArgument(f"{side!r} is not a valid coin side.")


@commands.command(name="coinflip", aliases=("flip", "coin", "cf"))
async def coinflip_command(self, ctx: Context, side: Optional[CoinSide]) -> None:
    flipped_side = random.choice(["heads", "tails"])

    if not side:
        flipped_side = random.choice(["heads", "tails"])
        await ctx.send(f"Flipped {flipped_side}!")
        return

    if side == flipped_side:
        await ctx.send(f"Yay! It was {flipped_side}.")
    else:
        await ctx.send(f"Oh no! It was {flipped_side}.")```out of interest, is this the sort of thing you envisioned for the coin flip command?
#

(The example you sent is no longer accessible since the paste expired)

left flume
#

Yeah, it was something similar, let me send you the enhanced version of the code

#
    @commands.command(aliases = ["toss", "coinflip"])
    @commands.cooldown(1, 3, commands.BucketType.member)
    async def flip(self, ctx, user_choice = None):
        result = random.choice(["Heads", "Tails"])

        if user_choice is None:
            # embed = discord.Embed(description = result, color = 0x7289da)
            await ctx.send(result)

        else:
            # embed = discord.Embed(description = "Flipping a coin...", color = 0x7289da)
            message = await ctx.send("Flipping a coin")
            await asyncio.sleep(.5)

            if user_choice == "heads":
                if result == "Heads":
                    # embed = discord.Embed(description = f"The coin flipped **{result}**\n{ctx.author.mention} won the toss!", color = 0x7289da)
                    await message.edit(content=f"The coin flipped **{result}**\n{ctx.author.mention} won the toss!")
                elif result == "Tails":
                    # embed = discord.Embed(description = f"The coin flipped **{result}**\n{ctx.author.mention} lost the toss!", color = 0x7289da)
                    await message.edit(content=f"The coin flipped **{result}**\n{ctx.author.mention} lost the toss!")
        
            elif user_choice == "tails":
                if result == "Heads":
                    # embed = discord.Embed(description = f"The coin flipped **{result}**\n{ctx.author.mention} lost the toss!", color = 0x7289da)
                    await message.edit(content=f"The coin flipped **{result}**\n{ctx.author.mention} lost the toss!")
                elif result == "Tails":
                    # embed = discord.Embed(description = f"The coin flipped **{result}**\n{ctx.author.mention} won the toss!", color = 0x7289da)
                    await message.edit(content=f"The coin flipped **{result}**\n{ctx.author.mention} won the toss!")

            else:
                embed = discord.Embed(description = "Invalid argument", color = 0xf35353)
                await ctx.send(embed=embed, delete_after = 5)
```Yeah, this was really simple
#

It can be made shorter I think

#

And the embeds can be changed into messages

static canyon
#

We probably do want embeds I think

#

.reverse example

dusky shoreBOT
#

elpmaxe

static canyon
#

.uwu example

dusky shoreBOT
#

exampwe

static canyon
#

Hmm doesn't look like most things use embeds actually

#

.rcase example

dusky shoreBOT
#

ExAMpLe

left flume
#

Yeah, even the rps command is not an embed

static canyon
#

.rps

dusky shoreBOT
#
That was a mistake.

Your input was invalid: move is a required argument that is missing.

Usage:.rps <move>

static canyon
#

.rps rock

dusky shoreBOT
#

@static canyon You and Sir Lancebot played rock, it's a tie.

static canyon
#

right yeah

#

I think embed would look nicer personally but I guess there's some convention or something against using embeds?

left flume
static canyon
#

I prefer the custom-converter version of the side argument but am interested in what other people think ^^

left flume
#

Even I would go with that if it makes the code more efficient. I just have a pretty basic version of it which works decently. It can still be made shorter and/or efficient.

static canyon
#

@left flume Which of these sets of messages do you prefer?```py
if side == flipped_side:
await ctx.send(f"Yay {ctx.author.mention}! It was {flipped_side}.")
else:
await ctx.send(f"Oh no {ctx.author.mention}! It was {flipped_side}.")

    message = f"{ctx.author.mention} The coin flipped **{flipped_side}**. "
    if side == flipped_side:
       message += "You guessed correctly! Congrats!"
    else:
        message += "You guessed incorrectly. Better luck next time!"
    await ctx.send(message)```
left flume
#

Considering that both do the same thing, I'd go with any

static canyon
#

It's just what message you think sounds/looks better

left flume
#

oh if youre talking about the message then...

static canyon
#

yeah

left flume
#

let me think

static canyon
#

The actual message

left flume
#

The second one as it sounds more formal and clear, I suppose

static canyon
#

Yeah, I agree to be honest

#

You guessed correctly! lemon_hyperpleased

You guessed incorrectly. lemon_pensive

thorny obsidian
#

why not emoji first?

static canyon
#

lemon_hyperpleased You guessed correctly!

lemon_pensive You guessed incorrectly.

#

hmm

#

Not sure which I prefer

patent pivot
#

!remind 1h this

stable mountainBOT
#
You're the boss!

Your reminder will arrive on <t:1629749927:F>!

patent pivot
#

I did run this before and we were pretty alright, but I don't have the output on hand, so I'll run it again

#

It's worth noting we're not trying to hoard NSA data, lol, so not all of the points are entirely relevant

static canyon
static canyon
fallen patrol
#

if someone has to work on the file tho they won't have the emojis which is the only reason why I can see using constants.py

static canyon
#

I'd do likepy LEMON_HYPERPLEASED = "![lemon_hyperpleased](https://cdn.discordapp.com/emojis/754441879822663811.webp?size=128 "lemon_hyperpleased")" LEMON_PENSIVE = "![lemon_pensive](https://cdn.discordapp.com/emojis/754441880246419486.webp?size=128 "lemon_pensive")"

#

I suppose I might as well put it in constants.py?

#

Unless stuff there is reserved for some reason

fallen patrol
#

oh

fallen patrol
#

just remembered that lance doesn't have a configuration system except for constants.py lol

static canyon
#

Yeah

#

Would it go in constants.py or just the top of the file I'm working on?

fallen patrol
#

top of the file you're working on, IMO

static canyon
#

Okay

#

And should I add this coinflip command to an existing cog (e.g. bot.exts.evergreen.fun.Fun) or create a new one (bot.exts.evergreen.coinflip.CoinFlip)?

#

I suppose a new file since I'm creating another class

#

Yeah, I think that makes the most sense

clever wraith
#

Um

#

@vocal wolf

#

Hey

#

I just saw this message

#

But I didnโ€™t respond to it in time

#

Is there a chance where I can still try?

brazen charm
#

Don't see why not if nobody started working on it

green oriole
#

Yup, if nobody claimed it you can get back to it!

static canyon
#
import random
from typing import Optional, Tuple

from discord.ext import commands

from bot.bot import Bot


LEMON_HYPERPLEASED = "![lemon_hyperpleased](https://cdn.discordapp.com/emojis/754441879822663811.webp?size=128 "lemon_hyperpleased")"
LEMON_PENSIVE = "![lemon_pensive](https://cdn.discordapp.com/emojis/754441880246419486.webp?size=128 "lemon_pensive")"


class CoinSide(commands.Converter):
    HEADS: Tuple[str] = ("h", "head", "heads")
    TAILS: Tuple[str] = ("t", "tail", "tails")

    async def convert(self, ctx: commands.Context, side: str) -> str:
        if side in CoinSide.HEADS:
            return "heads"

        elif side in CoinSide.TAILS:
            return "tails"

        else:
            raise commands.BadArgument(f"{side!r} is not a valid coin side.")


class CoinFlip(commands.Cog):
    """Cog for the CoinFlip command."""

    @commands.command(name="coinflip", aliases=("flip", "coin", "cf"))
    async def coinflip_command(self, ctx: commands.Context, side: Optional[CoinSide]) -> None:
        """
        Flips a coin.

        If `coin_side` is provided will state whether you guessed the side correctly.
        """
        flipped_side = random.choice(["heads", "tails"])

        if not side:
            flipped_side = random.choice(["heads", "tails"])
            await ctx.send(f"{ctx.author.mention} Flipped **{flipped_side}**!")
            return

        message = f"{ctx.author.mention} Flipped **{flipped_side}**. "
        if side == flipped_side:
            message += f"You guessed correctly! {LEMON_HYPERPLEASED}"
        else:
            message += f"You guessed incorrectly. {LEMON_PENSIVE}"
        await ctx.send(message)


def setup(bot: Bot) -> None:
    """Loads the coinflip cog."""
    bot.add_cog(CoinFlip())
```does this look good? @left flume @fallen patrol
vocal wolf
#

@clever wraith which issue is this?

clever wraith
#

one sec

clever wraith
vocal wolf
#

sir-lancebot#730

dusky shoreBOT
clever wraith
#

yeap

vocal wolf
#

I've re-assigned you to this issue, you can now work on it

clever wraith
#

But i believe itโ€™s free

#

I havenโ€™t touched the code since may lol

vocal wolf
#

it do be like that sometimes

#

since it's a free api, you should be good

timid sentinel
#

Looks like the issue shouldn't necessarily need an API, unless it's just to get a random word rather than using a word list file, which I guess is fine

#

Although actually I'm not sure how that would work... would have to see the usage

stable mountainBOT
clever wraith
#

oh god my code is so spaghetti

#

jesus

#

it is currently at 120 ish lines

#

holy moly

static canyon
#

How do I create a pull request from git? My understanding is I need to do something like hub pull-request -m "Create CoinFlip command" -m "Closes #612" -m "Adds a coinflip command to the bot." -a TizzySaurus -l "type: feature" but hub comes up as an unrecognised command

green oriole
#

I'd recommend using gh now, but those two are github specific tools, you need to install them separately

static canyon
#

Ah right, I see

#

I'll just use GitHub then

brisk brook
#

GitHub Desktop should allow you to open a pull request, though I think that just opens a tab on your browser

green oriole
#

Tizzyyyyyyyyyy

#

Where is my precommit at

static canyon
#

precommit?

#

@green oriole

brisk brook
#

Precommit hooks, stuff that run before you commit

#

Stuff like linters and tests, in this case Akarys is claiming that either of the two failed. It would've been caught by these

static canyon
#

Ah right yeah

green oriole
#

It will run flake8 before committing, making sure you get no failed lint, yep

static canyon
#

I did know I was missing the docstrings but apparently forgot to add anyway

#

How do I undo a local commit again?

brisk brook
clever wraith
#

how does this look for issue 730?

clever wraith
#

extremely spaghetti code - 140 lines

static canyon
#

I made a commit fixing the docstrings that didn't completely fix the docstrings

clever wraith
#

dont h8 pls it was from may

cold island
#

git revert HEAD~1 iirc

brisk brook
brazen charm
#

just amend it

brisk brook
cold island
#

reset just undoes git add

#

revert --hard loses changes

green oriole
#

Reset will keep changes unless the hard flag is passed

cold island
#

Without --hard it keeps them

green oriole
brisk brook
# clever wraith dont h8 pls it was from may

I am sure you've grown a bit as a programmer since, see if you can design it differently. Otherwise clean it up and submit a pull request, the way you've done it may be the only way.

#

Ah right, I see now @green oriole @cold island

clever wraith
green oriole
#

The amend flag is perfect for fixing lint errors though

cold island
green oriole
#

git commit -a --amend --no-edit is my favorite

brisk brook
#

Hmm

static canyon
#

Couldn't get it to work so just added another commit

#

If I really wanted to I could squash them but like can't be bothered

brazen charm
green oriole
#

Soft: delete commit, keep staged, keep changes
Mixed: delete commit, unstage, keep changes
Hard: nuke everything

cold island
green oriole
#

Revert will apply the invert of a commit, yeah

brazen charm
#

amends and fixups should be enough for most things like this

static canyon
#

Eh I decided to squash in the end lol

brazen charm
#

I have been wondering about merge commits, would it be fine to add code to fix errors introduced from the merge in them, or should those be commited separately?
For example in https://github.com/python-discord/bot/pull/1731 the be9bc9c commit fixes an error introduced by the previous merge commit, would it be okay to do that in the merge?

green oriole
#

I think so, I do that from time to time. I try to always have working commits, in case of a future bisect.

patent pivot
#

@clever wraith

green oriole
#

What am I looking at

#

This looks like some form of audit

patent pivot
#

how the united states national security agency views our kubernetes cluster

green oriole
#

lol, they seem quite happy

#

Are we getting recruited

patent pivot
#

lmfao

#

I'll go through these at some point and correct, a lot of them are fairly trivial

last patio
#

immutable fs is fun

dim pelican
#

NSA has joined the chat (probably)

green oriole
#

I mean they are already in every chat

patent pivot
cold island
dry folio
#

.bm test

#

this should be whitelisted as well

#

also, nice

#

.source bm

static canyon
#

sir-lancebot#814 also needs reviews please

dusky shoreBOT
fallen patrol
#

thank god

dim pelican
#

Anyone want to check out Sir-Lancebot#805 ?

dusky shoreBOT
green oriole
#

If it doesn't work, try with the full link

#

If the bot restarted, using only the ID won't work

#

Anything that takes messages will also work with links, glad it worked!

vale ibex
#

Yea, message IDs aren't enough to specifiy an exact message. You need a channel ID & message ID. If you supply just a message ID, we assume you are referring to a message in the current channel

#

You can either use a full link, or do channelID-messageID

#

IE 635950537262759947-879652841806004255

#

We don't have a set list of things that we approve or don't. It's more of a feeling of if something is suitable for our server

stable mountainBOT
#

discord/ext/commands/converter.py lines 373 to 386

class MessageConverter(IDConverter[discord.Message]):
    """Converts to a :class:`โ€‹discord.Message`โ€‹.

    .. versionadded:: 1.1

    The lookup strategy is as follows (in order):

    1. Lookup by "{channel ID}-{message ID}" (retrieved by shift-clicking on "Copy ID")
    2. Lookup by message ID (the message **must** be in the context channel)
    3. Lookup by message URL

    .. versionchanged:: 1.5
         Raise :exc:`โ€‹.ChannelNotFound`โ€‹, :exc:`โ€‹.MessageNotFound`โ€‹ or :exc:`โ€‹.ChannelNotReadable`โ€‹ instead of generic :exc:`โ€‹.BadArgument`โ€‹
    """```
patent pivot
#

most stuff is default tbh

#

and control plane stuff is managed by Linode

#

eh, doubtful

#

kubeadm and k3s and whatnot have very sane defaults

#

A lot of the checks on control plane are things you need to explicitly configure to be unsafe, the defaults assume the most safety

#

I'd certainly view the default settings but Kubelet configuration can be hundreds of lines, and if you just keep defaults it's not worth overriding

celest charm
#

What are the benefits of adding mypy to the CI?

brazen charm
#

less bugs for reviewers to take care of? Although I think more time will be spent on making the checker happy than what'll be gained

celest charm
#

...and then the only solution will turn out to be slapping Any on half the things

#

I like static typing, but it always disappoints me

brisk brook
#

We don't need to run it on strict, bit just the normal one with errors could be good. As @static canyon has explored though, the codebase has a lot of these errors already

static canyon
#

A lot of said errors are easy fixes though. Things like making t.List[str] into a t.Sequence[str] etc.

#

Some are even just making t.Union[x, None] into t.Optional[x]

viscid coral
vale ibex
#

This isn't snekbox, this is directly inside @stable mountain

viscid coral
#

Oh

vale ibex
#

Admins+ have the ability to exec code directly on the python instance using !internal eval

#

So this change means that if you share a testing server with someone else, they can't exec code on your computer by default

vale ibex
#

No, we still have

#

There's now an env var BOT_DEBUG that is True by default

#

which disables internal eval to only the bot owner

#

we have that disabled in prod though

viscid coral
#

Oh ok

#

And is there a guide for me t host it by myself from VSCode?

vale ibex
#

The python bot?

viscid coral
#

Oh thank you very much!

static canyon
#

If an import is too long, how do I make it compliant to the 120 chars?py from bot.constants import Guild, Icons, MODERATION_ROLES, POSITIVE_REPLIES, Roles, STAFF_PARTNERS_COMMUNITY_ROLES, STAFF_ROLES

brazen charm
#

warp in parentheses and import the names on individual lines

static canyon
brisk brook
#

Unless you've changed it

static canyon
#

I haven't changed yet

#

Black goes with what I did

static canyon
#

Thanks ๐Ÿ‘

static canyon
#

Any ideas how to shorten this to 120 chars (currently 136)?py # If the user is not staff, partner or part of the python community, we need to verify whether or not to make a reminder at all.

green oriole
#

put a line break after community mmLul

static canyon
#

I've also got an issue with a docstring which is too long to be on one line but when I put it on its own line (separate from quotes) I get a lint error saying it should be on the same line (One-line docstring should fit on one line with quotes)

green oriole
#

Yep

#

No idea about docstrings though

static canyon
#

Tried adding a blankline after before ending quotes but that didn't work

#

This version is over 120 charspy """Lists all users who aren't staff, partners or members of the python community and have permission to stream."""and this gives error saying it should be on a single line (which makes it >120 chars)py """ Lists all users who aren't staff, partners or members of the python community and have permission to stream. """

green oriole
#

Right, I guess we need a smaller docstring then

static canyon
#
        """Lists all users who aren't staff, partners or members of the python community and have stream permissions."""
#

Exactly 120

green oriole
#

Really Tizzy, please install precommit

static canyon
#

I have no clue how

#

I'm able to do poetry run task lint but just keep forgetting to

vale ibex
#

poetry install then poetry run task precommit

#

that'll install the hook for you

static canyon
#
(bot-6mLjCNeK-py3.9) C:\Users\tizzy\bot>poetry run task precommit
pre-commit installed at .git\hooks\pre-commit
vale ibex
#

yup that's it

static canyon
#

So now whenever I commit it'll automatically run the task?

vale ibex
#

now, when you try to commit, it'll run the linting against the staged files

static canyon
#

Right

#

And it prevents the commit if there's issues?

vale ibex
#

yup

static canyon
#

Nice ๐Ÿ‘

vale ibex
#

sometimes it'll even fix them for you

static canyon
#

Wait what

#

The linting passes locally but failed on github

#

Nvm, it's because I did a merge

#

I think it's all good now ๐Ÿคž

#

Eh fuck

#

It broke the tests

#

No clue how to fix them

#

I think it's because the decorators use constants.STAFF_PARTNERS_COMMUNITY_ROLES but that's not defined in the test?

#

Yeah, I think so

#

I'll try and fix locally

#

Eh, I have no clue what I'm doing lol @vale ibex

#
    @unittest.mock.patch("bot.exts.info.information.Information.create_user_embed")
    async def test_staff_members_can_bypass_channel_restriction(self, create_embed, constants):
        """Staff members should be able to bypass the bot-commands channel restriction."""
        constants.STAFF_ROLES = [self.moderator_role.id]
        ctx = helpers.MockContext(author=self.moderator, channel=helpers.MockTextChannel(id=200))

        await self.cog.user_info(self.cog, ctx)

        create_embed.assert_called_once_with(ctx, self.moderator)
        ctx.send.assert_called_once()
```this is one of the tests that I need to fix/update
#

It's staff and partners+python community members that can bypass so I suppose it should be updated to test all three?

vale ibex
#

The problem is coming from that fact that this test is overwriting constants.STAFF_ROLES to a set ID

#

but, we don't use that for the whitelist check anymore, and updating the constant there, doesn't also update the new constant

#

So the fix for this test would be to update the constant on the first line to the new one

static canyon
#

๐Ÿค”

static canyon
vale ibex
#

yup

#

There may be more tests that fail like this too

#

So you probably want to run poetry run task test before commiting

#

so you can get all the failures in one commit

static canyon
#

Yeah there's 1 more

static canyon
vale ibex
#

Nice ๐Ÿ˜„

static canyon
#

All works ๐Ÿ‘

#

8 warnings but I'm assuming we don't care about those

#

Pushing ๐Ÿคž

#

Nice ๐Ÿ˜„

molten perch
#

Hey! I know it's a fairly old issue, but I believe it's still relevant.
Could someone take a look at bot#1348 ?

dusky shoreBOT
vale ibex
#

ehhh, I'm not sure how I feel about this in general

#

I'm not sure what problem it's trying to solve

molten perch
#

Generalising embed creation.
Like, sometimes we create embeds like

embed = Embed(title=random.choice(NEGATIVE_REPLIES), colour=Colours.soft_red)

Sometimes we use functions like:

    def _get_error_embed(self, title: str, body: str) -> Embed:
        """Return an embed that contains the exception."""
        return Embed(
            title=title,
            colour=Colours.soft_red,
            description=body
        )

That would make it way more convenient.

#

(Not sure why syntax highlighting is not working, I'm sorry :/ )

brisk brook
molten perch
#

Do what, precisely?

brisk brook
#

Have a helper function

molten perch
#

Yes, indeed. But that would generalise it, and you wouldn't have to define functions all around the code to make it easier to create an embed.

molten perch
#

Well, I have an idea based on the previous discussions in that issue. It's explained there in depth. (bot#1348)

dusky shoreBOT
molten perch
#

(I'd call it a suggestion, rather than an idea ๐Ÿ˜„ )

tawdry vapor
#

I don't think something as trivial as changing the colour needs to have a helper function

#

If there is a more complex set of operations that consistently need to be performed, then that's a good candidate

molten perch
#

As mentioned in the issue, there would also be an option like allow_delete that would handle reaction based messaged delete.
(With the trash can emoji)

#

Also, if you want to add other operations along the way, it is as easy as adding it to the helper function this way it can be used everywhere.

tawdry vapor
#

Squeezing to much functionality into a single function can make for a clunky, confusing, and/or inflexible interface

molten perch
#

As of now, the only functionalities it would have are categories, and handling the deletion of those embeds.

vale ibex
#

So the category would control the colour, and in the case of errors auto add the title

#

but for the other categories, it would still accept a title as an arg?

molten perch
#

I believe so, yes.

vale ibex
#

So there, you're trading the import of the negative replies and flexibility, for the import of this helper function

#

automatically handling the deletion is nice though, having it in a helper function would mean that when we want to migrate to buttons that would be easier

molten perch
molten perch
tawdry vapor
#

Keep in mind that the deletion cannot be added without actually sending the embed. It means a channel has to be passed to the function.

molten perch
#

Indeed, but that would be handled by this helper function.
(Tbh. I might have made a bad example in the issue, I passed the whole context object as an arg)

vale ibex
#

yea, and actually when we want to swap to buttons, those aren't part of the embed

#

so would need to be done in the send itself too

molten perch
#

Yes, you'd just pass the view in the send instead of reacting with an emoji and waiting for a reaction.

vale ibex
#

This would also mean that we need to send the embed within the helper function, which means we lose the option to add fields to it

#

unless we make this a whole class with a send function

#

It seems like quite a lot of effort for somewhat minimal gain

molten perch
#

Yes, that was my first plan, but I trashed it because it did not seem consistent to have a separate send function.

vale ibex
#

since we could just make the view creation itself a util

tawdry vapor
#

How many instances does the code base have of all of the above

  1. Only sending 1 embed
  2. Not sending any messages or attachments with the embed
  3. Not modifying any of wait_for_deletion's params besides message and user_ids

For more flexibility the embed can be created externally passed rather than passing args and having the util construct the embed object. Would also make for a cleaner interface.

vale ibex
#

when we migrate to d.py 2.0 I can see the use in having a generic delete ui.View, since that will have the same implementation for pretty much everything

molten perch
#

Well, in that case it's also a solution to halt the issue until the release of dpy 2.0

vale ibex
#

I think that would be a separate issue though

#

to create the deletion button view

#

I don't think this issue itself is worth it

molten perch
#

It was opened back in January, back then I believe dpy 2 was far away! ๐Ÿ™‚

vale ibex
#

hah yea

molten perch
#

I guess, this issue can be closed, then? ๐Ÿ™‚

vale ibex
#

Yea I could be, unless other core devs are highly in favour of it

green oriole
#

bot#1348?

dusky shoreBOT
green oriole
#

I'd close it, yes

#

I agree with your comment, I don't see what it is trying to solve

vale ibex
#

yea, having generic ui.Views will be really useful when 2.0 comes

green oriole
#

Ah yeah obviously I don't know anything about the 2.0 api

vale ibex
#

they're how you add buttons and drop downs

#

and define what happens when you click them

#

it's a new kwarg on .send() calls

green oriole
#

So you make a thing, add it to the thing, and that gives you a thing you can send to the thing to have a thing you can click to do thingy things?

#

Is that a good abstract?

vale ibex
#

!paste

stable mountainBOT
#

Pasting large amounts of code

If your code is too long to fit in a codeblock in discord, you can paste your code here:
https://paste.pydis.com/

After pasting your code, save it by clicking the floppy disk icon in the top right, or by typing ctrl + S. After doing that, the URL should change. Copy the URL and post it here so others can see it.

vale ibex
#

this is how I do the email thingy for the appeal

#

then I just do ctx.send("some message", view=ConfirmAppealResponse())

#

the init and stop methods are just so I could have more control

#

they're not needed

green oriole
#

This manual lock interaction makes me go really sadge

vale ibex
#

I'm not even sure it is needed

#

I should really actually test it

#

We solve this in arthur by only allowing the author to click buttons afaik

#

but since I wanted anyone with access to click, I added this

#

didn't see any controls in d.py itself

vale ibex
austere hornet
#

Wait I thought the dev-voice channel was locked before... just curious why it is unlocked now?

vocal wolf
#

it was locked a while back

#

I think there was no reason for it to be locked, so it became unlocked

austere hornet
#

Oh ok, I see

vale ibex
#

Yea, but only contribs+ have speak perms

vocal wolf
#

ye

austere hornet
#

Ohhh

vocal wolf
#

that too

austere hornet
#

That makes more sense

#

Thanks

last patio
vocal wolf
#

we may never know

last patio
#

๐Ÿฅฒ

austere hornet
#

Wait what is this stream about? Sorry I can't really join rn to listen and I just found out. Maybe I missed an announcement or smth

last patio
#

Joe is securing containers / pods in the Kubernetes cluster according to security guidelines created by the Kubernetes operators at NSA

austere hornet
#

Oh, I see

last patio
#

like read-only root filesystem, restricting access permissions

austere hornet
#

Cool, thanks

molten perch
#

Can I stay? ๐Ÿ˜›

solemn kayak
#

I think some of the builtin docs are missing from @stable mountain , e.g. list.index, tuple.index

tawdry vapor
#

I believe this is a consequence of how Python organises their documentation.

#

These functions are not directly attributed to the list type. Instead they're documented under a more generic "mutable sequence" type which I don't think has an actual symbol.

torpid cedar
#

@patent pivot why use Redis ??

last patio
#

"it's webscale"

torpid cedar
last patio
#

i am the messenger, please interview @patent pivot

torpid cedar
#

@patent pivot God night redis or good night redis ??

Also good and god night all

vocal wolf
#

json is the only viable database /s

eager fable
molten perch
#

Thank you! Bye!

patent pivot
#

lol, immutable fs & non-root is something I've wanted to do for a long while, this just reminded me

thorny obsidian
#

me, not noticing Chris had fucking automerge enabled: pensive_cowboy

clever wraith
patent pivot
#

paper from the NSA on securing Kubernetes clusters

#

we do use Kubernetes yeah

static canyon
#

Is bot#1382 still something we want? I don't think it was ever formally approved

dusky shoreBOT
static canyon
#

I'm also not sure as to how exactly it would be implemented, since it's a tag and so content is hard-coded in a file

#

Could perhaps add a placeholder which we do str.format on but that seems untidy

gritty wind
#

A lot of people were against it

#

I donโ€™t think it adds much benefit

patent pivot
#

it's a method of deploying and managing your applications, centered around containers

gritty wind
#

Itโ€™s also only important in like py-gen, so itโ€™s never been a problem I encountered, so maybe Iโ€™m not the best judge

patent pivot
gritty wind
#

!paste

patent pivot
#

Kubernetes is the tool and platform, the above paper is on ensuring your usage is secure

gritty wind
#

(The message the bot sends would have a ping for you)

static canyon
#

The idea was to make it clear who the message is for, within the message

#

And since embeds don't actually ping the user you don't have an issue of double pings

#

Yeah

gritty wind
#

I donโ€™t like the idea, for the reasons I mentioned above. From an execution standpoint, it isnโ€™t too difficult to inject to the beginning or end of the content

static canyon
#

If people are against it then perhaps it should be closed

static canyon
gritty wind
#

Yeah, I got that. You donโ€™t need to change anything

#

Just add a new line embed.content = embed.content + ping

#

If itโ€™s immutable, clone it

#

Just basically people discussing here and on the issue

#

The things that are discussed are along the lines of:

  • do we want this feature?
  • will it cost too much?
  • is it possible to technically implement
#

Well, sort of. One person is all thatโ€™s needed to close something, we donโ€™t have a set limit.

So far, no one has abused that power, so it remains the system.

green oriole
#

is

#

!paste Hey at-Scaleios, please use a paste for longer snippet

stable mountainBOT
#

Pasting large amounts of code

If your code is too long to fit in a codeblock in discord, you can paste your code here:
https://paste.pydis.com/

After pasting your code, save it by clicking the floppy disk icon in the top right, or by typing ctrl + S. After doing that, the URL should change. Copy the URL and post it here so others can see it.

green oriole
#

not enough?

static canyon
static canyon
green oriole
#

but it is just under the command?

#

I never seen someone being confused by that

static canyon
#

That seems to be an exaggeration actually

green oriole
#

Should we use tags in pygen at peak times though?

#

because if it scrolls that fast, it doesn't seem like we want to

static canyon
#

It's also public members doing it a lot of the time, and we can't exactly restrict that without restricting tags from #python-discussion to staff+ (and partners/py community I guess)

static canyon
short snow
#

why not just reply to the context message?

static canyon
#

And !paste @user would reply to the author not user

#

Suppose that's not a big deal though

#

Could probably even make it so that all tags reply to the invocation

#

Don't really see the harm in it

#

But then is it really needed?

green oriole
#

In most cases it will be useless echo though

static canyon
#

Yeah

#

I don't really think it's worth it to be honest

#

Nor do I think bot#1382 is really worth it

dusky shoreBOT
molten perch
#

As a future idea, it might be also a solution (maybe a wrong one), that when you invoke a command like paste and a mention it'll send the mentioned user an embed with the title (eg.: "Pasting large amounts of code") and a button like Show more that'll reply with the full content in an ephemeral message.
But, that's still far away ๐Ÿ™‚

vale ibex
#

Yea that does sounds pretty nice

#

There's a whole bunch of new features we can make use of in Discord now, I think we mostly need to spend some time playing with them and I'm sure we'll think of loads of improvements we can make

#

Some easy ones are replacing emoji interactions with buttons

molten perch
#

Is there any official statement when dpy. v2 might be released?
(This morning they released a changelog of a lot of changes that'd been made)

vale ibex
#

nope, no official release date

#

it's fairly stable now though and most of the things they wanted are in

#

We're using 2.0 in @brisk belfry and @radiant merlin right now, and it's working fairly well

molten perch
#

But I believe you'll wait to implement it in @stable mountain , until it's officially stable.

vale ibex
#

Yup, that's the plan

#

I've been writing @brisk belfry in a way that the cogs can be dropped into Python with minimal changes

molten perch
#

Oh, I see.
Though, it's quite hard to maintain a bot in production when..

    - Message.start_thread was renamed to Message.create_thread
    - TextChannel.start_thread was renamed to TextChannel.create_thread

๐Ÿ˜„

vale ibex
#

yea lol, I stumbled into that

gritty wind
#

I meanโ€ฆ I presume most sane places lock versions. This is only a prod problem if youโ€™ve got real bad practices ๐Ÿคก

vale ibex
#

yea, that burn made me then lock the revision lol

gritty wind
#

Oh this wasnโ€™t a dig at threadbot, I didnโ€™t know lol

vale ibex
#

it should have been lol, I spent like30 minutes trying to figure out why it broke

gritty wind
#

Oh man, thatโ€™s not fun

gritty wind
#

Hey @green oriole can we use a pipe in the env vars so we donโ€™t need backslashes after every line?

#

Well then

#

Nvm

green oriole
#

apparently you don't even need backslashes?

#

Not sure

#

Sadge it has to go through Poetry install every time

#

hmf

gritty wind
#

Seems aliases are not fully fully handled

#

Still better than nothing

#

Or what

#

I donโ€™t acc understand

green oriole
#

no I think the problem are the spaces between the ;

#

Yep

#

That's dumb

#

Yep, that's it. I am sending an upstream PR.

gritty wind
#

Does the pipe fix this

green oriole
#

It does not

gritty wind
#

Youโ€™re Italian, how could you have not tried the pipe

green oriole
#

In YAML you have to convert the line breaks to space or keep line breaks, you can't have nothing

gritty wind
#

Bleh, no rush on the PR

green oriole
timid sentinel
green oriole
#

yes sir

#

Ah I was about to say you could dismiss my review but you also need a core dev review

#

If anyone here doesn't know where that button, since it is pretty much hidden, it is right there

#

It allows you to basically void the review and pretend it never existed

#

Quite useful, even if the embed generated by the webhook sucks

brisk brook
#

Why? If you'd approve it again that would just override the Requested Changes review?

green oriole
#

Yep, but imagine I wasn't around and the requirements were met, only my stale requested changes blocked the merge. Wookie could have dismissed my review since the changes have been applied, and merge.

timid sentinel
vale ibex
#

I also dismiss reviews if someone approved, but there have been significant changes since then

gritty wind
#

Petition to auto dismiss reviews and make everyone suffer

vale ibex
#

I pretty sure we looked into doing that before

green oriole
#

no catkill

gritty wind
#

I think we have (or had) it on forms

narrow stream
#

yea[

#

p

molten perch
#

Hey! Any thoughts on this? site#369 it still seems to persist, and the migration to FastAPI is still far away. ๐Ÿ™‚

dusky shoreBOT
junior grove
#

is this the place to put server related suggestions?

tawdry vapor
#

If it's for a project-specific suggestion then create an issue on the relevant project or comment here

static canyon
junior grove
#

cheers

tawdry vapor
#

@patent pivot can you push your templates to meta?

patent pivot
#

yep yep, will put them there now

tawdry vapor
#

I think they are decent and we can refine them as we go, but anything is better than what we currently have

patent pivot
#

where did we land on blank issues?

tawdry vapor
#

I don't think we landed

patent pivot
#

hm, personally I'd rather keep them off because we have defined a set of good flows with the templates, but it does break mobile support

tawdry vapor
#

It only breaks on the official mobile app

#

Works fine through browser

patent pivot
#

ah right, that's better then

tawdry vapor
#

I guess I agree. Keep it off

patent pivot
tawdry vapor
#

Thanks

patent pivot
#

yep, already posted it in our dev-ops chat

#

we'll likely standardise some stuff

#

notably kubernetes deployments & maybe docker image builds

#

will probably move to single manifests again too

gritty wind
#

Are there docs for this. Iโ€™ve read the blog post and guide, but those are more general overviews

#

If there arenโ€™t, anyone know how secrets are handled? Namely, can you have a secret in the action repo that you use in the final repo

green oriole
#

Taking a blind guess but I really don't think secrets will be copied. We have all of our secrets as org secrets either way

short snow
#

Did github change its colours?

green oriole
#

Where?

static canyon
#

The bot will still ban them (you can ban people who aren't in the server)

#

It didn't just now because I got the id wrong

#

No

#

That's not the case for user ids. name#discrim etc. won't work but ids will

#

Yes

#

Mhm

#

Our ban has MemberOrUser since we do extra stuff if they're in the server (such as sending dm)

deft patrol
#

oooo dev voice

short snow
# green oriole Where?

the green colour on approval, then the review file area, the yellow review equest are kinda more darker imo

austere hornet
deft patrol
#

I see.

green oriole
short snow
#

default dark

green oriole
vale ibex
#

.int e print("test")

dusky shoreBOT
#
test

vale ibex
#

๐Ÿ‘Œ

green oriole
#

Damn, chris 2 fast

#

thank you

static canyon
#

Can I get some reviews on bot#1778 please? Just a small little addition

static canyon
#

Thank you lemon_hyperpleased

molten perch
#

Hey! Any opinions on this issue? bot#1057
It's a fairly simple thing, still quite useful.

dusky shoreBOT
short snow
short snow
green oriole
timid sentinel
# short snow What's your thought on this <@!493839819168808962> ?

You could probably .split the title and then redact the individual words individually, it could give some weird results (e.g. if the title was ben and jerry it would remove all occurences of the word and), but at least wouldn't give the answer away. It could also be good to replace the words with placeholders of the same length to give a bit of a hint (e.g. hello you would become ***** ***) although I don't mind about that

molten perch
gritty wind
#

Some errors are not worth handling

#

For instance, theoretically any time we communicate with the discord API, we run into the risk of hitting a 500 error

#

But that doesnโ€™t mean we should wrap every single api call

thorny obsidian
#

Have we hit recent 404 issues, like with applying the muted role?

gritty wind
#

Just ones that we know are problems

green oriole
#

I don't think we want to handle every 404, we surely want to be aware where they can happen and see if it is an expected failure or not

green oriole
green oriole
molten perch
thorny obsidian
#

Because if a user leaves while we try to apply the muted role, what happens?

green oriole
#

It doesn't apply it, and next time they join it is applied

gritty wind
green oriole
green oriole
gritty wind
#

Do we really get all that many 500s to begin with

molten perch
gritty wind
#

Any error already triggers a sentry error

#

There isnโ€™t anything a global handler can change other than swallow up the error

#

To go back to the original issue, if itโ€™s no longer relevant, because the code has been removed, we should close it. We shouldnโ€™t add anything extra globally here. If we have 404s in the future, weโ€™ll handle them as needed

#

This is my official medical designer opinion

molten perch
green oriole
gritty wind
#

Not sure what youโ€™re talking about, havenโ€™t been following alerts. Were they not grouped?

green oriole
#

You wish

#

Every execution path creates a new alert

#

we had roughly 50-100 alerts this day?

spare chasm
#

Hello

#

I was trying to run a bot that can use snekbox for an eval command and wanted to know how I could add some external environments to it if it is possible?

#

i'm using docker compose to run the snekbox and the discord bot

short snow
vale ibex
#

What is this in your message?

short snow
#

the public URL

vale ibex
#

yea, you can load it

#

you jsut won't have a login

short snow
#

example lemon_hyperpleased

vale ibex
short snow
#

i have to login

#

hence i asked the quesiton

vale ibex
#

Yea, i still don't understand what you were asking

#

Are you asking if my change means you now have access to metabase?

short snow
#

Yeah, if we can see the query results, from what I remember you need to be logged in to interact with the Metabase, you can't do anything if you are logged in, but then you said, so when you mentioned "sharing link" I thought that was meant for sharing it to us.

vale ibex
#

Ah, right ok. So yea, metabase has a way for you to open a given question (their term for report) to public, this change is jsut a bug fix so that it uses the right URL

#

Since only admins have normal access to metabase, not admin access which is needed to share something, we use this command as a way for admins to share reports with mods during raids, or others if needed

short snow
#

Ohh, could you run an example query?

short snow
#

Nice, you don't get the โœจ graphs โœจ ?

vale ibex
#

This one is just a table

#

there are graphs etc

vale ibex
#

@severe tangle in what context do you imagine this new tag would be used? bot#1784

dusky shoreBOT
severe tangle
#

Ah, well many people in #discord-bots channel tend to use global variables for their functions, but using bot variables is considered better for discord.py

vale ibex
#

Ok, so this tag would be used when a user is trying to use a global variable in their code, so we can show them a preferred way?

severe tangle
#

Yup

vale ibex
#

Alright, I think we should simplify the tag a lot to focus on that then

severe tangle
#

or if they want to use a variable across different files, where they can access the bot instance

#

Ah, thanks for that!

vale ibex
#

Also, in future, please open an issue before writing a PR

severe tangle
#

ah ok. sorry, my bad :c

vale ibex
#

since we can have these discussions before you raise a PR

severe tangle
#

ohk

brisk brook
#

Oh right you're in here, so we can discuss it here over IRC

severe tangle
#

ah, better haha

#

BTW, would there be really a need to add the name kwarg in the decorator?

vale ibex
#

Bot variables are a new type of global variables
They're not really global variables, so we shouldn't call them that

#

I think think tag should be, why global vars are bad, and how to define bot attr vars

severe tangle
#

ah

vale ibex
#

everything else is just noise that dissuades users from actually reading it

severe tangle
#

ohk

#

so u mean, something like. How bot variables are better than globals?

brisk brook
#

Uhh, I made some changes to the docstrings of those commands. Other than that, I am at the ends of my knowledge. I don't really think there is anything else which I can change (Though thanks to you for suggesting all those changes)...

What I am specifically looking to change is the first and last messages. We want to explain the following:

  • Bots are classes that you can add attributes - no need to explain them, just mention they're like variables
  • You can both get and set attributes as you wish
  • You can reach these attributes anywhere you have the bot because the attributes are on the bot itself
  • They may overwrite discord.py attributes, so be careful

Currently, you're explaining this:

  • In ONLY discord.py there's something called bot variables, they're new - you won't find this definition elsewhere so users can't google to learn more
  • You can access them anywhere you have your bot instance
  • They're better than global variables because they can be accessed anywhere you have the bot
  • They can overwrite existing attributes
severe tangle
#

Oh

brisk brook
#

To be fair, there's actually nothing wrong with using global x. But using an attribute on the bot is much more swifter agreed

#

Many people only have their bot in one file, so it makes sense

#

We should clarify that it's when the bot is over several files that it is the most helpful

severe tangle
#

But people who are seriously into some advanced bot deving would certainly divide their bots into many files/Cogs. So this tag can become helpful for them.

brisk brook
#

Oh yeah I am not doubting the tags effectiveness, it will be useful.

#

Since this tag is discord.py focused, I think it should also say "You can do the same to cogs (self)" or similar

severe tangle
#

Ah, ok

#

So I can just start the tag with something like, Bot variable is something, that the library allows us to set, by setting attributes to the existing commands.Bot instance

brisk brook
#

Ehh, no. I dislike the term "bot variable". It's not called a bot variable, that's not a thing.

Also, it's not like this is something special that discord.py is allowing us to do, it's just attributes

severe tangle
#

hmm

#

edited the message (also those are known as Bot Variables in the discord.py server also and I didn't come up with that term myself haha)

brisk brook
#

Changing discord.py to the library doesn't really help in my opinion, you're still referring to discord.py right?

brisk brook
severe tangle
#

uhh, I haven't really used any other library, so I cannot say anything about any other lib tbh, so I am just referring to discord.py itself. But changing to the library just makes it more general, imho

brisk brook
#

You could start it more or less along the lines of

In Python you can set attributes to any class instance, your bot is one such instance. By setting attributes on your bot you can have variables across the whole bot

severe tangle
#

Ah, so just make it more targeted towards General Python?

brisk brook
#

Because we want to get the idea across that "Here's a Python thing that's useful, here's how to utilize it in discord.py"

severe tangle
#

ah

brisk brook
severe tangle
#

yup, understood

#

lemme do the required changes

#

Python allows you to set custom attributes to instances and your bot is one such instance. You can add custom attributes to your bot instance and access them **anywhere** you access you bot.

#

in the next line, I can do something like. In discord.py, these attributes are commonly known as bot variables?

brisk brook
severe tangle
#

(I commited the changes, u can take a look)

dim pelican
#

Blue since you are active, what do you think the next steps are for Sir-Lancebot#805 ?

dusky shoreBOT
brisk brook
severe tangle
#

lmao

#

hehe

vale ibex
dim pelican
#

I can understand lol

dim pelican
vale ibex
#

Just so that we have a record

dim pelican
#

๐Ÿ‘

vale ibex
#

Cheers I've got it

#

I'm just going to reach out to Dan directly to get explicit approval

tough imp
#

slapping an attribute on an object after instantiation and then relying on it being there everywhere seems worse than having a variable in a module that can be imported globally

celest charm
#

an alternative approach is to use proper dependency injection, i.e. instead of passing the gorilla and the entire jundge, pass the banana, i.e. things you need (like a cache or a handle to a database pool)

#

but it surely seems more convenient to just pass the entire bot object everywhere ๐Ÿคท

brisk brook
# tough imp slapping an attribute on an object after instantiation and then relying on it be...

No? The object instance is always from that one singleton where the attribute is created directly after.

When you use an attribute on an object, you rely on __init__() being called to set these. We know, thanks to how Python works, that it will always have happened.

The same way we know that the bot will always have said attribute, notice how test is initialized at first. If it wasn't, and was only set in the command then yes you could have a case where you'd get an AttributeError

brisk brook
#

@dim pelican are you planning on just changing the commit that included those changes, or squash a substantial amount of commits to clean up the history?

dim pelican
#

Changing the commit that included those changes

celest charm
#

Actually, now that I think about, what's the purpose of passing the bot instance to each cog?

#

There's a circular dependency anyway

tough imp
brisk brook
tough imp
#

I know it works, but I don't know whether there should be a tag incentivising beginners to be solving problems in this way

dim pelican
brisk brook
tough imp
#

The bot is basically global state anyway

#

May as well be explicit and transparent about it

celest charm
clever wraith
#

Discord is real tricky

brisk brook
# tough imp I do not think it is the same situation at all. If you have a function that's su...

Python really isn't statically typed by any means, and at the point where members will subclass the bot they will already be adding the attributes inside of their new __init__().

It's better to recommend this, which is very common thing to do, instead of pulling someone into subclassing/super/self/methods. This is just a small step into understanding classes with us explaining attributes

clever wraith
#

They seem to use a custom JWT format

brisk brook
stable mountainBOT
#

bot/__init__.py line 25

instance: "Bot" = None  # Global Bot instance.```
celest charm
#

this thing

brisk brook
#

That's still somewhat of a work-around no?

celest charm
#

around what?

brisk brook
#

I've never had issues of circular imports the way bot is passed around with discord.py

brisk brook
#

I don't think I've seen this used to be honest, at least in the PRs I've reviewed

celest charm
#

To avoid circular imports, you just need to use namespaced import, i.e. import module instead of from module import X

#

since there's a circular dependency anyway, might as well make it explicit ๐Ÿคท

brisk brook
celest charm
#

Circular imports are sometimes allowed, when it doesn't violate causality

brisk brook
celest charm
#

For example, if you have a situation like

# a.py
import b

def foo():
    print(b.bar)

# b.py
import a

def bar():
    print(a.foo)

There's no reason to reject this, because neither of the files needs to access the other module to complete execution.

tough imp
# brisk brook Python really isn't statically typed by any means, and at the point where member...

I understand it's common, yet I don't think that makes it a good solution, especially if both the language and the framework give you tools to solve the problem. Adding an attribute to the instance's namespace post-instantiation doesn't seem to be a good solution ever. If you annotate your cog's init as needing bot: Bot, but internally you rely on bot.test, that's already an unnecessary lie making it more difficult to reason about the program statically, regardless of whether it is statically typed or not, and I don't think beginners should be told that it is a good solution; the tag brings a lot of authority.

celest charm
#

it also doesn't play very well with the plans to add mypy to the CI

celest charm
tough imp
#

In d.py I believe cogs are registered by passing their path as a string

#

and letting the lib do the importing & dynamic lookup of the setup

celest charm
tough imp
#

Yes, to solve the same problem, we are

#

but the tag in question is saying to just assign bot.test = "something" and be done with it

celest charm
#

ah

#

what tag??

tough imp
#

despite Bot.test not being a thing you can statically reason about

celest charm
#

yeah that sounds terrible

#

that's the sort of thing people outside of Python say "sounds like Python" to

tough imp
#

d.py also does a funny thing where it force-reloads modules when you reload an extension, which can be convenient doing development, but it forces types to be redefined, so insintance and except ErrorType begin magically failing

brisk brook
# tough imp I understand it's common, yet I don't think that makes it a good solution, espec...

But- no ๐Ÿ˜…

No one annotates nothing as needing nothing. This is pretty standard thing to do, hence I would say it's good advice. Python is a dynamically typed language and we're utilizing that. You're not meant to be able to statically reason about anything.

The point where someone needs their bot to pass MyPy or Pyright as well have custom attributes and complex knowledge about classes, they're already knowledgeable in what the tag teaches you.

tough imp
#

have you come across a situation where the proposed solution would be good, that wasn't a discord bot?

brisk brook
tough imp
#

fastapi has request.state right?

brisk brook
#

Any other case where you're using a library that resolved around a single instance of an object