Skip to content
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 CoreEvent enum as argument for Sphinx.callback #12259

Closed
wants to merge 2 commits into from

Conversation

chrisjsewell
Copy link
Member

@chrisjsewell chrisjsewell commented Apr 10, 2024

When creating sphinx extensions (or looking at existing ones), it is always a source of annoyance/confusion trying to remember what callback events are available, what their purpose is, and also what their signatures should be.

Here I add the sphinx.events.CoreEvent enum, and allow this to be passed to Sphinx.connect, as an alternative to a str name.
This makes it easier to write and introspect extensions, and also more type safe.

I could also add @overload functions to the EventManager.callback, with specific function signatures for each of the items,
but I will wait to get feedback first.

It would also be interesting to consider using this to "auto-generate" some of https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx-core-events, but that is likely beyond the scope of this PR.
(I am definitely a fan of co-locating API documentation close to where it is implemented 😄 )

@danieleades
Copy link
Contributor

Yay typesafety!

@chrisjsewell chrisjsewell changed the title 👌 Add CoreEvent enum 👌 Add CoreEvent enum as argument for Sphinx.callback Apr 10, 2024
@@ -64,8 +171,10 @@ def add(self, name: str) -> None:
raise ExtensionError(__('Event %r already present') % name)
self.events[name] = ''

def connect(self, name: str, callback: Callable, priority: int) -> int:
def connect(self, name: str | CoreEvent, callback: Callable, priority: int) -> int:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could take this further and make the CoreEvent enum the preferred approach (without breaking existing code)

Suggested change
def connect(self, name: str | CoreEvent, callback: Callable, priority: int) -> int:
@deprecated(reason="...")
@overload
def connect(self, name: str, callback: Callable, priority: int) -> int: ...
@overload
def connect(self, name: CoreEvent, callback: Callable, priority: int) -> int: ...
def connect(self, name: str | CoreEvent, callback: Callable, priority: int) -> int:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The deprecated decorator is only a 3.13 feature :(

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(In addition, you still want to connect with your own events)

Copy link
Member

@picnixz picnixz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine but the issue is that people would need to import the events module if they want to use the enumeration. So you should put it in a standalone module to avoid possible circular imports.

On the other hand, you could instead use Literal strings maybe? it could probably help if you want overloads since enumerations + literals are not happy together sometimes (I had an issue with that but I don't remember whether it's fixed or not).

@AA-Turner
Copy link
Member

We've significantly improved typing and documentation for app.connect() (largely thanks to Chris), and I would prefer to keep the simpler string interface over an enum, so I'll close this PR.

A

@AA-Turner AA-Turner closed this Oct 7, 2024
@timhoffm
Copy link
Contributor

timhoffm commented Oct 7, 2024

Would it solve the issue if we could use StrEnum (python>=3.11)? That should make usage of strings and the enum largely interchangable, i.e. anybody who wants type safety can use the enum, and anybody who prefers the simplicity of strings can use them.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants