@@ -823,14 +823,15 @@ def __init__(
823823 requests after network, transport, or timeout failures. Defaults
824824 to 1. Set to 0 to disable retries.
825825 super_properties: Properties for every captured event. They fill
826- only keys the event leaves unset, after ``before_send`` runs.
827- An event's own properties, ``before_send`` changes and context
828- tags override them.
826+ only keys the event leaves unset, before ``before_send`` runs.
827+ ``$set``, ``$set_once``, ``$groups`` and ``$group_set`` fill
828+ one level deep. An event's own properties and context tags
829+ override them, and ``before_send`` can change or remove them.
829830 super_options: Capture options for every captured event, such as
830831 ``{"cookieless_mode": True}``. They fill only options the event
831- leaves unset, after ``before_send`` runs. An event's own
832- ``options``, ``before_send`` changes and context options
833- override them. They also win over an event's legacy property
832+ leaves unset, before ``before_send`` runs. An event's own
833+ ``options`` and context options override them, and
834+ ``before_send`` can change them. They also win over an event's legacy property
834835 for the same key, such as ``$cookieless_mode``, so pass
835836 per-event overrides of that key as ``options``.
836837 enable_exception_autocapture: Automatically capture uncaught
@@ -847,9 +848,9 @@ def __init__(
847848 through unredacted. ``privacy_mode`` always wins. Defaults to
848849 False.
849850 before_send: Optional callback that can modify or drop events before
850- upload. Return ``None`` to drop an event. It does not see
851- context tags, context options, ``super_properties`` or
852- ``super_options``. They fill in after it runs.
851+ upload. Return ``None`` to drop an event. Context tags,
852+ context options, ``super_properties`` and ``super_options``
853+ fill in before it runs, so it can change or remove them .
853854 flag_fallback_cache_url: Optional feature flag fallback cache URL,
854855 such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.
855856 enable_local_evaluation: Whether to poll feature flag definitions for
@@ -1357,9 +1358,10 @@ def set_context_option(self, key: str, value: Any) -> None:
13571358 """
13581359 Set a capture option for every event captured within the current context.
13591360
1360- Context options fill options an event leaves unset, after
1361- ``before_send`` runs. They override ``super_options``. An event's own
1362- ``options`` and ``before_send`` changes override them.
1361+ Context options fill options an event leaves unset, before
1362+ ``before_send`` runs, so the hook sees them. They override
1363+ ``super_options``. An event's own ``options`` override them, and
1364+ ``before_send`` can change them.
13631365
13641366 Args:
13651367 key: The option name, such as ``"process_person_profile"``.
@@ -1703,7 +1705,7 @@ def capture(
17031705 options: Capture options for this event, such as
17041706 ``{"process_person_profile": False}``. Sent as given, for
17051707 PostHog to validate. They override context options and
1706- ``super_options``, which fill in after ``before_send`` runs.
1708+ ``super_options``, which fill in before ``before_send`` runs.
17071709 An option set at any layer wins over its
17081710 legacy ``$`` property, such as ``$process_person_profile``,
17091711 set at any layer. A ``None`` option counts as unset.
@@ -2540,10 +2542,22 @@ def _enqueue(
25402542 if self .is_server :
25412543 msg ["properties" ]["$is_server" ] = True
25422544
2543- # Applied after every enrichment step (system context, $lib/$lib_version)
2544- # and again to the defaults filled in after before_send, so the final
2545- # event shape is exactly the allowlist regardless of where a property
2546- # came from.
2545+ _fill_event_defaults (
2546+ msg ,
2547+ _build_event_defaults (
2548+ super_properties = self .super_properties ,
2549+ super_options = self .super_options ,
2550+ release_id = self ._release_id ,
2551+ context_properties = context_properties ,
2552+ context_options = context_options ,
2553+ derived_options = derived_options ,
2554+ property_allowlist = property_allowlist ,
2555+ ),
2556+ )
2557+
2558+ # Applied after every enrichment step (system context, $lib/$lib_version,
2559+ # filled defaults), so the final event shape is exactly the allowlist
2560+ # regardless of where a property came from.
25472561 if property_allowlist is not None :
25482562 msg ["properties" ] = {
25492563 k : v for k , v in msg ["properties" ].items () if k in property_allowlist
@@ -2566,19 +2580,6 @@ def _enqueue(
25662580 self .log .exception (f"Error in before_send callback: { e } " )
25672581 return None
25682582
2569- _fill_event_defaults (
2570- msg ,
2571- _build_event_defaults (
2572- super_properties = self .super_properties ,
2573- super_options = self .super_options ,
2574- release_id = self ._release_id ,
2575- context_properties = context_properties ,
2576- context_options = context_options ,
2577- derived_options = derived_options ,
2578- property_allowlist = property_allowlist ,
2579- ),
2580- )
2581-
25822583 # Re-normalized after before_send, which may have replaced or removed
25832584 # msg["uuid"], so the returned uuid always matches the wire event.
25842585 self ._normalize_event_uuid (msg )
0 commit comments