{ "info": { "author": "", "author_email": "", "bugtrack_url": null, "classifiers": [], "description": "compose\n=======\nYet another namedtuple alternative for Python\n\n``compose.Struct`` is something like an alternative to namedtuple,\nattrs_ and now dataclasses_ in Python 3.7.\n\n.. _attrs: https://github.com/python-attrs/attrs\n.. _dataclasses: https://docs.python.org/3/library/dataclasses.html\n\nto create a new struct, you simply:\n\n.. code:: Python\n\n\n class Foo(compose.Struct):\n bar = ...\n baz = 'spam'\n\nThis generates a class like this:\n\n.. code:: Python\n\n class Foo:\n __slots__ = 'bar', 'baz'\n\n def __init__(self, bar, baz='spam'):\n self.bar = bar\n self.baz = baz\n\nYou can, naturally, implement any other methods you wish.\n\nYou can also use type annotation syntax for positional arguments:\n\n.. code:: Python\n\n class Foo(compose.Struct):\n bar: int\n baz: str = 'spam'\n\nIf the ``name = ...`` syntax is used in combination with type annotation\nsyntax for positional arguments, all positional arguments with\nannotations will come before positional arguments without. However, this\nshould be considered an implementation detail. best practice is to not\nmix the two styles. Use ``typing.Any`` if you are using type\nannotations and don't want one of the arguments to care about type.\n\nHow's this different from attrs_ and dataclasses_? A few ways. Aside\nfrom the use of ellipsis to create positional parameters, another\ndifference that can be seen here is that everything is based on\n``__slots__``, which means your attribute lookup will be faster and your\ninstances more compact in memory. attrs_ allows you to use slots, but\n``struct`` only uses slots. This means that attributes cannot be\ndynamically created. If a class needs private attributes, you may create\nadditional slots with the usual method of defining ``__slots__`` inside\nthe class body.\n\nAnother important distinction is ``compose.Struct`` doesn't define a\nbunch of random dunder methods. You get your ``__init__``, ``__repr__``,\nand ``to_dict`` and that's it [#]_. It is the opinion of the author that\nsticking all attributes in a tuple and comparing them usually is *not*\nwhat you want when defining a new type. However, it is still easy to get\nmore dunder methods, as you will see in the following section.\n\n.. [#] OK, It actually also gives you __getstate__ and __setstate__,\n which are required for pickling objects.\n\nInterfaces\n----------\nPerhaps the most significant difference between our structs and\nalternatives is that we emphasize composition over inheritance. A\n``struct`` isn't even able to inherit in the normal way! It's an\noutrage! What about interfaces!? What about polymorphism!? Well, what\n``compose`` provides is a simple way to generate pass-through methods to\nattributes.\n\n.. code:: Python\n\n from compose import Struct, Provider\n\n class ListWrapper(Struct):\n data = Provider('__getitem__', '__iter__')\n metadata = None\n\n\nSo this will generate pass-through methods for ``__getitem__`` and\n``__iter__`` to the ``data`` attribute. Certain python keywords and\noperators can be used as shorthand for adding dunder methods as well.\n\n.. code:: Python\n\n @struct\n class ListWrapper:\n data = Provider('[]', 'for')\n metadata = None\n\nHere, ``[]`` is shorthand for item access and implements\n``__getitem__``, ``__setitem__`` and ``__delitem__``. ``for`` implements\nthe ``__iter__`` method. A full list of these abbreviations can be found\nbelow in the `Pre-Defined Interfaces`_ section.\n\nGoing even deeper, interfaces can be specified as classes. Wrapper\nmethods will be created for any method attached to a class which is\ngiven as an argument to ``Provider``. The following code is more or less\nequivalent to subclassing ``collections.UserList``, but no inheritance\nis used.\n\n.. code:: Python\n\n from collections import abc\n\n class ListWrapper(Struct):\n data = Provider(abc.MutableSequence)\n metadata = None\n\nAn instances of this class tested with ``isinstance(instance,\nabc.MutableSequence)`` will return ``True`` because wrapper methods\nhave been generated on ``self.data`` for all the methods in\n``abc.MutableSequence``. *Note that ``abc.MutableSequence`` does not\nactually provide all of the methods a real list does. If you want ALL\nof them, you can use ``Provides(list)``.*\n\nYou cannot implicitly make pass-through methods for ``__setattr__`` and\n``__getattribute__`` by passing in a class that implements them, since\nthey have some rather strange behaviors. You can, however, pass them\nexplicitly to ``Provider`` to force the issue. In the case of\n``__setattr__``, This invokes special behavior. See `__setattr__ hacks`_\nfor details.\n\nAll methods defined with a provider can be overridden in the body of the\nclass as desired. Methods can also be overridden by other providers.\nIt's first-come, first-serve in that case. The Provider you want to\ndefine the methods has to be placed *above* any other interfaces that\nimplement the same method.\n\nMix-in Classes vs. Inheritance\n------------------------------\nThere is no inheritance with Structs. Because of metaclass magic, a\nclass that inherits from Struct is not its child. It is always a child\nof ``object``. ``Provider`` is a way to implement pass-through methods\neasily. Mix-in classes bind methods from other classes directly to your\nclass. It doesn't go through the class hierarchy and rebind everything,\nonly methods defined directly on the mix-in class. Inheriting from\nnormal python classes may have unpredictable results.\n\n``compose`` provides one mix-in class: ``Immutable``, which is\nimplemented like this:\n\n.. code:: Python\n\n class Mutablility(Exception):\n pass\n\n\n class Immutable:\n def __setattr__(self, attr, value):\n raise Mutablility(\n \"can't set {0}.{1}. type {0} is immutable.\".format(\n self.__class__.__name__,\n attr,\n value\n ))\n\nIt can be used like this:\n\n.. code:: Python\n\n from compose import Struct, Immutable\n\n\n class Foo(Struct, Immutable):\n bar = ...\n baz = ...\n\nWhen an instance of ``Foo`` is created, it will not be possible to set\nattributes afterwards in the normal way. (Though it is technically\npossible if you set it with ``object.__setattr__(instance, 'attr',\nvalue)``). Attempting to do ``foo.bar = 7`` will raise a ``Mutability``\nerror.\n\nIf you need a ``struct`` to look like a child of another class, I\nsuggest using the abc_ module to define abstract classes. This allows\nclasses to look like children for the purposes of type-checking, but\nwithout actually using inheritance.\n\n.. _abc: https://docs.python.org/3/library/abc.html\n\nOrder\n~~~~~\nThis is the order of priority for where methods come from:\n\n- Struct generates a unique ``__init__`` method for each class it\n creates. This cannot be overriden. Alternative constructors should be\n implemented as class methods.\n- methods defined in the body of the struct get next dibs.\n- any attributes defined on your mix-ins will be defined on the class if\n they don't already exist.\n- Only then are ``Provider`` attributes allowed to add any methods which\n haven't yet been defined.\n\n``*args`` and ``**kwargs``\n--------------------------\nThough it is not especially recommended, it is possible to implement\n``*args`` and ``**kwargs`` for your constructor.\n\n.. code:: Python\n\n >>> from compose import Struct, args, kwargs\n >>> class Foo(Struct):\n ... items = args\n ... mapping = kwargs\n ...\n >>> f = Foo('bar', 'baz', spam='eggs')\n >>> f\n Foo(*items=('bar', 'baz'), **mapping={'spam': 'eggs'})\n\nThis breaks the principle that the object's repr can be used to\ninstantiate an identical instance, but it does at least give the option\nand still makes the internal structure of the class transparent. With\n``Provider`` parameters, simply pass in ``compose.args`` or\n``compose.kwargs`` as arguments the constructor.\n\n.. code:: Python\n\n >>> class MySequence(Struct):\n ... data = Provider('__getitem__', '__iter__', args)\n ...\n >>> s = MySequence('foo', 'bar', 'baz')\n >>> s\n MySequence(*data=('foo', 'bar', 'baz'))\n >>> for i in s:\n ... print(i)\n ...\n foo\n bar\n baz\n\nCaveats\n-------\nThis library uses code generation at class-creation time. The intent is\nto optimize performance of instances at the cost of slowing class\ncreation. If you're dynamically creating huge numbers of classes, using\n``compose.Struct`` might be a bad idea. FYI, ``namedtuple`` does the\nsame. I haven't looked at the source for attrs_ too much, but I did see\nsome strings with sourcecode there as well.\n\nPre-Defined Interfaces\n----------------------\nThis is the code that implements the expansion of interface\nabbreviations for dunder methods. Any key in the ``interfaces``\ndictionary may be used to implement the corresponding dunder methods on\nan attribute with the ``Provides()`` constructor.\n\n.. code:: Python\n\n interfaces = {\n '+': 'add radd',\n '-': 'sub rsub',\n '*': 'mul rmul',\n '@': 'matmul rmatmul',\n '/': 'truediv rtruediv',\n '//': 'floordiv rfloordiv',\n '%': 'mod rmod',\n '**': 'pow rpow',\n '<<': 'lshift rlshift',\n '>>': 'rshift rrshift',\n '&': 'and rand',\n '^': 'xor rxor',\n '|': 'or ror',\n '~': 'invert',\n '==': 'eq',\n '!=': 'ne',\n '>': 'gt',\n '<': 'lt',\n '>=': 'ge',\n '<=': 'le',\n '()': 'call',\n '[]': 'getitem setitem delitem',\n '.': 'get set delete set_name',\n 'in': 'contains',\n 'for': 'iter',\n 'with': 'enter exit',\n 'del': 'del',\n 'await': 'await'\n }\n interfaces = {k: ['__%s__' % n for n in v.split()]\n for k, v in interfaces.items()}\n\n__setattr__ hacks\n-----------------\nIf you choose to create an attribute\nwrapper for ``__setattr__``, the default will look like this so you\nwon't hit a recursion error while accessing pre-defined attributes:\n\n.. code:: Python\n\n def __setattr__(self, attribute, value):\n try:\n object.__setattr__(self, attribute, value)\n except AttributeError:\n setattr(self.wrapped_attribute, attribute, value)\n\nIf you want to override ``__setattr__`` with a more, eh, \"exotic\"\nmethod, the attributes defined in the class body will be set properly\nwhen the instance is initialized, but will use your method at all other\ntimes, *including in other methods, which may break your stuff*.\n\n\n", "description_content_type": "text/x-rst", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ninjaaron/compose-struct", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "compose-struct", "package_url": "https://pypi.org/project/compose-struct/", "platform": "", "project_url": "https://pypi.org/project/compose-struct/", "project_urls": { "Homepage": "https://github.com/ninjaaron/compose-struct" }, "release_url": "https://pypi.org/project/compose-struct/0.8.0/", "requires_dist": null, "requires_python": ">=3.5", "summary": "yet another namedtuple alternative", "version": "0.8.0" }, "last_serial": 5439977, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "a36ae55c864823a43529253df3862351", "sha256": "192f59f581ff9f0cc547b6bd003598d9f8346e7f41a5c37454524d1a2419011c" }, "downloads": -1, "filename": "compose_struct-0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "a36ae55c864823a43529253df3862351", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 7469, "upload_time": "2018-07-02T13:20:13", "url": "https://files.pythonhosted.org/packages/b9/e9/ddb7264f541e2c3017e76ad0f31faad493ff6365ed98678a0a997daa91ed/compose_struct-0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "fa0733496a272eb111f2f871564a05b0", "sha256": "ed42aad18d30521373a733121309dff8a6eec6f49238beae53b3f9efca7a1cda" }, "downloads": -1, "filename": "compose_struct-0.1.tar.gz", "has_sig": false, "md5_digest": "fa0733496a272eb111f2f871564a05b0", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 6909, "upload_time": "2018-07-02T13:20:14", "url": "https://files.pythonhosted.org/packages/b3/c2/44de8ff5f527c7d48ffc13b51b14574b9166cdce405ad1cf4e4bfca681c1/compose_struct-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "d6a40f28497bab6f4c9c2590a033dd6f", "sha256": "bd66ffe4e117db1da7f38860b4bb1115b1f0adb73a94832def493c846d35d159" }, "downloads": -1, "filename": "compose_struct-0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "d6a40f28497bab6f4c9c2590a033dd6f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 7485, "upload_time": "2018-07-02T15:27:54", "url": "https://files.pythonhosted.org/packages/52/5f/c1b23fb8daf47c3390fce0e963052bc59c592b9cdde03f8bdbf3b1b1fca2/compose_struct-0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c31dacdf6798e360ccccf4ed1e1dceec", "sha256": "5578378d9892c1cc8abdef6b80717419c693adb0fc223e1afed6ad4d2a80a567" }, "downloads": -1, "filename": "compose_struct-0.2.tar.gz", "has_sig": false, "md5_digest": "c31dacdf6798e360ccccf4ed1e1dceec", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 6857, "upload_time": "2018-07-02T15:27:55", "url": "https://files.pythonhosted.org/packages/f2/53/48c1d795cb097823e930e524eb37ca39d4089e397a3ecd0f7a726ab0d4e8/compose_struct-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "606802213bc8671cfd7c0ae6036eadbe", "sha256": "81b2458966677c04454c6870f751b907c13772d74d926763fb50e94d88114a77" }, "downloads": -1, "filename": "compose_struct-0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "606802213bc8671cfd7c0ae6036eadbe", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 8619, "upload_time": "2018-07-04T08:08:44", "url": "https://files.pythonhosted.org/packages/a6/e7/ac512babfadd71662433475a6e3df8d25deeae7bebc92321cbbabb76d829/compose_struct-0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "85de6d6d16a6f6d476a48d4323bbdcb8", "sha256": "196d3ebf964a4f1b4fc09d3522e7add99b5b09fd86b246afe56b0545f73a53fe" }, "downloads": -1, "filename": "compose_struct-0.3.tar.gz", "has_sig": false, "md5_digest": "85de6d6d16a6f6d476a48d4323bbdcb8", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 8046, "upload_time": "2018-07-04T08:08:45", "url": "https://files.pythonhosted.org/packages/50/00/4a4ec18bbc7ed8c7200f1ee25ff5322622d4aa9800dd00b3104f65e18baa/compose_struct-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "3c7ca9841101e31c9779a504d826ca0b", "sha256": "8bbf008613ee86f89ccced941560fc4142b43dd97ae6df85e1c89dfbc4251685" }, "downloads": -1, "filename": "compose_struct-0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "3c7ca9841101e31c9779a504d826ca0b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 8639, "upload_time": "2018-07-09T06:02:54", "url": "https://files.pythonhosted.org/packages/3a/36/edff260dd632cffdba43599f3aeedfe43759780997cbe27c7dfed63c516e/compose_struct-0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bad7fe50bf5f3e56c393ebb83a436c47", "sha256": "961edc592bbddd391ab7c6431cf896351f62a9fceb4c6d2454e7e008fc9a7f76" }, "downloads": -1, "filename": "compose_struct-0.4.tar.gz", "has_sig": false, "md5_digest": "bad7fe50bf5f3e56c393ebb83a436c47", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 8072, "upload_time": "2018-07-09T06:02:56", "url": "https://files.pythonhosted.org/packages/b4/5d/625a8a2f4b95bab63448286c327d0f3c7f306dacc636e94295e042d56437/compose_struct-0.4.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "ebc687e91b344441e43cbbf778b2eccd", "sha256": "39a0b8084810a527f8d2d918d8ff6ff4884f97c04fe8f9667c3d2839f2ad6638" }, "downloads": -1, "filename": "compose_struct-0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "ebc687e91b344441e43cbbf778b2eccd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 9157, "upload_time": "2018-07-11T09:12:50", "url": "https://files.pythonhosted.org/packages/e7/b7/c1ddb240d70a46ee36134b206dd032f60d3fc080cfa2568823cfcfd75a9f/compose_struct-0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9cc2ff68f23ccf676c803ed699ab660d", "sha256": "d81de79536b2ac91526645a727a434e8814ca78d27a68a3d67509fc725d0803c" }, "downloads": -1, "filename": "compose_struct-0.5.tar.gz", "has_sig": false, "md5_digest": "9cc2ff68f23ccf676c803ed699ab660d", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 8744, "upload_time": "2018-07-11T09:12:51", "url": "https://files.pythonhosted.org/packages/75/f3/67639f314e446fc7bfab4aca0d3a4073c8a90c31ffc23e25c3e33f96e1a2/compose_struct-0.5.tar.gz" } ], "0.6": [ { "comment_text": "", "digests": { "md5": "a9ef4319fd4a85ea85df857ecf11dfb6", "sha256": "601e7c32e61ceefb9b3652b4a8049743b52ce2dec89c6f0cad68be8d03dd749b" }, "downloads": -1, "filename": "compose_struct-0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "a9ef4319fd4a85ea85df857ecf11dfb6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 14048, "upload_time": "2018-07-17T13:40:28", "url": "https://files.pythonhosted.org/packages/f6/5c/a0468ddaaa5bfda70fb82f766c404ce324b639e218e1af897bcac381d3ae/compose_struct-0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b437f832f6b317cbff656693f9f59b0f", "sha256": "44c1adb7e96253bd62e4c97db3531ffde103973052b480e755198904dae53ae7" }, "downloads": -1, "filename": "compose_struct-0.6.tar.gz", "has_sig": false, "md5_digest": "b437f832f6b317cbff656693f9f59b0f", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 9236, "upload_time": "2018-07-17T13:40:30", "url": "https://files.pythonhosted.org/packages/e2/40/3fb30340f5c2d6b8d9f6d690e8ad52831eea16f9d708a417b9634623d67e/compose_struct-0.6.tar.gz" } ], "0.7": [ { "comment_text": "", "digests": { "md5": "6dc1cb2ca1d7d4b404774dc201651a3f", "sha256": "15e13bbc6be7a1acc2b6e54f9a84c0ea0d2bc6e901e422eefb6c422dcfdca9ed" }, "downloads": -1, "filename": "compose_struct-0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "6dc1cb2ca1d7d4b404774dc201651a3f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 14045, "upload_time": "2018-07-17T13:44:07", "url": "https://files.pythonhosted.org/packages/66/2b/ab9265eb4e808085daeb2da6651caf489ad7598bbe2708a3abbd0e717c04/compose_struct-0.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bb3b14cf6d62f1f8e2252fb944db20cc", "sha256": "4dcd2f05bef7efc509998d78472706065d98e5d8190a181e71b1b60acac08645" }, "downloads": -1, "filename": "compose_struct-0.7.tar.gz", "has_sig": false, "md5_digest": "bb3b14cf6d62f1f8e2252fb944db20cc", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 9228, "upload_time": "2018-07-17T13:44:08", "url": "https://files.pythonhosted.org/packages/bc/dd/8c0d2f1381dafd440eb06792196bee552556919b1bd7f2b575918b98333e/compose_struct-0.7.tar.gz" } ], "0.7.1": [ { "comment_text": "", "digests": { "md5": "a15c18f5ee21a3143047cc2dc4f61efa", "sha256": "b6e638939f1716b078e576280d5a73e3f364e363a2f8d10e8478fc4438d843a7" }, "downloads": -1, "filename": "compose_struct-0.7.1-py3-none-any.whl", "has_sig": false, "md5_digest": "a15c18f5ee21a3143047cc2dc4f61efa", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 14078, "upload_time": "2018-07-17T13:47:35", "url": "https://files.pythonhosted.org/packages/be/78/01347424b3bbe758017bbfa8d5cf3805947a165f64f8f62fdac0c2b1a4f3/compose_struct-0.7.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9fdb9f1de918c7f8cfbb8bd06aed9655", "sha256": "5595fb22aa5d292a312031116c3c149b22c5164a994a9a28560dbf31b913cca1" }, "downloads": -1, "filename": "compose_struct-0.7.1.tar.gz", "has_sig": false, "md5_digest": "9fdb9f1de918c7f8cfbb8bd06aed9655", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 9235, "upload_time": "2018-07-17T13:47:36", "url": "https://files.pythonhosted.org/packages/f0/fe/bee64f8376ea17a8b8071dbbb5e8e616b6b3c7e738af7868a50daded1458/compose_struct-0.7.1.tar.gz" } ], "0.7.2": [ { "comment_text": "", "digests": { "md5": "b5e3849f3774610866216abd9d0038dc", "sha256": "222389d778d4498e2a25a26d60da44ca9ab6f77c5d420763baf14662e8d6c3fb" }, "downloads": -1, "filename": "compose_struct-0.7.2-py3-none-any.whl", "has_sig": false, "md5_digest": "b5e3849f3774610866216abd9d0038dc", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 14306, "upload_time": "2018-07-17T13:55:02", "url": "https://files.pythonhosted.org/packages/f2/4b/e052322b1593f7fa81e4a84cccd3047c4abb8bbff1280d311945bca9c36a/compose_struct-0.7.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "fde12d725ef9079145b4ec48e7e26122", "sha256": "aeeb8aedeb02a0b1a436fecf24cc18361ba125b5fba36ab9b5d7a82d66e288bd" }, "downloads": -1, "filename": "compose_struct-0.7.2.tar.gz", "has_sig": false, "md5_digest": "fde12d725ef9079145b4ec48e7e26122", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 9273, "upload_time": "2018-07-17T13:55:04", "url": "https://files.pythonhosted.org/packages/30/d2/44ba870ffc998e60bebd68cb7d673076ddbcd162506105942feef3770d31/compose_struct-0.7.2.tar.gz" } ], "0.7.4": [ { "comment_text": "", "digests": { "md5": "5eaeddbe8d83839c532b3075c9b86d02", "sha256": "0d44c05d47f4f2cfd41a16cce3b86e86f92558c57789edc3372013ab72e19638" }, "downloads": -1, "filename": "compose_struct-0.7.4-py3-none-any.whl", "has_sig": false, "md5_digest": "5eaeddbe8d83839c532b3075c9b86d02", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 10201, "upload_time": "2018-09-02T02:24:27", "url": "https://files.pythonhosted.org/packages/67/ba/d63e72469079a67331dc59b878642cc2da8b8de8cb848e887a919103d7b3/compose_struct-0.7.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b8eadb0d68049162c6bb6cf91def1c60", "sha256": "134a50c15f8e87f79e5fc3bbb383668f51f46c3ee032f06e4dec823b50bf3816" }, "downloads": -1, "filename": "compose_struct-0.7.4.tar.gz", "has_sig": false, "md5_digest": "b8eadb0d68049162c6bb6cf91def1c60", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 10337, "upload_time": "2018-09-02T02:24:29", "url": "https://files.pythonhosted.org/packages/f2/0b/e383fee2087da435b0e4a80a4c7771fb0b7da4480bf089a6177665677db2/compose_struct-0.7.4.tar.gz" } ], "0.7.5": [ { "comment_text": "", "digests": { "md5": "2225d26fea754c89a3ae211bd25801e0", "sha256": "48596f458980940cf577dc395ad8b861e13632dc83697c37a57225561dc962e0" }, "downloads": -1, "filename": "compose_struct-0.7.5-py3-none-any.whl", "has_sig": false, "md5_digest": "2225d26fea754c89a3ae211bd25801e0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 16132, "upload_time": "2018-10-31T17:34:38", "url": "https://files.pythonhosted.org/packages/4d/aa/ba162e5b91956a3b379354d7a44af66d7072de06f89155d50667dfcd7527/compose_struct-0.7.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6a5cf2ca5fca4a94db56e62f9d6a36b6", "sha256": "ea1d5ff244e7d1b902bc3ce9c317df59fbafa208ea17ae9027c3d7bef73359bb" }, "downloads": -1, "filename": "compose_struct-0.7.5.tar.gz", "has_sig": false, "md5_digest": "6a5cf2ca5fca4a94db56e62f9d6a36b6", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 11009, "upload_time": "2018-10-31T17:34:39", "url": "https://files.pythonhosted.org/packages/8b/42/28f0503e3680f3a4b64ca1fda79251bf148c59648e96fa39839ca423ec76/compose_struct-0.7.5.tar.gz" } ], "0.8.0": [ { "comment_text": "", "digests": { "md5": "88099b86c5630851fab44b9c7ffc499c", "sha256": "21efc91112cc3a9dfd3fb3d6d173b7f3a92302370c168d5bc91eaf429de76e1f" }, "downloads": -1, "filename": "compose_struct-0.8.0-py3-none-any.whl", "has_sig": false, "md5_digest": "88099b86c5630851fab44b9c7ffc499c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 16146, "upload_time": "2019-06-24T10:10:44", "url": "https://files.pythonhosted.org/packages/ee/d3/c1ee5b785ae3f9d54d866e04c5d699816edcd5cc441b52cd543181816fb0/compose_struct-0.8.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7d27d167b0f16f9fff7676a6af2e0255", "sha256": "d102c65c69a29b62ff1a3f5c51736d01ef46a509449490197ebb2de1b7bffe68" }, "downloads": -1, "filename": "compose_struct-0.8.0.tar.gz", "has_sig": false, "md5_digest": "7d27d167b0f16f9fff7676a6af2e0255", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 11027, "upload_time": "2019-06-24T10:10:46", "url": "https://files.pythonhosted.org/packages/10/f9/636655487023061a904121c1bafb68f2895f59a450c9890cc9e78ef60dfd/compose_struct-0.8.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "88099b86c5630851fab44b9c7ffc499c", "sha256": "21efc91112cc3a9dfd3fb3d6d173b7f3a92302370c168d5bc91eaf429de76e1f" }, "downloads": -1, "filename": "compose_struct-0.8.0-py3-none-any.whl", "has_sig": false, "md5_digest": "88099b86c5630851fab44b9c7ffc499c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 16146, "upload_time": "2019-06-24T10:10:44", "url": "https://files.pythonhosted.org/packages/ee/d3/c1ee5b785ae3f9d54d866e04c5d699816edcd5cc441b52cd543181816fb0/compose_struct-0.8.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7d27d167b0f16f9fff7676a6af2e0255", "sha256": "d102c65c69a29b62ff1a3f5c51736d01ef46a509449490197ebb2de1b7bffe68" }, "downloads": -1, "filename": "compose_struct-0.8.0.tar.gz", "has_sig": false, "md5_digest": "7d27d167b0f16f9fff7676a6af2e0255", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 11027, "upload_time": "2019-06-24T10:10:46", "url": "https://files.pythonhosted.org/packages/10/f9/636655487023061a904121c1bafb68f2895f59a450c9890cc9e78ef60dfd/compose_struct-0.8.0.tar.gz" } ] }