Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.xs4all.nl!newsfeed5.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; 'python.': 0.02; 'python,': 0.02; 'explicitly': 0.04; '"no"': 0.07; '*args,': 0.07; 'arguments': 0.07; 'decorator': 0.07; 'performs': 0.07; 'welcome.': 0.07; 'api': 0.09; 'python': 0.09; '**kwargs):': 0.09; 'agree,': 0.09; 'descriptor': 0.09; 'typed': 0.09; 'def': 0.10; 'language,': 0.11; 'programmer': 0.11; 'ignore': 0.13; '(but': 0.15; 'interfaces': 0.15; 'source,': 0.15; 'attribute,': 0.16; 'both,': 0.16; 'check?': 0.16; 'classes:': 0.16; 'descriptors': 0.16; 'fail,': 0.16; 'foo(object):': 0.16; 'general.': 0.16; 'hierarchy,': 0.16; 'ignores': 0.16; 'principal.': 0.16; 'properties,': 0.16; 'replaces': 0.16; 'right:': 0.16; 'wrote:': 0.17; 'basically': 0.17; 'example.': 0.17; 'thu,': 0.17; 'typing': 0.17; 'appears': 0.18; 'to:name:python-list@python.org': 0.20; 'skip:- 40': 0.21; 'thanks.': 0.21; 'not,': 0.21; 'names.': 0.22; 'programming': 0.23; 'this:': 0.23; 'to:2**1': 0.23; 'thus': 0.24; 'testing': 0.24; 'pass': 0.25; 'header:In-Reply-To:1': 0.25; 'looks': 0.26; 'am,': 0.27; 'implemented': 0.27; 'strongly': 0.27; 'interface': 0.27; 'post': 0.28; 'assert': 0.29; 'declared': 0.29; 'enforce': 0.29; 'exclude': 0.29; 'date:': 0.29; 'url:mailman': 0.29; 'skip:_ 10': 0.29; 'class': 0.29; 'related': 0.30; 'that.': 0.30; 'checks': 0.30; 'e.g.': 0.30; 'expect': 0.31; 'sense': 0.31; 'code': 0.31; 'asking': 0.32; 'url:python': 0.32; 'room': 0.32; 'url:listinfo': 0.32; 'comments': 0.33; 'from:addr:live.com': 0.33; 'to:addr:python-list': 0.33; 'languages': 0.33; 'another': 0.33; 'nov': 0.35; 'something': 0.35; 'there': 0.35; 'subject:': 0.36; 'but': 0.36; 'url:org': 0.36; 'email addr:python.org': 0.36; 'method': 0.36; 'useful': 0.36; 'should': 0.36; 'thank': 0.36; 'does': 0.37; 'two': 0.37; 'being': 0.37; 'why': 0.37; 'subject:: ': 0.38; 'from:': 0.38; 'comment': 0.38; 'skip:l 20': 0.38; 'some': 0.38; 'shows': 0.38; 'to:addr:python.org': 0.39; 'apply': 0.39; 'skip:" 10': 0.40; 'url:mail': 0.40; 'think': 0.40; '(that': 0.62; 'email name:python-list': 0.62; 'between': 0.63; 'skip:n 10': 0.63; 'email addr:gmail.com': 0.63; 'more': 0.63; 'here': 0.65; 'offer': 0.65; 'skip:m 50': 0.65; 'potentially': 0.66; 'believe': 0.69; 'skip:n 30': 0.69; 'lack': 0.71; 'special': 0.73; 'attention': 0.75; 'decorate': 0.84; 'ian,': 0.84; '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0': 0.84; 'do:': 0.91; 'inheritance,': 0.93; 'overall,': 0.93; 'hand,': 0.97; 'charset:windows-1251': 0.97 X-Originating-IP: [213.130.16.2] From: Andriy Kornatskyy To: , "python-list@python.org" Subject: RE: duck typing assert Date: Thu, 8 Nov 2012 22:29:10 +0300 Importance: Normal In-Reply-To: References: , Content-Type: text/plain; charset="windows-1251" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginalArrivalTime: 08 Nov 2012 19:29:10.0038 (UTC) FILETIME=[538BD360:01CDBDE7] 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: 118 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1352402952 news.xs4all.nl 6905 [2001:888:2000:d::a6]:49393 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:32973 Ian=2C Thank you for the comments. There is definitely a room for improvement=2C however there are limits. One= of them is related to decorator that replaces decorated method arguments w= ith something like *args=2C **kwargs. Here is an example. def x(): =A0=A0=A0 def decorate(m): =A0=A0=A0=A0=A0=A0=A0 def x(*args=2C **kwargs): =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 pass =A0=A0=A0=A0=A0=A0=A0 return x =A0=A0=A0 return decorate class Foo(object): =A0=A0=A0 @x =A0=A0=A0 def bar(self=2C a): =A0=A0=A0=A0=A0=A0=A0 pass Another one challenge is related to inheritance=2C or even more complex cas= e: multiple inheritance. I do not believe there is a need to scan whole hie= rarchy=2C better apply checks separately=2C the assert will be more readabl= e. class IFoo(object): =A0=A0=A0 def foo(self): =A0=A0=A0=A0=A0=A0=A0 pass class IBar(IFoo): =A0=A0=A0 def bar(self): =A0=A0=A0=A0=A0=A0=A0 pass class Bar(IBar): =A0=A0=A0 def foo(self): =A0=A0=A0=A0=A0=A0=A0 pass =A0=A0=A0 def bar(self): =A0=A0=A0=A0=A0=A0=A0 pass assert looks(Bar).like(IBar) assert looks(Bar).like(IFoo) I agree=2C special methods __?__ should not be considered private... but wh= at is right: know which one are special (how about some custom? e.g. __ctx_= _) or enforce check for it by explicitly asking for such check? # 1 assert looks(Foo).like(IFoo=2C notice=3D['__len__']) # 2 assert looks(Foo=2C notice=3D['__len__']).like(IFoo) I believe if IFoo.foo is decorated as property=2C it must remain property= =2C otherwise you need exclude it from checks=2C thus this way you pay code= reviewer attention to that. Thanks. Andriy Kornatskyy ---------------------------------------- > From: ian.g.kelly@gmail.com > Date: Thu=2C 8 Nov 2012 11:34:45 -0700 > Subject: Re: duck typing assert > To: python-list@python.org > > On Thu=2C Nov 8=2C 2012 at 10:30 AM=2C Andriy Kornatskyy > wrote: > > > > People who come from strongly typed languages that offer interfaces oft= en are confused by lack of one in Python. Python=2C being dynamic typing pr= ogramming language=2C follows duck typing principal. It can as simple as th= is: > > > > assert looks(Foo).like(IFoo) > > > > The post below shows how programmer can assert duck typing between two = Python classes: > > > > mindref.blogspot.com/2012/11/python-duck-typing-assert.html > > > > Comments or suggestions are welcome. > > Overall=2C it looks potentially useful to me. Looking over the > wheezy.core.introspection source=2C it appears to ignore special method > names. For example=2C if you do: > > class IFoo(object): > def __len__(self): > pass > > class Foo(object): > pass > > assert looks(Foo).like(IFoo) > > I would expect this to fail=2C but judging from the code it would not=2C > as it ignores all names starting with '_'. That makes some sense for > private names (but on the other hand=2C why would you declare private > names in an interface unless you want to enforce their presence?)=2C but > names like __len__ should not be considered private. > > Another comment I have is on properties=2C and descriptors in general. > Does this allow something declared as a property to be implemented as > a simple class attribute=2C and vice versa? Or can something declared > as a property be implemented with some custom descriptor class? I > think the answer is "no" to both=2C as the check it performs is > "t2.__class__ is not t.__class__". I assert though that in general > the type of a descriptor (that is not a simple class attribute) is not > as important in duck testing as its API -- and all descriptors have > basically the same API of __get__=2C __set__=2C and __delete__. > -- > http://mail.python.org/mailman/listinfo/python-list =