{ "info": { "author": "Alice Bevan-McGregor", "author_email": "alice@gothcandy.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Utilities" ], "description": "=============\nMarrow Schema\n=============\n\n \u00a9 2013-2018 Alice Bevan-McGregor and contributors.\n\n..\n\n https://github.com/marrow/schema\n\n..\n\n |latestversion| |ghtag| |downloads| |masterstatus| |mastercover| |masterreq| |ghwatch| |ghstar|\n\n.. warning:: This project is no longer Python 2 compatible, and due to the change in how namespace packages are\n packaged this project is directly incompatible with any other project utilizing the ``marrow`` namespace\n that **is** compatible with Python 2. *Always pin your version ranges.*\n\n\n1. What is Marrow Schema?\n=========================\n\nMarrow Schema is a tiny and fully tested, 3.3+ compatible declarative syntax toolkit. This basically means you use\nhigh-level objects to define other high-level object data structures. Simplified: you'll never have to write a class\nconstructor that only assigns instance variables again.\n\nExamples of use include:\n\n* Attribute-access dictionaries with predefined \"slots\".\n\n* The object mapper aspect of an ORM or ODM for database access. One example would be `Marrow Mongo\n `_\n\n* Declarative schema-driven serialization systems.\n\n* `Marrow Interface `_, declarative schema validation for arbitrary Python\n objects similar in purpose to ``zope.interface`` or Python's own abstract base classes.\n\n* `Marrow Widgets `_ are defined declaratively allowing for far more flexible\n and cooperative subclassing.\n\n* Powerful data validation and transformation using the included frameworks.\n\n\n1.1 Goals\n---------\n\nMarrow Schema was created with the goal of extracting a component common to nearly every database ORM, ODM, widget\nsystem, form validation library, structured serialzation format, or other schema-based tool into a common shared\nlibrary to benefit all. While some of the basic principles (data descriptors, etc.) are relatively simple, few\nimplementations are truly complete. Often you would lose access to standard Python idioms such as the use of\npositional arguments with class constructors or Pythonic exceptions.\n\nWith a proven generic implementation we discovered quickly that the possibilities weren't limited to the typical uses.\nOne commercial project that uses Marrow Schema does so to define generic CRUD *controllers* declaratively, greatly\nreducing development time and encouraging WORM (write-once, read-many) best practice.\n\nMarrow Schema additionally aims to have a very narrow scope and to \"eat its own dog food\", using a declarative syntax\nto define the declarative syntax. This is in stark contrast to alternatives (such as\n`scheme `_) which utilize multiple metaclasses and a hodge-podge of magical attributes\ninternally. Or `guts `_, which is heavily tied to its XML and YAML data processing\ncapabilities. Neither of these currently support positional instantiation, and both can be implemented as a\nlight-weight superset of Marrow Schema.\n\n\n2. Installation\n===============\n\nInstalling ``marrow.schema`` is easy, just execute the following in a terminal::\n\n pip install marrow.schema\n\n**Note:** We *strongly* recommend always using a container, virtualization, or sandboxing environment of some kind when\ndeveloping using Python; installing things system-wide is yucky (for a variety of reasons) nine times out of ten. We\nprefer light-weight `virtualenv `_, others prefer solutions as\nrobust as `Vagrant `_.\n\nIf you add ``marrow.schema`` to the ``install_requires`` argument of the call to ``setup()`` in your applicaiton's\n``setup.py`` file, Marrow Schema will be automatically installed and made available when your own application or\nlibrary is installed. We recommend using \"less than\" version numbers to ensure there are no unintentional\nside-effects when updating. Use ``marrow.schema<2.1`` to get all bugfixes for the current release, and\n``marrow.schema<3.0`` to get bugfixes and feature updates while ensuring that large breaking changes are not installed.\n\n\n2.1. Development Version\n------------------------\n\n |developstatus| |developcover| |ghsince| |issuecount| |ghfork|\n\nDevelopment takes place on `GitHub `_ in the\n`marrow/schema `_ project. Issue tracking, documentation, and downloads\nare provided there.\n\nInstalling the current development version requires `Git `_, a distributed source code management\nsystem. If you have Git you can run the following to download and *link* the development version into your Python\nruntime::\n\n git clone https://github.com/marrow/schema.git\n (cd schema; python setup.py develop)\n\nYou can then upgrade to the latest version at any time::\n\n (cd schema; git pull; python setup.py develop)\n\nIf you would like to make changes and contribute them back to the project, fork the GitHub project, make your changes,\nand submit a pull request. This process is beyond the scope of this documentation; for more information see\n`GitHub's documentation `_.\n\n\n3. Basic Concepts\n=================\n\n3.1. Element\n------------\n\nInstantiation order tracking and attribute naming / collection base class.\n\nTo use, construct subclasses of the ``Element`` class whose attributes are themselves instances of ``Element``\nsubclasses. Five attributes on your subclass have magical properties:\n\n* ``inst.__sequence__`` \u2014 \n An atomically incrementing (for the life of the process) counter used to preserve order. Each instance of an\n ``Element`` subclass is given a new sequence number automatically.\n\n* ``inst.__name__`` \u2014 \n ``Element`` subclasses automatically associate attributes that are ``Element`` subclass instances with the name of\n the attribute they were assigned to.\n\n* ``cls.__attributes__`` \u2014 \n An ordered dictionary of all ``Element`` subclass instances assigned as attributes to your class. Class inheritance\n of this attribute is handled differently: it is a combination of the ``__attributes__`` of all parent classes.\n **Note:** This is only calculated at class construction time; this makes it efficient to consult frequently.\n\n* ``cls.__attributed__`` \u2014 \n Called after class construction to allow you to easily perform additional work, post-annotation. Should be a\n classmethod for full effect.\n\n* ``cls.__fixup__`` \u2014 \n If an instance of your ``Element`` subclass is assigned as a property to an ``Element`` subclass, this method of your\n class will be called to notify you and allow you to make additional adjustments to the class using your subclass.\n Should be a classmethod.\n\nGenerally you will want to use one of the helper classes provided (``Container``, ``Attribute``, etc.) however this can\nbe useful if you only require extremely light-weight attribute features on custom objects.\n\n3.2. Container\n--------------\n\nThe underlying machinery for handling class instantiation for schema elements whose primary purpose is containing other\nschema elements, i.e. ``Document``, ``Record``, ``CompoundWidget``, etc.\n\nAssociation of declarative attribute names (at class construction time) is handled by the ``Element`` metaclass.\n\nProcesses arguments and assigns values to instance attributes at class instantiation time, basically defining\n``__init__`` so you don't have to. You could extend this to support validation during instantiation, or to process\nadditional programmatic arguments, as examples, and benefit from not having to repeat the same leg-work each time.\n\n``Container`` subclasses have one additional magical property:\n\n* ``inst.__data__`` \u2014 \n Primary instance data storage for all ``DataAttribute`` instances. Equivalent to ``_data`` from MongoEngine.\n\nMost of the data storage requirements of Marrow Schema-derived objects comes from this dictionary. Additionally,\nMarrow Schema-derived objects tend to move data from the instance ``__dict__`` to this ``__data__`` dictionary, having\nan unfortunate side-effect on the class-based performance optimizations of Pypy. We hope to resolve this in the future\nthrough optional annotations for that interpreter.\n\n3.3. DataAttribute\n------------------\n\nDescriptor protocol support for ``Element`` subclasses.\n\nThe base attribute class which implements the descriptor protocol, pulling the instance value of the attribute from\nthe containing object's ``__data__`` dictionary. If an attempt is made to read an attribute that does not have a\ncorresponding value in the data dictionary an ``AttributeError`` will be raised.\n\n3.4. Attribute\n--------------\n\nRe-naming, default value, and container support for data attributes.\n\nAll \"data\" is stored in the container's ``__data__`` dictionary. The key defaults to the ``Attribute`` instance name\nand can be overridden, unlike ``DataAttribute``, by passing a name as the first positional parameter, or as the\n``name`` keyword argument.\n\nMay contain nested ``Element`` instances to define properties for your ``Attribute`` subclass declaratively.\n\nIf ``assign`` is ``True`` and the default value is ever utilized, immediately pretend the default value was assigned to\nthis attribute. (Override this in subclasses.)\n\n3.5. CallbackAttribute\n----------------------\n\nAn attribute that automatically executes the value upon retrieval, if a callable routine.\n\nFrequently used by validation, transformation, and object mapper systems, especially as default value attributes. E.g.\nMongoEngine's ``choices`` argument to ``Field`` subclasses.\n\n3.6. Attributes\n---------------\n\nA declarative attribute you can use in your own ``Container`` subclasses to provide views across the known attributes\nof that container. Can provide a filter (which uses ``isinstance``) to limit to specific attributes.\n\nThis is a dynamic property that generates an ``OrderedDict`` on each retrieval. If you wish to use it frequently it \nwould be prudent to make a more local-scope reference.\n\n\n4. Validation\n=============\n\nMarrow Schema offers a wide variety of data validation primitives. These are constructed declaratively where possible,\nand participate in Marrow Schema's ``Element`` protocol as both ``Container`` and ``Attribute``.\n\nYou can create hybrid subclasses of individual validator classes to create basic compound validators. Dedicated\ncompound validators are also provided which give more fine-grained control over how the child validators are executed.\nA hybrid validator's behaviour will depend on the order of the parent classes. It will execute the parent validators\nuntil one fails, or all succeed.\n\n4.1. Validation Basics\n----------------------\n\nGiven an instance of a ``Validator`` subclass you simply call the ``validate`` method with the value to validate and\nan optional execution context passed positionally, in that order. The value, potentially transformed as required to\nvalidate, is returned. For example, the simple validator provided that always passes can be used like this::\n\n from marrow.schema.validation import always\n\n assert always.validate(\"Hello world!\") == \"Hello world!\"\n\nWriting your own validators can be as simple as subclassing ``Validator`` and overriding the ``validate`` method,\nhowever there are other (more declarative) ways to create custom validators.\n\nFor now, though, we can write a validator that only accepts the number 27::\n\n from marrow.schema.validation import Concern, Validator\n\n class TwentySeven(Validator):\n def validate(self, value, context=None):\n if value != 27:\n raise Concern(\"Totally not twenty seven, dude.\")\n return value\n\n validate = TwentySeven().validate\n\n assert validate(27) == 27\n validate(42) # Boom!\n\nYou can see that validators should return the value if successful and raise an exception if not. What if you want the\nvalidator to be more generic, allowing you to define any arbitrary number to compare against::\n\n from marrow.schema import Attribute\n\n class Equals(Validator):\n value = Attribute()\n\n def validate(self, value, context=None):\n if value != self.value:\n raise Concern(\"Value of {0!r} doesn't match expectation of {1!r}.\", value, self.value)\n\n return value\n\n validate = Equals(3).validate\n\n assert validate(3) == 3\n validate(27) # Boom!\n\nThat's basically the built-in Equal validator, right there. (You'll notice that it doesn't even care if the value is a\nnumber or not. Python is awesome that way.)\n\n4.1.1. Concerns\n~~~~~~~~~~~~~~~\n\nValidators raise \"concerns\" if they encounter problems with the data being validated. A ``Concern`` exception has a\nlevel, identical to a logging level, and only errors (and above) should be treated as such. This level defaults to\n``logging.ERROR``. Because most validation concerns should probably be fatal, overriding this value isn't done much\nwithin Marrow Schema; it's mostly there for developer use. Because of this, though, ``Concern`` has a somewhat strange\nconstructor::\n\n Concern([level, ]message, *args, concerns=[], **kw)\n\nAn optional integer logging level, then a message followed by zero or more additional arguments, an optional\n``concerns`` keyword-only argument that is either not supplied or an iterable of child ``Concern`` instances, and zero\nor more additional keyword arguments. Compound validators that aggregate multiple failures (i.e. ``Pipe``)\nautomatically determine their aggregate ``Concern`` level from the maximum of the child concerns.\n\n``Concern`` instances render to ``str`` instances; the result of calling ``message.format(*args, **kw)`` using the\narguments provided above. Care should be taken to only include JSON-safe datatypes in these arguments.\n\n\n4.2. Basic Validators\n---------------------\n\nMarrow Schema includes a *lot* of validators for you to use. They tend to be organized based on purpose, but the basic\nvalidators have such widespread usage they're importable straight from ``marrow.schema.validation``.\n\n* ``Validator`` \u2014 the base validator; a no-op.\n* ``Always`` \u2014 effectively the same in effect as using Validator directly, always passes. Singleton: ``always``\n* ``Never`` \u2014 the opposite of Always, this never passes. Singleton: ``never``\n* ``AlwaysTruthy`` \u2014 the value must always evaluate to True. Singleton: ``truthy``\n* ``Truthy`` \u2014 A mixin-able version of AlwaysTruthy whose behaviour is toggled by the ``truthy`` attribute.\n* ``AlwaysFalsy`` \u2014 as per AlwaysTruthy. Singleton: ``falsy``\n* ``Falsy`` \u2014 A mixin-able version of AlwaysFalsy, as per Truthy with the ``falsy`` attribute instead.\n* ``AlwaysRequried`` \u2014 Value must be non-None. Singleton: ``required``\n* ``Required`` \u2014 A mixin-able version of AlwaysRequired using the ``required`` attribute.\n* ``AlwaysMissing`` \u2014 Value must be None or otherwise have a length of zero. Singleton: ``missing``\n* ``Missing`` \u2014 A mixin-able version of AlwaysMissing using the ``missing`` attribute.\n* ``Callback`` \u2014 Execute a simple callback to validate the value. More on this one later.\n* ``In`` \u2014 Value must be contained within the provided iterable, ``choices``.\n* ``Contains`` \u2014 Value must contain (via ``in``) the provided value, ``contains``.\n* ``Length`` \u2014 Value must have either an exact length or a length within a given range, ``length``. (Hint: assign a tuple or a ``slice()``.)\n* ``Range`` \u2014 Value must exist within a specific range (``minimum`` and ``maximum``) either end of which may be unbounded.\n* ``Pattern`` \u2014 Value must match a regular expression, ``pattern``. The expression will be compiled for you during assignment if passing in raw strings.\n* ``Instance`` \u2014 Value must be an instance of the given class ``instance`` or an instance of one of a set of classes (by passing a tuple).\n* ``Subclass`` \u2014 Value must be a subclass of the given class ``subclass`` or a subclass of one of a set of classes (by passing a tuple).\n* ``Equal`` \u2014 Value must equal a given value, ``equals``.\n* ``Unique`` \u2014 No element of the provided iterable value may be repeated. Uses sets, so all values must also be hashable. Singleton: ``unique``\n\n4.3. Callback Validators\n------------------------\n\nCallback validators allow you to write validator logic using simple lambda statements, amongst other uses. They\nrapidly enter the realm of the spooky door when you realize the Callback validator class can be used as a decorator, though. To see what we mean you could define the \"Always\" validator like this::\n\n from marrow.schema.validation import Callback\n\n @Callback\n def always(validator, value, context=None):\n return value\n\n assert always.validate(27) == 27\n\nThe callback that callback validators use may return a value, raise a Concern like any normal ``validate`` method, or\nsimply *return* a Concern instance which will then be raised on behalf of the callback. The original callback function\nis reachable as ``always.validator`` in this instance.\n\n(If the decorator thing has you scratching your head, notice that the callback is assigned using an Attribute instance\u2026 and positional arguments fill out attributes! Magic!)\n\n4.4. Compound Validators\n------------------------\n\nCompound validators (imported from ``marrow.schema.validation.compound``) use other validators as declarative\nattributes. Additionally, you can pass validators at class instantiation time positionally or using the ``validators``\nkeyword argument. Declarative child validators take priority.\n\nThe ``__validators__`` aggregate is provided to filter the known attributes of the ``Compound`` subclass to just the\nassigned validators. A generator property named ``_validators`` is provided to merge the two sources.\n\nThe purpose of this type of validator is to give you additional control over how multiple validators are run against a\nsingle value, and how validators are run against collections (such as lists and dictionaries).\n\n* ``Compound`` \u2014 The base class providing validator aggregation; effectively a no-op.\n* ``Any`` \u2014 Stop processing on first success, but gather multiple failures into one.\n* ``All`` \u2014 Ensure all validators pass, but stop processing on the first failure. Does not gather failures.\n* ``Pipe`` \u2014 Execute all validators and only declare success if all pass. Gathers failures together.\n* ``Iterable`` \u2014 Value must be an iterable whose elements pass validation using the base scheme defined by ``require``,\n generally one of ``Any``, ``All``, or ``Pipe``, but may be recursive. (The class, not an instance of the class, or\n a ``functools.partial``-wrapped class for recursive use.)\n* ``Mapping`` \u2014 Value must be a mapping (``dict``-like) whose values non-recursively validate using the base scheme\n defined by ``require``. As per ``Iterable``, you can use ``functools.partial`` to build recursive compound\n validators.\n\n4.5. Date and Time Validators\n-----------------------------\n\n* ``Date`` \u2014 A ``Range`` filter that only accepts datetime and date instances.\n* ``Time`` \u2014 A ``Range`` filter that only accepts datetime and time instances.\n* ``DateTime`` \u2014 A ``Range`` filter that only accepts datetime instances.\n* ``Delta`` \u2014 A ``Range`` filter that only accepts timedelta instances.\n\n4.6. Geographic Validators\n--------------------------\n\nAll have singletons using the all-lower-case name.\n\n* ``Latitude`` \u2014 A ``Compound`` validator ensuring the value is a number between -90 and 90 (degrees).\n* ``Longitude`` \u2014 A ``Compound`` validator ensuring the value is a number between -180 and 180 (degrees).\n* ``Position`` \u2014 A ``Compound`` validator ensuring the value is a sequence of length two whose first element is a valid\n latitude and whose second element is a valid longitude.\n\n4.7. Network-Related Validators\n-------------------------------\n\nAll have singletons using the all-lower-case name. All are ``Pattern`` validators.\n\n* ``IPv4`` \u2014 IPv4 dot-notation address.\n* ``IPv4`` \u2014 IPv6 dot-notation address.\n* ``CIDRv4`` \u2014 IPv4 network range.\n* ``CIDRv6`` \u2014 IPv6 network range.\n* ``IPAddress`` \u2014 An IPv4 *or* IPv6 address.\n* ``CIDR`` \u2014 An IPv4 *or* IPv6 network range.\n* ``Hostname`` \u2014 Valid ASCII host name validator.\n* ``DNSName`` \u2014 Valid DNS RFC host name validator.\n* ``MAC`` \u2014 Media Access Control (MAC) address validator.\n* ``URI`` \u2014 Uniform Resource Locator (URI) validator.\n\n4.8. Regular Expression Pattern Validators\n------------------------------------------\n\nThese were not more specific to another task. All are ``Pattern`` validators. All have singletons using the\nall-lower-case name.\n\n* ``Alphanumeric`` \u2014 Case-insensitive letters and numbers.\n* ``Username`` \u2014 Simple username validator: leading character must be alphabetical, subsequent characters may be alphanumeric, hyphen, period, or underscore.\n* ``TwitterUsername`` \u2014 A validator for modern Twitter handles.\n* ``FacebookUsername`` \u2014 A validator for modern Facebook usernames.\n* ``CreditCard`` \u2014 A basic CC validator; does not validate checksum.\n* ``HexColor`` \u2014 Hashmark color code of either three or six elements. (Half-byte or full-byte RGB accuracy.)\n* ``AlphaHexColor`` \u2014 Hashmark color code of either four or eight elements. (Half-byte or full-byte RGBA accuracy.)\n* ``ISBN`` \u2014 A very complete ISBN validator.\n* ``Slug`` \u2014 Generally acceptable URL component validator. Includes word characters, underscore, and hyphen.\n* ``UUID`` \u2014 Basic UUID validation. Accepts technically invalid UUIDs that are nontheless well-formed.\n\n4.9. Utilities\n--------------\n\n* ``marrow.schema.validation:Validated`` \u2014 A mix-in for ``Attribute`` subclasses that performs validation on any\n attempt to assign a value. Not useful by itself.\n* ``marrow.schema.validation.util:SliceAttribute`` \u2014 Enforce a typecasting to a ``slice()`` instance by consuming\n iterables.\n* ``marrow.schema.validation.util:RegexAttribute`` \u2014 Automatically attempt to ``re.compile`` objects that do not have a\n ``match`` method.\n\n4.9.1 Testing\n~~~~~~~~~~~~~\n\nA helper class is provided to aid in testing your own validators. It is a test generator allowing you to quickly and\neasily define a validator and iterables of valid and invalid values to try. This class is used extensively by Marrow\nSchema itself and is agnostic to your preferred test runner. (As long as the runner understands test generators.)\n\nThis utility class (``marrow.schema.validation.testing:ValidationTest``) has been tested under Nose and py.test.\n\n\n5. Version History\n==================\n\nVersion 1.0\n-----------\n\n* Initial release.\n\nVersion 1.0.1\n-------------\n\n* Compatibility with Python 2.6.\n\n* Added pypy3 to test suite.\n\nVersion 1.0.2\n-------------\n\n* Callbacks are now provided to inform attributes when they are defined, and for containers when they likewise defined.\n\n* If an attribute is overridden by a non-attribute value, it shouldn't be included in ``__attributes__`` and co.\n\n* If an attribute is overridden by a new attribute, preserve the original definition order. This is useful, as an\n example, to ensure the order of positional arguments don't change even if you override the default value through\n redefinition.\n\nVersion 1.1.0\n-------------\n\n* **Massive update to documentation.** Now most lines of code are also covered by descriptive comments.\n\n* **Validation primitives.** A large component of this release is a newly added and fully tested suite of data\n validation tools.\n\n* **Tests to Ludicrous Speed.** Marrow Schema now has more individual tests (600+) than executable statements, and\n they execute in a few seconds on most interpreters! Remember, kids: mad science is never stopping to ask \"what's the\n worst that could happen?\"\n\n* **Expanded Travis coverage.** Travis now runs the py26 and pypy3 test runners.\n\nVersion 1.1.1\n-------------\n\n* Removal of diagnostic aides.\n\nVersion 1.2.0\n-------------\n\n* Updated documentation sheilds and test coverage provider.\n\n* **Added tested data transformation tools.**\n\n* Attributes passed positionally or by name during ``Container`` initialization have their attribute order preserved\n during assignment.\n\n* ``Container`` subclasses can now override the callable used to construct ``__data__`` on instances.\n\nVersion 2.0.0\n-------------\n\n* Removed Python 2 compatibility and testing.\n* Updated to modern namespace packaging practices. This is **incompatible with any marrow project version that is Python 2 compatible**.\n\n\n6. License\n==========\n\nMarrow Schema has been released under the MIT Open Source license.\n\n6.1. The MIT License\n--------------------\n\nCopyright \u00a9 2013-2018 Alice Bevan-McGregor and contributors.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\ndocumentation files (the \u201cSoftware\u201d), to deal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit\npersons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the\nSoftware.\n\nTHE SOFTWARE IS PROVIDED \u201cAS IS\u201d, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\nWARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n.. |ghwatch| image:: https://img.shields.io/github/watchers/marrow/schema.svg?style=social&label=Watch\n :target: https://github.com/marrow/schema/subscription\n :alt: Subscribe to project activity on Github.\n\n.. |ghstar| image:: https://img.shields.io/github/stars/marrow/schema.svg?style=social&label=Star\n :target: https://github.com/marrow/schema/subscription\n :alt: Star this project on Github.\n\n.. |ghfork| image:: https://img.shields.io/github/forks/marrow/schema.svg?style=social&label=Fork\n :target: https://github.com/marrow/schema/fork\n :alt: Fork this project on Github.\n\n.. |masterstatus| image:: http://img.shields.io/travis/marrow/schema/master.svg?style=flat\n :target: https://travis-ci.org/marrow/schema/branches\n :alt: Release build status.\n\n.. |mastercover| image:: http://img.shields.io/codecov/c/github/marrow/schema/master.svg?style=flat\n :target: https://codecov.io/github/marrow/schema?branch=master\n :alt: Release test coverage.\n\n.. |masterreq| image:: https://img.shields.io/requires/github/marrow/schema.svg\n :target: https://requires.io/github/marrow/schema/requirements/?branch=master\n :alt: Status of release dependencies.\n\n.. |developstatus| image:: http://img.shields.io/travis/marrow/schema/develop.svg?style=flat\n :target: https://travis-ci.org/marrow/schema/branches\n :alt: Development build status.\n\n.. |developcover| image:: http://img.shields.io/codecov/c/github/marrow/schema/develop.svg?style=flat\n :target: https://codecov.io/github/marrow/schema?branch=develop\n :alt: Development test coverage.\n\n.. |developreq| image:: https://img.shields.io/requires/github/marrow/schema.svg\n :target: https://requires.io/github/marrow/schema/requirements/?branch=develop\n :alt: Status of development dependencies.\n\n.. |issuecount| image:: http://img.shields.io/github/issues-raw/marrow/schema.svg?style=flat\n :target: https://github.com/marrow/schema/issues\n :alt: Github Issues\n\n.. |ghsince| image:: https://img.shields.io/github/commits-since/marrow/schema/1.2.0.svg\n :target: https://github.com/marrow/schema/commits/develop\n :alt: Changes since last release.\n\n.. |ghtag| image:: https://img.shields.io/github/tag/marrow/schema.svg\n :target: https://github.com/marrow/schema/tree/1.2.0\n :alt: Latest Github tagged release.\n\n.. |latestversion| image:: http://img.shields.io/pypi/v/marrow.schema.svg?style=flat\n :target: https://pypi.python.org/pypi/marrow.schema\n :alt: Latest released version.\n\n.. |downloads| image:: http://img.shields.io/pypi/dw/marrow.schema.svg?style=flat\n :target: https://pypi.python.org/pypi/marrow.schema\n :alt: Downloads per week.\n\n.. |cake| image:: http://img.shields.io/badge/cake-lie-1b87fb.svg?style=flat\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/marrow/schema/", "keywords": "declarative syntax,metaprogramming,schema toolkit", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "marrow.schema", "package_url": "https://pypi.org/project/marrow.schema/", "platform": "", "project_url": "https://pypi.org/project/marrow.schema/", "project_urls": { "Homepage": "https://github.com/marrow/schema/" }, "release_url": "https://pypi.org/project/marrow.schema/2.0.0/", "requires_dist": [ "pytest ; extra == 'development'", "pytest-cov ; extra == 'development'", "pytest-spec ; extra == 'development'", "pytest-flakes ; extra == 'development'" ], "requires_python": "", "summary": "A generic declarative syntax toolkit for Python objects that uses itself to define itself. Really.", "version": "2.0.0" }, "last_serial": 4911116, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "d6911704d264d59edec90337727cea0b", "sha256": "52a70638784b803fdf62c11d6d90515c3d4f737444020114eeaae2704d8e5130" }, "downloads": -1, "filename": "marrow.schema-1.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d6911704d264d59edec90337727cea0b", "packagetype": "bdist_wheel", "python_version": "3.4", "requires_python": null, "size": 12492, "upload_time": "2014-07-02T20:27:33", "url": "https://files.pythonhosted.org/packages/47/3a/4c7a5bc10052092cd9323487fb95b63f8431c3dc402ea9d85e413a42bf14/marrow.schema-1.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f7da59db146475d12d6a8e98a6ad341a", "sha256": "d15c927308cedbc0fbd0e7c0e667f389aeb01836ff4bc5086cc60f03ff10b5f9" }, "downloads": -1, "filename": "marrow.schema-1.0.0-py3.4.egg", "has_sig": false, "md5_digest": "f7da59db146475d12d6a8e98a6ad341a", "packagetype": "bdist_egg", "python_version": "3.4", "requires_python": null, "size": 13999, "upload_time": "2014-07-02T19:44:49", "url": "https://files.pythonhosted.org/packages/42/19/4d2b4a4a2adcc943538219583ae06eae8315ce9667c46fd886bf7b5afabd/marrow.schema-1.0.0-py3.4.egg" }, { "comment_text": "", "digests": { "md5": "1fb17e55c56131322486fb9dc4e70eb9", "sha256": "a1063e0a6655a572cc9e11ed06642269223eb4ca2a2769efeb6cf16394b9bf07" }, "downloads": -1, "filename": "marrow.schema-1.0.0.tar.gz", "has_sig": false, "md5_digest": "1fb17e55c56131322486fb9dc4e70eb9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9065, "upload_time": "2014-07-02T19:44:47", "url": "https://files.pythonhosted.org/packages/01/ff/47b91e820494b2414793de3f2ecf563c5fbbfa4e2c5fb2566c7b7ebecc56/marrow.schema-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "5a30b4a13e774e89ec4c7b14d96b5b0f", "sha256": "af7cdbf3fd35a401adae4e874be5767632710ff2f1a2fb3019dfd393357e9cab" }, "downloads": -1, "filename": "marrow.schema-1.0.1-py2.6.egg", "has_sig": false, "md5_digest": "5a30b4a13e774e89ec4c7b14d96b5b0f", "packagetype": "bdist_egg", "python_version": "2.6", "requires_python": null, "size": 14157, "upload_time": "2014-07-04T19:41:35", "url": "https://files.pythonhosted.org/packages/51/ef/e4eea01dd43f4d996b730e4550531a41cd8359084f1a63ce9bba2edab65c/marrow.schema-1.0.1-py2.6.egg" }, { "comment_text": "", "digests": { "md5": "d964c4be04a950782b6f798f99a8bc71", "sha256": "75303531a4101b8656ca392e07f932aabf2bc9c2a663a95953fa9ce5a2b9b38c" }, "downloads": -1, "filename": "marrow.schema-1.0.1-py2.7.egg", "has_sig": false, "md5_digest": "d964c4be04a950782b6f798f99a8bc71", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 14072, "upload_time": "2014-07-04T19:41:44", "url": "https://files.pythonhosted.org/packages/79/11/49b19e3faffbe254641bfa5e1806bde60ce4c657888370f2ce9b09ab7aa3/marrow.schema-1.0.1-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "3bd44bc6901ca69200560b6adc952f0b", "sha256": "27f5b494202d1562ad6b951f1ad506e37a44d018c1a6b59af18db05e37d35fde" }, "downloads": -1, "filename": "marrow.schema-1.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3bd44bc6901ca69200560b6adc952f0b", "packagetype": "bdist_wheel", "python_version": "2.6", "requires_python": null, "size": 13203, "upload_time": "2014-07-04T19:41:38", "url": "https://files.pythonhosted.org/packages/9a/a6/16444b42d455c59bbbd6617a9a3dcbe08c92533677df79b8bf7ba54fb867/marrow.schema-1.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b4dfbc16f89c11d5743d7f13bab8ddb6", "sha256": "90aa2a04b2178718f7bb28bab3306dbf53d5f51803834acbf9722d3292354e95" }, "downloads": -1, "filename": "marrow.schema-1.0.1-py3.2.egg", "has_sig": false, "md5_digest": "b4dfbc16f89c11d5743d7f13bab8ddb6", "packagetype": "bdist_egg", "python_version": "3.2", "requires_python": null, "size": 14470, "upload_time": "2014-07-04T19:41:50", "url": "https://files.pythonhosted.org/packages/72/5a/8db4f1f5a7bbfd74df02c373febe748e3feeac490e855ac8c922d2b28c11/marrow.schema-1.0.1-py3.2.egg" }, { "comment_text": "", "digests": { "md5": "25426cd0bc8498d1e0a1db4bd85437ad", "sha256": "f189f45ea23dbf6361b7e5f5a58dffac78c3004f91a41a7aaec5c9ef53aa9cec" }, "downloads": -1, "filename": "marrow.schema-1.0.1-py3.3.egg", "has_sig": false, "md5_digest": "25426cd0bc8498d1e0a1db4bd85437ad", "packagetype": "bdist_egg", "python_version": "3.3", "requires_python": null, "size": 14734, "upload_time": "2014-07-04T19:41:57", "url": "https://files.pythonhosted.org/packages/ca/42/cf7177f5181f2c1f39759f255c221b428102373720a2c88a8227a8bcd903/marrow.schema-1.0.1-py3.3.egg" }, { "comment_text": "", "digests": { "md5": "81a62d5dd27acd321902f6aabcbe9ea9", "sha256": "0d83610c728bbbb3e8b1bf5c523ef513cefd36412b44b22917fe736e5ecd6efb" }, "downloads": -1, "filename": "marrow.schema-1.0.1-py3.4.egg", "has_sig": false, "md5_digest": "81a62d5dd27acd321902f6aabcbe9ea9", "packagetype": "bdist_egg", "python_version": "3.4", "requires_python": null, "size": 14564, "upload_time": "2014-07-04T19:42:30", "url": "https://files.pythonhosted.org/packages/ca/2b/14335760853aa2c0adf5865ab94b4141779d57eec6d4c9a7dc2e1b46cee1/marrow.schema-1.0.1-py3.4.egg" }, { "comment_text": "", "digests": { "md5": "36f164bcd67c7d4d59f9ec093e99ba7e", "sha256": "7312f67c6d7f67552dd0d72857da4e28f8ca9444ed3a3e534209b3254ffa4e9b" }, "downloads": -1, "filename": "marrow.schema-1.0.1.tar.gz", "has_sig": false, "md5_digest": "36f164bcd67c7d4d59f9ec093e99ba7e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10292, "upload_time": "2014-07-04T19:41:32", "url": "https://files.pythonhosted.org/packages/0b/34/76f8146e6803596be43e84163cc88708869e5679b2a1bb2e6a6214ffe25a/marrow.schema-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "51e0a46f452e9b96f425eaf13bf13c00", "sha256": "6b82f5287151f4e1cc1eb338a312fb7f39b896a66be80071c04fc6ebdad1b91d" }, "downloads": -1, "filename": "marrow.schema-1.0.2-py2.6.egg", "has_sig": false, "md5_digest": "51e0a46f452e9b96f425eaf13bf13c00", "packagetype": "bdist_egg", "python_version": "2.6", "requires_python": null, "size": 20606, "upload_time": "2014-07-10T14:59:21", "url": "https://files.pythonhosted.org/packages/84/3c/815c9524756337a3a87332be2d596efd5b69173da5e88468c9698841235b/marrow.schema-1.0.2-py2.6.egg" }, { "comment_text": "", "digests": { "md5": "74dcb3e46a97594e2e419caa3040eb1a", "sha256": "ec42b82571dc1b7584ef3f4b6d7f36ee1600bede70e2cd7eabe9069e414a045d" }, "downloads": -1, "filename": "marrow.schema-1.0.2-py2.7.egg", "has_sig": false, "md5_digest": "74dcb3e46a97594e2e419caa3040eb1a", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 20540, "upload_time": "2014-07-10T14:59:30", "url": "https://files.pythonhosted.org/packages/2a/f2/f59955951b6436d95d6c81786e4065f94673f6e86a9d0c370b936c88f64e/marrow.schema-1.0.2-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "1c9c2c188c40cb862358abd8c2b4d7b2", "sha256": "f991b3e25b602d99ad08d9801f6dfcb0b529fda7484e974b68304d8c9e99f707" }, "downloads": -1, "filename": "marrow.schema-1.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "1c9c2c188c40cb862358abd8c2b4d7b2", "packagetype": "bdist_wheel", "python_version": "2.6", "requires_python": null, "size": 16261, "upload_time": "2014-07-10T14:59:24", "url": "https://files.pythonhosted.org/packages/7b/7f/a7caf52dcabcbd54a3ba0f8a169b7d0e1794da5b5373ff890c177a2c1009/marrow.schema-1.0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3818ee7c0922e0e0b112ec7c9f5c8245", "sha256": "dc70d5bd70e4b46b1c38754087f327591737e5d4c5893955d0f7463c419e8e59" }, "downloads": -1, "filename": "marrow.schema-1.0.2-py3.2.egg", "has_sig": false, "md5_digest": "3818ee7c0922e0e0b112ec7c9f5c8245", "packagetype": "bdist_egg", "python_version": "3.2", "requires_python": null, "size": 21157, "upload_time": "2014-07-10T14:59:36", "url": "https://files.pythonhosted.org/packages/ad/33/2117f04835fec071956fc3d452008e0c1b6cf09b5d05e21a618dea0f8c58/marrow.schema-1.0.2-py3.2.egg" }, { "comment_text": "", "digests": { "md5": "65690f2b78ba1b9fb1e8ae0a2efb5df0", "sha256": "c4c861ce6a3b11b63ebf5144449b3e606a361c2fea00f1e83c9ddea7de1db9eb" }, "downloads": -1, "filename": "marrow.schema-1.0.2-py3.3.egg", "has_sig": false, "md5_digest": "65690f2b78ba1b9fb1e8ae0a2efb5df0", "packagetype": "bdist_egg", "python_version": "3.3", "requires_python": null, "size": 21511, "upload_time": "2014-07-10T14:59:42", "url": "https://files.pythonhosted.org/packages/40/90/35b39670be6cd152f16e53fd9a8529a3971e8a1e031d6e1b2e8fca0026c7/marrow.schema-1.0.2-py3.3.egg" }, { "comment_text": "", "digests": { "md5": "4fa4da91f9fb33b3e5cdbb1aa891f58d", "sha256": "147416886c6026d4910da681149516d01449374741a3642ca82ff430bcab9d92" }, "downloads": -1, "filename": "marrow.schema-1.0.2-py3.4.egg", "has_sig": false, "md5_digest": "4fa4da91f9fb33b3e5cdbb1aa891f58d", "packagetype": "bdist_egg", "python_version": "3.4", "requires_python": null, "size": 21287, "upload_time": "2014-07-10T14:59:49", "url": "https://files.pythonhosted.org/packages/00/e5/a47890d3636d331eab9dc46ca4649e052cc747f296954a96ed12f82db62c/marrow.schema-1.0.2-py3.4.egg" }, { "comment_text": "", "digests": { "md5": "5e786c3fb09d59c778cba832ab7556f8", "sha256": "bd438696f90a12d20f91d8ff8924ba0a87c69f072d90134efca3e39c4a7e1570" }, "downloads": -1, "filename": "marrow.schema-1.0.2.tar.gz", "has_sig": false, "md5_digest": "5e786c3fb09d59c778cba832ab7556f8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12298, "upload_time": "2014-07-10T14:59:19", "url": "https://files.pythonhosted.org/packages/fc/6e/89dd1828365630911412c76b0977430d5ec0c97a517883b9ea7fd5546dc5/marrow.schema-1.0.2.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "e9e2aca737acd85724ed02314346120b", "sha256": "1ca2061d0b523356b7aac3121a3ca9afce37c3fa0c151874a14227fa4cdfedfb" }, "downloads": -1, "filename": "marrow.schema-1.1.0-py2.6.egg", "has_sig": false, "md5_digest": "e9e2aca737acd85724ed02314346120b", "packagetype": "bdist_egg", "python_version": "2.6", "requires_python": null, "size": 74244, "upload_time": "2014-10-21T07:00:49", "url": "https://files.pythonhosted.org/packages/29/72/dd4b17178b3fdfc20bb606abf8328b609154491f9e5f9667ecd5a765480c/marrow.schema-1.1.0-py2.6.egg" }, { "comment_text": "", "digests": { "md5": "f4be186d2989c0c6f6976ecf6b3dec56", "sha256": "80355b21f53b3445016d9898785cbd6581999404a0b619b4e97fca582d4ace19" }, "downloads": -1, "filename": "marrow.schema-1.1.0-py2.7.egg", "has_sig": false, "md5_digest": "f4be186d2989c0c6f6976ecf6b3dec56", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 74168, "upload_time": "2014-10-21T07:00:58", "url": "https://files.pythonhosted.org/packages/82/cb/25aefd9bd11367d5b2c317a2b03f46ad7e8db2512ad0f46ac489c64ec501/marrow.schema-1.1.0-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "0c06797176d3a4ce6fac5a8c60397ef6", "sha256": "aa76b9ed4f768985967b00e6fe6e2090e57b79f9cf8f0b79ee743282b21d89db" }, "downloads": -1, "filename": "marrow.schema-1.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "0c06797176d3a4ce6fac5a8c60397ef6", "packagetype": "bdist_wheel", "python_version": "2.6", "requires_python": null, "size": 45321, "upload_time": "2014-10-21T07:00:51", "url": "https://files.pythonhosted.org/packages/6c/4a/e2c669eb7dd351cb149491c70c19b0cb86caa8ffff6c61de39d6daaef5b0/marrow.schema-1.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "957c9f788adb25588718420d2d550959", "sha256": "f72c457f2f2f55c59c70d372b7c86eff31f166dbec617bdac875287a617200b7" }, "downloads": -1, "filename": "marrow.schema-1.1.0-py3.4.egg", "has_sig": false, "md5_digest": "957c9f788adb25588718420d2d550959", "packagetype": "bdist_egg", "python_version": "3.4", "requires_python": null, "size": 76785, "upload_time": "2014-10-21T07:01:06", "url": "https://files.pythonhosted.org/packages/1a/0c/ce582a7774db7edd5f5df378de2a72c84fae122320fa1a7eb062097978ff/marrow.schema-1.1.0-py3.4.egg" }, { "comment_text": "", "digests": { "md5": "49e3fc354c7d84328b904e1f81e1e219", "sha256": "5529dadd62608f2b63b9cdfcd5905b17b1ea1e739050fd04f3cbae04eb2bc785" }, "downloads": -1, "filename": "marrow.schema-1.1.0.tar.gz", "has_sig": false, "md5_digest": "49e3fc354c7d84328b904e1f81e1e219", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40049, "upload_time": "2014-10-21T07:00:46", "url": "https://files.pythonhosted.org/packages/f1/59/12bd7651fc0ef4042977a33299eb6cbefc496c1a641b75663721f96d1c4e/marrow.schema-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "c5d2bfa96d1a095b49b4f759865c3fa7", "sha256": "933b13797ad2d22c109e08a85152d71d5470cdc9fdb526529249dbba80695b16" }, "downloads": -1, "filename": "marrow.schema-1.1.1-py2.6.egg", "has_sig": false, "md5_digest": "c5d2bfa96d1a095b49b4f759865c3fa7", "packagetype": "bdist_egg", "python_version": "2.6", "requires_python": null, "size": 75300, "upload_time": "2014-11-14T17:12:42", "url": "https://files.pythonhosted.org/packages/c2/72/7d0a13694a90cc38a86cfd454f6de55fc20c40ea77c1452d9bd4084ed3e0/marrow.schema-1.1.1-py2.6.egg" }, { "comment_text": "", "digests": { "md5": "bfd2ff88e09f842f5bcb1af6d34c1222", "sha256": "d18d7cff4a4cba7627b32ab854a0d23d783ae2510ae2ed6552949dc3421e8e97" }, "downloads": -1, "filename": "marrow.schema-1.1.1-py2.7.egg", "has_sig": false, "md5_digest": "bfd2ff88e09f842f5bcb1af6d34c1222", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 75220, "upload_time": "2014-11-14T17:12:51", "url": "https://files.pythonhosted.org/packages/21/5c/1a6fc259f2a3d9f604c6976616f27ebbd90ecd5a9111d3ca032d62edc4c8/marrow.schema-1.1.1-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "ba12ff40955a30ed04f2241fff678770", "sha256": "b83d0e2e0e0a633abd32d0e53b5c681dd752d1cd5fbf06e81b555adf5dd7915b" }, "downloads": -1, "filename": "marrow.schema-1.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "ba12ff40955a30ed04f2241fff678770", "packagetype": "bdist_wheel", "python_version": "2.6", "requires_python": null, "size": 47496, "upload_time": "2014-11-14T17:12:45", "url": "https://files.pythonhosted.org/packages/f2/be/1bdb14799df7be5c655177fcf79bf4c1819247a9411a251ec5f597314a9a/marrow.schema-1.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "75c16def3f1d2bbdbaf75153ce6b9e41", "sha256": "1b4f8482d4f4137327c597d8563e1ef0ce61b69e74081818de6e25760509db06" }, "downloads": -1, "filename": "marrow.schema-1.1.1-py3.2.egg", "has_sig": false, "md5_digest": "75c16def3f1d2bbdbaf75153ce6b9e41", "packagetype": "bdist_egg", "python_version": "3.2", "requires_python": null, "size": 76783, "upload_time": "2014-11-14T17:12:57", "url": "https://files.pythonhosted.org/packages/ca/90/c510ce72d90a5deecd4528aea2bf84408e001fd6598afb52a94d35d427d0/marrow.schema-1.1.1-py3.2.egg" }, { "comment_text": "", "digests": { "md5": "ac6470d3d1c469a575299445a3d3154c", "sha256": "33f8e301998ab17ed918f8e560a02c6dbf3389bf342f407c76c8e9c0676048a3" }, "downloads": -1, "filename": "marrow.schema-1.1.1-py3.3.egg", "has_sig": false, "md5_digest": "ac6470d3d1c469a575299445a3d3154c", "packagetype": "bdist_egg", "python_version": "3.3", "requires_python": null, "size": 78688, "upload_time": "2014-11-14T17:13:05", "url": "https://files.pythonhosted.org/packages/8f/81/0351791feeba8315608d9c0d157b8d52fa16c7ef24cbd999ce8eee82a025/marrow.schema-1.1.1-py3.3.egg" }, { "comment_text": "", "digests": { "md5": "96387ef6a18dee74a1abc18d386a55e4", "sha256": "922c97ab2f997b2efae714a9c766952aeb2e2c31bcf9e78541ef4ed0f688fc79" }, "downloads": -1, "filename": "marrow.schema-1.1.1-py3.4.egg", "has_sig": false, "md5_digest": "96387ef6a18dee74a1abc18d386a55e4", "packagetype": "bdist_egg", "python_version": "3.4", "requires_python": null, "size": 77847, "upload_time": "2014-11-14T17:13:12", "url": "https://files.pythonhosted.org/packages/9e/dc/62851a62c797a19ebfa8de4f4add9fed6ea4e0016972f16c88c44055c6d8/marrow.schema-1.1.1-py3.4.egg" }, { "comment_text": "", "digests": { "md5": "6f87c96ec7536b6871723701f16b0ea3", "sha256": "59281438d9e44326a2d5a9ee19836ec3a9a791273efc5c1b7189225b20a85212" }, "downloads": -1, "filename": "marrow.schema-1.1.1.tar.gz", "has_sig": false, "md5_digest": "6f87c96ec7536b6871723701f16b0ea3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 42730, "upload_time": "2014-11-14T17:12:40", "url": "https://files.pythonhosted.org/packages/a3/0c/39d2c172c1acafa44a383d3831dd556ef001d018ac2c23993d4acf44ce47/marrow.schema-1.1.1.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "e3ec9958e3347821d34e74e1b3ab86eb", "sha256": "97f2485fdee1b5e72a1ece126d6805a59fb961d89ddee2f4e673a5e8ae82bd9e" }, "downloads": -1, "filename": "marrow.schema-1.2.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e3ec9958e3347821d34e74e1b3ab86eb", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 62219, "upload_time": "2016-02-24T04:19:09", "url": "https://files.pythonhosted.org/packages/0a/f5/a1399eebd42899199ce5c3feea1cb7b4b3c38327d17d53e0d3e947624716/marrow.schema-1.2.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e0fc30dfde87b867f884e0b5fa9a4ced", "sha256": "50401d923ffdf78b1ade25617301f3de6e4e8c407428c897ba3e71e94d4b058a" }, "downloads": -1, "filename": "marrow.schema-1.2.0.tar.gz", "has_sig": false, "md5_digest": "e0fc30dfde87b867f884e0b5fa9a4ced", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 55341, "upload_time": "2016-02-24T04:19:04", "url": "https://files.pythonhosted.org/packages/73/34/47117fac127a006aa702ff2af6f1ee53d055b0b66bb442cf5651532fab4e/marrow.schema-1.2.0.tar.gz" } ], "2.0.0": [ { "comment_text": "", "digests": { "md5": "56affb91c60b66f27e9c8eae4348114f", "sha256": "dd38ca033266f39bc8ba9e8da5e5c61cd4e3d69f9eb6f33e5aa7a23d20c11fda" }, "downloads": -1, "filename": "marrow.schema-2.0.0-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "56affb91c60b66f27e9c8eae4348114f", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 78437, "upload_time": "2019-01-21T21:11:40", "url": "https://files.pythonhosted.org/packages/51/7a/c2646296a7372efb08103bc3eb316296d2fed4270c7cd198f688363f16ae/marrow.schema-2.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "012bfff52d8bc7f8a7e2201cd3085dfd", "sha256": "42b4c11180f2cc95319f8706f28b095e110834562e44021ce2f6af53eea967ee" }, "downloads": -1, "filename": "marrow.schema-2.0.0.tar.gz", "has_sig": true, "md5_digest": "012bfff52d8bc7f8a7e2201cd3085dfd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 56002, "upload_time": "2019-01-21T21:11:42", "url": "https://files.pythonhosted.org/packages/1f/b1/c2b5959b16464ca10bc2e9fbfa6bc6790d020bfe0d12d6548384eec97952/marrow.schema-2.0.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "56affb91c60b66f27e9c8eae4348114f", "sha256": "dd38ca033266f39bc8ba9e8da5e5c61cd4e3d69f9eb6f33e5aa7a23d20c11fda" }, "downloads": -1, "filename": "marrow.schema-2.0.0-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "56affb91c60b66f27e9c8eae4348114f", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 78437, "upload_time": "2019-01-21T21:11:40", "url": "https://files.pythonhosted.org/packages/51/7a/c2646296a7372efb08103bc3eb316296d2fed4270c7cd198f688363f16ae/marrow.schema-2.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "012bfff52d8bc7f8a7e2201cd3085dfd", "sha256": "42b4c11180f2cc95319f8706f28b095e110834562e44021ce2f6af53eea967ee" }, "downloads": -1, "filename": "marrow.schema-2.0.0.tar.gz", "has_sig": true, "md5_digest": "012bfff52d8bc7f8a7e2201cd3085dfd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 56002, "upload_time": "2019-01-21T21:11:42", "url": "https://files.pythonhosted.org/packages/1f/b1/c2b5959b16464ca10bc2e9fbfa6bc6790d020bfe0d12d6548384eec97952/marrow.schema-2.0.0.tar.gz" } ] }