Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!news.mixmin.net!feeds.phibee-telecom.net!newsfeed.xs4all.nl!newsfeed5.news.xs4all.nl!xs4all!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; '"no"': 0.07; 'performs': 0.07; 'welcome.': 0.07; 'api': 0.09; 'python': 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; 'classes:': 0.16; 'descriptors': 0.16; 'fail,': 0.16; 'foo(object):': 0.16; 'general.': 0.16; 'ignores': 0.16; 'principal.': 0.16; 'properties,': 0.16; 'wrote:': 0.17; 'basically': 0.17; 'thu,': 0.17; 'typing': 0.17; 'appears': 0.18; 'not,': 0.21; 'names.': 0.22; 'programming': 0.23; 'this:': 0.23; '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; 'message-id:@mail.gmail.com': 0.27; 'interface': 0.27; 'post': 0.28; 'assert': 0.29; 'declared': 0.29; 'enforce': 0.29; 'skip:_ 10': 0.29; 'class': 0.29; 'received:209.85.215.46': 0.30; 'expect': 0.31; 'sense': 0.31; 'code': 0.31; 'comments': 0.33; 'to:addr:python-list': 0.33; 'languages': 0.33; 'another': 0.33; 'received:google.com': 0.34; 'nov': 0.35; 'received:209.85': 0.35; 'something': 0.35; 'but': 0.36; 'method': 0.36; 'useful': 0.36; 'should': 0.36; 'does': 0.37; 'two': 0.37; 'being': 0.37; 'why': 0.37; 'received:209': 0.37; 'subject:: ': 0.38; 'comment': 0.38; 'skip:l 20': 0.38; 'some': 0.38; 'shows': 0.38; 'to:addr:python.org': 0.39; 'skip:" 10': 0.40; 'header:Received:5': 0.40; 'think': 0.40; '(that': 0.62; 'between': 0.63; 'offer': 0.65; 'skip:m 50': 0.65; 'potentially': 0.66; 'lack': 0.71; 'special': 0.73; 'to:name:python': 0.84; 'do:': 0.91; 'overall,': 0.93; 'hand,': 0.97 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; bh=hifNjpKmc2aSlcb544oYptzGfHzYIbrUbkbYfDgBd2Q=; b=Qyrfqt3/ZL13Vc+eGyHFY9Me6vmsxWMIdpg5ITVqBmYZm6rtcbSfUSwjX3ihUFFpTc OKZ62RFv7N4Fk7ct0bQ5GWRoxhW89FJYi69uAwOrpWaFFt+jMQ4RVGkdClvBzIBKwagd tP+YdaWNf2zTXOBah2U0g0UoChMLT24dDfigLVnlVSO/Nc52WbB6Cq26gBcsb8yuSTGY ghv+quWS07ebB2nH6CP7IbRWIzdQSN5yd+FUJlvut+NNjfV6IiBjVJpWB77Vr1CqjIyP nqW9NLdtmYkIaVDuiX4KtnMn7HwS8BofHDRcX/NsiTTNcc3G1gu9IWSyllVD4V/wPLtR MSAQ== MIME-Version: 1.0 In-Reply-To: References: From: Ian Kelly Date: Thu, 8 Nov 2012 11:34:45 -0700 Subject: Re: duck typing assert To: Python Content-Type: text/plain; charset=ISO-8859-1 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: 41 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1352399717 news.xs4all.nl 6858 [2001:888:2000:d::a6]:42386 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:32971 On Thu, Nov 8, 2012 at 10:30 AM, Andriy Kornatskyy wrote: > > People who come from strongly typed languages that offer interfaces often are confused by lack of one in Python. Python, being dynamic typing programming language, follows duck typing principal. It can as simple as this: > > 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, it looks potentially useful to me. Looking over the wheezy.core.introspection source, it appears to ignore special method names. For example, 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, but judging from the code it would not, as it ignores all names starting with '_'. That makes some sense for private names (but on the other hand, why would you declare private names in an interface unless you want to enforce their presence?), but names like __len__ should not be considered private. Another comment I have is on properties, and descriptors in general. Does this allow something declared as a property to be implemented as a simple class attribute, 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, 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__, __set__, and __delete__.