Skip to content

chore: move CancelledError and InvalidStateError to tasks #55

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

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions asyncio/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@
except:
from .task import TaskQueue, Task

# Depending on the version of CircuitPython, these errors may exist in the build-in C code
# even if _asyncio exists
try:
from _asyncio import CancelledError, InvalidStateError
except:
from .task import CancelledError, InvalidStateError

################################################################################
# Exceptions


class CancelledError(BaseException):
"""Injected into a task when calling `Task.cancel()`"""

pass


class TimeoutError(Exception):
"""Raised when waiting for a task longer than the specified timeout."""

Expand Down
12 changes: 12 additions & 0 deletions asyncio/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@
from . import core


class CancelledError(BaseException):
"""Injected into a task when calling `Task.cancel()`"""

pass


class InvalidStateError(Exception):
"""Can be raised in situations like setting a result value for a task object that already has a result value set."""

pass


Copy link
Contributor

Choose a reason for hiding this comment

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

You could define these conditionally by testing whether they are in _asyncio, using hasattr(). I don't know whether you would then want to define them in task.py or core.py.

Copy link
Contributor Author

@imnotjames imnotjames Nov 14, 2023

Choose a reason for hiding this comment

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

I can do that, sure.

To clarify, I was kind of doing this already by the from _asyncio import CancelledError, InvalidStateError. In the case of the _asyncio existing but missing the exceptions (because of a mismatched version of CircuitPython?) an AttributeError is raised, leading to pulling them from task instead.

Even with that in mind, these should use hasattr()?

I don't know whether you would then want to define them in task.py or core.py.

Where they live is somewhat inconsequential, as long as they're loaded when they don't exist in CircuitPython proper. An alternative was that they'd live under an exceptions.py.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was thinking these exceptions are defined unconditionally in task.py right now, and that they could be conditionalized. But now I'm realizing that task.py is not used at all if _asyncio exists. Is that right? If so, then I'm off the mark.

Copy link
Contributor Author

@imnotjames imnotjames Nov 14, 2023

Choose a reason for hiding this comment

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

If _asyncio exists, that's right.

With this new change, if _asyncio exists but doesn't have the two new errors we'll reach into task.py and grab these two errors. That does mean that we'll interpret the rest of task.py -- which I'm realizing now might be undesirable to save on memory usage.

If you think that's a concern I can move them to their own conditionally imported file

Copy link
Contributor

@dhalbert dhalbert Nov 14, 2023

Choose a reason for hiding this comment

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

which I'm realizing now might be undesirable?

Yes, it would be a waste of time and RAM space if it gets imported. So maybe just define them inside one of the arms of the import try-except, or factor them into exceptions.py as you suggested.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated per request - it's in the import try-except because I didn't want to move the TimeoutError

# pairing-heap meld of 2 heaps; O(1)
def ph_meld(h1, h2):
if h1 is None:
Expand Down