pax_global_header00006660000000000000000000000064132252552510014514gustar00rootroot0000000000000052 comment=517b3f2f2d74c9fae3a33553f395350f61c4c33b itypes-1.1.0/000077500000000000000000000000001322525525100130305ustar00rootroot00000000000000itypes-1.1.0/PKG-INFO000066400000000000000000000010631322525525100141250ustar00rootroot00000000000000Metadata-Version: 1.1 Name: itypes Version: 1.1.0 Summary: Simple immutable types for python. Home-page: http://github.com/tomchristie/itypes Author: Tom Christie Author-email: tom@tomchristie.com License: BSD Description: UNKNOWN Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Internet :: WWW/HTTP itypes-1.1.0/itypes.egg-info/000077500000000000000000000000001322525525100160375ustar00rootroot00000000000000itypes-1.1.0/itypes.egg-info/PKG-INFO000066400000000000000000000010631322525525100171340ustar00rootroot00000000000000Metadata-Version: 1.1 Name: itypes Version: 1.1.0 Summary: Simple immutable types for python. Home-page: http://github.com/tomchristie/itypes Author: Tom Christie Author-email: tom@tomchristie.com License: BSD Description: UNKNOWN Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Internet :: WWW/HTTP itypes-1.1.0/itypes.egg-info/SOURCES.txt000066400000000000000000000002121322525525100177160ustar00rootroot00000000000000itypes.py setup.py itypes.egg-info/PKG-INFO itypes.egg-info/SOURCES.txt itypes.egg-info/dependency_links.txt itypes.egg-info/top_level.txtitypes-1.1.0/itypes.egg-info/dependency_links.txt000066400000000000000000000000011322525525100221050ustar00rootroot00000000000000 itypes-1.1.0/itypes.egg-info/top_level.txt000066400000000000000000000000071322525525100205660ustar00rootroot00000000000000itypes itypes-1.1.0/itypes.py000066400000000000000000000126561322525525100147310ustar00rootroot00000000000000# coding: utf-8 from collections import Mapping, Sequence __version__ = '1.1.0' def to_mutable(instance): if isinstance(instance, Dict): return { key: to_mutable(value) for key, value in instance.items() } elif isinstance(instance, List): return [ to_mutable(value) for value in instance ] return instance def to_immutable(value): if isinstance(value, dict): return Dict(value) elif isinstance(value, list): return List(value) return value def _to_hashable(instance): if isinstance(instance, Dict): items = sorted(instance.items(), key=lambda item: item[0]) return ( (key, _to_hashable(value)) for key, value in items ) elif isinstance(instance, List): return [ _to_hashable(value) for value in instance ] return instance def _set_in(node, keys, value): if not keys: return value elif len(keys) == 1: return node.set(keys[0], value) key = keys[0] child = node[key] if not isinstance(child, (Dict, List)): msg = "Expected a container type at key '%s', but got '%s'" raise KeyError(msg % type(child)) child = child.set_in(keys[1:], value) return node.set(key, child) def _delete_in(node, keys): if not keys: return elif len(keys) == 1: return node.delete(keys[0]) key = keys[0] child = node[key] if not isinstance(child, (Dict, List)): msg = "Expected a container type at key '%s', but got '%s'" raise KeyError(msg % type(child)) child = child.delete_in(keys[1:]) return node.set(key, child) def _get_in(node, keys, default=None): if not keys: return default key = keys[0] try: child = node[key] except (KeyError, IndexError): return default if len(keys) == 1: return child return child.get_in(keys[1:], default=default) class Object(object): def __setattr__(self, key, value): if key.startswith('_'): return object.__setattr__(self, key, value) msg = "'%s' object doesn't support property assignment." raise TypeError(msg % self.__class__.__name__) class Dict(Mapping): def __init__(self, *args, **kwargs): self._data = { key: to_immutable(value) for key, value in dict(*args, **kwargs).items() } def __setattr__(self, key, value): if key.startswith('_'): return object.__setattr__(self, key, value) msg = "'%s' object doesn't support property assignment." raise TypeError(msg % self.__class__.__name__) def __getitem__(self, key): return self._data[key] def __iter__(self): return iter(self._data) def __len__(self): return len(self._data) def __eq__(self, other): if isinstance(other, self.__class__): return self._data == other._data return self._data == other def __hash__(self): return hash(_to_hashable(self)) def __repr__(self): return "%s(%s)" % ( self.__class__.__name__, to_mutable(self) ) def __str__(self): return str(self._data) def set(self, key, value): data = dict(self._data) data[key] = value if hasattr(self, 'clone'): return self.clone(data) return type(self)(data) def delete(self, key): data = dict(self._data) data.pop(key) if hasattr(self, 'clone'): return self.clone(data) return type(self)(data) def get_in(self, keys, default=None): return _get_in(self, keys, default=default) def set_in(self, keys, value): return _set_in(self, keys, value) def delete_in(self, keys): return _delete_in(self, keys) class List(Sequence): def __init__(self, *args): self._data = [ to_immutable(value) for value in list(*args) ] def __setattr__(self, key, value): if key == '_data': return object.__setattr__(self, key, value) msg = "'%s' object doesn't support property assignment." raise TypeError(msg % self.__class__.__name__) def __getitem__(self, key): return self._data[key] def __iter__(self): return iter(self._data) def __len__(self): return len(self._data) def __eq__(self, other): if isinstance(other, self.__class__): return self._data == other._data return self._data == other def __hash__(self): return hash(_to_hashable(self)) def __repr__(self): return "%s(%s)" % ( self.__class__.__name__, to_mutable(self) ) def __str__(self): return str(self._data) def set(self, key, value): data = list(self._data) data[key] = value if hasattr(self, 'clone'): return self.clone(data) return type(self)(data) def delete(self, key): data = list(self._data) data.pop(key) if hasattr(self, 'clone'): return self.clone(data) return type(self)(data) def get_in(self, keys, default=None): return _get_in(self, keys, default=default) def set_in(self, keys, value): return _set_in(self, keys, value) def delete_in(self, keys): return _delete_in(self, keys) itypes-1.1.0/setup.cfg000066400000000000000000000000731322525525100146510ustar00rootroot00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 itypes-1.1.0/setup.py000077500000000000000000000022601322525525100145450ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- from setuptools import setup import re import os import sys def get_version(): """ Return package version as listed in `__version__` in `init.py`. """ init_py = open('itypes.py').read() return re.search("__version__ = ['\"]([^'\"]+)['\"]", init_py).group(1) version = get_version() if sys.argv[-1] == 'publish': os.system("python setup.py sdist upload") print("You probably want to also tag the version now:") print(" git tag -a %s -m 'version %s'" % (version, version)) print(" git push --tags") sys.exit() setup( name='itypes', version=version, url='http://github.com/tomchristie/itypes', license='BSD', description='Simple immutable types for python.', author='Tom Christie', author_email='tom@tomchristie.com', py_modules=['itypes'], classifiers=[ 'Development Status :: 3 - Alpha', 'Environment :: Web Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Internet :: WWW/HTTP', ] )