-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add announcements subcommand to gen release announcement text #573
Conversation
0cb95cc
to
d480ed8
Compare
src/antsibull/announcements.py
Outdated
async def verify_dists(dists: SdistAndWheel, dist_dir: Path) -> str | None: | ||
for dist in dists: | ||
file = dist_dir / dist.filename | ||
if not await asyncio.to_thread(file.is_file): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, I didn't realize you don't need parens with await
in such cases..
Anyway, I think this is hard to parse. Would you consider labeling this check with a human-readable var?
if not await asyncio.to_thread(file.is_file): | |
dist_file_exists = await asyncio.to_thread(file.is_file) | |
if not dist_file_exists: |
I think, it'd be good for readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of assigning an extra variable here. The reason I added the asyncio.to_thread
thing is that file.is_file
is a sync function that calls stat()
which is technically blocking IO. I guess it doesn't really matter in this code (there's no concurrency going on here), so I could just call the sync method directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Async could persist, it's just that a named variable communicates the high-level intent of the check, which refers to the low-level details otherwise.
There's a difference between "an arbitrary file exists" and "a distribution is available". OTOH, I suppose this could be improved by renaming the file
variable (which used to be a builtin, alias of open()
, by the way).
src/antsibull/pypi.py
Outdated
""" | ||
checks: list[bool] = [ | ||
await verify_hash(file, self.sha256sum), | ||
file.name == self.filename, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be much cheaper to make this a separate check and bail early, before attempting hashing. It's already performed unconditionally regardless of the hash verification result, anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true. I guess I'll have to get rid of the list of checks thing. I wish there were async lambdas so I could do a list of those instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A had some utils for async mapping and stuff somewhere in octomachinery. Plus there was some utility lib for func/itertools like async stuff. But that's an overkill here.
Also, frameworks like Trio have better abstractions for this. And some of them inspired stdlib improvements, but I don't think many would be possible to adopt there. Anyway, I like running everything through the anyio shim layer to get the best of two worlds...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback, @webknjaz! I will apply it later.
src/antsibull/pypi.py
Outdated
""" | ||
checks: list[bool] = [ | ||
await verify_hash(file, self.sha256sum), | ||
file.name == self.filename, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true. I guess I'll have to get rid of the list of checks thing. I wish there were async lambdas so I could do a list of those instead.
src/antsibull/announcements.py
Outdated
async def verify_dists(dists: SdistAndWheel, dist_dir: Path) -> str | None: | ||
for dist in dists: | ||
file = dist_dir / dist.filename | ||
if not await asyncio.to_thread(file.is_file): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of assigning an extra variable here. The reason I added the asyncio.to_thread
thing is that file.is_file
is a sync function that calls stat()
which is technically blocking IO. I guess it doesn't really matter in this code (there's no concurrency going on here), so I could just call the sync method directly.
d480ed8
to
1b9e881
Compare
@webknjaz, I amended the commits with your feedback and gave you a |
f568b44
to
a6c292e
Compare
The lint session failures are fixed by #574 |
a6c292e
to
3de0a78
Compare
Rebased on top of main |
Well, the formatter ones were... There were still pylint issues. |
2b39cab
to
837316b
Compare
I'm marking this as ready for review. I think we can address the yarl transition separately. |
Okay, fair. I don't see any obvious problems, otherwise, except for maybe |
837316b
to
4363f0d
Compare
# pydantic already pulls it in, but we use it for TypedDict | ||
"typing_extensions", | ||
# Used for sending announcements | ||
"pyperclip", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This module doesn't seem to be maintained anymore (see for example asweigart/pyperclip#248, the referenced issues, and the absence of any comments of the author in these issues). I don't like the idea of adding a dependency to something that's already dead.
Also it might make sense to make this dependency, or alternatives like clipman, optional, so that they only need to be installed if they're actually used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, that's too bad about pyperclip. I'm still a bit partial to pyperclip, as I've used it a while, it's stable, and, unlike clipman, it has at least some basic unit tests. I can try out clipman and make it an optional dependency if you prefer, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meh, clipman fails with
Failed to setup the clipboard engine: Please install dbus-python package.
- Via your system package manager. Possible package names: "python3-dbus-python" or "python3-dbus"
- Or via PIP: "pip3 install dbus".
for me on KDE Plasma. It should fall back to xclip or wl-clipboard like pyperclip does, but instead it's failing, because it doesn't have the dbus
module to communicate with klipper.
For now, I think I'll keep pyperclip and make it optional. We can always switch away from it or add a fallback if pyperclip starts causing problems.
And yes, I know I can install the dbus-python module, but that requires installing dbus development headers and compiling the wheel locally or not using system packages instead of a venv.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now, I think I'll keep pyperclip and make it optional. We can always switch away from it or add a fallback if pyperclip starts causing problems.
This was done in 28fb8de. Let me know what you think of that solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks! It's annoying that the state of Python clipboard libraries seems to be somewhat a mess :)
Co-authored-by: Sviatoslav Sydorenko (Святослав Сидоренко) <webknjaz@redhat.com>
9b36868
to
2f0287b
Compare
Add a new send-announcements process to interactively send announcements to email, the forum, and Matrix. Instead of requiring release managers to generate API tokens and input passwords, I chose this compromise approach. The command automatically opens up pre-filled email and forum posts and prompts the user about posting to Matrix. Credits to the Ansible Core developers whose release script that uses the webbrowser module in a similar way inspired this approach.
This makes it easier to chain together the announcements and send-announcements command.
2f0287b
to
28fb8de
Compare
No description provided.