<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>Disqus - Latest Comments for Kevin Teague</title><link>http://disqus.com/people/35aa6fee222660ce1382d45a7a9a92fd/</link><description></description><language>en</language><lastBuildDate>Tue, 30 Jun 2009 19:50:20 -0000</lastBuildDate><item><title>Re: Need help with data files and setup.py</title><link>http://tplus1.disqus.com/need_help_with_data_files_and_setuppy/#comment-8597888</link><description>Also consider providing an installer for your application instead. It may be overkill for command-line app with only a couple files which the user needs to customize ... but distutils and setuptools are focused on just managing Python packagaes. If you want to install a python-based application it's nice to have a proper installer. Buildout makes a nice cross-platform install tool - although again that maybe overkill, and you could have a simple 'install-pitz-instance.py' script or such that handles copying the files into a user-editable location.&lt;br&gt;&lt;br&gt;Also, using entry points is more preferable than using the distutils 'scripts' metadata. The advantage of entry points is that you can write-out the script at install time such that it has a shebang that is hard-coded to a particular Python install and location of the pitz package files. Where as with 'scripts' you need to use #!/usr/bin/env python -- which requires that the user's environment conform to the application (e.g. on some terminals on my computer this might point to a Python 3 install, and on another terminal it's supporting an old Python 2.3 based app). It also requires that you install the library files into a specific Python's site-packages, and that also has downsides.</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Kevin Teague</dc:creator><pubDate>Thu, 23 Apr 2009 00:31:30 -0000</pubDate></item><item><title>Re: Commentary on Python from a Java programming perspective - Part 2 - How duck typing influences class design and design principles</title><link>http://var-log-mind.disqus.com/commentary_on_python_from_a_java_programming_perspective_part_2_how_duck_typing_influences_class_des/#comment-2635095</link><description>Nice article. A few minor points:&lt;br&gt;&lt;br&gt;I think you can further merge the Button class and ButtonImpl class together in the Python example in the Dependency Inversion Principle (DIP) section?&lt;br&gt;&lt;br&gt;In Python I very rarely see the suffix "Impl" appended to a class name. Since all classes in Python by nature are implementation classes, it makes sense to just leave "Impl" out of the name since it's redundant. The exception to this is existing extensions to the Python language which add "Interfaces" and re-use the class keyword to implement the interface concept out of necessity. In which case there is the strong convention to prefix an Interface class name with a capital I.&lt;br&gt;&lt;br&gt;The phrasing of "TripBooker which would in turn call interface methods on other interfaces" is a bit fuzzy, since interfaces are only specifications and you can't actually "call interface methods" but instead something like "call methods on an object that provides an implementation of an interface".&lt;br&gt;&lt;br&gt;You end the dependency inversion principle with, "In terms of the definition of DIP itself - abstractions no longer necessarily have to be implemented. They exist implicitly in the detail classes but are no longer explicitly documented." Python has a saying, "Explicit is better than Implicit", but in cases such as your Python dependency inversion example, the contract between what an object ("self") depends upon and the external object ("self.client") is highly implicit. You can only deduce the interface required by this dependency by inspecting the entire Button class and looking for all uses of "self.client". This is a common critique against using Python in a "large team" project, but there has been interesting work done in allowing you to make this dependency explicit with the Zope Component Architecture (ZCA). The Zope Component Architecture provides an Interface package (zope.interface) which lets you specify a contract (such as "IButtonClient has methods on() and off()") and then make explicit the fact that a class such as Button requires the "self.client" object to provide the IButtonClient interface. In cases where one object depends upon only a single other external object, there it's a common convention in Python to call that external object "context" (so it would be referred to as "self.context").&lt;br&gt;&lt;br&gt;Zope 3 is a framework that builds upon the Zope Component Architecture, and XML is used to specify the dependencies between components (e.g. configuration and code are kept separate). There are also many who find developing with this strict separation tedious, especially in cases of agile or prototype-based development. In this case the practice of "convention over configuration" has been applied to the configuration aspects, and the configuration is deduced by using Python's powerful introspection capabilities - this technique is called "grokking" and is implemented in the Grok web framework - of which I am a happy Grok user :)&lt;br&gt;&lt;br&gt;&lt;a href="http://wiki.zope.org/zope3/Zope3Wiki" rel="nofollow"&gt;http://wiki.zope.org/zope3/Zope3Wiki&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href="http://grok.zope.org" rel="nofollow"&gt;http://grok.zope.org&lt;/a&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Kevin Teague</dc:creator><pubDate>Thu, 25 Sep 2008 21:31:49 -0000</pubDate></item><item><title>Re: The Problem With Django</title><link>http://metajack.disqus.com/the_problem_with_django/#comment-4568105</link><description>It is not good when people are releasing django add-on projects against "a recent trunk". Not all releases need to be stable and finished. Releases with names such as -dev, -svn-r***, -preview, -rc, -beta, and -alpha are possible. Stating that an add-on project depends upon "django-1.0-alpha1" is much better than "a recent trunk", because you won't break that add-on project's installation insructions and dependency information when trunk gets updated.&lt;br&gt;&lt;br&gt;Ideally a Django add-on should be able to state in it's setup.py (or somewhere such as packages.cfg or versions.cfg) "install_requires = ['Django' == 'django-1.0-alpha1','django.contrib.comments' == '2.0','djano.someotheraddon',]".&lt;br&gt;&lt;br&gt;Grok has been going through the teething process of refining it's release and dependency management in the last year or so, but it's getting quite slick (I would say it's dependency management is better than the recent dependency features added to Rails 2.1). With a Grok application, a release is just a list of versions of the specific packages it's composed from, e.g.:&lt;br&gt;&lt;br&gt; &lt;a href="http://grok.zope.org/releaseinfo/grok-0.12.1.cfg" rel="nofollow"&gt;http://grok.zope.org/releaseinfo/grok-0.12.1.cfg&lt;/a&gt;&lt;br&gt;&lt;br&gt; &lt;a href="http://grok.zope.org/releaseinfo/grok-0.11.cfg" rel="nofollow"&gt;http://grok.zope.org/releaseinfo/grok-0.11.cfg&lt;/a&gt;&lt;br&gt;&lt;br&gt;This is useful, because if I have a Grok 0.11 app that I want to bring up to 0.12.1, I can just diff the two lists of package specifications and see which parts of the application have changed.&lt;br&gt;&lt;br&gt;A Grok add-on can specify the version of Grok it requires, and you can also specify that you wish to upgrade a single package from the Grok release to a newer version. When managing a project's dependencies there is no difference between "the packages that compose a web framework", "the packages that are installed from reusable application add-ons" and "your own development packages". It's easy to update the "working set" of packages with a newer release of a specific package, regardless of what part of the stack that package came from. Specific packages can also specify that they do or do not work with older/newer versions of the packages that they depend upon.&lt;br&gt;&lt;br&gt;If you are trying to get two add-ons with incompatible version dependencies to work together, it's a lot easier if you can see "add-on A requires version = 0.9 of package C" and "add-on B requires version 1.0 of package C". You know that you need to resolve in add-on A what is keeping it from working with version 1.0 of package C. Instead in Django you would have to do more digging when you hit version conflicts since you would be presented with only "add-on A requires a recent trunk" and "add-on B requires a recent trunk".</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Kevin Teague</dc:creator><pubDate>Wed, 11 Jun 2008 11:55:00 -0000</pubDate></item><item><title>Re: Ruby Best Practices - The Decorator Delegator Disco</title><link>http://rbp-blog.disqus.com/ruby_best_practices_the_decorator_delegator_disco/#comment-11952885</link><description>This is fairly similar to a solution we settled upon in Python, with the Zope Component Architecture (ZCA): creating throwaway proxy objects to extend existing objects. There is a talk available online which does a great job of explaining some of the alternative approaches, as well as explaining why extensions (we tend to call them adapter objects) provides a number of benefits that other approaches lack:&lt;br&gt;&lt;br&gt;&lt;a href="http://plone.tv/media/1442083381/view" rel="nofollow"&gt;http://plone.tv/media/1442083381/view&lt;/a&gt;&lt;br&gt;&lt;br&gt;The ZCA does add some overall complexity to the extension mechanism: you need to explicitly register which classes extends which other classes. Although the ZCA predates Rails, we later ripped off a page from Rails and can now introspect Python code to apply convention-over-configuration rules to avoid doing default registrations these days - for example, if you have a Model class and View class in the same module, then that View class is automatically registered as an extension for that Model class. In return for this added complexity though, the objects doing the extending *don't need to subclass from anything*, which makes code easier to understand, unit testing easier to do, and you can even cleanly declare that 3rd party classes participate in this extension process *without modifying any of those classes in any way*.&lt;br&gt;&lt;br&gt;The ZCA works around any fragility that results from registering one type of class as extending another type of class by using interfaces. Several classes can declare they implement a set of methods, and then an extension class can declare that it extends any object which provides that interface. This not Java-style interfaces though - having an alternative type-hierarchy doesn't interfere with duck typing in any way.&lt;br&gt;&lt;br&gt;And yes, extending core objects can get pretty gross, especially as you begin to share code and make judicious use of 3rd party libraries - that's why the term "monkey patching" was coined in the first place! Not to mention the "80 million instance methods" problem, a problem which still dogs Plone to this day since it's a big job to re-factor a large application out of a poor architecture. But introspecting an object that has 500+ methods just makes developer's break down and weep!</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Kevin Teague</dc:creator><pubDate>Tue, 30 Jun 2009 19:50:20 -0000</pubDate></item></channel></rss>