#dev-contrib

1 messages · Page 103 of 1

sleek steppe
#

Tells the linter what type the object will be

placid ermine
#

or you could just do from typing import List and it'd be pretty much same lol

green oriole
#

Riiight, I see

fallen patrol
#

but why

#

typing.Dict[str, str]

#

why is it a dict of the same times what

placid ermine
#

yes

fallen patrol
#

!d typing

gritty wind
stable mountainBOT
#

New in version 3.5.

Source code: Lib/typing.py

Note

The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc.

This module provides runtime support for type hints as specified by PEP 484, PEP 526, PEP 544, PEP 586, PEP 589, and PEP 591. The most fundamental support consists of the types Any, Union, Tuple, Callable, TypeVar, and Generic. For full specification please see PEP 484. For a simplified introduction to type hints see PEP 483.

The function below takes and returns a string and is annotated as follows...

sleek steppe
#

I mean lowercase looks better

gritty wind
#

it doesn't do any actual logic

#

but your IDE can help you with that annotation

green oriole
#

Typing is useless during runtime, except in specific cases

gritty wind
#

Like d.py cases, where it chooses to analyze the signature for some god forsaken reason

sleek steppe
#

In 3.10 it's completely ignored until you call get_type_hints or something

green oriole
#

d,py makes a really bad use case of typing haha

fallen patrol
#

its actually becoming increasing more important as argument validation

brazen charm
#

It is a bit more reasonable with the introduction of Annotated

fallen patrol
sleek steppe
green oriole
#

Yikes

gritty wind
#

decorators are the worst offenders imo

#

You typehint one thing, but get another

gritty wind
#

converters*

green oriole
#

I was about to say that decorators are good 😄

gritty wind
#

lol, brain fart

sleek steppe
#

Type hinting to functions are the worst

placid ermine
#

even pygen reminds me of latex pain now 😔

gritty wind
#

@green oriole migrated the command to a new file, and removed unnecessary imports

#

Currently looking at

#
import pathlib
import resource
import signal
import sys
import types
import typing
from functools import partial
from io import BytesIO

import matplotlib.pyplot as plt```
#

still need 400mb though

#

any ideas why

green oriole
#

Hmm okay

#

If you just import, nothing else, how much ram do you need?

gritty wind
#

Hmm

#

let me test that

#

disclaimer: I'm not actually counting, I'm just seeing the minimum needed to not get an error

#

Ok, if I remove nothing except the call to the render

#

I can go down as low as 0.0001mb

#

probably lower

#

I haven't tested

#

Ok, new idea

#

I'll also use matplotlib.Figure

green oriole
#

Interesting

#

can you try to like incrementally add new parts of the script?

gritty wind
#

Sure, the 0.0001 figure was everything other than the render call

placid ermine
#

what

#

how are you needing 400mb

gritty wind
#

ask matplotlib lol

placid ermine
#

it barely crossed 200mb without changes for me

gritty wind
#

ok with 10mb

#

I got as far as

vale ibex
#

iirc matplotlib uses a gui backend for every plot

#

so I'm not surprised on the memory reqs

gritty wind
#
plt.savefig(rendered_image, bbox_inches="tight", dpi=600)

everything before this line

placid ermine
#

that line spikes about 42mb for me

thorny obsidian
#

I don't remember which rendering backend is the lowest in mem usage... You can specify different ones though

vale ibex
#

You could try matplotilb.use('agg')

gritty wind
#

jumping up to 100, it still fails

green oriole
#

Interesting

gritty wind
#

and I don't think we'll give one command even 100mb in prod

vale ibex
#

using agg, it'll remove the need to teardown and gui objects

gritty wind
vale ibex
#

before

gritty wind
#

ok, still nothing on 10mb

#

jumping to 100

#

still a no

#

why is savefig taking so much ram

#

and what can we do about it

#

ok better question, what does it actually do

#

we write to file after that

green oriole
#

Can you pipe it to stdout?

placid ermine
#

this is fairly comprehensive

gritty wind
green oriole
#

The image

#

ah, we save it to a file, don’t we

gritty wind
#

yeah, but we never get past the savefig

#

so my question is what does that do

#

Documentation says it "saves the figure"

green oriole
#

Wow

gritty wind
#

so... what does the writing to file do

green oriole
#

what a documentation

gritty wind
#

Maybe I just

#

remove that line and see what happens

green oriole
#

600 dpi is enormous dear god

gritty wind
#

30dpi is still too high

#

10 just throws a face error

green oriole
#

It should 32

#

you won’t be able to tell the difference

gritty wind
#

32 is still too high for 100mb

green oriole
#

Looking at some backend source code, savefig triggers the render (?)

gritty wind
#

32 dpi will not work

#

not a very promising start

green oriole
#

i- what is the image size?

gritty wind
#

I wonder if it's because of windows

#

I just dropped to 32dpi

#

no other changes

#

I'll deploy this on my server

green oriole
#

There is no image size setting?

gritty wind
#
    matplotlib.use("agg")
    fig = plt.figure()
    rendered_image = BytesIO()
    fig.text(0, 1, text, horizontalalignment="left", verticalalignment="top")
    plt.savefig(rendered_image, bbox_inches="tight", dpi=32)

    rendered_image.seek(0)

    with open(filepath, "wb") as f:
        f.write(rendered_image.getbuffer())
#

entire code right now

placid ermine
#

and the font size is set in rcParams.update

#

i think i set it to 16

#

plt.figure() isn't reference counted properly apparently, that's why I switched to figure.Figure

gritty wind
#

that still has the same problem

#

it takes too much mem to save

#

even for really short inputs

placid ermine
#

i don't think the input size affects it much at all

green oriole
#

Yeah it shouldn’t

gritty wind
#

it was definitely enough to cause the initial memory trips that caused this issue to be raised in the first place

green oriole
#

I am guessing the backend is just heavy as heck

#

Try with the tk backend?

gritty wind
#

matplotlib.use("tk")?

vale ibex
#

agg is the raw backend

#

not sure how much better tk would be

#

worth trying at least though shrugR

gritty wind
#
'tk' is not a valid value for backend; supported values are ['GTK3Agg', 'GTK3Cairo', 'MacOSX', 'nbAgg', 'Qt4Agg', 'Qt4Cairo', 'Qt5Agg', 'Qt5Cairo', 'TkAgg', 'TkCairo', 'WebAgg', 'WX', 'WXAgg', 'WXCairo', 'agg', 'cairo', 'pdf', 'pgf', 'ps', 'svg', 'template']
#

take your pick lol

#

TkAgg?

placid ermine
#

TkAgg probably

gritty wind
#

that's not happy with 100mb either, but on 500:

#
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "/bot/bot/exts/evergreen/latex.py", line 105, in latex
    raise Exception(process.stdout.read().decode())
Exception: libtk8.6.so: cannot open shared object file: No such file or directory
#

it's not writing the file 🤷‍♂️

#

or not writing it correctly

placid ermine
#

looks like it happens when tkinter is not installed

green oriole
#

Yeah

#

Although

#

It is interesting

#

Because it is failing before the backend is initialized

gritty wind
#

alright, tested on a clean linux install

#

still same prob with 100mb

#

bumping it higher is fine

#

(note: I've jumped back to 600dpi)

placid ermine
#

with just the command and without the dpy boilerplate the mem usage rarely jumps over 80mb for me /shrug

#

with the gc.collects that is

gritty wind
#

Ok, even if I added the gc.collect

#

it wouldn't matter

green oriole
#

So the library is doing something before initializing the backend that requires that much memory

gritty wind
#

we don't even get past the save

#

you put the collect after the save

green oriole
#

Is it because it is a forked process

gritty wind
#

possibly

placid ermine
#

oh right
yeah it just about touches 97MB for me before the gc.collect

#

no wait

green oriole
#

Let's see

gritty wind
#

that doesn't explain the remaining 300mb but even then

placid ermine
#

half of that is from the memory profiler

green oriole
#

How do you create the new process again?

gritty wind
#

100mb is a lot for one command

#

subprocess.run([python, path_to_file, args])

placid ermine
#

its 45MB for me then, discounting for the memory profiler

#

i have absolutely no idea why you're needing something like 400mb

gritty wind
#

I can just push my changes

#

did you try profiling my branch?

placid ermine
#

no

#

doing it now

#

link please

green oriole
#

Hmmmm it seems to indeed be sharing the same resources as the main process

gritty wind
#

one sec, going to push the current changes too

green oriole
#

Can you try to run the generation script directly, not through the bot?

gritty wind
#

Sure

#

what's the unused import noqa

green oriole
#

¯\_(ツ)_/¯

gritty wind
#

401, got it lol

placid ermine
#

I'm supposed to profile only render right

gritty wind
#

Well, try profiling it from the subprocess, instead of on it's own

#

that way we can see where the extra size is coming from

#

and to confirm: running the render on its own does in fact use more than 100mb

#

I called it like python utils/latex.py test ./something.png

#

and it errored out

vale ibex
#

out of interest, is the huge memory requirement just on the first plot?

#

IE if you try to plot a second directly after, does it use a normal amount of memory?

gritty wind
#

how would I test that lol

#

I guess I can actually

placid ermine
#

module 'signal' has no attribute 'SIGXCPU'
🤔

gritty wind
#

what OS are you on

vale ibex
#

are you on windows?

#

lol

gritty wind
#

These changes are for unix based system exclusively

placid ermine
#

windows

#

yeah

gritty wind
#

what are you using to profile?

placid ermine
#

!pypi memory_profiler

stable mountainBOT
gritty wind
#

ok, going to test the second drawing idea

#

then I'll do profiling

#

ok, the second one does run, I'll try to do it from the bot itself now

#

hmm, no, I lie

#

it failed on the second one

#

also failed from the bot obv

thorny obsidian
#

So question: is this still dealing with mpl's latex rendering? Could we just sidestep this and see if a slim but robust latex install might be the way to go?

gritty wind
#

yes

placid ermine
#

interesting

#

what about the infinite loops and file read write and all that that would come with it

#

wonder how much plain latex allows, hmm

gritty wind
#

Profiler refused to profile, so I'll just try the function itself now

#
Line #    Mem usage    Increment  Occurences   Line Contents
============================================================
    57     84.7 MiB     84.7 MiB           1       @profile
    58                                             async def _latex(self, ctx: commands.Context, *, text: str) -> None:
    59                                                 """Renders the text in latex and sends the image."""
    60     84.7 MiB      0.0 MiB           1           text = self._prepare_input(text)
    61     84.7 MiB      0.0 MiB           1           query_hash = hashlib.md5(text.encode()).hexdigest()
    62     84.7 MiB      0.0 MiB           1           image_path = CACHE_DIRECTORY.joinpath(f"{query_hash}.png")
    63     84.8 MiB      0.1 MiB           2           async with ctx.typing():
    64     84.8 MiB      0.0 MiB           1               if image_path.exists():
    65     84.8 MiB      0.0 MiB           2                   await ctx.send(file=discord.File(image_path))
    66     84.8 MiB      0.0 MiB           1                   return

everything after this line is unprofiled

#

that's ugly

#

there lol

green oriole
#

It seems to have 80Mb of globals doesn't it?

gritty wind
#

that's the bot itself though

#

(and the profiler probably)

placid ermine
#

profiler is approx 50mb

green oriole
#

What am I supposed to look at then haha

gritty wind
#

yup, the profiler was kind of useless

#

I'm currently trying to profile the function itself

green oriole
#

Can you perhaps profile the script?

#

Yeah

gritty wind
#

Ok, gonna do that after dinner

#

brb

placid ermine
#

looks like even minimal latex installations still take at least 50MB+

green oriole
#

I think 50MB of library is honestly pretty okay

#

We aren't short in memory by any mean right now

placid ermine
#

hmm

fallen patrol
#

If at all

#

That takes up 200mb

#

Including its 100 dependencies

placid ermine
#

lol

vale ibex
#

I don't think it's used at all, need to do more testing though. sir-lancebot#686 for reference

dusky shoreBOT
fallen patrol
#

it would be nice if tests were complete

#

Lol

#

In that case you could just delete the dependency and run all of the tests

vale ibex
#

There's no tests on lancebot

fallen patrol
#

Oh

#

Explains a lot

#

Mostly: why I've never seen coveralls report on a lancebot pr

patent pivot
#

Yeah heavy testing raises the entry bar to contribution, especially for discord.py bots

fallen patrol
#

Yeah

fervent sage
#

testing in bots is miserable

vale ibex
#

sir-lancebot#686 is ready for review, couldn't find anything that actually uses discord voice or ffmpeg

dusky shoreBOT
placid ermine
#

noob question
how would latex be installed locally

#

not like you can just download a file and run the installer or something

#

right

#

?

gritty wind
#

between linux internals, and a random pypi library, not sure which to believe

#

oh, ignore the logging lol

fallen patrol
#

!pypi latex

stable mountainBOT
fallen patrol
#

Oof

#

@gritty wind have you found a latex lib yet?

gritty wind
#

I'm not working on that

#

@placid ermine might be

fallen patrol
#

Oh

#

Cause the one above is last updated 2017

placid ermine
#

not jpeg

#

or png

#

we could still use matplotlib

#

and just make it use system's latex instead of its own engine

fallen patrol
#

Wut

#

Did you

placid ermine
#

and, well, if that has memory issues

fallen patrol
#

Not sure if that thing would work

placid ermine
#

we could switch

placid ermine
placid ermine
#

yeah i've seen that

#

sympy

#

hmm

fallen patrol
#

I forgot

#

@placid ermine Recap: whats the current issue and also main issue with the latex command?

placid ermine
#

memory usage goes brrrr

fallen patrol
#

Iirc what's happening is its not closing right?

placid ermine
#

well the cog is currently unloaded

#

but it used to restart every few seconds

gritty wind
#

Well, I'm not really sure there is anything left for me to try with the process stuff, so I'll just deploy it on my cluster, and we'll see if it hits limits

placid ermine
#

'ight

gritty wind
#

kubernetes cluster

placid ermine
#

any updates

gritty wind
#

I have access to the manifest used to deploy sir-lance, so I can get something pretty similiar

#

Well, it's a 200mb image

#

taking a minute to push to the hub lol

#

~100mb done

placid ermine
#

o

fallen patrol
patent pivot
#

iirc scaleios self-hosts k8s

gritty wind
#

managed DO cluster

patent pivot
#

who was it that self-hosts

gritty wind
#

I would self-host if I wasn't a moron

patent pivot
#

oh lak

#

lul

gritty wind
#

yeah lak haha

fallen patrol
#

!src

stable mountainBOT
gritty wind
#

Ok, well that's an interesting result lol

#

It can't find the cache file haha

placid ermine
#

👁️

#

what

gritty wind
#

Ok, we really need to fix the dockerignore

#

it loaded my .env

#

so I accidentally just published a bunch of tokens

vocal prairie
#

Oof

green oriole
#

Uh oh

vocal prairie
#

Time to regen ig

vale ibex
#

dockerignore doesn't work with docker compose afaik

tawdry vapor
#

And that is exactly why the approach of a whitelist is better than a blacklist.

#
# Exclude everything
*

# Make exceptions for what's needed
!bot

for example

gritty wind
#

That is the current config

#
# Exclude everything
*

# Make exceptions for what's needed
!bot
!Pipfile
!Pipfile.lock
!LICENSE
#

But I just sshed into the container, and there it was

#

my .env

tawdry vapor
#

Was it inside the bot directory?

gritty wind
#

it was not

#

it was in the top level directory

tawdry vapor
#

Then as far as I can tell that is an impossible situation

gritty wind
#

I don't know what to say

#

Maybe it's because of the docker-compose

fallen patrol
gritty wind
#

it's in my .env

#

the image loaded the .env

fallen patrol
#

yeah

gritty wind
#

which I published before noticing

fallen patrol
#

how is it being in the image

#

bad

#

?

gritty wind
#

Well, I just pushed the image

#

To ghcr

#

Now, theortically, that won't happen much

tawdry vapor
#

If you run a container locally do you also see the file in there?

gritty wind
#

but ideally, the .env file would be loaded as env variables, not an actual file

vale ibex
#

So do I

gritty wind
#

Maybe it's this line

#
# Copy project code
COPY . .
tawdry vapor
#

COPY respects dockerignore

gritty wind
#

Then theoretically, it shouldn't have copied my env

tawdry vapor
#

What actually happens is that the build context is modified by the dockerignore

gritty wind
#

Well, shouldn't it still ignore everything

vale ibex
#

I think it's this in the docker-compose ```
volumes:
- .:/bot

gritty wind
#

Right now, it is not ignoring anything

vale ibex
#

since that'll share the whole folder right?

gritty wind
#

I think that's the interior bot folder

tawdry vapor
#

It may need to be ** instead of *

gritty wind
#

I'll try building with **

#

Still the same result

#

Ok, chris might be right actually

tawdry vapor
#

I see some saying ** and others *

gritty wind
#

Yeah volumes worked

#
    volumes:
      - ./bot:/bot/bot
#

compared to the old .:/bot

vale ibex
#

I removed that entire volumes section

#

and changed to **

#

and it's all good

gritty wind
#

the star didn't seem to matter

tawdry vapor
#

I don't think ** is necessary

vale ibex
#

👍

gritty wind
#

but the volume is important for hotloading

#

hotswapping*

tawdry vapor
#

I didn't expect a volume to matter for building purposes

gritty wind
#

Hmm

#

I'll check the uploaded image

#

it shouldn't matter

#

that would be a relief

tawdry vapor
#

If you look at docker build there isn't even a way to specify a volume during building

vale ibex
#

Yea, so the COPY respects .dockerignore

#

but the volumes are straight shares

tawdry vapor
#

What was happening then? The volume being mounted was giving a misleading result when running the container?

gritty wind
#

I tested locally, and saw the .env

#

I didn't actually check the remote image

#

Didn't consider how the compose would affect it

vale ibex
#

Yea, so the volume was being mounted and all the files from the project root were put into the container

tawdry vapor
#

I thought you said you ssh'd. I interpreted that as ssh'ing into the prod or something

gritty wind
#

I sshed into my local container

#

I see how that would be misleading though

tawdry vapor
#

Why do you use ssh to connect to a local container?

#

Is it even running sshd?

vale ibex
#

k8s ig?

gritty wind
#

I don't think it does, that was not the right terminology

#

I opened a terminal in it locally

vale ibex
#

ahh just spawning a shell process

gritty wind
#

yup, that one's on me

#

yeah, nothing unexpected in the public image

gritty wind
#

Someone snuck in an nbsp into the dockerfile haha

vocal wolf
#

@sleek steppe Greetings. You around?

sleek steppe
#

Yep

vocal wolf
#

Although I realize I've already approved, we cannot accept the pull request since we can't exactly filter out all emojis that are inappropriate.

That's why we only allow the ones that we have on this server to be shown.

#

No relevant issues as this was discussed in .
This also cannot be accepted, as this PR should've been discussed within an issue before making a PR.

sleek steppe
#

I guess so my bad

#

But then we talked about it again

green oriole
#

May I ask who you talked to about this issue?

sleek steppe
#

So after I opened the PR I had already asked some people, and then you and ks discussed it here <#dev-contrib message>

#

I mean we could do !e print("bad word") really

green oriole
#

But who is "some people" here?

#

Also we actually filter eval output

sleek steppe
#

Other commands can do that too

green oriole
#

Besides eval doesn't allow image input

#

None does

sleek steppe
#

Someone with an nsfw pfp can use an avatar command

green oriole
#

Yeah but I doubt they'll stick around for any longer

#

Any community they are in can moderate them and report to discord

sleek steppe
#

Don't think there will ever be a scenario where someone with an nsfw emoji will use an emoji command, but I guess you don't want to take that risk ¯\_(ツ)_/¯

limber jolt
#

So, hi guys. Im from Rus, and i downloaded Ubunt (Linux). And i have many problems with python on terminal in this system. Who can help me to download and use python on Linux?

fallen patrol
gritty wind
#

How do people feel about adding aliases to the doc command. From a cursory look, it seems possible to add a list of aliases that the bot translates before searching, but it might require a schema change on site, and quite a bit of added logic to the bot.

The use case for something like this would be aliasing certain modules that are better known by other names. For example: np or pd (maybe dpy to a lesser extent). Other challenges I foresee, besides the complexity issues, are issues with namespace pollution. Adding np as an alias is fine, but you run into problems when you want to add a package called np. I don't think that's true for any of our current docs, but it's a consideration.

brazen charm
cold island
sleek steppe
#

That was before the doc improvements PR

#

!d discord

stable mountainBOT
#

In order to work with the library and the Discord API in general, we must first create a Discord Bot account.

Creating a Bot account is a pretty straightforward process.

cold island
#

nice

fallen patrol
patent pivot
#

hey folks! I've just deployed some changes to pythondiscord.com and a set of our other services to introduce a set of new security headers, stuff like disabling permissions we don't need, tightening our referrer policy, rejecting iframes and so on (and of course disabling the horror that is FLoC). If you notice anything weird about resource loading on site please let me know.

fallen patrol
#

(and of course disabling the horror that is FLoC)
every header. its stupid way to opt out

patent pivot
#

huh?

#

I think that it's not the best idea, but the header opt out isn't too bad.

fallen patrol
#

i mean that's how you opt out, no? every request has the specific opt out header

patent pivot
#

you add it to your existing permissions policy

fallen patrol
#

ah

#

i think i need to learn some front end some time

#

puts it on a list for months from now

patent pivot
#

I am also deploying an exiting change shortly which is uhhhh

#

actually I'll just deploy it and then talk about it

fallen patrol
#

for those who wanna know if they're in the "beta" https://amifloced.org/

Am I FLoCed?

This page will check whether Google Chrome's experimental new ad-targeting technology is enabled in your browser.

fallen patrol
#

was gonna say it isn't possible for FLoC to be on iPhones since every browser has to use webkit but that's wrong

patent pivot
#

allllllrigh

#

t

#

there we go

#

should be live

#

CSP is enabled on all python discord web properties, for now though we're only reporting instead of enforcing

#

we're also passing it through a worker to strip off IP data

vocal prairie
#

Is bot#1498 still possibly useful, or not?

thorny obsidian
#

lol that's a great title

patent pivot
#

basically instead of identifying people individually through cookies identifying them through groups of cohorts with similar interests

vocal prairie
thorny obsidian
#

FLoC is FLoCing terrible

patent pivot
#

yeah, it's a very bad idea

cold island
#

@sleek steppe assigned you

sleek steppe
#

Oh thanks

#

I think I'll need to rework redirect_output or make a new utility function

#

Maybe an allowed_channels parameter

fallen patrol
patent pivot
#

content security policy

cold island
patent pivot
#

a header which basically says which origins/locations any scripts/stylesheets/images can be loaded from

fallen patrol
#

oh

#

lol

patent pivot
#

right now it's set to anything https://, pythondiscord.com or inline, I'll make it more granular in coming weeks

fallen patrol
#

i thought it was

#

related to tracking since you said it right after floc and cookies

patent pivot
#

nah, CSP is a security move for clients

#

so if we have a failure in that policy I see something like uhhh

fallen patrol
#

lmfao

#

update grafana 😂

patent pivot
#

it's a minor versionn

#

i will at some point

fallen patrol
#

ah

sleek steppe
#

I think I'm ready to make a PR now, I also made not_in_blacklist useless

short snow
clever wraith
#

If I wanted to add a feature to the @stable mountain bot do I just go for it with a pull request? Or discuss it here first or..?

#

I'm totally new to open source stuff rooDerpCoffee

#

And I wanted to see if I (or someone) could make it so editing !e into a code post will execute it

thorny obsidian
#

So the first step would be to open an issue on the @stable mountain repo. There should be a link in the description or in the pins

#

From there discussion will happen and a core dev will approve the issue and assign you to it (if you want to work on the issue). From there you're welcome to PR!

#

We do have contributing guidelines and all that good stuff to walk you through the process

#

We're also super friendly here, so you're always welcome to ask questions and provide suggestions

vocal prairie
#

That's the contributing guide for @stable mountain

clever wraith
#

All makes sense bearStudy thanks

thorny obsidian
#

I'm a bit tired, so hellooo to a bit of a philosophical rant.
One of our core ethos, especially for development, is that we do encourage people to learn new things and contribute to open source. @dusky shore is our fun and community bot that's encouraged for first time contributors to get started with.

That being said, our core server functionality (like the !e) does stay in Python. We have some stricter standards in Python because that bot is responsible for administrating the community, but our core devs and contributors are wonderful folks who can help you out

#

Also, remember to lint before you push hyperlemon

#

(really you should lint before you commit)

vocal prairie
thorny obsidian
#

yes!

clever wraith
#

Do you that that feature would be likely to be approved? I help in the help channels a lot and it's just annoying when you type out a bunch of code but forget the !e at the start. I've seen other people try to edit the !e in to to retroactively execute.

vocal prairie
#

Noice

clever wraith
vocal prairie
#

Thanks Jason!

thorny obsidian
#

I do know our bot has the functionality of if we run !e, and then edit it within a time frame, it'll provide the option to re-run the eval with the edits

clever wraith
#

yeah, that's real handy

#

my idea is the same but for if you edit the !e in at the start of the message

short snow
thorny obsidian
#

I'm not sure how the bot will do with editting in the command since it'll be a different process. Someone a bit more knowledgeable will have to correct me here, but I believe when we do !e the process of listening for corrections only happens once the command is initially invoked. But maybe Python could still listen for the command on message edit

vocal prairie
#

I'm pretty sure you only check when the message is sent

clever wraith
short snow
vocal prairie
#

So you'd have to listen for commands on message edit

short snow
#

that's my guess, not sure

thorny obsidian
#

Well, definitely write up an issue! This is interesting and I'm all for helping people help people...

#

If it's your first time writing an issue, you can check out the issue template on Sir Lancebot's repo. It'll give you some guidance on what to include

#

or just blindly steal the format from an existing issue

clever wraith
#

Alrighty CheshireOkayThen I will look into writing an issue

short snow
#

scal has a gist of a better issue template

#

lemme get the link

vocal prairie
#

sir-lancebot#685

dusky shoreBOT
vocal prairie
#

It's in there

clever wraith
#

thanks

sleek steppe
#

For bot#1498, should I only include the eval command?

green oriole
cold island
#

@short snow it would have been better to break up this commit into several. The title doesn't convey what it changes properly either

short snow
cold island
#

Yes, the commit title is important. You go to the body to see more details, but the title needs to convey what was changed

#

Adding an edit listener is not a refactor

brazen charm
#

having separate commits for separate changes with a fitting subject is important both when going over the history and with the blame

short snow
#

agree with that, any idea how i would be able to do it

brazen charm
#

If it's already pushed and reviewed then redoing it would probably lead to a mess in the PR but it is something to keep in mind for the future

short snow
#

maybe i can edit the commit title to make it clear? if that's possible

brazen charm
#

That will have to redo the commit as any other change, I'm not sure if review comments would be lost or kept with a detached commit on a force push

short snow
#

hmmm, what do you think @cold island ?

cold island
#

You can leave it for now, I'll see what others think

short snow
#

ok

thorny obsidian
#

@green oriole Could I trouble you for a re-review for lance's int e?

gritty wind
#

Anyways, I don't know how feasible it would be to listen to commands being added in after the fact. The eval command runs through the following checks and conversions in the regular on-message flow:

    @command(name="eval", aliases=("e",))
    @guild_only()
    @not_in_blacklist(channels=NO_EVAL_CHANNELS, categories=NO_EVAL_CATEGORIES, override_roles=EVAL_ROLES)
    async def eval_command(self, ctx: Context, *, code: str = None) -> None:

Now, these checks are not run for message edits, but they will have to be run to add your feature

#

That's a lot of overhead, because a ton of edits happen (trust me, we have logs lol)

#

I can't say for certain how high that overhead will be

#

But I can definitely tell you copying your message and sending it again is not too difficult

#

This also raises questions about how you make the distinction between an eval that had already been run, and one that has just been edited in

#

The event does pass in the old and new message

#

but that means you may end up running the checks twice

#

so that's doubling the overhead

#

</rant>

green oriole
#

!remind 30M review

stable mountainBOT
#
Affirmative!

Your reminder will arrive in 30 minutes!

cold island
# sleek steppe Yes

It should be implemented with that idea in mind (meaning, it should be a simple decorator), but the issue deals with eval specifically

sleek steppe
#

I added a categories + channels parameter to redirect_output

stable mountainBOT
#

@green oriole

It has arrived!

Here's your reminder: review.
[Jump back to when you created the reminder](#dev-contrib message)

green oriole
#

Hey @thorny obsidian re: https://github.com/python-discord/sir-lancebot/pull/673#discussion_r611223893 sorry I didn't see your answer.

You can run exit() in the container to make it exit which will make k8s restart it, that's quite handy. But due to the fact that str.startswith was used, doing so will just trigger the context reset while it wasn't what you necessarily wanted to do. You can do !int e 1;exit() to bypass this restriction but that's a bit silly.

GitHub

Relevant Issues
Closes #653
Description
This internal eval comes from rattlesnake primarily. It was ripped out of rattlesnack whole sale and subsequently modified to fit Sir Lancebot's stru...

clever wraith
#

hello, would you guys agree to add a similar feature to lancebot as 8bitify?
my idea is to take an image, split it in x pieces, randomize those pieces and stitch it back up

green oriole
clever wraith
#

yes ill do the whole thing

#

i have it done already

#

but i would just have to make it work as a discord command

thorny obsidian
green oriole
thorny obsidian
#

.int e ctx.send("hi")

green oriole
#

lol wait a minute for it to deploy

thorny obsidian
#

<_<

#

_>

green oriole
#

haha

#

Blame our DevOps guy

clever wraith
#

ill try, gotta do smth real quick

thorny obsidian
#

.int e ctx.send("hi")

dusky shoreBOT
#

hi

#
[Captured] <Message id=833009569848492092 channel=<TextChannel id=635950537262759947 name='dev-contrib' position=59 nsfw=False news=False category_id=411199786025484308> type=<MessageType.default: 0> author=<Member id=528937022996611082 name='Sir Lancebot' discriminator='9543' bot=True nick=None guild=<Guild id=267624335836053506 name='Python' shard_id=None chunked=False member_count=178917>> flags=<MessageFlags value=0>>
thorny obsidian
#

eeeeeey

vocal prairie
#

Would it be possible/useful to do permission/role validation before channel validation?

balmy sparrow
#

int e doesn't need you to await things? pithink

patent pivot
#

how FAST do you WANT deployments to be SMH

green oriole
#

nope

green oriole
balmy sparrow
#

interesting

green oriole
#

just faster

patent pivot
#

the deployment is the fastest bit it's the docker part that is slow because docker is slow ohyeahohyeahohyeah

vocal prairie
green oriole
patent pivot
clever wraith
#

@green oriole hi i added the issue with an example

green oriole
#

Cool, thanks

#

Can you add a more specific title to your issue though?

clever wraith
#

ok

sleek steppe
balmy sparrow
#

yeah, saw that

#

pretty cool

#

thanks

clever wraith
#

@green oriole i think its better

#

now

sleek steppe
upper lion
#

random question - is that beautiful open graph protocol github repo preview something that github has done lately? : o

sleek steppe
#

I assume so

sleek steppe
#

Bot#1531 needs some reviews.

green oriole
#

Don't worry, we will review it in due time :D

sleek steppe
#

Great

green oriole
#

Otherwise Xith doesn't get his weekly lemon delivery

green oriole
#

Hey @clever wraith, I forgot to ask, where did you get the code from?

clever wraith
#

myself

green oriole
#

Is it just something you kept locally, it isn't licensed anywhere?

clever wraith
#

i wrote it from yesterday to today, its nothing special

#

its not some api or anything like that

#

just some PIL magic

green oriole
#

Cool, all good then

clever wraith
#

@green oriole btw where can i find 8bitify's source?

#

i wanna see something

green oriole
#

.source 8bitify

dusky shoreBOT
#
Command: 8bitify

Pixelates your avatar and changes the palette to an 8bit one.

Source Code
green oriole
#

Riiight here

clever wraith
#

thanks

fervent sage
#

i have a connection to the 8bitify command by now lol

clever wraith
#

aight, so it works as a discord command @green oriole

fervent sage
#

basically all of my lancebot stuff has been invoking commands from other commands, so 8bitify is my normal test subject

clever wraith
#

my command that is

#

im not really sure what should i do from now

#

i dont use github so i dont know how you guys add the code there

gritty wind
#

Have you ever used git or some other version control software before?

clever wraith
#

ive used git for heroku ig

#

but i dont really know about that

#

i can just give you guys the code maybe

gritty wind
#

If you really wanted to, it might be possible, but I'd also be down to walk you through some git basics

sleek steppe
clever wraith
#

also i have another question

clever wraith
#

im suppose to do all the error handling for my command, right?

sleek steppe
#

Nope, sir-lancebot has its own global error handler for commands

gritty wind
#

Some of it, yes. For the most, you'd handle errors specific to your code, for example, errors that PIL might throw, but the error handler can format it for discord for example

clever wraith
#

i have some local stuff here that is relevant only to my own command so ill do it rn

sleek steppe
#

For example, type hinting to int for the amount of slices will raise a BadArgument if someone were to pass foo for it, and sir-lancebot will send an error message saying that converting to in failed

clever wraith
#

so for the wrong argument types that bot will handle it?

#

i just have to type hint it?

sleek steppe
#

Yep.

clever wraith
#

ok ty

sleek steppe
#

You'd need to type hint anyways because of flake8

clever wraith
#

and my command only takes numbers that you can get the square root of, so would this be allowed to add:

    if not math.sqrt(splits).is_integer():
        await ctx.send(f'Could not get the square root of `{splits}` :confused:')```
sleek steppe
#

I mean (0.0).is_integer() is True

#

I would raise commands.BadArgument so that the error handler could catch that and note in the docstring that the number must be a perfect square

clever wraith
#

but it doesnt make sense

#

anything that has .something is a float, no?

sleek steppe
#

Yes. (0.0).is_integer() will return True. Only floats have that method

#

!d float.is_integer

stable mountainBOT
#

float.is_integer()```
Return `True` if the float instance is finite with integral value, and `False` otherwise:

```py
>>> (-2.0).is_integer()
True
>>> (3.2).is_integer()
False
clever wraith
#

@sleek steppe ok thanks

clever wraith
#

hello, so i finished my command fully and now would like someone to help me add it

sleek steppe
#

What do you mean add it?

clever wraith
sleek steppe
#

Yeah they did

clever wraith
#

yes

fallen patrol
#

OH DANG

#

sorry

#

seems that github updated their embeds

sleek steppe
#

It's like a 50% chance it actually shows

fallen patrol
#

kind of annoying

fallen patrol
#

how you do that is with git

#

short statement: git is complicated so we can walk through every step hehe

#

@clever wraith what do you have so far?

sleek steppe
clever wraith
#

ok

clever wraith
#

i can also show how it all works in my testing server

sleek steppe
#

You'll probably need to run the PIL and BytesIO stuff in an executor

fallen patrol
#

i presume its running on a lancebot clone?

clever wraith
fallen patrol
clever wraith
#

i made a testing one

fallen patrol
#

ah

#

so

#

yeah

#

follow the guide

#
clever wraith
#

so am i suppose to fork lancebot?

fallen patrol
#

yeah

clever wraith
#

i think i did it

sleek steppe
#

Follow the guide and test the command to see if it works

clever wraith
#

i got it in my pycharm i think

#

the whole lancebot

#

btw what are environment variables?

#

not sure what to do here

#

oh i found them

clever wraith
#

can someone help me with docker

#

i installed it but i dont know how to run it

vale ibex
#

docker-compose up

#

From the project root dir

clever wraith
#

yeah and it says error during connect: This error may indicate that the docker daemon is not running.

vale ibex
#

What OS?

clever wraith
#

windows

vale ibex
#

Do you have docker desktop running?

clever wraith
#

prob not

vale ibex
#

If you start that up

#

When it says running, try again

clever wraith
vale ibex
#

Ah, give that url a read

#

Likely a bios setting you need to enable

clever wraith
#

is the ones u get to access when ur pc starts up?

sleek steppe
#

Ah right had to do that the first time I tried using a vm

clever wraith
#

like while its starting up i mean

vale ibex
#

Yea, it is

clever wraith
#

ok

#

vm?

#

im not using that

vale ibex
#

You'll need to enable it for the same reason as a vm, docker engine uses virtualization for the container

#

And you need to enable that option in the bios

clever wraith
#

one of the circled settings is that vm thing and i dont even have it

vale ibex
#

In that link, does it explain anything about bios options?

#

I'm on mobile so can't find you resources myself

clever wraith
#

has this

#

so i gotta restart my pc, get in those settings and enable that Virtualization Technology (VTx)?

vale ibex
#

Yea, exactly

clever wraith
#

ok ill go for it

vale ibex
#

If you can't find the option, google the name along with your motherboard name

sleek steppe
#

See you on the other side 👋

clever wraith
#

soo smth weird keep happening

#

whenever id go into those settings, my mouse kept getting repositioned in the top right corner and it was all glitchy

#

i tried restarting multiple times and also shutting down the pc and then booting it back up but same thing

clever wraith
#

i installed pipenv with pip but when i try to use it, it says its unrecognized

fallen patrol
#

Path, more like pita

fallen patrol
clever wraith
#

im doing py -m pipenv run now but it says im missing a command and i bit confused here

vocal wolf
short snow
#

akarys told to move the webhook as cog level attribute that means i would have to add:

self.incidents_webhook = await self.bot.fetch_webhook(Webhooks.incidents)

to the __init__, so i would need to make the function async as it uses await

so the question is, is it ok to make init async?

gritty wind
#

I don't even think that's possible

#

The way to go about that here would be to call using an asynchronous caller

#

something like an asyncio task, or if this is @stable mountain, the scheduler

short snow
#

that fetches the webhook every x minutes?

gritty wind
#

is that what you want to do, or are you saying that's what it does

short snow
#

no i mean, should i make it fetch every x minutes or just fetch once at runtime

gritty wind
#

I don't have full context, but I'm assuming if it was updated, you'd need to update the config too

#

No real reason to fetch it multiple times

short snow
#

the config has been updated, joe had made a webhook in incidents channel, bot#1446

gritty wind
#

I think you missed my point

#

There is no need for it to be fetched repeatedly during runtime, because there are no runtime changes that it can adapt to

patent pivot
#

I'm meh on attachments being included

#

I think that has potential to be very noisy

#

for example, some reports may be to do with a question in a help channel and people might attach a code screenshot

#

I'll check internally though

vocal prairie
gritty wind
#

The docs link for pytest is broken

#

I'm working on fixing it

brazen charm
#

Looks like it's missing a slash in the base url

gritty wind
#

yup

#

I'm trying to pull it but

#

get just caused the last error in #dev-log

#

What happens if I just try to override it

brazen charm
#

Should be able to change it with the web admin panel

patent pivot
#

yeah

#

one sec

gritty wind
#

ahhh that exists

#

I don't know my password lol

patent pivot
#

discord oauth lul

#

updated

gritty wind
#

it drops me in a user-password login page, but maybe I'm on the wrong site

#

!d assert

stable mountainBOT
#
gritty wind
#

cool, that works

#

well, the cache is corrupt

#

(presumably)

fallen patrol
#

aaaaHHHH

#

how to pull main into a branch?!!

#

or fork

gritty wind
#

git fetch upstream && git merge upstream/main

#

while you have your main branch checked out

fallen patrol
gritty wind
#

the links were fixed

#

but the cache is still invalid

fallen patrol
#

it gave me https://docs.pytest.org/en/stableindex.html in #dev-log

gritty wind
#

because it was not updated

fallen patrol
#

not https://docs.pytest.org/en/stable/index.html

gritty wind
#

I'm talking about the cache that holds the actual content of the symbol

#

the one that formats the embed

fallen patrol
#

also since when does python send errors to #dev-log ??

gritty wind
#

it sends some things there

#

such as missing defcon

fallen patrol
#

ik what defcon is but what is missing defcon

gritty wind
#

Missing settings

#

It tries to read them from the redis cache

#

if they aren't there, it writes defaults, and sends a warning

#

(It is no longer a thing, but long ago whenever someone would start up their bot in the staff testing server, we'd all get a nice ping)

brazen charm
#

The cache shouldn't be set on failed items so it's probably just parsing the html weirdly. But I wonder why the python symbol is the moved one

fallen patrol
gritty wind
#

I think you may be able to PR or something?

#

Doesn't seem possible

#

Ok found a way

vocal prairie
#

I actually thought "your_username" was an account.

gritty wind
#

haha it probably is somewhere

vocal prairie
#

I don't think usernames can have underlines.

#

But I wish.

patent pivot
gritty wind
#

woah

#

I'm still going to ask you to do things for me

brazen charm
gritty wind
#

hmm why wasn't that merged way back when

#

!remind 12H Review site# 373

stable mountainBOT
#
Sure.

Your reminder will arrive in 12 hours!

short snow
gritty wind
#

You don't seem to be calling init at all, so that's a valid error

#

Besides that

fallen patrol
#

very cool github

gritty wind
#

there's a problem with your approach

gritty wind
#

you assume the task will be done before the webhook is ever used

#

which won't always be true

#

if d.py has any sort of async call on load, that would be the way to do it

#

otherwise, you're better off checking if the hook exists whenever you go to use it

short snow
#

i went through the duck pond and python news, and they are done in the same way, dunno why it is failing on mine pithink

gritty wind
#

You aren't calling the init in your tests

#

neither of those modules seem to have tests lol

short snow
gritty wind
#

Oh, I didn't see the parent class

#
        Note that this will not schedule `crawl_incidents` in the background, as everything
        is being mocked. The `crawl_task` attribute will end up being None.
#

The create task isn't called by the mock

short snow
#

should i just add a line self.cog_instance.get_webhook() in setUp then?

gritty wind
#

Maaaaybe? Technically that is the behavior your init is doing, but if someone modifies the init without modifying that setUp, the tests will be exhibiting weird side behaviors

#

Ultimately this will fall down to the reviewer, but it makes more sense to me to possibly monkey patch that create_task

#

Basically:
Monkeypatch self.bot.loop.create_task to map it to a create_task from your async setup

short snow
gritty wind
#

The action that gets skipped, but we want called is:

self.bot.loop.create_task(self.get_webhook())

that's because self.bot.loop.create_task doesn't actually do anything
when defining your bot, you can point self.bot.loop.create_task to the create task of a real loop, or optionally asyncio.create_task

#

You will have to see how that affects the other create_task in that init though

short snow
#

rather than monkey patching self.bot.loop.create_task we could just make a async function to this, which gets called in init, iirc it is the asyncio equivalent of starting a thread.

gritty wind
#

asyncio.create_task exists

short snow
#

yeah, either could be done i guess?

gritty wind
#

If I understand you correctly, you want something to call create_task without actually having the bot.loop

#

in which case, you don't need to roll your own helper for that

short snow
#

right, i will try doing that

fallen patrol
#

Guys @patent pivot is being mean on metricity#3

dusky shoreBOT
short snow
#

lol

green oriole
#

Lmao joe

brazen charm
#

Can someone refresh the doc inventories?

green oriole
#

Nice

#

What’s the command?

brazen charm
#

refreshdoc

green oriole
#

!refreshdoc

brazen charm
#

(under doc)

green oriole
#

!doc refreshdoc

stable mountainBOT
#
Inventories refreshed
green oriole
#

That’s a weird command lol

brazen charm
#

Thanks

green oriole
#

Np

vale ibex
tawdry vapor
#

Yeah it's weird to avoid name conflicts with symbols

brazen charm
#

I don't think it's used nearly enough to have a root alias

green oriole
#

I wonder if it could be !doc _refresh to avoid conflicts

tawdry vapor
#

I agree but it can if someone wants I don't really mind

green oriole
#

Or is d.py rejecting this

tawdry vapor
#

That works I would imagine but it's ugly if you ask me

fervent sage
#

why not just a separate command?

tawdry vapor
#

Don't remember

#

That was brought up though

#

Probably something to do with being unintuitive to separate especially considering it used to all be under one group

fervent sage
#

tbh i'm not sure being unintuitive is a concern seeing as it's used approximately never

brazen charm
#

Probably not worth losing much time on it for the same reason

tawdry vapor
#

Yeah :🙍

#

Iirc I laid out both options and said you decide which to pick

#

Well, maybe it was even your idea not mine

brazen charm
#

For the few uses it'll be easier to check the help on doc than going over the general help

stable mountainBOT
#

@patent pivot

It has arrived!

Here's your reminder: metricity PR 3 can be merged.
[Jump back to when you created the reminder](#dev-contrib message)

green oriole
#

It is tiiiiiime

placid ermine
#

@fallen patrol :^)

stable mountainBOT
#

Hey @sand oracle!

It looks like you tried to attach file type(s) that we do not allow (.pdf). We currently allow the following file types: .gif, .jpg, .jpeg, .mov, .mp4, .mpg, .png, .mp3, .wav, .ogg, .webm, .webp, .flac, .m4a.

Feel free to ask in #community-meta if you think this is a mistake.

vocal prairie
#

It's time

patent pivot
#

merged

clever wraith
#

and i installed it with pip

#

i tried py -m bot right now (py is instead of python for me) and im getting this:

    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 11001] getaddrinfo failed```
thorny obsidian
#

@clever wraith Do you have in your .env file FAKE_REDIS = true ?

clever wraith
#
BOT_TOKEN='ODMzMDE0NTQNlcKnKGdYQFrw'
BOT_GUILD=833014638723072020
BOT_ADMIN_ROLE_ID=833090174942052383
ROLE_HELPERS=833090255573876776
CHANNEL_ANNOUNCEMENTS=833090325605515274
CHANNEL_DEVLOG=833090377916874772
CHANNEL_COMMUNITY_BOT_COMMANDS=833090470052626482
USE_FAKEREDIS=true```
#

this is it

#

i altered the token so dw btw

clever wraith
#

and this is where its loacated

thorny obsidian
#

What does py -m pipenv run start
do?

clever wraith
#

OOH

#

its creating smth

#

some vm env

#

now its saying im missing module arrow

#

even tho i installed it

thorny obsidian
#

Let's do py -m pipenv install

clever wraith
#

ok

#

its installing rn

thorny obsidian
#

You did install it, but not in the venv that was just created

clever wraith
#

ah

thorny obsidian
#

Alright, now let's do the py -m pipenv run start

clever wraith
#

ok

#

oh it sent some messages in my server

#

i think its running

#

is it ok if a lot of channels are missing?

#

cuz i just made the required ones

#

that were in the guide

thorny obsidian
#

Oh yeah, that's fine

clever wraith
#

ok

#

so how do i now add my command to this bot?

vale ibex
#

Nice! I'd suggest you also do py -m pipenv sync --dev and py -m pipenv run precommit

#

This will get you setup with the precommit hook

clever wraith
#

its already running rn so should i turn it off and run those commands?

vale ibex
clever wraith
#

ill just do it now

vale ibex
#

Is your command setup as a cog?

clever wraith
#

its not setup at all

#

thats what i was asking about

vale ibex
#

I mean you said you have code right?

clever wraith
#

i have the whole code but it was only made to work with my test bot

vale ibex
#

Is it written as a cog

clever wraith
#

its just written for a bot

vale ibex
#

Or a plain command

clever wraith
#

like a test bot

#

plain

#

ran both commands, no errors

vale ibex
#

Alright if you take a look at bot/exts/evergreen there will be a bunch of files in there

clever wraith
#

yeah already saw

vale ibex
#

Those are a few commands we have there

clever wraith
#

should i use 8bitify for reference?

vale ibex
#

I suggest you copy one of the smaller files and use that as a base

clever wraith
#

cuz its kind of similar prob

vale ibex
#

Wait, what issue is this for?

clever wraith
#

a command similar to 8bitify

#

akarys or atkarys already approved it

vale ibex
#

Hmm, I've got a PR open at the minute that changes all of the profile pic modifying code

clever wraith
#

btw the way i coded it was that i had 1 module for the actual pfp mod and other module for the bot so should i merge them together in one module for this?

vale ibex
#

It might be easier to wait until that's done, since it'll be easier to slot it in

clever wraith
#

so should i just not code it?

#

cuz i could do it now

vale ibex
#

Hmm, let's get it into a PR, so we can see what your code looks like, and go from there

clever wraith
#

im not too familiar with all this github stuff, so to get this clear, i should code it into a cog for lancebot and then do the pr?

vale ibex
#

Did you fork the repo?

clever wraith
#

yes i have everything already here

vale ibex
#

Cool, I'd suggest making a branch on your repo, it'll make it easier later

#

1 sec, let me get a guide

clever wraith
#

ok

vale ibex
#

OK, from the root dir run git checkout -b name

#

Where name is what you want to call your branch

clever wraith
#

ok, also is the name for me to decide or does it have to be approved

vale ibex
#

You can call it what you like

clever wraith
#

ok

vale ibex
#

Just try to summarise what yours doing in 3-4 words

#

Doesn't need to be too descriptive

clever wraith
#

oh

#

i thought it was suppose to be the name of my command?

#

or can that be multiple words

#

cuz i just named it splitify

#

similar to 8bitify

vale ibex
#

Branch names can be multiple words if you seperate with dashes

#

But it doesn't matter

clever wraith
#

ok ok

vale ibex
#

So you've got a branch now Yea?

clever wraith
#

ye

vale ibex
#

Alright, make a new file in the evergreen folder

#

Call splitify or whatever you want it to be called

clever wraith
#

done

#

so should i make the cog now?

vale ibex
#

Yea, put all the cog code in there

clever wraith
#

ok

#

thanks for helping

vale ibex
#

Sure

stable mountainBOT
#

@gritty wind

It has arrived!

Here's your reminder: Review site# 373.
[Jump back to when you created the reminder](#dev-contrib message)

clever wraith
#

@vale ibex its done

#

works and all with the lancebot

sleek steppe
#
pipenv run precommit
git add .
git commit -m "Your commit message"
clever wraith
#

i just have 1 question

#

my command requires a perfect square num and i made a little error handler to check that and if the num isnt perfect square it raises commands.BadArgument().
but the thing is that i dont think that error that the user would get from the lancebot would clarify why their provided num was not accepted

#

this is what i mean

placid ermine
#

you can specify an error message like raise commands.BadArgument("not a square")

clever wraith
#

oh

#

ok ill try

#

ty

#

ok all done now

clever wraith
#

it says that pipenv was not recognized

sleek steppe
#
python -m pip install pipenv
clever wraith
#

i already got it

#

and i did now, says requirement satisifed

sleek steppe
#

Try running the commands again then?

clever wraith
#

which?

clever wraith
#

so i should just skip the first one?

#

and when i try to add it says: /usr/bin/env: ‘python’: Permission denied

clever wraith
#

if anyone can help, ping me