Skip to content

Add namespacing or dot notation #56

@bitprophet

Description

@bitprophet

Description

Might be handy to have a namespace concept similar to Cap/Rake's namespaces (which over there are implemented as Ruby blocks) to make it easier for people to organize large bodies of fabfile code.

master already has the ability to load up Fabfile packages; we could build on this by allowing normal Python dot notation, so that a fabfile setup containing e.g. fabfile/foo.py, defining def bar():, could be invoked as fab foo.bar. This would be pretty Pythonic, which is a good thing, and avoids wheel reinvention (e.g. using context managers or something to really ape the Cap/Rake stuff.)

Ask has a first draft implementation of this in his GitHub fork but points out that it makes it harder to get the "big picture", i.e. fab --list and the code that aborts if no callables were found in the given fabfile.

I don't have time right now to go over his implementation in detail, but offhand I would imagine there are non-nasty ways of introspecting a Python package in the manner we need -- e.g. whatever PyLint and Nose and other tools do. This could possibly be made easier by requiring that people list their intended public API in __init__.py -- i.e. in the above scenario, fabfile/__init__.py would import foo, then our code can simply nab fabfile and look for any attributes which are modules, then introspect those modules in the same way we introspect fabfiles now, and recurse.

Not sure whether that would be preferable over full autodiscovery; the above approach semi-violates DRY, but at the same time allows one to be explicit about what's "public" in their fabfile. However, it has a lot of potential to be confusing -- people will expect it to "just work" if they are aware of the functionality, and may not read any fine print about the explicit import into __init__.


See comments below for another (? should go review Ask's stuff sometime) approach by Travis, basically just importing submodules and adding them to the dict as submodule.taskname.


Also, some folks have raised (a few times; also see Domen's recent comments below) the point that one can leverage setuptools junk to get a "third party Fabric namespace" set up so that one can install Fabric proper, and then install these other modules, and the other modules can be imported (generally, not by Fabric's core) as e.g. fabric.ext.whatever.

Link to partial discussion on the ML (thought there was >1 such discussion but can't find right now): [http://lists.gnu.org/archive/html/fab-user/2009-12/msg00000.html](early December discussion).

Benefit of this is that the Python module namespace looks neater -- otherwise users would have to come up with independent names for their own collections of tasks, e.g. distribute them as fabric_whatever or joes_fab_tasks. Which isn't awful and would sort of be my preference; but I have to admit that the super-easy "I'll just distribute my stuff as fabric.ext.sysadmin" might at least help with that.

On the other hand, what if two people want to add to fabric.ext.sysadmin? Can they divvy it up? What if someone unsuspecting installs two sysadmin packages with some identically named subroutines? etc.

Another possible downside is that Distribute may not continue to support this pkg_resources stuff in future releases; it's unclear right now. I definitely want to support Distribute in the future.


Originally submitted by Jeff Forcier (bitprophet) on 2009-08-27 at 09:48am EDT

Relations


Closed as Done on 2011-06-21 at 04:24pm EDT

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions