#dev-contrib
1 messages Β· Page 54 of 1
Is it like so you can always discard the last item?
Yeah that was it
Looks like it works
But I think it's less intuitive than what I had
Yeah so just the len can be checked, but they're both a bit hacky
Maybe I'd use that if it wasn't in a separate function, cause that'd be more convenient
But since it's in a function I'll go for what is easier to understand
I put it in a function anyway to hide the hack
I just couldn't live with doing .count
Even though it's negligible here
Ah right I couldn't use count anyway cause of the trailing newline thing
yeah it doesn't scale too nicely when you don't care about most of the results, and the manual depends on where the last newline is
My benchmarks were with 2k chars (max for a discord message) and IDK, maybe 10-15 newlines total
I used 3 as the count
count was .10 seconds
Split was like .035
And my manual method was 1.1 seconds
typo?
Where?
the 1.1 sec
No. In the help channel I said that
that seems way too slow
I believe it's cause string functions are in C
So they are super fast
Oh it's cause I have 100000 runs for the timeit
π
that's better then
the manual should be the fastest if the chars are near the start but that's fairly unlikely to happen with newlines
Good evening, I was looking at how the reminder command was coded, because I needed a similar thing for another project, and looking at the converter: https://github.com/python-discord/bot/blob/d11f077a3402b5efd79f1948c6067e9972dfbea4/bot/converters.py#L197
What's the point of passing ctx as a parameter since it's not used?
It's a library requirement
@hollow lichen It's required on every command
Thanks for the insights! I thought it was called like as a "normal" function, but it's not
This is specifically for converters that inherit Converter, you can also decorate annotate them with regular functions where context doesn't need to be passed
It uses the implicit conversion provided by discord.py, ok. I want to say the server's bot is the standard I refer to when searching things on discord bots, thanks for that! I should contribute again
Was looking at doing some reviews to help out; with core dev features developed on the repo's branches I can simply pull and then switch to that branch to test it out.
How would I achieve this across forks without some cloning etc.?
Forks still have all the branches
Here's an alias you can add which will make it easy to check out PRs
[alias]
cpr = "!cd ${GIT_PREFIX:-.} && git fetch origin refs/pull/${1}/head && git checkout FETCH_HEAD #"
You'd just need to type the PR number
A more cumbersome way is to add a new remote for the user and then you can checkout PRs from that remote
@mellow hare how did this end up? https://discordapp.com/channels/267624335836053506/635950537262759947/707252195006873662
It didn't. Sorry, I've been really scatter brained as of late. I think the best course of action is to make an issue for it so it can be discussed and put on the record there
Can someone tell me where exactly await ctx.guild.ban is located?
@gusty sonnet Can you help me please
It's exactly within apply_ban() you can see it here - https://github.com/python-discord/bot/blob/44b33d570642905d4eeb64300a3a2d3d0cb80b72/bot/cogs/moderation/infractions.py#L247
Oh!
It's using the ban() from discord.py, which you can read about here
!docs get discord.Guild.ban
await ban(user, *, reason=None, delete_message_days=1)```
This function is a [*coroutine*](https://docs.python.org/3/library/asyncio-task.html#coroutine).
Bans a user from the guild.
The user must meet the [`abc.Snowflake`](#discord.abc.Snowflake "discord.abc.Snowflake") abc.
You must have the [`ban_members`](#discord.Permissions.ban_members "discord.Permissions.ban_members") permission to do this.
Parameters β’ **user** ([`abc.Snowflake`](#discord.abc.Snowflake "discord.abc.Snowflake")) β The user to ban from their guild.
β’ **delete\_message\_days** ([`int`](https://docs.python.org/3/library/functions.html#int "(in Python v3.8)")) β The number of days worth of messages to delete from the user in the guild. The minimum is 0 and the maximum is 7.
β’ **reason** (Optional[[`str`](https://docs.python.org/3/library/stdtypes.html#str "(in Python v3.8)")]) β The reason the user got banned.
Raises β’ [`Forbidden`](#discord.Forbidden "discord.Forbidden") β You do not have the proper permissions to ban.
... [read more](https://discordpy.readthedocs.io/en/stable/api.html#discord.Guild.ban)
Where is shadow_tempban function being used?
okay, its a command
but what is FetchedMember
It's a converter, so we can do user: FetchedMember in our command, you can read about it here - https://github.com/python-discord/bot/blob/44b33d570642905d4eeb64300a3a2d3d0cb80b72/bot/converters.py#L288
You can read about converters here - https://discordpy.readthedocs.io/en/latest/ext/commands/commands.html#converters
Oh
@gusty sonnet Can you please teach me how to use this converter to ban a user, I have this in my pydisconverter.py file: https://paste.pythondiscord.com/itibajobuv.py
How should I use it if I want to make a simple await ctx.guild.ban?
For normal usages you don't really need to go this far, what are you trying to do
I'm trying to ban/unban a user even if he leaves with his tag or id
You can still do it if you simply create a discord.Object using their id
If they have left the guild, then you have to use the id
I dont know if this is the right channel, but IMHO it would be great to have an alias for !remind as !remindme
Think #community-meta would be more sutied but you could also make an issue
here is pretty fine i think
if you want do want it not potentially lost, an issue will always be better, but casual suggestions as a topic isn't a bad thing here
@bronze hare I think it's a good suggestion and you have my approval if you wanna make an issue or a pull request. it's a oneliner to add this alias, so its pretty much a free contribution.
unfortunately I'm a bit busy lately and don't think I can set up workflow for it, so if anyone want's to take it over it'd be great.
any <@&295488872404484098> want a five minute PR? 
hey man i can turn a five minute PR into a five year PR π
im here
just an alias right?
just an alias.
merged. feature will be live in like ten minutes, @bronze hare
thanks @rocky bloom
appreciate it.
It's awesome, ty all folks
yes, the whole game jam page also needs to be updated. i can work on that tomorrow if someone else doesn't want to do it
When would this raise a ValueError? https://github.com/python-discord/bot/blob/master/bot/cogs/token_remover.py#L119
Ah I was testing with "x.y." but if I remove the last dot then it throws the error
Never mind
@sullen phoenix would be great if you could look at that.
will do
https://github.com/python-discord/bot/pull/901#pullrequestreview-408800768 About it, I'd like to get some core devs opinion before I start making changes.
numerlors comments look good
However
I've been meaning to add stats to the pep command for a while
on the PEP command (once we have confirmed it exists and sent it and whatnot) a line like:
self.bot.stats.incr(f"pep_fetches.{pep_number}")
Basically I should add this to end, then this is guaranteed that this exist
But one thing: What about these refreshes command? Should I revert it like this was?
what do you mean?
Numerlor said that current refreshing is not required and this loop request was enough.
So should I revert this change or stay like it is?
@dry turret I recently encountered the same thing when writings tests
Here's how I did it
I moved the string template into a module-scoped variable here https://github.com/python-discord/bot/pull/937/commits/09a6c2e211c0f209b258a02d9677240282c4fab3
Here I wrote the test for it https://github.com/python-discord/bot/pull/937/commits/567a5f9242912d6a3340c088c0ae1a62977a141e
I mock the string itself so I can assert format() gets called
Do you think that is a good approach?
Yes, seems I just had a case of tunnel vision with it being a f-string to start with, this way makes sense.
Thanks for the in depth reviews mark, I'm planning on doing some more to get accustomed with the code base and then maybe move on to also doing some features.
@clever wraith I left a comment under your PR, could you please let us know what the status is? https://github.com/python-discord/seasonalbot/pull/386
If you don't want to work on it anymore that's ok, but please let us know, so that someone else can finish it
I think i don't have anymore time to work on it . sorry for that
alright, thats ok
just need to fix the conflict and it can be merged imo
trying to contribute to repos in python-discord github
repos are mostly for @dusky shore @stable mountain and pythondiscord.com
We're a large, friendly community focused around the Python programming language. Our community is open to those who wish to learn the language, as well as those looking to help others.
you can look here if you wanna contribute
you can take a look at the individual issues in the repos and see if you can help
seasonalbot is more friendly to start with and is easier to set up
About bookmark, is Core Devs able to solve conflicts?
yeah but since AG no longer has time to work on it, I think it'd be best for potential contributors to implement the feature in their own forks and open their own PRs
reading through and taking into account already existing feedback
if you can tell me how can i solve conflicts i can try to do so
You should see Resolve Conflicts button?
it is blocked ....
You should use Sublime Merge https://www.youtube.com/watch?v=ZrdkEBJV660
I need to first set it up since i hopped my OS
is it normal for this to take ages ?
restarted..
pipenv can be slow at times.
ok i installed pipenv
but it is not in path
can't lint ...
looks like i needed to have something in my Scripts folder with name pipenv.exe can't seems to find that
how did you create the environment?
python -m pipenv
you can do the same for lint then
you can change the entry in pre-commit-config.yaml under flake8 or run it directly
but did you create your path var manually? If python is on path then its tools should also be there
I am confused i reinstalled it saying pipenv is already installed
still no path
should try installing somewhere else
if it all works like above, just run flake8 through pipenv run
@green oriole since you are working on my issue
Here is the solution to last problem
You use discord.Member instead User in typing and comparing this fix it all and make it ready to be merged
I have tested that and that works
Okay thanks for the tip!
When using async_cache decorator on function that increase stat, is this increasing stat every time when function is called in cache or not?
I presume not
Hmm...
Maybe I should make get_pep_embed returning bool too that show is this success or not?
what does it do?
With this I can make check in !pep command function is embed that returned correct PEP embed, not error message
returning the proper embed or None seems to be what you want here
This may return error embed too
imo it would be better if it the error embed was handled elsewhere, since it wouldn't be a pep embed then
hi i'm trying to start out by contributing to something, and if i've done it right so far this issue may be assigned to me later? https://github.com/python-discord/seasonalbot/issues/174
i'm just wondering how to start with it
here's the guide to setup seasonalbot https://pythondiscord.com/pages/contributing/seasonalbot/
We're a large, friendly community focused around the Python programming language. Our community is open to those who wish to learn the language, as well as those looking to help others.
alright thanks!
iβve assigned you the issue
thank you
i'm not sure why but when I try to add the bot to my server, it doesn't do anything when I click on the server I made
I do have manage server permissions
and it lights up and everything
but it doesn't do anything
hm clicking on your server doesn't work?
yeah
it just doesn't do anything
maybe i'm trying to do it from the wrong url?
i found this in some stackoverflow thread on adding a bot to discord
oh i see what i did wrong
i went to a different url
still won't let me click π¦
same issue
odd
i tried making a new bot and using that, didn't work either
new server also didn't work
you followed the guide i sent right? it seems like some sort of discord issue
yeah it's 100% with discord
discord oauth is broken right now I thinkk
solution for now is to add &guild_id=<YOUR GUILD ID> to the end
no problem!
What database is @stable mountain running on?
Its probably the site with rest api, isn't it?
yes, the site runs postgre
How much do you guys pay to run it?
we're sponsored, so none
Okay, thank you π
here's $100 digital ocean free credits if you want it: https://www.digitalocean.com/?refcode=74a1c5d63dac&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=CopyPaste
Thank you @sullen phoenix !
no problem!
@sullen phoenix I had some questions about it
What can I do with $100?
And will it ask me to pay for anything unless if I ask to purchase something?
let's move to an off-topic channel instead
Oh, sure
Hello,@quartz halo, probably! This is a channel for discussion our community's open source projects, though (see https://git.pythondiscord.com)
ok
Wait, mods was getting pinged eveytime someone did a @something?
Only in #352442727016693763
Ah I see
mostly because when someone pinged us in #352442727016693763 the message is deleted by the bot
so we needed to relay it somewhere so we could actually read it
but for some reason, users see an @Admins ping on the #352442727016693763 page and they just ping it immediately, for no reason.
or they do stuff like !accept @Admins
or 1 million other variations on this
Can confirm, people do this on another server where we have a similar setup
Super weird
Weird people
It seems like the .uwu <link> feature isn't working properly, am I doing something wrong?
Uses the ID I think
The help page says message link
@gusty sonnet Im not sure how to resolve the conflict
I don't see a button to resolve it :/
Normally you can resolve it when you pull from master into the branch
Then you can resolve the conflict locally, and push a commit to resolve that
When you pull there will be a conflict being raised
okay I will try
ah yeah you'll need to migrate to a fork
I use Sublime Merge for this
hi, someone sent me the guide for working on seasonal bot - i just had a quick question
at the top it says to make a channel "seasonalbot-log" for the server i'm testing in
but around the middle it asks for a "dev-log" channel instead
which one do I need?
It had its own log channel but they got merged into dev-log, so you should only need that one along with the other required channels
The guide has been fixed
alright thanks!
One thing I found on python-discord/bot repo: this have python37 tag, but this should python38 now
The tag has been changed
https://github.com/python-discord/bot/pull/817 Can anyone give 2nd review to it? This is pretty old now already and I'd like that when now someone change code, then he change tests too instead that I have to do it.
how should i find the file i'm looking to modify? for the issue i'm working on right now it's modifying the ".earth_photo" command but i'm not sure where to find said command to modify it.
I believe that is a new command
https://github.com/python-discord/seasonalbot/issues/174
this thread seems to say that it's been added but needed to be modified, i'm not sure - if it is a new command, where should i create that file? thanks for the help π
@solemn cliff if you meant the previous pull request that has been opened, then that was closed without merging so it's not in the codebase right now. The file itself should be placed into the easter folder inside exts as suggested by the easter tag on the issue
alright, so create a file called "earth_photo.py" in the easter folder?
ok ill summarize what i need rn, i posted this in a help thread but i didnt realize i should probably get someone to help me first
i'm trying to write a ".earth_photo" command for seasonalbot, and i'm not really sure where to start; looking at a similar function "april fools videos", I found a basic structure for what i'm writing but i'm not sure how to expand on it.
my code so far:
from pathlib import Path
from discord.ext import commands
log = logging.getLogger(__name__)
class earthPhotos(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot```
a suggestion was to use images from r/earthporn on reddit in order to get the images
but i'm not sure how to load those images or even start with that, this is my first time writing code for a discord bot and any help would be appreciated π
@jade tiger hey dude, are you around?
Just about to head off to bed, what's up @crude gyro?
we dismissed a stale review on your help PR and are now discussing some of the implementation details
I think we figured it out, though
it's related to which part you decided to create_taskify in the decorator and why that means you have wrap it around a ctx helper to get it to run properly
Ah. Something about it stopping stuff from running while waiting for a delete or timeout or something iirc. I can have a look
Yeah, no worries. I know what it does and why you've done it, I'm looking at another solution that will work for all interactive commands that don't finish immediately
instead of making help a special case with an early-return helper function to make sure the decorator finishes in time
I also left a review with some minor nitpicks and a question about why you're decorating the prepare function instead of the command function, @jade tiger
and Ves will run a quick test and add his thoughts about the redirect. once these things are settled, we will merge it immediately.
it's old and it's time to get it merged.
the prepare function is currently necessary
because the early return is needed for the decorator to continue in its execution
but I've got a proposal to change that
yes
I think it's very surprising that it decorates that one
and it looks suspicious to me
a bit like a code smell
Anyway, I've tested the alternative and it works
Uhhhh there was a reason why I put the decorator on that one
yes
Does ctx.send_help work when it's on the command?
The decorated function needs to return to allow the decorator to continue its execution
that's why you needed a helper that quickly returns
That's the one
but I've got an alternative that will work in general (for if we decide to add more interactive/long-running commands)
Sweet π I'll get to the nitpicks in the morning.... Tired + coding never goes down well with me π
sorry it took so long to get to
No prob
I asked in issues too but can I get assigned on @stable mountain repo issue #939 and #898?
Sure, I'll assign you @cold moon
Hmm, I can't assign you on 898, didnt show up in the list for me
It was still in planning last time I checked so probably needs more discussion on the actual implementation
That's probably why
oh ves just commented
939 is clear enough, if we can coordinate and get it done with 898 it'll be great too
It's something that could lead to a very ugly implementation rather quickly
but we need something that's robust and doesn't use a lot of resources
What's our stand on the persistent cache, how will it be implemented
Redis
@patent pivot was already working on that
There may be an issue in the organisation repo
not sure
Hmm, should we wait for it first then, having a redis is probably better to execute this
Hmm says Joe is done with it, the issue is here - https://github.com/python-discord/organisation/issues/239
Okay, but is it already easy to use from bot?
I've never worked with redis before and we probably need some examples so everyone follows the same naming conventions and the like (for keys and so on)
@hardy gorge my part is done
I was just setting up redis, @crude gyro is integrating it
Is it kicking into action?
@gusty sonnet with regards to the persistent cache: in theory it will require zero to minimal code changes. the design will be a dictionary like structure but backed by redis. you can still assign with blah["abcdef"] = "abcdef" and fetch with the same method.
this will be reused around the bot and be namespaced so it will store in redis as like blah.<key>
lemon will write that class and then any persistent storage will be done with that
however I see a bit of a flaw with the internal issue. @crude gyro when you say cog-local I think it needs to be more local than that. the help channel cog needs two caches, unanswered & help channel claimants. I think doing it by cog is more confusing than just doing like self.help_channel_claimants = RedisDictionary("prefix")
Can't have nested dictionaries?
not with redis no
well
you could
but I don't think it needs to be that complex
either way the proposal is that all cogs get self.cache as a dictionary
there needs to be some way to have individual dictionaries, whether that be using a manual constructor or some other clever way
dinner time
Caches are mapping a string to a string, it cannot hold anything fancier, right?
Yeah
What if we make a RedisSerializable ABC, with a method for serializing and deserializing the object, and work around that? We could have a serializable subcache dict that can go in any cache, and will be serialized using simple json?
I don't think our Cogs should become mappings
They could have a caching/mapping attribute, as in composition, but they are not mapping objects themselves
I don't think we need an abstract base class in this case
redis is a Dict[str, str] iirc
So unless we have ways to serializable complex structure
Technically, all objects are mapping
I mean, we can also use json
But for what it's worth redis should stay a simple cache
Agreed Ves
(Mind explaining why not in #internals-and-peps you got me curious?
)
I don't like the idea of serialising it @green oriole
Nested dictionaries aren't a pretty cache
And we'd have to be careful of race conditions
Redis alone wouldn't have race conditions but if we were serialising the same key we'd have to knock off some performance with locks to achieve the same thing as just have two keys
@patent pivot I got StatsD now working, but how to make this logging to console?
I think a hash set might be a better alternative
If we did a hash set we'd have two namespaces
the command looks like this https://redis.io/commands/hset
But is making two cache so much of a problem?
HSET help-channel-claimants 112233445566778899 123456789123456789
then you get a nice dictionary
I think that's the better way of doing things
Two keys one value
One key for the cache name, one key for the cache key, one value
Also means less prefixing and easier debugging
that is what that would look like
@crude gyro what do you think of that? prevents us having an overload of keys in the top level namespace. I think hashes are the way to go for the redis integration
also I think it's tidier than prefixes
@patent pivot I got StatsD now working, but how to make this logging to console?
@cold moon
What do you mean? To test the stats function you've added? Or?
yeah I was telling ks earlier how to debug statsd
nah it's easier than that
you can run a statsd instance to test it
uhhh
{
port: 8125,
backends: [ "./backends/console" ]
}
that's all the config I needed
and then basically instead of flushing to another backend and storing it just logs all the stats it's accumulated since the last flush there
Do we have that documented somewhere?
I'll add it to the stats infra page now
Added @hardy gorge @cold moon https://pythondiscord.com/pages/statistic-infrastructure/#running-a-local-statsd-client
We're a large, friendly community focused around the Python programming language. Our community is open to those who wish to learn the language, as well as those looking to help others.
yep yep
@jade tiger I'm sorry, I wrote an essay to suggest a one-line change
Something to print and frame on the wall π
You could make a blog post out of this one haha 
"Why should you use asyncio.schedule_taskcreate_task instead of await"
Nice, thanks
I'm working on a library to fetch docstrings from builtins and modules, with some smart caching for another project, would you be interested into integrating it into the !doc command, so things like str.replace can be found?
!d str.replace
str.replace(old, new[, count])```
Return a copy of the string with all occurrences of substring *old* replaced by *new*. If the optional argument *count* is given, only the first *count* occurrences are replaced.
seems to work
!d str.index
str.index(sub[, start[, end]])```
Like [`find()`](#str.find "str.find"), but raise [`ValueError`](exceptions.html#ValueError "ValueError") when the substring is not found.
not recently
But I have an issue up for some improvements
It can't find most of the list methods because they aren't in the inventory if you were remembering those
Maybe that wasn't str, but some of the builtins doesn't have a proper documentation and are only documented in the tutorial pages
I remember there was an issue like that
hmm I think I remember
Those are the list methods just mentioned
how would it work?
the closest the inventory gets is some tut-whatever entries on the page where the list methods are listed, so for getting them individually it would have to crawl the docs in some way or some sort of specific way to get those
Akarys probably means fetching the docstrings from the function objects
Yup, that's the library I'm working on
Well, not only functions, modules and attributes have docstrings too
Are you using inspect.getdoc?
Lol. No worries ves. And I seemed to find a lot of "ninja code" floating around π
quick question. how the heck do I run these linters? π
I tried running pipenv run lint and that went along and fixed a million other files so I just had to revert
I then tried pre-commit run --files blah and it tells me flake8 failed
I then tried pipenv run flake8 and it tells me that flake8 passed, lol
oh and just committing fails too and tells me flake8 failed
and running flake8 is fine too
What error is it failing with?
May need to recreate the precommit or something, there have been some larger changes to the type of linting that gets ran
Flake8...................................................................Failed - hook id: flake8 - exit code: 1 Loading .env environment variablesοΏ½
maybe I screwed something up with .env
is there anything below that ?
that is the first line that shows up when it runs
do you also get the other checks with precommit like check blanket noqa?
that one should be above flake8
I added nvm that's me mixing up arg order-v flag to pre-commit and it's telling me there's no hook with id /bot/cogs/help.py in stage commit. Not sure what that's about
yeah they all passed fine
pre-commit run -v --files bot/cogs/help.py
Check for merge conflicts................................................Passed
- hook id: check-merge-conflict
- duration: 0.3s
Check Toml...........................................(no files to check)Skipped
- hook id: check-toml
Check Yaml...........................................(no files to check)Skipped
- hook id: check-yaml
Fix End of Files.........................................................Passed
- hook id: end-of-file-fixer
- duration: 0.34s
Mixed line ending........................................................Passed
- hook id: mixed-line-ending
- duration: 0.4s
Trim Trailing Whitespace.................................................Passed
- hook id: trailing-whitespace
- duration: 0.33s
check blanket noqa.......................................................Passed
- hook id: python-check-blanket-noqa
- duration: 0.77s
Flake8...................................................................Failed
- hook id: flake8
- duration: 1.71s
- exit code: 1
Loading .env environment variablesοΏ½
if everything's up to date and pipenv run flake8 works then I've got no idea
If you'd like, you can create a patch and send it to me. I can then apply it locally and test it out
Hey @jade tiger!
It looks like you tried to attach file type(s) that we do not allow (.patch). We currently allow the following file types: .3gp, .3g2, .avi, .bmp, .gif, .h264, .jpg, .jpeg, .m4v, .mkv, .mov, .mp4, .mpeg, .mpg, .png, .tiff, .wmv, .svg, .psd, .ai, .aep, .xcf, .mp3, .wav, .ogg.
Feel free to ask in #community-meta if you think this is a mistake.
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.
Everything works on my end
Try re-creating your venv and/or pre-commit cache
I just tested with a fresh venv on Windows
righto
Are you using
inspect.getdoc?
@hardy gorge well I was using the.__doc__attribute, it looks like this functions is just a fancy way of getting it, I guess I could use that if that's any better
I don't understand why but @stable mountain don't send stats to my local StatsD.
When I use IDLE and statsd myself, I can send stats
But bot don't do anything
Did you look at the __init__ of the Bot class
It redirects the output to localhost; is that should happen for you?
Maybe @patent pivot can help with that later, but I think he's currently at work
I haven't actually set it up myself yet
Yes, this redirect to localhost for me too
@patent pivot This is increasing correctly
But that's only in list. Bot stats should there too.
I found that setting Graphite + StatsD up is simple with Docker
there isn't much use for most people to run an extra container
@cold moon I think it's because your graphite function is incorrect
you probably want something like
integral(stats_counts.bot.test)
but yeah I'm on the fence about adding it to Docker
I mean we can have multiple dockerfiles
right, but this isn't even a dockerfile
docker run -d\
--name graphite\
--restart=always\
-p 80:80\
-p 2003-2004:2003-2004\
-p 2023-2024:2023-2024\
-p 8125:8125/udp\
-p 8126:8126\
graphiteapp/graphite-statsd
Well, we could do that too
My idea was that you have the main dockerfile, and then some other ones that are the main dockerfle plus some features, like redis or the stats stack
right, but they aren't custom pydis services
I was speaking with lemon on this and there is no point running redis locally
redis doesn't even have windows support
so we'll just back the redis cache with a dict locally
since persistence isn't required
And the dict will be dumped to the disk?
Because it would mean that you can't test redis features
Like what if for some reason redis doesn't properly load your cache? You'd push something broken in prod
well that's more on redis than the code in bot
our redis config file is only 3 lines long, none of which are technically needed in dev
# Store all commands used and replay on server startup
appendonly yes
# Set password
requirepass {{ pillar.redis.password }}
# Set working directory
dir /data
@patent pivot this don't show on cloned StatsD only node too
Yes
What you mean?
in IDLE
No, then this show
Maybe is thing on Docker because I can't connect to local snekbox too
oh yeah what IP are you using?
and are you running it with ```
docker run -d
--name graphite
--restart=always
-p 80:80
-p 2003-2004:2003-2004
-p 2023-2024:2023-2024
-p 8125:8125/udp
-p 8126:8126
graphiteapp/graphite-statsd
Yes
hmmmmmm
if you telnet to localhost:8125 and do something like
my_stat:1|c
does that appear in graphite
honestly I'm tempted to say don't bother running statsd locally
maybe you should try hosting a UDP service on port 8125 echoing all messages received (you can do this with netcat if you have it, else should be simple with python)
I have basically same problem with Snekbox: I can execute it in IDLE, but in bot (Docker) this say can't connect.
my_stat:1|c is working
hmmm
that's super weird
You could try it on Linux but I wrote all the stats stuff purely on Mac
Huh! Got it working: I run site + postgres in Docker and bot with pipenv run start
Then everything works
@patent pivot About server boosts, I think easiest way is make task that report amount of Nitro boosts like in every 1h. dpy don't provide events for these. Only way is scan #community-meta messages and message types, but this only show boosts, not unboosts.
ok
hi i'm working on a ".earth_photo" command for the seasonal bot
@patent pivot So I now added all statistics in https://github.com/python-discord/bot/pull/945 except these #303934982764625920 stats
and i found a library that would speed up the process called PRAW (python reddit API wrapper) and i was wondering if that was installed on the main branch, and if not would it be possible to do so? thanks for the help π
hi there
you can check that pretty easily, @solemn cliff
just look at the Pipfile in that repo
in the root
none
oh alright i found it! thanks for the help!
praw we don't have installed because it relies on requests pretty sure btw
that's how we track all the dependencies. I'm not sure whether praw is there, but probably not
can I add it? i'm not sure how to do that lol
also as a note, is there an issue ticket for the feature already and if so, did you comment on it?
coolio thanks
and no, you won't be able to add it as it uses requests, which is a http library designed for non-async projects
while the bot is async, so we must use an async-compatible http library, which is the lib called aiohttp
oh, okay
i'm very new to that kind of thing, are there any resources i can use to find out how to use that?
thanks for the link
the documentation for aiohttp is here:
https://docs.aiohttp.org/en/stable/
We have an aiohttp session available for usage already intitialised on the bot instance also, i think accessible under bot.http_session or something, will have to check the code to see
it's best to use this existing session though rather than creating a new one
alright, thanks for the help!
there also should be existing usages in the bot that access that session that you can use as an example
it's http_session
thanks
so is this just an API to access webpages?
it's a library to request data from web urls
so if it's an api, it'll return whatever data it's giving, such as a json formatted data
if you give it a webpage, then it'll download the raw html instead
oh so if i put in like "python.org" it'll return an html file?
it'll return the raw html content, not a file
like a string? sorry i'm new to this kind of thing lol
you'd save that content into a file after retreival if you wanted it to be a file, but we wouldn't since we'd need to use it
and yeah like a string
ok cool
reddit has an api, and they have docs for it too, but something of note is that we must authenticate our reddit requests to their apis
it's part of the agreement, even for apis that are considered public and unrestricted
is that in the docs for the reddit api?
it is, but we should have existing uses of this already
either in seasonalbot or pythonbot
oh, any specific commands I can check out?
i'll have a look, i can't recall atm
thanks
ok thanks!
Aren't those messages supposed to disappear after some time? #ot1-perplexing-regexing message
About https://github.com/python-discord/bot/issues/331 , should inspect.getsource help?
!d inspect.getsource
inspect.getsource(object)```
Return the text of the source code for an object. The argument may be a module, class, method, function, traceback, frame, or code object. The source code is returned as a single string. An [`OSError`](exceptions.html#OSError "OSError") is raised if the source code cannot be retrieved.
Changed in version 3.3: [`OSError`](exceptions.html#OSError "OSError") is raised instead of [`IOError`](exceptions.html#IOError "IOError"), now an alias of the former.
Aren't those messages supposed to disappear after some time? #ot1-perplexing-regexing message
@green oriole
I don't know, but the decorator has never implemented something like that. The redirect_output decorator does, but snekbox isn't using that one.
It's using the in_whitelist one (formerly in_channel)
The message did change slighty (for if you're wondering what changed)
Shouldn't we fix that then?
Mb
Shouldn't we fix that then?
@green oriole
What do you mean with fixing? The reason it's not redirected or autodeleted is that the code posted, even without output, is often relevant to the conversation in the channel to which it was posted. Deleting it would also mean we'd have to implement a custom decorator, as I'd hate for the member to lose their input message with the code they wrote during the redirection process.
I don't really see it as something that is not working at the moment
It's working as intended
mildly related, were there any thoughts about sending DMs with contents or something like that when a message gets deleted for attachments?
Have seen a few people post a longer message to start a help channel just for it to be removed and lost
They can send a message along with the attachments, which will get deleted
They seem to be talking about the eval command
And he's asking about something else
Oh right, I'm blind
Doesn't Discord only suggest the text file if you pasted text into the client?
I've not seen it happening when I actually typed a message myself
Which also means that deleting that .txt file should not erase the source they copied it from
In general when sending a file that'll get caught by the filter
You can add a message before uploading, or it'll use the existing one if something was in the input box
So, it's for the message/comment attached to the file?
yes
I guess we could try to DM it to the user. I'm less keen on saving a message off Discord, as it could contain personally identifiable information.
Could also be extended to some of the other filters, should I make an issue?
also got a small pr for increasing the timeout on !eval's re eval timeout if anyone feels like taking a look https://github.com/python-discord/bot/pull/944
It does check all the events, but I guess there aren't that many edits
I don't think it's much of an issue
We're not running into those kind of bottlenecks currently
Not that familiar with discordpy (or the dicsord api) but I assume it receives and handles those events in some way anyway?
The events are send out by the API regardless of what we do with them
They are gateway events, like your client also receives
discord.py dispatches them internally to all listeners
So, the cost is running the check function a couple times more, but it doesn't involve additional API calls
the simple checks probably take less than how d.py handles the event; what duration were you thinking of?
@tawdry vapor I think you should re-review https://github.com/python-discord/bot/pull/901 because this got really big changes after your review.
how to create your own repository in git
Not really the right channel, but if you're using GitHub, just click the + at the top right
#tools-and-devops is good for Git chat
thx
@molten bough in theory from these files that the program earned it is necessary only all .py?
Again, not the right channel (unless this is a project on the python-discord GitHub)
The files required for a project depend on the project, though.
@molten bough this project is simple GIF on avatar puts
!off-topic in that case, I guess
Off-topic channels
There are three off-topic channels:
β’ #ot0-psvmβs-eternal-disapproval
β’ #ot1-perplexing-regexing
β’ #ot2-never-nesterβs-nightmare
Their names change randomly every 24 hours, but you can always find them under the OFF-TOPIC/GENERAL category in the channel list.
@hardy gorge Note about Context.send_help: I already made this in https://github.com/python-discord/bot/pull/860 .
The help invocation was failling after the merge of the help command refactor PR
We had to fix it and fix it now
Re. Commands per page Ves, could always take that constant at top of file down to 6-7 if it's too annoying
https://github.com/python-discord/bot/issues/796 This issue have been opened some months, but still no decision is this approved or not?
seems like a bit more of a seasonalbot thing imo
I thought we took a stance that Python should be more focused on guild utilities a while ago
though i guess we have stuff like PEP in there so maybe not
I think this is a handy tool that could be used in most channels, while seasonalbot has "fun" commands that should ideally just be run in #sir-lancebot-playground
@hardy gorge well, that's fair, would it be possible to add reminders to this channel though?
@cold moon hi. I just noticed your pr and commits use "improvisation". I think you meant to use "improvement"? The former doesn't make sense
Oh shit... my english... sorry
It's alright
I wonder if it's worth rebasing right before merging to correct that
Also, you should keep each line of your commit message at a maximum of 72 characters. If I remember correctly, some of yours were too long and getting cut off for that PR
If the prefix is too long to make that feasible then either shorten the prefix (like to "pep:") or remove it completely.
Okay, I'm turning on PyCharm alerting for that
This is being said more for future reference as I'm not sure if a rebase should happen
Is first line limit 50 chars and body line 72 chars?
Yeah, ideally. Summary can go to 72 though
ok
how do i test code for the bot?
ie if made a new command how do i set up the usage of that command
yeah i have that
but i mean how do i make it so when i type in the command it runs the function
Do you know Discord.py well?
no i don't
You can look at how other commands are implemented and then use the logic you need for your own one
alright, is there a specific file within the seasonalbot\ repository where the commands are implemented?
They'll be under the exts
is it bot.py?
oops never mind
that's the wrong folder from me lmao
wait i think we're thinking of 2 different things
discordpy uses Cogs which are classes that contain commands (and then the code needed alongside) and for seasonalbot are loaded when the bot starts
the file i'm looking for is the file where it'll detect an input for example ".hello" and then run the command script which is within \exts\easter for example
ok ill read the docs on cogs
thanks
This is a short one which shows how a command is added https://github.com/python-discord/seasonalbot/blob/master/bot/exts/evergreen/recommend_game.py
you create the cog where your code and commands are, then the setup function, then in case of seasonalbot I believe they are added automatically
Hey @solemn cliff!
It looks like you tried to attach a Python file - please use a code-pasting service such as https://paste.pythondiscord.com
oops ok
i copy pasted reddit.py to see how it works
and was gonna modify it after
Why you have Reddit command there?
the command is ".earth_photo" and its supposed to fetch an image from r/earthporn (it's pictures of earth not... nsfw stuff lol) and send that image
already approved on github
Yes, but you can't just copy-paste existing command
yeah i'm not just submitting that obviously
i said im modifying it once i figure out how it works
so how do i make it go from
receives message ".earth_photo"
to
runs the function
that's what the command decorator does
is that how it works?
https://pastebin.com/70LDD5sw
anyone know how to fix this error? when i modified my stuff i didn't touch any of those files
ok thanks
My guess is something needs to specify unicode encoding when opening a file
yeah, but it's odd that it never happened until now
we were fixing a similar issue in bot for windows users right?
it happened when i ran pipenv run start if that matters
I don't know. The bot doesn't read as many files
Regardless, all files should explicitly specify an encoding
are you on windows, @solemn cliff ?
yes i am on windows
what's the default encoding there
not sure, how do i check? i'm really new to this
dont worry ill find it somewhere
It depends on the OS language
alright
right so that will be the culprit
yeah I can reproduce this if I specify encoding="cp1252"
so this particular traceback can be fixed if you go to bot.exts.evergreen.trivia_quiz.py and on line 43 specify p.open(encoding="utf-8") as ...
but I reckon another open will fail then
alright ill see if something else fails with that
it tries to open a lot of resource files
oh
I'm not sure what we can do to mitigate this apart from going through all of those open calls and specifying the encoding
Traceback (most recent call last):
File "c:\program files\python38\lib\runpy.py", line 184, in _run_module_as_main
mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
File "c:\program files\python38\lib\runpy.py", line 143, in _get_module_details
return _get_module_details(pkg_main_name, error)
File "c:\program files\python38\lib\runpy.py", line 110, in get_module_details
import(pkg_name)
File "C:\Users\aaryan\Documents\python stuff\git stuff\seasonalbot\bot_init.py", line 6, in <module>
import arrow
ModuleNotFoundError: No module named 'arrow'
looks like a different error
yeah thats a separate problem
have you done pipenv sync --dev?
your environment should have arrow if so, it's in the lock file
oh i think i know what happened
i renamed the folder so i probably have to redo pipenv stuff
yeah it may not be finding the venv then
anyway I should make an issue for the encoding thing
but I don't look forward to having to do it
May be it's worth linting for it?
does flake8 have a plugin for that?
probably
the sync --dev seems to have done something? but now my cmd is stuck on
05/17/20 11:00:32 - bot.utils.decorators INFO: Starting seasonal task PrideFacts.send_pride_fact_daily (June)
https://github.com/rayjolt/flake8-file-encoding I will try this and if it's good propose it in the issue
are you sure it's stuck?
that's weird
yeah
oh so is it just done loading?
it won't continue logging forever
ok but thats weird
are you saying that just specifying utf-8 once fixed everything?
I thought it'd just fail on another file but looks like that's not the case
yeah
ok
this is a completely different issue - it looks like I didn't fully input the code for something? i'm not sure what to do from here
uh oh
happened when i ran the command i just made
oh guess the seasonalbot also has the issue
is that the eventloop thing?
Looks like it
as a simple temporary fix, doing asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) where the bot starts should work beans
alright where should that be put in though? at the top of the <command name>.py file i made?
or in the _init_ function
it needs to be ran before the bot starts the event loop
sorry im not sure where to find that, is it in the setup() definition?
__init__.py or __main__.py should work
ok i'll put it in _init_
alright
you need to put it in the init file, not function; mind that
And the file under the above dir beacuse the others may be ran after it's running
should work, just make sure to import asyncio before that
yeah ok
ok now the error's in the thing im coding so i should be fine from here on out
thanks for the help
I'll make issues for those two problems so that we can get them fixed in the future, but it won't be instant
thanks for reporting them by the way
helps us improve the project and make setup easier for others
yeah of course!
@solemn cliff do you mind if I use the screenshot you posted for the official issue on our github
it shows your windows username
I can censor it if you prefer
uh censor the username but yeah you can post it
sure thing thanks
yup
would it be possible to import praw for this command? it would be a lot easier than using the kinda process that reddit.py uses
sorry to install* praw
not import it
No because praw doesn't support asyncio
oh ok
05/17/20 11:48:12 - bot.exts.evergreen.error_handler ERROR: Unhandled command error: 'NoneType' object has no attribute 'url'
Traceback (most recent call last):
File "C:\Users\aaryan\.virtualenvs\seasonalbot-okXAdm8a\lib\site-packages\discord\ext\commands\core.py", line 83, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\aaryan\Documents\python stuff\git stuff\seasonalbot\bot\exts\easter\earth_photo.py", line 125, in get_reddit
embed.set_author(name=f"r/{posts[0]['data']['subreddit']} - {sort}", icon_url=reddit_emoji.url)
AttributeError: 'NoneType' object has no attribute 'url'```
is this an error in my code or in evergreen code?
@tough imp were you planning to make an issue for the encodings?
yes but I was trying to investigate and got distracted
if you feel like doing it, it would be greatly appreciated
since it looks like it was just one file causing issues in this particular case, I wasn't sure whether we want to go & specify encoding for all io (I naively searched the repo for open( and got 57 results) and maybe propose introducing https://github.com/rayjolt/flake8-file-encoding or maybe just fix up that one line as a stop-gap
Will do, got 41 occurrences when I filtered out my search for the open
excellent, thank you!
@solemn cliff sorry for the late reply - yes it's getting triggered in bot\exts\easter\earth_photo.py, based on the traceback it looks like reddit_emoji was None and so didn't have the url attribute
alright, thanks for the help
anyone know how to get the emoji id for a non-custom emoji?
for example
π·
the \:emojiname: doesn't work
so do i just put π· into the place i'd have put the emoji id?
it's something for the discord bot
(i'm using google translate to see what that meant)
You are not allowed to use that command here. Please use the #bot-commands channel instead.
@tawdry vapor Removed loop from PEP refresh check
!rule 4 - sorry, but I can't understand you with Google Translate even
4. This is an English-speaking server, so please speak English to the best of your ability.
The staff here mostly speaks English, so it's impossible for them to moderate other languages
Why Mocks don't allow you to add new attribute: AttributeError: Mock object has no attribute ... (MockContext)
It's because they follow the specification of an actual instance of Context
Why do you want to assign an additional attribute?
I'm testing error handler and this check attribute invoked_from_error_handler.
If that's a custom attribute that we set, we need to adjust the mock to reflect that
Okay
You should be able to set it on the context instance we use to create the mock
But I need to do that this is not on every instance
We just need to make sure that the mock object recognizes that it's a valid attribute that may exist
If you add the second line to helpers.py at the right place, it should work:
context_instance = Context(message=unittest.mock.MagicMock(), prefix=unittest.mock.MagicMock())
context_intance.invoked_from_error_handler = None
OK, thanks
Wait, now I added this and now this attribute always exist
What mean existing tests fails
It always exists in the sense that just like with every other valid attribute of a normal Context instance, the mock will happily provide a mock for it
That is the default behavior of regular mocks that do not follow a specification:
>>> from unittest.mock import MagicMock
>>> m = MagicMock()
>>> hasattr(m, "invoked_from_error_handler")
True
What our spec_set does is say "Only every allow there attributes and raise an AttributeError for any other attribute that something tries to access or set"
Since we actually use that attribute in production, we must make sure that our mock allows it as an attribute as well
That's what you just did
I have to change error handler code then a bit
Why? Can you just check what kind of value we have for that attribute?
If the code assigns a value, you should be able to see that it assigned that explicit value
I changed hasattr to getattr
if isinstance(e, errors.CommandNotFound) and not getattr(ctx, "invoked_from_error_handler", False):
Does the bot support live reloading? Or do I have to restart the server every time I change a cog?
could unload and load it again
I just restart the bot personally, but I'm running it directly
I'm using docker
looks like there's https://github.com/python-discord/bot/blob/master/bot/cogs/extensions.py#L59 for a neat interface
Oh, thanks
Would a regexp testing command make sense on this server?
It can be kinda useful when explaining regular expressions.
You can use emojis as subcommand aliases... but I don't know how useful that is.
RuntimeWarning: coroutine 'AsyncMockMixin._mock_call' was never awaited
How to remove this warning without awaiting. https://paste.pythondiscord.com/zuritaqipe.py . This ErrorHandler.get_help_command is reason
But I don't know how to fix
Oh
That's actually something that's not okay in the current code
In some situations, the coroutine isn't awaited
I introduced that mistake
One way to solve this would be to change the way it's done
Remove the
prepared_help_command = self.get_help_command(ctx)
and alter these lines:
await prepared_help_command
to
await self.get_help_command(ctx)
OK, thanks
Does the bot support live reloading? Or do I have to restart the server every time I change a cog?
@celest charm!extensions reload <extension name>can do that
Should I include stats increasing too into tests?
I don't think so
Staff
But decorator-factory have only Contributor badge in GitHub?
You donβt need to make membership public
Oh
I'm new in this chanel and I'm Polish I use with google translater and I started with phyton I need some help with open image can anyone help me
@crimson beacon This is not right channel for this. I'd suggest to read #βο½how-to-get-help , smaller/quick questions you can ask in #python-discussion but something bigger get one available help channel and send your question and code.
This might also be helpful https://wiki.python.org/moin/LocalUserGroups#Poland
Wonder if it'd be useful to have a command that parses this page
There should tag
Hello people!
Is it OK if I stick to a shorter line length limit? Given that it's consistent inside a single file.
π
Although it might be an issue because of D200 One-line docstring should fit on one line with quotes
This fits in 80 characters, but fails with flake8:
"""
Commands for exploring the misterious world of regular expressions.
"""
But this one is 82 characters long:
"""Commands for exploring the misterious world of regular expressions."""
How do I add a new dependency?
I added this line to [packages] in bot's Pipfile:
regex = "~=2020.5.14"
then I ran:
pipenv lock
pipenv sync --dev
Now I can use regex in the REPL, but it can't find the module when running with docker.
I also have regex installed on all python3 interpreters on my system, so that isn't the problem.
You can murder the cache by running docker-compose up --build maybe that could help
@celest charm your local pipenv does not affect what's in the docker containers. it only installs new dependencies when you rebuild the container
so after changing the pipfile, do docker-compose build bot or docker-compose up --build
and it will take care of it.
the pipenv install for that dependency only happens inside the Dockerfile, but when you up a container it usually does not run the code in the Dockerfile. it just runs an existing container on your computer
that's why you have to rebuild
Thatβs weird that docker doesnβt want to rollback the container and rebuild, because the pipfile changed
I don't find it weird
Containers are not "tied" to the build steps
They're just instances of a certain build
I guess I need to read the docs again then haha
Think of it like this: Dockerfile is the analogous to source code, an image analogous to a binary, and a container analogous to a process
The process is executing a particular version of the binary. It's not aware of the underlying source.
About source command, should this have channel limitations?
probably not
@cold moon couple of questions for you on https://github.com/python-discord/bot/pull/864
sorry the review took a while, it's been a crazy month
my bad
@crude gyro This is now done.
will take a look in a second
@cold moon did you test this after making these changes?
Thanks, @crude gyro
no problem
I'm having a problem with the bot: I fetched the main repo to update Pipfile, and the bot fails to build now because of linting errors on lots of files:
https://dev.azure.com/python-discord/Python Discord/_build/results?buildId=7022&view=logs&j=5264e576-3c6f-51f6-f055-fab409685f20&t=ba73fe70-97c4-5e2d-5cc4-47c0f87130c8
and flake8 produces the same output. How to deal with that?
I mean, that f-string is missing placeholders
title=f"**PEP 0 - Index of Python Enhancement Proposals (PEPs)**",
I'm not really sure how the version pinning works but your flake8 got updated to 3.8.1 which introduced new linting errors
Can I just switch to a new branch and fix them?
The flake8 update is already in one of the open prs so I think it should all be handled there
Well, some of them aren't really errors, that's the issue.
(and probably already is)
could maybe pin the version directly for now? Feels hacky though
and the other pr may get merged before, not really sure myself how it should be handled here or if it's an issue with how pipenv interpreted the ~=
we should have probably done the flake8 bump in a separate PR
but the lockfile still has 3.7
so unless you re-lock you shouldn't have that problem
Well, I relocked, that's the issue
They did introduce a new package
Because I had to add feedparser and something else from master
And also a new package
ah right, is there no way to do that without relocking everything?
No
Was planning to make a pr but kept delaying it until lemon added it to the redis pr
But we could pin the flake8 version more strictly
could this be solved by cherry picking the commit from lemon's branch?
So I'll just pin flake8 to 3.8.0?
you'll want before 3.8
flake8 = "~=3.7.9" should work
we could also just bump it to 3.8 and fix up the new errors in a separate PR
yeah, but it will have to be done
I want to say that I can do it tonight, but I already have a lot on my plate
alas, I will have to see that god damn long Locking... animation again
@crude gyro How do you feel? The current change is in your PR, but that PR is probably going to take a while
I could do it if needed but I'm not very familiar with pipenv beyond setting it up for running
if you guys wanna do that work in a different PR, you can easily cherry pick my commit for it
yeah I'm thinking that the work is basically done
it is done, and it's all in one commit
just need to cherry pick it into a separate branch
yeah. and if you do that, I don't need to change anything either
true, I'd be in favour of doing that then
it's actually better because it makes my PR easier to review
removes all the noise
once it's merged to master, at least
So git cherry-pick -x e993566
Should I pick your version?
-x
When recording the commit, append a line that says "(cherry picked from commit β¦β)" to the original commit message in order to indicate which commit this change was cherry-picked from. This is done only for cherry picks without conflicts. Do not use this option if you are cherry-picking from your private branch because the information is useless to the recipient. If on the other hand you are cherry-picking between two publicly visible branches (e.g. backporting a fix to a maintenance branch for an older release from a development branch), adding this information can be useful.
yes, my version has the lint fix
or else the linter will complain on flake8 3.8
strings without any interpolated data don't need to be f-strings
flake8 3.8 complains about this
I'm curious, how does the ~= work that it skipped to 3.8?
π€
bot/cogs/error_handler.py:170:31: F821 undefined name 'help_command'
how can i help here?
Maybe I shouldn't have picked your version there
new here
@brazen charm ~= 2.2 means >= 2.2 and also ==2.*
ah so == 3.7.* would be more suited then?
if that's what you want
in this case I think upgrading to 3.8 is good
~= is called "closest compatible release"
in the relevant PEP
of course, minor versions do sometimes introduce breaking changes
but they're not really supposed to. with a linter it's a bit special
it's not really introducing breaking changes, just new rules
Upgrading is good, but with flake8 those usually need to be taken care of in a pr
In this case, "~=3.7.9" would have been the right pick
It says everything from 3.7.9 and up, but below 3.8
So, 3.7.10 would have been fine, but 3.8.0 not
And 3.7.6 also wouldn't have been fine (lower than 3.7.9)
Just that it could be changed in the update pr if it's still like before so the above problems could be avoided when 3.9 comes
cherry-picked the commit, build is successful! thanks everyone
I have one idea: !source command should have 2 subcommands: site and seasonalbot that have short description of these projects and GitHub link.
Maybe that commit could be removed later with git history screwery because here it's a temporary solution, but that sounds extra hacky.