Author: Rami Chowdhury <rami.chowdh...@gmail.com> Branch: improve-docs Changeset: r66435:0ddc7560abce Date: 2013-08-28 22:06 +0100 http://bitbucket.org/pypy/pypy/changeset/0ddc7560abce/
Log: Add Sphinx tags to `objspace-proxies`, fix `objspace` tags diff --git a/pypy/doc/objspace-proxies.rst b/pypy/doc/objspace-proxies.rst --- a/pypy/doc/objspace-proxies.rst +++ b/pypy/doc/objspace-proxies.rst @@ -6,8 +6,7 @@ Thanks to the :doc:`Object Space <objspace>` architecture, any feature that is based on proxying, extending, changing or otherwise controlling the -behavior of all objects in a running program is easy to implement on -top of PyPy. +behavior of objects in a running program is easy to implement on top of PyPy. Here is what we have implemented so far, in historical order: @@ -26,11 +25,11 @@ ------------------- PyPy's Transparent Proxies allow routing of operations on objects -to a callable. Application level code can customize objects without +to a callable. Application-level code can customize objects without interfering with the type system - ``type(proxied_list) is list`` holds true -when 'proxied_list' is a proxied built-in list - while +when :py:obj:`proxied_list` is a proxied built-in :py:class:`list` - while giving you full control on all operations that are performed on the -``proxied_list``. +:py:obj:`proxied_list`. See [D12.1]_ for more context, motivation and usage of transparent proxies. @@ -38,8 +37,8 @@ Example of the core mechanism ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The following example proxies a list and will -return ``42`` on any add operation to the list:: +The following example proxies a list and will return ``42`` on any addition +operations:: $ py.py --objspace-std-withtproxy >>>> from __pypy__ import tproxy @@ -59,7 +58,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose we want to have a list which stores all operations performed on -it for later analysis. We can use the small :source:`lib_pypy/tputil.py` module to help +it for later analysis. We can use the :source:`lib_pypy/tputil.py` module to help with transparently proxying builtin instances:: from tputil import make_proxy @@ -79,12 +78,12 @@ 2 ``make_proxy(recorder, obj=[])`` creates a transparent list -proxy where we can delegate operations to in the ``recorder`` function. +proxy that allows us to delegate operations to the :py:func:`recorder` function. Calling ``type(l)`` does not lead to any operation being executed at all. -Note that ``append`` shows up as ``__getattribute__`` and that ``type(lst)`` -does not show up at all - the type is the only aspect of the instance which -the controller cannot change. +Note that :py:meth:`append` shows up as :py:meth:`__getattribute__` and that +``type(l)`` does not show up at all - the type is the only aspect of the instance +which the proxy controller cannot change. .. _transparent proxy builtins: @@ -95,14 +94,16 @@ If you are using the `--objspace-std-withtproxy`_ option the :doc:`__pypy__ <__pypy__-module>` module provides the following builtins: -* ``tproxy(type, controller)``: returns a proxy object - representing the given type and forwarding all operations - on this type to the controller. On each such operation - ``controller(opname, *args, **kwargs)`` is invoked. +.. py:function:: tproxy(type, controller) -* ``get_tproxy_controller(obj)``: returns the responsible - controller for a given object. For non-proxied objects - ``None`` is returned. + Returns a proxy object representing the given type and forwarding all + operations on this type to the controller. On each operation, + ``controller(opname, *args, **kwargs)`` will be called. + +.. py:function:: get_tproxy_controller(obj) + + Returns the responsible controller for a given object. For non-proxied + objects :py:const:`None` is returned. .. _--objspace-std-withtproxy: config/objspace.std.withtproxy.html @@ -114,32 +115,43 @@ The :source:`lib_pypy/tputil.py` module provides: -* ``make_proxy(controller, type, obj)``: function which - creates a transparent proxy controlled by the given - 'controller' callable. The proxy will appear - as a completely regular instance of the given - type but all operations on it are send to the - specified controller - which receives a - ProxyOperation instance on each such operation. - A non-specified type will default to type(obj) if - `obj` was specified. +.. py:function:: make_proxy(controller, type, obj) + + Creates a transparent proxy controlled by the given :py:obj:`controller` + callable. The proxy will appear as a completely regular instance of the given + type, but all operations on it are sent to the specified controller - which + receives a :py:class:`ProxyOperation` instance on each operation. If :py:obj:`type` + is not specified, it defaults to ``type(obj)`` if :py:obj:`obj` is specified. ProxyOperation instances have the following attributes: - `proxyobj`: the transparent proxy object of this operation. + .. py:attribute:: proxyobj - `opname`: the operation name of this operation + The transparent proxy object of this operation. - `args`: positional arguments for this operation + .. py:attribute:: opname - `kwargs`: keyword arguments for this operation + The name of this operation. - `obj`: (if provided to `make_proxy`): a concrete object + .. py:attribute:: args - If you have specified a concrete object instance `obj` - to your `make_proxy` invocation, you may call - ``proxyoperation.delegate()`` to delegate the operation - to this object instance. + Any positional arguments for this operation. + + .. py:attribute:: kwargs + + Any keyword arguments for this operation. + + .. py:attribute:: obj + + (Only if provided to :py:func:`make_proxy`) + + A concrete object. + + .. py:method:: delegate + + If a concrete object instance :py:obj:`obj` was specified in the call to + :py:func:`make_proxy`, then :py:meth:`proxyoperation.delegate` can be called + to delegate the operation to the object instance. Further points of interest @@ -152,34 +164,33 @@ (think about transparent distribution) * Access to persistent storage such as a database (imagine an - SQL object mapper which looks like a real object) + SQL object mapper which looks like any other object). * Access to external data structures, such as other languages, as normal objects (of course some operations could raise exceptions, but - since they are purely done on application level, that is not real problem) + since operations are executed at the application level, that is not a major + problem) Implementation Notes ~~~~~~~~~~~~~~~~~~~~ -PyPy's standard object space allows to internally have multiple -implementations of a type and change the implementation at run -time while application level code consistently sees the exact -same type and object. Multiple performance optimizations using -this features are already implemented: see the document -about :doc:`alternative object implementations <interpreter-optimizations>`. Transparent -Proxies use the architecture to provide control back -to application level code. +PyPy's standard object space allows us to internally have multiple +implementations of a type and change the implementation at run-time, while +application-level code consistently sees the exact same type and object. +Multiple performance optimizations using these features have already been +implemented: :doc:`alternative object implementations <interpreter-optimizations>`. +Transparent Proxies use this architecture to provide control back to +application-level code. Transparent proxies are implemented on top of the :ref:`standard object -space <standard-object-space>`, in :source:`pypy/objspace/std/proxy_helpers.py`, :source:`pypy/objspace/std/proxyobject.py` and -:source:`pypy/objspace/std/transparent.py`. To use them you will need to pass a -`--objspace-std-withtproxy`_ option to ``py.py`` or -``translate.py``. This registers implementations named -``W_TransparentXxx`` - which usually correspond to an -appropriate ``W_XxxObject`` - and includes some interpreter hacks -for objects that are too close to the interpreter to be -implemented in the std objspace. The types of objects that can +space <standard-object-space>`, in :source:`pypy/objspace/std/proxy_helpers.py`, +:source:`pypy/objspace/std/proxyobject.py` and :source:`pypy/objspace/std/transparent.py`. +To use them you will need to pass a `--objspace-std-withtproxy`_ option to ``pypy`` +or ``translate.py``. This registers implementations named :py:class:`W_TransparentXxx` +- which usually correspond to an appropriate :py:class:`W_XxxObject` - and +includes some interpreter hacks for objects that are too close to the interpreter +to be implemented in the standard object space. The types of objects that can be proxied this way are user created classes & functions, lists, dicts, exceptions, tracebacks and frames. diff --git a/pypy/doc/objspace.rst b/pypy/doc/objspace.rst --- a/pypy/doc/objspace.rst +++ b/pypy/doc/objspace.rst @@ -575,7 +575,7 @@ Additionally, slicing ensures that ``5 .__add__(6L)`` correctly returns :py:exc:`NotImplemented` (because this particular slice does not include :py:func:`add__Long_Long` and there is no :py:func:`add__Int_Long`), which leads to -'`6L.__radd__(5)`` being called, as in CPython. +``6L.__radd__(5)`` being called, as in CPython. Object Space proxies _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit