Add type hinting across the package#565
Conversation
|
Kafka test PR is passing (though it was way behind and broken so that PR has a number of other fixes): openedx/event-bus-kafka#344 |
|
Redis bus PR: openedx/event-bus-redis#228 |
bradenmacdonald
left a comment
There was a problem hiding this comment.
Wow, awesome work - thanks! ✅ LGTM but I'm not a committer on this repo :)
| [mypy-opaque_keys.*] | ||
| ignore_missing_imports = True |
There was a problem hiding this comment.
opaque-keys has type info now, so we shouldn't need this.
| default=None, | ||
| converter=_default_id, |
There was a problem hiding this comment.
Why this converter pattern instead of
| default=None, | |
| converter=_default_id, | |
| factory=uuid1, |
or
| default=None, | |
| converter=_default_id, | |
| default=attrs.Factory(uuid1), |
? I think using default or factory like this is simpler, and you don't need to implement the _default_x functions yourself.
There was a problem hiding this comment.
The default + converter lets us handle None better, where the factory pattern would ignore any place where we explicitly pass None (tooling.py:88) vs just omitting the param. The converter runs before the validator so it produces an actual value. I wasn't sure if we have other places where we might pass in explicit None but this seemed safer.
|
@openedx/committers-openedx-events can folks offer opinions on whether this is a good direction? I can rebase and wrap it up if so. |
Adds a new public signal, ``REGISTRATION_DEMOGRAPHICS_CAPTURED``, fired by LMS once a learner has successfully registered and any optional demographic fields collected by an authn-form plugin have been validated. Why a new event rather than extending ``STUDENT_REGISTRATION_COMPLETED``? * ``STUDENT_REGISTRATION_COMPLETED`` carries only ``UserData`` today. Adding optional demographic fields to it would force every existing receiver to deal with the new attrs, and would couple a generic registration event to one specific use case (demographics collection). * A dedicated event lets deployments that don't collect demographics ignore it entirely, and lets deployments that do route it onto the event bus (Kafka/Redis) without touching the higher-volume registration-completed stream. * Versioning the signal independently (``...captured.v1``) means future changes to demographic field shape don't require bumping ``STUDENT_REGISTRATION_COMPLETED``. The payload is intentionally minimal: a ``UserData`` reference plus the two free-form string fields the plugin slot collects (``pronouns``, ``department``). Fields default to empty strings so receivers don't have to special-case "demographics not collected on this deployment". Reference: see the OEX 2026 workshop "Leveraging Open edX Extension Points" running example — this event is the one its registration demographics plugin subscribes to.
navinkarkera
left a comment
There was a problem hiding this comment.
@bmtcril Looks good. Thanks!
Some additional changes were needed here to work around problems inherited from the standard library. - Changing isinstance(obj, colletions.abc.Callable) to callable(obj) - Changing obj back to object, which is what upstream calls it, in spite of that being a redefine
This includes a major refactor from `attr.s` to `attrs` and moves away from a somewhat improper use of default_if_none to explicit functions that can be type checked (vs just taking a generic lambda).
Note: There is an interim state in enterprise for optional types, that needs a fix in Avro handling when we get there. These are identified by:
Note: This also includes several fields that will need to be updated when the Avro later is done, these are identified by: # type: ignore[assignment]
This includes the refactor in schema.py to better handle the None-optional types (see _unwrap_optional). Downstream data files are updated to match.
Note: A lot of these test functions take a large quantity of different input types, so there is a lot of Any usage here. Some of these should probably be broken up, but I'm trying to keep these changes scoped.
1103790 to
c0d0f25
Compare
|
This is the openedx-platform PR that tests these changes. There were a very few places that needed updating: |
|
@mariajgrimaldi @felipemontoya - last check here, I've got a thumb but wanted to make sure you have a chance to take a look before I merge it. @robrap - this is just a heads up in case you wanted to look for potential bus issues |
Description
This issue came up, and I had an old set of related changes. This PR should update the code to be mypy compliant and include typing for downstream packages. Several other style issues were fixed along the way, so it is a large set of changes, but should not introduce any new behaviors. If downstream code was using the existing type hinting previously, it may fail linting on these changes and require updates.
Notes:
attrsinstead of the olderattr.sfor clearer semantics (simply use type hinting instead of explicitly declaring the type viaattr.ib(...)in most casesAnyin this PR due to several places in the code that take wildly varied inputs. This can be tightened up, but I wanted to get this first pass up for review before spending any more time on itTesting instructions
I'll be adding PRs to the event bus repos and platform to see what the downstream impact is shortly, this will stay in draft until then.
Merge Checklist:
Post Merge:
finished.
Claude Sonnet 4.6 was used to modernize changes from an old PR and break them up into smaller commits.