feat!: Make Timestamp, Author params consistent#566
feat!: Make Timestamp, Author params consistent#566kdmccormick wants to merge 10 commits intokdmccormick/core-1from
Conversation
3f81533 to
8b2b362
Compare
8b2b362 to
58a9ef1
Compare
|
@ormsbee @bradenmacdonald Let me know what you think about this approach, and whether you feel confident enough in it that I should rush it in for Verawood or wait until post-1.0. |
22d0150 to
328ce33
Compare
328ce33 to
c8e6187
Compare
|
|
||
| A UserID is meant to hold a primary key of a User object, but this is not | ||
| enforced by the type checker. Future versions of openedx-core may enforce | ||
| this more strictly by making UserID a NewType (subclass) of int. |
There was a problem hiding this comment.
In the future, we could add a UserID type here, and/or move these types to openedx-core: https://github.com/openedx/openedx-platform/blob/master/openedx/core/types/user.py
I suspect that without modifying Django itself, aliasing UserID = int is the best we can do.
| """ | ||
| Attribute the operation to the same user as the enclosing `bulk_draft_changes_for` context. | ||
|
|
||
| Outside of a context, using `AUTHOR_AUTO` is meaningless and will result in a `ValueError`. |
There was a problem hiding this comment.
We could use djngo-crum or something to try to auto-detect the user, but I think it's better to just explicitly pass it in.
| if changed_at is TIMESTAMP_AUTO: | ||
| changed_at_dt = datetime.now(tz=timezone.utc) | ||
| else: | ||
| changed_at_dt = cast(datetime, changed_at) |
There was a problem hiding this comment.
Do we need this cast? If changed_at is a Timestamp and it's not TIMESTAMP_AUTO then it must be a datetime already right?
There was a problem hiding this comment.
Yeah, but I couldn't get mypy to believe it.
Getting the active
Yes, that would be a an extra query. |
f6cb1b7 to
905f820
Compare
| return LearningPackage.objects.filter(package_ref=package_ref).exists() | ||
|
|
||
|
|
||
| def resolve_timestamp( |
There was a problem hiding this comment.
ensure to add test data where datetime is None
| """ | ||
|
|
||
|
|
||
| type Timestamp = datetime | Literal["TIMESTAMP_AUTO"] |
There was a problem hiding this comment.
Maybe DATETIME_AUTO? In Python, "timestamp" specifically means a Unix float timestamp, i.e. seconds since the epoch. There's even a timestamp() method on datetime objects.
Description
This PR aims to unify handling of Timestamp and Author parameters across all API functions. It ensures that the default behavior is "figure out a reasonable Timestamp and Author" rather than "assume that they are
None". Timestamps are forbidden for beingNone, and Authors can only beNoneif explicitly specified as such using the specialAUTHOR_NONEsentinel.BREAKING CHANGE: Various Timestamp params (named
<verb>ed,<verb>ed_at) and Author params (named<verb>ed_by) have stricter rules. For example, a concreteUseror explicitAUTHOR_NONEmust always be specified outside of abulk_draft_changes_forcontext. Seeresolve_timestampandresolve_authorfunctions for details. I will make this breaking change message more specific before merging.Background
See:
Concerns
I haven't mapped it out exactly, but I believe this will add additional queries to several functions, where we need to get the active DraftChangeLogContext (for a given learning_package_id) in order to resolve TIMESTAMP_AUTO and AUTHOR_AUTO. Additionally, functions which only take an entity_id (or version_id, etc.) will need to perform an extra extra query in order to get the operation's learning_package_id.
Status
I'm just looking for feedback on the approach currently.
Done:
Todo:
AI
This code is all written by hand, but I used Claude Opus 4.7 to help me plan it. In particular, it suggested that:
which led me to add the
can_override_contextparameters.