[Python-ideas] CapPython's use of unbound methods

Guido van Rossum guido at python.org
Thu Mar 12 22:33:23 CET 2009


On Thu, Mar 12, 2009 at 1:24 PM, Mark Seaborn <mrs at mythic-beasts.com> wrote:
> Guido asked me to explain why the removal of unbound methods in Python
> 3.0 causes a problem for enforcing encapsulation in CapPython (an
> object-capability subset of Python), which I talked about in a blog
> post [1].  It also came up on python-dev [2].
>
> Let me try a slightly different example to answer Guido's immediate
> question.
>
> Suppose we have an object x with a private attribute, "_field",
> defined by a class Foo:
>
> class Foo(object):
>
>    def __init__(self):
>        self._field = "secret"
>
> x = Foo()

Can you add some principals to this example? Who wrote the Foo class
definition? Does CapPython have access to the source code for Foo? To
the class object?

> Suppose CapPython code is handed x.

What does it mean to "hand x to CapPython"? Who "is" CapPython?

> It should not be able to read
> x._field, and the expression x._field will be rejected by CapPython's
> static verifier.
>
> However, in Python 3.0, the CapPython code can do this:
>
> class C(object):
>
>    def f(self):
>        return self._field
>
> C.f(x) # returns "secret"
>
> Whereas in Python 2.x, C.f(x) would raise a TypeError, because C.f is
> not being called on an instance of C.

In Python 2.x I could write

class C(Foo):
  def f(self):
    return self._field

or alternatively

class C(x.__class__):
  <same f as before>

> Guido said, "I don't understand where the function object f gets its
> magic powers".
>
> The answer is that function definitions directly inside class
> statements are treated specially by the verifier.

Hm, this sounds like a major change in language semantics, and if I
were Sun I'd sue you for using the name "Python" in your product. :-)

> If you wrote the same function definition at the top level:
>
> def f(var):
>    return var._field # rejected
>
> the attribute access would be rejected by the verifier, because "var"
> is not a self variable, and private attributes may only be accessed
> through self variables.
>
> I renamed the variable in the example,

What do you mean by this?

> but the name of the variable
> makes no difference to whether it is considered to be a self variable.
>
> Self variables are defined as follows:
>
> If a function definition "def f(v1, ...)" appears immediately within a
> "class" statement, the function's first argument, v1, is a self
> variable, provided that:
>  * the "def" is not preceded by any decorators, and
>  * "f" is not read anywhere in class scope and is not declared as global.
>
> The reason for these two restrictions is to prevent the function
> object from escaping and being used directly.

Do you also catch things like

g = getattr
s = 'field'.replace('f', '_f')

print g(x, s)

?

> Mark
>
> [1] http://lackingrhoticity.blogspot.com/2008/09/cappython-unbound-methods-and-python-30.html
> [2] http://mail.python.org/pipermail/python-dev/2008-September/082499.html

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)



More information about the Python-ideas mailing list