Path: csiph.com!usenet.pasdenom.info!gegeweb.org!usenet-fr.net!proxad.net!feeder1-2.proxad.net!news.tele.dk!news.tele.dk!small.news.tele.dk!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; 'reason,': 0.07; '*args,': 0.09; 'decorator': 0.09; 'here?': 0.09; 'params': 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; 'from:addr:python.list': 0.16; 'from:addr:tim.thechases.com': 0.16; 'from:name:tim chase': 0.16; 'key)': 0.16; 'pdb;': 0.16; 'skip:@ 20': 0.16; 'wraps': 0.16; 'thanks,': 0.17; 'obviously': 0.18; 'example': 0.22; 'import': 0.22; 'print': 0.22; 'exists': 0.24; 'code:': 0.26; 'skip:" 20': 0.27; 'skip:_ 20': 0.27; 'raise': 0.29; "doesn't": 0.30; "i'm": 0.30; '(which': 0.31; 'keys': 0.31; 'file': 0.32; 'class': 0.32; '(most': 0.33; 'skip:_ 10': 0.34; 'skip:d 20': 0.34; 'charset:us- ascii': 0.36; 'wrong': 0.37; 'to:addr:python-list': 0.38; 'recent': 0.39; 'subject:" ': 0.39; 'to:addr:python.org': 0.39; "'foo'": 0.84; 'received:50.22': 0.84 Date: Fri, 25 Oct 2013 14:44:23 -0500 From: Tim Chase To: python-list@python.org Subject: decorators and mangled names for "private" methods X-Mailer: Claws Mail 3.8.1 (GTK+ 2.24.10; x86_64-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - boston.accountservergroup.com X-AntiAbuse: Original Domain - python.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - tim.thechases.com X-Get-Message-Sender-Via: boston.accountservergroup.com: authenticated_id: tim@thechases.com 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: 54 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1382730168 news.xs4all.nl 15916 [2001:888:2000:d::a6]:50998 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:57553 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() 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