[pypy-svn] r41348 - pypy/dist/pypy/doc
guido at codespeak.net
guido at codespeak.net
Mon Mar 26 14:52:17 CEST 2007
Author: guido
Date: Mon Mar 26 14:52:15 2007
New Revision: 41348
Modified:
pypy/dist/pypy/doc/objspace-proxies.txt
Log:
Some typos, grammar, etc.
Modified: pypy/dist/pypy/doc/objspace-proxies.txt
==============================================================================
--- pypy/dist/pypy/doc/objspace-proxies.txt (original)
+++ pypy/dist/pypy/doc/objspace-proxies.txt Mon Mar 26 14:52:15 2007
@@ -6,10 +6,10 @@
.. sectnum::
-Thanks to the `Object Space`_ architecture, there is a kind of feature
-that is easy to implement on top of PyPy: namely, any feature that is
+Thanks to the `Object Space`_ architecture, any feature that is
based on proxying, extending, changing or otherwise controlling the
-behavior of all objects in a running program.
+behavior of all objects in a running program is easy to implement on
+top of PyPy.
Here is what we implemented so far, in historical order:
@@ -21,9 +21,9 @@
* *Logic Object Space*: logical variables, i.e. placeholder objects
whose value can be bound once.
-* *Taint Object Space*: a soft security system. Your application cannot
+* *Taint Object Space*: a soft security system; your application cannot
accidentally compute results based on tainted objects unless it
- explicitly untaint them first.
+ explicitly untaints them first.
* *Dump Object Space*: dumps all operations performed on all the objects
into a large log file. For debugging your applications.
@@ -33,7 +33,8 @@
control operations on application and builtin objects,
e.g lists, dictionaries, tracebacks.
-Which object space to use can be chosen with :config:`objspace.name` option.
+Which object space to use can be chosen with the :config:`objspace.name`
+option.
.. _`Object Space`: objspace.html
@@ -44,10 +45,11 @@
This small object space, meant as a nice example, wraps another object
space (e.g. the standard one) and adds two capabilities: lazily computed
-objects (computed only when an operation is performed on them), and
-"become", which completely and globally replaces an object with another.
+objects, computed only when an operation is performed on them, and
+"become", a more obscure feature which allows to completely and globally
+replaces an object with another.
-Example usage::
+Example usage of lazily computed objects::
$ py.py -o thunk
>>>> from __pypy__ import thunk
@@ -66,8 +68,8 @@
computing...
<type 'int'>
-A related, but more obscure feature, allows one object to be instantly
-and globally replaced with another::
+Example of how one object can be instantly and globally replaced with
+another::
$ py.py -o thunk
>>>> from __pypy__ import become
@@ -111,7 +113,7 @@
and arguments. When a space operation follows the ``w_thunkalias``
chains of objects, it special-cases ``W_Thunk``: it invokes the stored
callable if necessary to compute the real value and then stores it in
-the ``w_thunkalias`` field of the ``W_Thunk``, which has the effect of
+the ``w_thunkalias`` field of the ``W_Thunk``. This has the effect of
replacing the latter with the real value.
.. _thunk-interface:
@@ -130,7 +132,7 @@
* ``become(obj1, obj2)``: globally replace ``obj1`` with ``obj2``.
- * ``lazy(callable)``: Should be used as a function decorator. The decorated
+ * ``lazy(callable)``: should be used as a function decorator - the decorated
function behaves lazily: all calls to it return a thunk object.
@@ -143,18 +145,20 @@
including the notion of logical variable. A logical variable is really
an object from the Python point of view; it is called "variable" for
consistency with logic programming terminology. It is an "empty" object
-with no initial value at all. It is possible to put a value into this
-object once, and only once, at any point in time.
+with no initial value: it's value can be set once, and only once, at any
+point in time.
-This is not entirely unrelated to a lazily-computed object, except that
-the object has no built-in knowledge about how it should compute itself.
-Trying to use such an object before it got a value results in a lock:
+Logical variables are not entirely different from lazily-computed objects,
+except that the objects have no built-in knowledge about how they should
+compute themselves.
+
+Using a logical variable before it gets a value results in a lock:
the current thread is suspended, in the hope that another thread will
-eventually put a value into the object. In practice, this works well
+eventually give it a value. In practice, this works well
with microthreads instead of real threads (see `Stackless features`_).
The `EU Interim Report`_ (PDF) describes the Logic Object Space in
-more details.
+more detail.
.. _`EU Interim Report`: http://codespeak.net/pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2007-02-28.pdf
.. _`Stackless features`: stackless.html
@@ -197,7 +201,7 @@
careful security review, the rest of the application no longer does,
because even a bug would be unable to leak the information.
-We have implemented a simple two-levels model: objects are either
+We have implemented a simple two-level model: objects are either
regular (untainted), or sensitive (tainted). Objects are marked as
sensitive if they are secret or untrusted, and only declassified at
carefully-checked positions (e.g. where the secret data is needed, or
@@ -296,21 +300,21 @@
reviewed for what occurs if they receive a Taint Bomb; they might catch
the ``TaintError`` and give the user a generic message that something
went wrong, if we are reasonably careful that the message or even its
-presence doesn't give information away. This might be a decliate
-problem by itself, but there is no satisfying general solution to this
-problem; it must be considered on a case-by-case basis. Again, what the
+presence doesn't give information away. This might be a
+problem by itself, but there is no satisfying general solution here:
+it must be considered on a case-by-case basis. Again, what the
Taint Object Space approach achieves is not solving these problems, but
localizing them to well-defined small parts of the application - namely,
around calls to ``untaint()``.
-Note that the ``TaintError`` exception is deliberately not including any
-useful error message, because that might give information away too.
-However, it makes debugging quite harder. This is a difficult problem
-to solve in general too; so far we implemented a way to peek in a Taint
+The ``TaintError`` exception deliberately does not include any
+useful error messages, because they might give information away.
+Of course, this makes debugging quite a bit harder; a difficult
+problem to solve properly. So far we have implemented a way to peek in a Taint
Box or Bomb, ``__pypy__._taint_look(x)``, and a "debug mode" that
-prints the exception as soon as a Bomb is created. Both write
+prints the exception as soon as a Bomb is created - both write
information to the low-level stderr of the application, where we hope
-that it is unlikely to be seen by anyone else than the application
+that it is unlikely to be seen by anyone but the application
developer.
@@ -318,11 +322,11 @@
----------------------
Occasionally, a more complicated computation must be performed on a
-tainted object. This requires first untainting the object, perform the
+tainted object. This requires first untainting the object, performing the
computations, and then carefully tainting the result again (including
hiding all exceptions into Bombs).
-There is a built-in decorator that does exactly that::
+There is a built-in decorator that does this for you::
>>>> @__pypy__.taint_atomic
>>>> def myop(x, y):
@@ -345,7 +349,7 @@
result is tainted again (possibly in a Taint Bomb).
It is important for the function marked as ``taint_atomic`` to have no
-visible side effects, otherwise information could be leaked that way.
+visible side effects, as these could cause information leakage.
This is currently not enforced, which means that all ``taint_atomic``
functions have to be carefully reviewed for security (but not the
callers of ``taint_atomic`` functions).
@@ -403,7 +407,7 @@
in the Python sense). Each box internally contains a regular object;
each bomb internally contains an exception object. An operation
involving Tainted Boxes is performed on the objects contained in the
-boxes, and give a Tainted Box or a Tainted Bomb as a result (such an
+boxes, and gives a Tainted Box or a Tainted Bomb as a result (such an
operation does not let an exception be raised). An operation called
with a Tainted Bomb argument immediately returns the same Tainted Bomb.
@@ -453,11 +457,11 @@
The Dump Object Space
=====================
-When PyPy is run with (or translated with) the Dump Object Space, all
+When PyPy is run with (or translated with) the *Dump Object Space*, all
operations between objects are dumped to a file called
``pypy-space-dump``. This should give a powerful way to debug
applications, but so far the dump can only be inspected in a text
-editor; better browsing tools are needed before it can be really useful.
+editor; better browsing tools are needed before it becomes really useful.
Try::
@@ -476,13 +480,14 @@
Transparent Proxies
================================
-PyPy's Transparent Proxies allow to route operations to objects
-to a callable. Application level code can customize e.g. list
-and dictionary objects without interfering with the type system,
-i.e. ``type(proxied_list) is list`` holds true while still
+PyPy's Transparent Proxies allow routing of operations on objects
+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
giving you full control on all operations that are performed on the
-``proxied_list``. Please see [D12.1]_ for context,
-motivation and usage of transparent proxies.
+``proxied_list``.
+
+See [D12.1]_ for more context, motivation and usage of transparent proxies.
Example of the core mechanism
-------------------------------------------
@@ -509,8 +514,8 @@
Example of recording all operations on builtins
----------------------------------------------------
-Suppose we want to have list which stores all operations performed on
-it for later analysis. We use a small `tputil`_ module that helps
+Suppose we want to have a list which stores all operations performed on
+it for later analysis. We can use the small `tputil`_ module to help
with transparently proxying builtin instances::
from tputil import make_proxy
@@ -531,15 +536,15 @@
``make_proxy(recorder, obj=[])`` creates a transparent list
proxy where we can delegate operations to in the ``recorder`` function.
-Calling ``type(l)`` does not lead to any operation at all.
+Calling ``type(l)`` does not lead to any operation being executed at all.
-XXX Note that ``append`` shows up as ``__getattribute__`` and that the ``type(lst)``
-does not show up at all (indeed the type is the only aspect of the instance that
-the controller cannot change).
+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.
.. _`transparent proxy builtins`:
-Transparent Proxy PyPy Builtins and support
+Transparent Proxy PyPy builtins and support
-----------------------------------------------------------
If you are using the `--objspace-std-withtproxy`_ option
@@ -564,7 +569,7 @@
The `tputil.py`_ module provides:
-* ``make_proxy(controller, type, obj)`` function which
+* ``make_proxy(controller, type, obj)``: function which
creates a tranparent proxy controlled by the given
'controller' callable. The proxy will appear
as a completely regular instance of the given
@@ -584,7 +589,7 @@
`kwargs`: keyword arguments for this operation
- `obj`: (if provided to `make_proxy`: an concrete object)
+ `obj`: (if provided to `make_proxy`): a concrete object
If you have specified a concrete object instance `obj`
to your `make_proxy` invocation, you may call
@@ -594,18 +599,18 @@
Further points of interest
---------------------------
-A lot of tasks could be performed using transparent proxies. Including,
+A lot of tasks could be performed using transparent proxies, including,
but not limited to:
-* A Remote version of objects, on which we perform operations
+* Remote versions of objects, on which we can directly perform operations
(think about transparent distribution)
-* Access to some persistent-storages like databases (imagine an
- SQL object mapper which looks like real object)
+* Access to persistent storage such as a database (imagine an
+ SQL object mapper which looks like a real object)
-* Access to external data structures, like other languages as normal
- objects. (Of course some operations on them could raise exceptions, but it's
- purely done in application level, so it's not real problem)
+* 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)
Implementation Notes
-----------------------------
@@ -613,22 +618,22 @@
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 optimisations using
-this features are already implemented, see the document
+same type and object. Multiple performance optimizations using
+this features are already implemented: see the document
about `alternative object implementations`_. Transparent
Proxies use the architecture to provide control back
to application level code.
-Transparent proxy is implemented on top of `standard object
+Transparent proxies are implemented on top of the `standard object
space`_, in `proxy_helpers.py`_, `proxyobject.py`_ and
-`transparent.py`_. To run it you need to pass
+`transparent.py`_. To use them you will need to pass a
`--objspace-std-withtproxy`_ option to ``py.py`` or
-``translate.py``. It registers implementations like a
-``W_TransparentXxx`` which usually corresponds to an
-apropriate ``W_XxxObject``, including some interpreter hacks
+``translate.py``. This registers implementations named
+``W_TransparentXxx`` - which usually correspond to an
+apropriate ``W_XxxObject`` - and includes some interpreter hacks
for objects that are too close to the interpreter to be
-implemented in a std objspace. The types of objects that can
-be proxied like this are: user created classes & functions,
+implemented in the std objspace. The types of objects that can
+be proxied this way are user created classes & functions,
lists, dicts, exceptions, tracebacks and frames.
.. _`standard object space`: objspace.html#the-standard-object-space
More information about the Pypy-commit
mailing list