8000 PEP 669: Add an enum and namespace the interface. by markshannon · Pull Request #2186 · python/peps · GitHub
[go: up one dir, main page]

Skip to content

PEP 669: Add an enum and namespace the interface. #2186

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 1 commit into from
Dec 10, 2021
Merged
Changes from all commits
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
62 changes: 36 additions & 26 deletions pep-0669.rst
758A
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ on CPython that will enable monitoring at low cost.
Although this PEP does not specify an implementation, it is expected that
it will be implemented using the quickening step of PEP 659 [1]_.

A ``sys.monitoring`` namespace will be added, which will contain
the relevant functions and enum.


Motivation
==========

Expand Down Expand Up @@ -80,18 +84,23 @@ For 3.11, CPython will support the following events:

More events may be added in the future.

All event codes are integer powers of two and can be bitwise or-ed together to
activate multiple events.
All events will be attributes of the ``Event`` enum in ``sys.monitoring``::

class Event(enum.IntFlag):
PY_CALL = ...

Note that ``Event`` is an ``IntFlag`` which means that the events can be or-ed
together to form a set of events.

Setting events globally
-----------------------

Events can be controlled globally by modifying the set of events being monitored:

* ``sys.get_monitoring_events()->int``
Returns the ``int`` resulting from bitwise-oring all the active events.
* ``sys.monitoring.get_events()->Event``
Returns the ``Event`` set for all the active events.

* ``sys.set_monitoring_events(event_set: int)``
* ``sys.monitoring.set_events(event_set: Event)``
Activates all events which are set in ``event_set``.

No events are active by default.
Expand All @@ -101,11 +110,11 @@ Per code object events

Events can also be controlled on a per code object basis:

* ``sys.get_local_monitoring_events(code: CodeType)->int``
Returns the ``int`` resulting from bitwise-oring all the local events for ``code``
* ``sys.monitoring.get_local_events(code: CodeType)->Event``
Returns the ``Event`` set for all the local events for ``code``

* ``sys.set_local_monitoring_events(code: CodeType, event_set: int)``
Returns the ``int`` resulting from bitwise-oring all the local events for ``code``
* ``sys.monitoring.set_local_events(code: CodeType, event_set: Event)``
Activates all the local events for ``code`` which are set in ``event_set``.

Local events add to global events, but do not mask them.
In other words, all global events will trigger for a code object, regardless of the local events.
Expand All @@ -116,10 +125,10 @@ Register callback functions

To register a callable for events call::

sys.register_monitoring_callback(event, func)
sys.monitoring.register_callback(event, func)

Functions can be unregistered by calling
``sys.register_monitoring_callback(event, None)``.
``sys.monitoring.register_callback(event, None)``.

Callback functions can be registered and unregistered at any time.

Expand Down Expand Up @@ -168,23 +177,24 @@ Inserting and removing markers

Two new functions are added to the ``sys`` module to support markers.

* ``sys.insert_marker(code: CodeType, offset: int, marker_id=0: range(256))``
* ``sys.remove_marker(code: CodeType, offset: int)``
* ``sys.monitoring.insert_marker(code: CodeType, offset: int, marker_id=0: range(256))``
* ``sys.monitoring.remove_marker(code: CodeType, offset: int)``

The ``marker_id`` has no meaning to the VM,
and is used only as an argument to the callback function.
The ``marker_id`` must in the range 0 to 255 (inclusive).

List of new functions
'''''''''''''''''''''
Attributes of the ``sys.monitoring`` namespace
''''''''''''''''''''''''''''''''''''''''''''''

* ``sys.get_monitoring_events()->int``
* ``sys.set_monitoring_events(event_set: int)``
* ``sys.get_local_monitoring_events(code: CodeType)->int``
* ``sys.set_local_monitoring_events(code: CodeType, event_set: int)``
* ``sys.register_monitoring_callback(event: int, func: Callable)``
* ``sys.insert_marker(code: CodeType, offset: int, marker_id=0: range(256))``
* ``sys.remove_marker(code: CodeType, offset: int)``
* ``class Event(enum.IntFlag)``
* ``def get_events()->Event``
* ``def set_events(event_set: Event)->None``
* ``def get_local_events(code: CodeType)->Event``
* ``def set_local_events(code: CodeType, event_set: Event)->None``
* ``def register_callback(event: Event, func: Callable)->None``
* ``def insert_marker(code: CodeType, offset: Event, marker_id=0: range(256))->None``
* ``def remove_marker(code: CodeType, offset: Event)->None``

Backwards Compatibility
=======================
Expand All @@ -196,11 +206,11 @@ However, if it is used it will effectively disable ``sys.settrace``,
``sys.setprofile`` and PEP 523 frame evaluation.

If PEP 523 is in use, or ``sys.settrace`` or ``sys.setprofile`` has been
set, then calling ``sys.set_monitoring_events()`` or
``sys.set_local_monitoring_events()`` will raise an exception.
set, then calling ``sys.monitoring.set_events()`` or
``sys.monitoring.set_local_events()`` will raise an exception.

Likewise, if ``sys.set_monitoring_events()`` or
``sys.set_local_monitoring_events()`` has been called, then using PEP 523
Likewise, if ``sys.monitoring.set_events()`` or
``sys.monitoring.set_local_events()`` has been called, then using PEP 523
or calling ``sys.settrace`` or ``sys.setprofile`` will raise an exception.

This PEP is incompatible with ``sys.settrace`` and ``sys.setprofile``
Expand Down
0