Are ABCs an anti-pattern?

Trent Nelson trent at snakebite.org
Fri Oct 5 15:58:37 EDT 2012


On Tue, Oct 02, 2012 at 07:23:05AM -0700, Demian Brecht wrote:
> I don't use them anymore, but I'm curious about others opinions on this 
> list...

    I like them.  In particular, I like that I can enumerate all the
    subclasses that happen to implement the ABC via the metaclass's
    __subclasses__() method.  I also like that I can trust Python
    not to instantiate a subclass of an ABC unless it meets all the
    interface criteria I've stipulated.

    Both of these aspects make ABCs a great fit when your base classes
    will be subclassed by other users/libraries (i.e. that you have no
    control over).

    For example, I use them in a project of mine called Enversion in
    order to automatically generate command-line scaffolding with as
    little effort (programming/typing-wise as possible).  The ABC
    stuff lives in 'evn.cli' and provides a set of generic classes
    for command-line tools.

    One of the command line tools that ships with Enversion is the
    'evnadmin' command.  Thanks to all the ABC scaffolding in the
    'evn.cli/command' module, all I need to write is the following
    to get an 'evnadmin' command-line interface:
    
        from evn.cli import (
            CLI,
            CommandLine,
        )

        class AdminCommandLine(CommandLine):
            @property
            def commands_module(self):
                return evn.admin.commands

        class AdminCLI(CLI):

            @property
            def program_name(self):
                return 'evnadmin'

            @property
            def commandline_subclasses(self):
                return AdminCommandLine.__subclasses__()

        class DoctestCommandLine(AdminCommandLine):
            _quiet_ = True

        class DumpDefaultConfigCommandLine(AdminCommandLine):
            pass

        class DumpConfigCommandLine(AdminCommandLine):
            _conf_ = True

        class ShowConfigFileLoadOrderCommandLine(AdminCommandLine):
            _conf_ = True

        class DumpHookCodeCommandLine(AdminCommandLine):
            _conf_ = True
            _repo_ = True

        [snip]

    Running 'evnadmin' with no arguments yields this:

        % evnadmin
        Type 'evnadmin <subcommand> help' for help on a specific subcommand.

        Available subcommands:
            analyze
            create
            disable-remote-debug (drd)
            doctest
            dump-config (dc)
            dump-default-config (ddc)
            dump-hook-code (dhc)
            enable
            enable-remote-debug (erd)
            find-merges (fm)
            fix-hooks (fh)
            root-info (ri)
            run-hook (rh)
            show-config-file-load-order (scflo)
            show-repo-hook-status (srhs)
            show-repo-remote-debug-sessions (srrds)
            show-roots (sr)
            toggle-remote-debug (trd)
            version

    The scaffolding can generate all of that automatically thanks to the
    ability to enumerate __subclasses__() of a metaclass.  The fact that
    Python will bomb out if a derived class doesn't implement all the
    required methods/properties is icing on the cake.  When you are
    expecting other developers to leverage your ABCs, getting instant
    feedback when you forget to implement a required method/property
    is incredibly useful.  It's definitely not a case of battling the
    design decisions made by the ABC author...

    Relevant Python files:
        https://github.com/tpn/enversion/blob/master/evn/cli.py
        https://github.com/tpn/enversion/blob/master/evn/admin/cli.py

    Regards,

        Trent.

> Demian Brecht
> @demianbrecht
> http://demianbrecht.github.com
> -- 
> http://mail.python.org/mailman/listinfo/python-list



More information about the Python-list mailing list