Path: csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!newsfeed.xs4all.nl!newsfeed1.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'attribute': 0.07; 'elegant': 0.07; 'reason,': 0.07; '*args,': 0.09; 'decorator': 0.09; 'here?': 0.09; 'literal': 0.09; 'params': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'req': 0.09; 'def': 0.12; '2.7': 0.14; '**kwargs)': 0.16; '**kwargs):': 0.16; '-tkc': 0.16; 'exception:': 0.16; 'foo(object):': 0.16; 'key)': 0.16; 'mangled': 0.16; 'pdb;': 0.16; 'received:80.91.229.3': 0.16; 'received:dip0.t-ipconnect.de': 0.16; 'received:plane.gmane.org': 0.16; 'received:t-ipconnect.de': 0.16; 'skip:@ 20': 0.16; 'wraps': 0.16; 'thanks,': 0.17; 'wrote:': 0.18; 'obviously': 0.18; 'example': 0.22; 'import': 0.22; 'print': 0.22; 'header:User- Agent:1': 0.23; 'exists': 0.24; 'code:': 0.26; 'skip:" 20': 0.27; 'skip:_ 20': 0.27; 'header:X-Complaints-To:1': 0.27; 'raise': 0.29; 'tim': 0.29; "doesn't": 0.30; "i'm": 0.30; '(which': 0.31; 'chase': 0.31; 'keys': 0.31; 'file': 0.32; 'class': 0.32; '(most': 0.33; 'skip:_ 10': 0.34; 'skip:d 20': 0.34; "can't": 0.35; 'wrong': 0.37; 'to:addr:python-list': 0.38; 'recent': 0.39; 'subject:" ': 0.39; 'to:addr:python.org': 0.39; 'received:org': 0.40; 'skip:u 10': 0.60; 'therefore': 0.72; "'foo'": 0.84 X-Injected-Via-Gmane: http://gmane.org/ To: python-list@python.org From: Peter Otten <__peter__@web.de> Subject: Re: decorators and mangled names for "private" methods Date: Fri, 25 Oct 2013 22:01:01 +0200 Organization: None References: <20131025144423.74c8e3c9@bigbox.christie.dr> Mime-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7Bit X-Gmane-NNTP-Posting-Host: p5084b9cf.dip0.t-ipconnect.de User-Agent: KNode/4.7.3 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 61 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1382731256 news.xs4all.nl 15931 [2001:888:2000:d::a6]:58228 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:57555 Tim Chase wrote: > Given the following example 2.7 code: > > from functools import wraps > class require_keys: > def __init__(self, *keys): > self.keys = keys > def __call__(decorator_self, fn): > @wraps(fn) > def result_fn(method_self, *args, **kwargs): > # import pdb; pdb.set_trace() > req = method_self.__private() The above __private literal is in the (statically determined) scope of the require_keys class and therefore magically mangled to _require_keys__private. Unfortunately I can't think of an elegant way to work around that... > for key in decorator_self.keys: > if key not in req: > raise ValueError("Missing [%s] parameter" % key) > return fn(method_self, *args, **kwargs) > return result_fn > class Foo(object): > def __init__(self, *params): > self.params = params > self.__private = params * 2 > def __private(self, *args, **kwargs): > return self.__private > @require_keys("hello", "world") > def action(self): > print self.params > f1 = Foo("hello", "world") > f1.action() > f2 = Foo("world") > f2.action() > > > I'm surprised to get the exception: > > Traceback (most recent call last): > File "dec_examp.py", line 28, in > f1.action() > File "dec_examp.py", line 10, in result_fn > req = method_self.__private() > AttributeError: 'Foo' object has no attribute '_require_keys__private' > > For some reason, it's looking for "_require_keys__private" (which > obviously doesn't exist) instead of "_Foo__private" which exists > and would be what I expect. > > What am I missing here? Why is the decorator class finding the wrong > private-scope? > > Thanks, > > -tkc