From fa830f9d46023a829226d7f2df2842edceceb20d Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Tue, 5 Sep 2017 11:01:39 -0700 Subject: [PATCH] Added PEP 549, "Instance Properties". --- pep-0549.rst | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 pep-0549.rst diff --git a/pep-0549.rst b/pep-0549.rst new file mode 100644 index 000000000..82751d854 --- /dev/null +++ b/pep-0549.rst @@ -0,0 +1,118 @@ +PEP: XXXX +Title: Instance Properties +Version: $Revision$ +Last-Modified: $Date$ +Author: larry@hastings.org (Larry Hastings) +Status: Draft +Type: Standards Track +Created: 4-Sep-2017 +Python-Version: 3.7 +Post-History: 4-Sep-2017 + + +Abstract +-------- + + Python's descriptor protocol requires that descriptors + be members of the *type* of an object. This PEP proposes + an extension to the descriptor protocol allowing use of + the descriptor protocol for members of *instances.* This + would permit using properties in modules. + +Rationale +--------- + + Python's descriptor protocol guides programmers towards + elegant API design. If your class supports a data-like + member, and you *might* someday need to run code when + changing the member's value, you're encouraged to + simply declare it as a simple data member of the class + for now. If in the future you do need to run code, you + can change it to a "property", and happily the API doesn't + change. + + Unfortunately this doesn't work with modules. Modules are + instances of a single generic ``module`` type, and it's not + feasible to modify or subclass this type to add a property + to one's module. This means that programmers facing this + API design decision, where the data-like member is a singleton + stored in a module, must preemptively add ugly "getters" + and "setters" for the data. + + Adding support for module properties in pure Python is possible + only by using hacks like: + + * peeking in ``sys.getframe()``, + + * changing the type of an object after it's created, or + + * replacing the object stored in ``sys.modules``. + + These techniques can be made to work, but they're fragile. + + This PEP proposes a per-type opt-in extension to the descriptor + protocol specifically designed to enable properties in modules. + The mechanism is a way to honor the descriptor protocol for + members of *instances* of a class without the member being declared + as a class variable. + + Although this is being proposed as a general mechanism, the author + currently only forsees this as being useful for module objects. + +Implementation +-------------- + + The basic idea is simple: modify the ``tp_descr_get`` and ``tp_descr_set`` + functions exposed by ``PyModule_Type`` to inspect the attribute interacted + with, and if it supports the descriptor protocol, call the relevant + exposed function. + + Our implementation faces two challenges: + + 1. Since this code will be run every time an attribute is looked up on a + method, it needs to add very little overhead in the general case, + where the object stored in the attribute is not a descriptor. + + 2. Since functions are descriptors, we must take care to *not* honor + the descriptor protocol for all objects. Otherwise, all module-level + functions will suddenly become bound to the module instance as if + they were method calls on the module object. The module handle would + be passed in as a "self" argument to all module-level functions. + + Both challenges can be solved with the same approach: we define a new + "fast subclass" flag that means "This object is a desciptor, and it + should be honored directly when this object is looked up as an + attribute of an instance". So far the only placed where this flag + is set is on ``PyProperty_Type``. + +Prototype +--------- + + A prototype of this functionality is under development + at GitHub [github]_. + +Acknowledgements +---------------- + + Armin Rigo essentially proposed this mechanism when presented + with the idea of "module properties", and educated the author + both on the complexities of the problem and the proper solution. + +References +---------- + +.. [github] + https://github.com/larryhastings/cpython/tree/module-properties + +Copyright +--------- + + This document has been placed in the public domain. + + + +Local Variables: +mode: indented-text +indent-tabs-mode: nil +fill-column: 70 +End: