bunch-1.0.1/0000775000076500000240000000000011676427013012515 5ustar dscstaff00000000000000bunch-1.0.1/bunch/0000775000076500000240000000000011676427013013614 5ustar dscstaff00000000000000bunch-1.0.1/bunch/__init__.py0000644000076500000240000003162311676426217015735 0ustar dscstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """ Bunch is a subclass of dict with attribute-style access. >>> b = Bunch() >>> b.hello = 'world' >>> b.hello 'world' >>> b['hello'] += "!" >>> b.hello 'world!' >>> b.foo = Bunch(lol=True) >>> b.foo.lol True >>> b.foo is b['foo'] True It is safe to import * from this module: __all__ = ('Bunch', 'bunchify','unbunchify') un/bunchify provide dictionary conversion; Bunches can also be converted via Bunch.to/fromDict(). """ __version__ = '1.0.1' VERSION = tuple(map(int, __version__.split('.'))) __all__ = ('Bunch', 'bunchify','unbunchify',) class Bunch(dict): """ A dictionary that provides attribute-style access. >>> b = Bunch() >>> b.hello = 'world' >>> b.hello 'world' >>> b['hello'] += "!" >>> b.hello 'world!' >>> b.foo = Bunch(lol=True) >>> b.foo.lol True >>> b.foo is b['foo'] True A Bunch is a subclass of dict; it supports all the methods a dict does... >>> b.keys() ['foo', 'hello'] Including update()... >>> b.update({ 'ponies': 'are pretty!' }, hello=42) >>> print repr(b) Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') As well as iteration... >>> [ (k,b[k]) for k in b ] [('ponies', 'are pretty!'), ('foo', Bunch(lol=True)), ('hello', 42)] And "splats". >>> "The {knights} who say {ni}!".format(**Bunch(knights='lolcats', ni='can haz')) 'The lolcats who say can haz!' See unbunchify/Bunch.toDict, bunchify/Bunch.fromDict for notes about conversion. """ def __contains__(self, k): """ >>> b = Bunch(ponies='are pretty!') >>> 'ponies' in b True >>> 'foo' in b False >>> b['foo'] = 42 >>> 'foo' in b True >>> b.hello = 'hai' >>> 'hello' in b True """ try: return hasattr(self, k) or dict.__contains__(self, k) except: return False # only called if k not found in normal places def __getattr__(self, k): """ Gets key if it exists, otherwise throws AttributeError. nb. __getattr__ is only called if key is not found in normal places. >>> b = Bunch(bar='baz', lol={}) >>> b.foo Traceback (most recent call last): ... AttributeError: foo >>> b.bar 'baz' >>> getattr(b, 'bar') 'baz' >>> b['bar'] 'baz' >>> b.lol is b['lol'] True >>> b.lol is getattr(b, 'lol') True """ try: # Throws exception if not in prototype chain return object.__getattribute__(self, k) except AttributeError: try: return self[k] except KeyError: raise AttributeError(k) def __setattr__(self, k, v): """ Sets attribute k if it exists, otherwise sets key k. A KeyError raised by set-item (only likely if you subclass Bunch) will propagate as an AttributeError instead. >>> b = Bunch(foo='bar', this_is='useful when subclassing') >>> b.values #doctest: +ELLIPSIS >>> b.values = 'uh oh' >>> b.values 'uh oh' >>> b['values'] Traceback (most recent call last): ... KeyError: 'values' """ try: # Throws exception if not in prototype chain object.__getattribute__(self, k) except AttributeError: try: self[k] = v except: raise AttributeError(k) else: object.__setattr__(self, k, v) def __delattr__(self, k): """ Deletes attribute k if it exists, otherwise deletes key k. A KeyError raised by deleting the key--such as when the key is missing--will propagate as an AttributeError instead. >>> b = Bunch(lol=42) >>> del b.values Traceback (most recent call last): ... AttributeError: 'Bunch' object attribute 'values' is read-only >>> del b.lol >>> b.lol Traceback (most recent call last): ... AttributeError: lol """ try: # Throws exception if not in prototype chain object.__getattribute__(self, k) except AttributeError: try: del self[k] except KeyError: raise AttributeError(k) else: object.__delattr__(self, k) def toDict(self): """ Recursively converts a bunch back into a dictionary. >>> b = Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') >>> b.toDict() {'ponies': 'are pretty!', 'foo': {'lol': True}, 'hello': 42} See unbunchify for more info. """ return unbunchify(self) def __repr__(self): """ Invertible* string-form of a Bunch. >>> b = Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') >>> print repr(b) Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') >>> eval(repr(b)) Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') (*) Invertible so long as collection contents are each repr-invertible. """ keys = self.keys() keys.sort() args = ', '.join(['%s=%r' % (key, self[key]) for key in keys]) return '%s(%s)' % (self.__class__.__name__, args) @staticmethod def fromDict(d): """ Recursively transforms a dictionary into a Bunch via copy. >>> b = Bunch.fromDict({'urmom': {'sez': {'what': 'what'}}}) >>> b.urmom.sez.what 'what' See bunchify for more info. """ return bunchify(d) # While we could convert abstract types like Mapping or Iterable, I think # bunchify is more likely to "do what you mean" if it is conservative about # casting (ex: isinstance(str,Iterable) == True ). # # Should you disagree, it is not difficult to duplicate this function with # more aggressive coercion to suit your own purposes. def bunchify(x): """ Recursively transforms a dictionary into a Bunch via copy. >>> b = bunchify({'urmom': {'sez': {'what': 'what'}}}) >>> b.urmom.sez.what 'what' bunchify can handle intermediary dicts, lists and tuples (as well as their subclasses), but ymmv on custom datatypes. >>> b = bunchify({ 'lol': ('cats', {'hah':'i win again'}), ... 'hello': [{'french':'salut', 'german':'hallo'}] }) >>> b.hello[0].french 'salut' >>> b.lol[1].hah 'i win again' nb. As dicts are not hashable, they cannot be nested in sets/frozensets. """ if isinstance(x, dict): return Bunch( (k, bunchify(v)) for k,v in x.iteritems() ) elif isinstance(x, (list, tuple)): return type(x)( bunchify(v) for v in x ) else: return x def unbunchify(x): """ Recursively converts a Bunch into a dictionary. >>> b = Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') >>> unbunchify(b) {'ponies': 'are pretty!', 'foo': {'lol': True}, 'hello': 42} unbunchify will handle intermediary dicts, lists and tuples (as well as their subclasses), but ymmv on custom datatypes. >>> b = Bunch(foo=['bar', Bunch(lol=True)], hello=42, ... ponies=('are pretty!', Bunch(lies='are trouble!'))) >>> unbunchify(b) #doctest: +NORMALIZE_WHITESPACE {'ponies': ('are pretty!', {'lies': 'are trouble!'}), 'foo': ['bar', {'lol': True}], 'hello': 42} nb. As dicts are not hashable, they cannot be nested in sets/frozensets. """ if isinstance(x, dict): return dict( (k, unbunchify(v)) for k,v in x.iteritems() ) elif isinstance(x, (list, tuple)): return type(x)( unbunchify(v) for v in x ) else: return x ### Serialization try: try: import json except ImportError: import simplejson as json def toJSON(self, **options): """ Serializes this Bunch to JSON. Accepts the same keyword options as `json.dumps()`. >>> b = Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') >>> json.dumps(b) '{"ponies": "are pretty!", "foo": {"lol": true}, "hello": 42}' >>> b.toJSON() '{"ponies": "are pretty!", "foo": {"lol": true}, "hello": 42}' """ return json.dumps(self, **options) Bunch.toJSON = toJSON except ImportError: pass try: # Attempt to register ourself with PyYAML as a representer import yaml from yaml.representer import Representer, SafeRepresenter def from_yaml(loader, node): """ PyYAML support for Bunches using the tag `!bunch` and `!bunch.Bunch`. >>> import yaml >>> yaml.load(''' ... Flow style: !bunch.Bunch { Clark: Evans, Brian: Ingerson, Oren: Ben-Kiki } ... Block style: !bunch ... Clark : Evans ... Brian : Ingerson ... Oren : Ben-Kiki ... ''') #doctest: +NORMALIZE_WHITESPACE {'Flow style': Bunch(Brian='Ingerson', Clark='Evans', Oren='Ben-Kiki'), 'Block style': Bunch(Brian='Ingerson', Clark='Evans', Oren='Ben-Kiki')} This module registers itself automatically to cover both Bunch and any subclasses. Should you want to customize the representation of a subclass, simply register it with PyYAML yourself. """ data = Bunch() yield data value = loader.construct_mapping(node) data.update(value) def to_yaml_safe(dumper, data): """ Converts Bunch to a normal mapping node, making it appear as a dict in the YAML output. >>> b = Bunch(foo=['bar', Bunch(lol=True)], hello=42) >>> import yaml >>> yaml.safe_dump(b, default_flow_style=True) '{foo: [bar, {lol: true}], hello: 42}\\n' """ return dumper.represent_dict(data) def to_yaml(dumper, data): """ Converts Bunch to a representation node. >>> b = Bunch(foo=['bar', Bunch(lol=True)], hello=42) >>> import yaml >>> yaml.dump(b, default_flow_style=True) '!bunch.Bunch {foo: [bar, !bunch.Bunch {lol: true}], hello: 42}\\n' """ return dumper.represent_mapping(u'!bunch.Bunch', data) yaml.add_constructor(u'!bunch', from_yaml) yaml.add_constructor(u'!bunch.Bunch', from_yaml) SafeRepresenter.add_representer(Bunch, to_yaml_safe) SafeRepresenter.add_multi_representer(Bunch, to_yaml_safe) Representer.add_representer(Bunch, to_yaml) Representer.add_multi_representer(Bunch, to_yaml) # Instance methods for YAML conversion def toYAML(self, **options): """ Serializes this Bunch to YAML, using `yaml.safe_dump()` if no `Dumper` is provided. See the PyYAML documentation for more info. >>> b = Bunch(foo=['bar', Bunch(lol=True)], hello=42) >>> import yaml >>> yaml.safe_dump(b, default_flow_style=True) '{foo: [bar, {lol: true}], hello: 42}\\n' >>> b.toYAML(default_flow_style=True) '{foo: [bar, {lol: true}], hello: 42}\\n' >>> yaml.dump(b, default_flow_style=True) '!bunch.Bunch {foo: [bar, !bunch.Bunch {lol: true}], hello: 42}\\n' >>> b.toYAML(Dumper=yaml.Dumper, default_flow_style=True) '!bunch.Bunch {foo: [bar, !bunch.Bunch {lol: true}], hello: 42}\\n' """ opts = dict(indent=4, default_flow_style=False) opts.update(options) if 'Dumper' not in opts: return yaml.safe_dump(self, **opts) else: return yaml.dump(self, **opts) def fromYAML(*args, **kwargs): return bunchify( yaml.load(*args, **kwargs) ) Bunch.toYAML = Bunch.__str__ = toYAML Bunch.fromYAML = staticmethod(fromYAML) except ImportError: pass if __name__ == "__main__": import doctest doctest.testmod() bunch-1.0.1/bunch/test.py0000644000076500000240000000024111630106450015125 0ustar dscstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- def test(): import bunch import doctest doctest.testmod(bunch) if __name__ == '__main__': test() bunch-1.0.1/bunch.egg-info/0000775000076500000240000000000011676427013015306 5ustar dscstaff00000000000000bunch-1.0.1/bunch.egg-info/dependency_links.txt0000644000076500000240000000000111676426712021357 0ustar dscstaff00000000000000 bunch-1.0.1/bunch.egg-info/PKG-INFO0000644000076500000240000001011511676426712016404 0ustar dscstaff00000000000000Metadata-Version: 1.0 Name: bunch Version: 1.0.1 Summary: A dot-accessible dictionary (a la JavaScript objects) Home-page: http://github.com/dsc/bunch Author: David Schoonover Author-email: dsc@less.ly License: MIT Description: bunch ===== Bunch is a dictionary that supports attribute-style access, a la JavaScript. >>> b = Bunch() >>> b.hello = 'world' >>> b.hello 'world' >>> b['hello'] += "!" >>> b.hello 'world!' >>> b.foo = Bunch(lol=True) >>> b.foo.lol True >>> b.foo is b['foo'] True Dictionary Methods ------------------ A Bunch is a subclass of ``dict``; it supports all the methods a ``dict`` does: >>> b.keys() ['foo', 'hello'] Including ``update()``: >>> b.update({ 'ponies': 'are pretty!' }, hello=42) >>> print repr(b) Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') As well as iteration: >>> [ (k,b[k]) for k in b ] [('ponies', 'are pretty!'), ('foo', Bunch(lol=True)), ('hello', 42)] And "splats": >>> "The {knights} who say {ni}!".format(**Bunch(knights='lolcats', ni='can haz')) 'The lolcats who say can haz!' Serialization ------------- Bunches happily and transparently serialize to JSON and YAML. >>> b = Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') >>> import json >>> json.dumps(b) '{"ponies": "are pretty!", "foo": {"lol": true}, "hello": 42}' If JSON support is present (``json`` or ``simplejson``), ``Bunch`` will have a ``toJSON()`` method which returns the object as a JSON string. If you have `PyYAML`_ installed, Bunch attempts to register itself with the various YAML Representers so that Bunches can be transparently dumped and loaded. >>> b = Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') >>> import yaml >>> yaml.dump(b) '!bunch.Bunch\nfoo: !bunch.Bunch {lol: true}\nhello: 42\nponies: are pretty!\n' >>> yaml.safe_dump(b) 'foo: {lol: true}\nhello: 42\nponies: are pretty!\n' In addition, Bunch instances will have a ``toYAML()`` method that returns the YAML string using ``yaml.safe_dump()``. This method also replaces ``__str__`` if present, as I find it far more readable. You can revert back to Python's default use of ``__repr__`` with a simple assignment: ``Bunch.__str__ = Bunch.__repr__``. The Bunch class will also have a static method ``Bunch.fromYAML()``, which loads a Bunch out of a YAML string. Finally, Bunch converts easily and recursively to (``unbunchify()``, ``Bunch.toDict()``) and from (``bunchify()``, ``Bunch.fromDict()``) a normal ``dict``, making it easy to cleanly serialize them in other formats. Miscellaneous ------------- * It is safe to ``import *`` from this module. You'll get: ``Bunch``, ``bunchify``, and ``unbunchify``. * Ample doctests:: $ python -m bunch.test -v Feedback -------- Open a ticket at http://github.com/dsc/bunch or send me an email at dsc@less.ly . Keywords: bunch,dict,mapping,container,collection Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.5 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Topic :: Software Development Classifier: Topic :: Software Development :: Libraries Classifier: Topic :: Utilities Classifier: License :: OSI Approved :: MIT License bunch-1.0.1/bunch.egg-info/SOURCES.txt0000644000076500000240000000027711676426712017203 0ustar dscstaff00000000000000LICENSE.txt MANIFEST.in README.rst setup.py bunch/__init__.py bunch/test.py bunch.egg-info/PKG-INFO bunch.egg-info/SOURCES.txt bunch.egg-info/dependency_links.txt bunch.egg-info/top_level.txtbunch-1.0.1/bunch.egg-info/top_level.txt0000644000076500000240000000000611676426712020037 0ustar dscstaff00000000000000bunch bunch-1.0.1/LICENSE.txt0000644000076500000240000000206711327474415014344 0ustar dscstaff00000000000000Copyright (c) 2010 David Schoonover Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. bunch-1.0.1/MANIFEST.in0000644000076500000240000000004711327500215014237 0ustar dscstaff00000000000000include LICENSE.txt include README.rst bunch-1.0.1/PKG-INFO0000664000076500000240000001011511676427013013610 0ustar dscstaff00000000000000Metadata-Version: 1.0 Name: bunch Version: 1.0.1 Summary: A dot-accessible dictionary (a la JavaScript objects) Home-page: http://github.com/dsc/bunch Author: David Schoonover Author-email: dsc@less.ly License: MIT Description: bunch ===== Bunch is a dictionary that supports attribute-style access, a la JavaScript. >>> b = Bunch() >>> b.hello = 'world' >>> b.hello 'world' >>> b['hello'] += "!" >>> b.hello 'world!' >>> b.foo = Bunch(lol=True) >>> b.foo.lol True >>> b.foo is b['foo'] True Dictionary Methods ------------------ A Bunch is a subclass of ``dict``; it supports all the methods a ``dict`` does: >>> b.keys() ['foo', 'hello'] Including ``update()``: >>> b.update({ 'ponies': 'are pretty!' }, hello=42) >>> print repr(b) Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') As well as iteration: >>> [ (k,b[k]) for k in b ] [('ponies', 'are pretty!'), ('foo', Bunch(lol=True)), ('hello', 42)] And "splats": >>> "The {knights} who say {ni}!".format(**Bunch(knights='lolcats', ni='can haz')) 'The lolcats who say can haz!' Serialization ------------- Bunches happily and transparently serialize to JSON and YAML. >>> b = Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') >>> import json >>> json.dumps(b) '{"ponies": "are pretty!", "foo": {"lol": true}, "hello": 42}' If JSON support is present (``json`` or ``simplejson``), ``Bunch`` will have a ``toJSON()`` method which returns the object as a JSON string. If you have `PyYAML`_ installed, Bunch attempts to register itself with the various YAML Representers so that Bunches can be transparently dumped and loaded. >>> b = Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') >>> import yaml >>> yaml.dump(b) '!bunch.Bunch\nfoo: !bunch.Bunch {lol: true}\nhello: 42\nponies: are pretty!\n' >>> yaml.safe_dump(b) 'foo: {lol: true}\nhello: 42\nponies: are pretty!\n' In addition, Bunch instances will have a ``toYAML()`` method that returns the YAML string using ``yaml.safe_dump()``. This method also replaces ``__str__`` if present, as I find it far more readable. You can revert back to Python's default use of ``__repr__`` with a simple assignment: ``Bunch.__str__ = Bunch.__repr__``. The Bunch class will also have a static method ``Bunch.fromYAML()``, which loads a Bunch out of a YAML string. Finally, Bunch converts easily and recursively to (``unbunchify()``, ``Bunch.toDict()``) and from (``bunchify()``, ``Bunch.fromDict()``) a normal ``dict``, making it easy to cleanly serialize them in other formats. Miscellaneous ------------- * It is safe to ``import *`` from this module. You'll get: ``Bunch``, ``bunchify``, and ``unbunchify``. * Ample doctests:: $ python -m bunch.test -v Feedback -------- Open a ticket at http://github.com/dsc/bunch or send me an email at dsc@less.ly . Keywords: bunch,dict,mapping,container,collection Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.5 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Topic :: Software Development Classifier: Topic :: Software Development :: Libraries Classifier: Topic :: Utilities Classifier: License :: OSI Approved :: MIT License bunch-1.0.1/README.rst0000644000076500000240000000506511676426603014214 0ustar dscstaff00000000000000bunch ===== Bunch is a dictionary that supports attribute-style access, a la JavaScript. >>> b = Bunch() >>> b.hello = 'world' >>> b.hello 'world' >>> b['hello'] += "!" >>> b.hello 'world!' >>> b.foo = Bunch(lol=True) >>> b.foo.lol True >>> b.foo is b['foo'] True Dictionary Methods ------------------ A Bunch is a subclass of ``dict``; it supports all the methods a ``dict`` does: >>> b.keys() ['foo', 'hello'] Including ``update()``: >>> b.update({ 'ponies': 'are pretty!' }, hello=42) >>> print repr(b) Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') As well as iteration: >>> [ (k,b[k]) for k in b ] [('ponies', 'are pretty!'), ('foo', Bunch(lol=True)), ('hello', 42)] And "splats": >>> "The {knights} who say {ni}!".format(**Bunch(knights='lolcats', ni='can haz')) 'The lolcats who say can haz!' Serialization ------------- Bunches happily and transparently serialize to JSON and YAML. >>> b = Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') >>> import json >>> json.dumps(b) '{"ponies": "are pretty!", "foo": {"lol": true}, "hello": 42}' If JSON support is present (``json`` or ``simplejson``), ``Bunch`` will have a ``toJSON()`` method which returns the object as a JSON string. If you have `PyYAML`_ installed, Bunch attempts to register itself with the various YAML Representers so that Bunches can be transparently dumped and loaded. >>> b = Bunch(foo=Bunch(lol=True), hello=42, ponies='are pretty!') >>> import yaml >>> yaml.dump(b) '!bunch.Bunch\nfoo: !bunch.Bunch {lol: true}\nhello: 42\nponies: are pretty!\n' >>> yaml.safe_dump(b) 'foo: {lol: true}\nhello: 42\nponies: are pretty!\n' In addition, Bunch instances will have a ``toYAML()`` method that returns the YAML string using ``yaml.safe_dump()``. This method also replaces ``__str__`` if present, as I find it far more readable. You can revert back to Python's default use of ``__repr__`` with a simple assignment: ``Bunch.__str__ = Bunch.__repr__``. The Bunch class will also have a static method ``Bunch.fromYAML()``, which loads a Bunch out of a YAML string. Finally, Bunch converts easily and recursively to (``unbunchify()``, ``Bunch.toDict()``) and from (``bunchify()``, ``Bunch.fromDict()``) a normal ``dict``, making it easy to cleanly serialize them in other formats. Miscellaneous ------------- * It is safe to ``import *`` from this module. You'll get: ``Bunch``, ``bunchify``, and ``unbunchify``. * Ample doctests:: $ python -m bunch.test -v Feedback -------- Open a ticket at http://github.com/dsc/bunch or send me an email at dsc@less.ly . bunch-1.0.1/setup.cfg0000664000076500000240000000007311676427013014336 0ustar dscstaff00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 bunch-1.0.1/setup.py0000644000076500000240000000302011676423032014215 0ustar dscstaff00000000000000#!python # -*- coding: utf-8 -*- import sys, os, re from os.path import dirname, abspath, join from setuptools import setup HERE = abspath(dirname(__file__)) readme = open(join(HERE, 'README.rst')).read() package_file = open(join(HERE, 'bunch/__init__.py'), 'rU') __version__ = re.sub( r".*\b__version__\s+=\s+'([^']+)'.*", r'\1', [ line.strip() for line in package_file if '__version__' in line ].pop(0) ) setup( name = "bunch", version = __version__, description = "A dot-accessible dictionary (a la JavaScript objects)", long_description = readme, url = "http://github.com/dsc/bunch", author = "David Schoonover", author_email = "dsc@less.ly", packages = ['bunch',], keywords = ['bunch', 'dict', 'mapping', 'container', 'collection'], classifiers = [ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'Operating System :: OS Independent', 'Programming Language :: Python', "Programming Language :: Python :: 2.5", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", 'Topic :: Software Development', 'Topic :: Software Development :: Libraries', 'Topic :: Utilities', 'License :: OSI Approved :: MIT License', ], # download_url = "http://pypi.python.org/packages/source/b/bunch/bunch-%s.tar.gz" % __version__, license = 'MIT', )