{ "info": { "author": "Lele Gaifax", "author_email": "lele@metapensiero.it", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Framework :: Sphinx :: Extension", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Natural Language :: English", "Natural Language :: Italian", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Database", "Topic :: Utilities" ], "description": ".. -*- coding: utf-8 -*-\n.. :Project: PatchDB\n.. :Created: Sat Aug 22 16:19:15 2009 +0000\n.. :Author: Lele Gaifax \n.. :License: GNU General Public License version 3 or later\n.. :Copyright: \u00a9 2009, 2010, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Lele Gaifax\n..\n\n=============================\n metapensiero.sphinx.patchdb\n=============================\n\nCollects and applies scripts embedded in a reST document\n========================================================\n\n:version: 2.0\n:author: Lele Gaifax \n:license: GPLv3\n\nBuilding and maintaining the schema of a database is always a challenge. It may quickly become\na nightmare when dealing with even moderately complex databases, in a distribuited development\nenvironment. You have new features going in, and fixes here and there, that keeps accumulating\nin the development `branch`. You also have several already deployed instances of the database\nyou wanna upgrade now and then.\n\nIn my experience, it's very difficult to impossible to come up with a completely automated\nsolution, for several reasons:\n\n* comparison between different releases of a database schema is tricky\n\n* actual contents of the database must be preserved\n\n* some changes require specific recipes to upgrade the data\n\n* any automated solution hides some detail, by definition: I need complete control, to be able\n to create temporary tables and/or procedures for example\n\nI tried, and wrote myself, several different approaches to the problem\\ [*]_, and this package\nis my latest and most satisfying effort: it builds on top of `docutils`_ and `Sphinx`_, with\nthe side advantage that you get a quite nice and good documentation of the whole architecture:\n`literate database scheming`!\n\n.. _docutils: http://docutils.sourceforge.net/\n.. _sphinx: http://sphinx.pocoo.org/intro.html\n\n\n.. contents::\n\n.. [*] Just to mention a few alternatives:\n\n `Alembic `_\n Written on top of SQLAlchemy_ by the same author: it does not help when you need to\n manage something outside SA knowledge (stored procedures, permissions, \u2026)\n\n `Sqlibrist `_\n Some similarities with PatchDB, very young, Django integration.\n\n `Sqitch `_\n Quite good, *although* Perl based\u2026\n\n See the `schema migration `_ page on\n Wikipedia for further details.\n\n----\n\nHow it works\n------------\n\nThe package contains two distinct pieces: a `Sphinx`_ extension and the ``patchdb`` command\nline tool.\n\nThe extension implements a new `ReST` directive able to embed a `script` in the document: when\nprocessed by the ``sphinx-build`` tool, all the scripts will be collected in an external file,\nconfigurable.\n\nThe ``patchdb`` tool takes that script collection and determines which scripts need to be\napplied to some database, and the right order.\n\nIt creates and maintains a single very simple table within the database (unsurprisingly named\n``patchdb``), where it records the last version of each script it successfully execute, so that\nit won't reexecute the same script (actually, a particular `revision` of it) twice.\n\nSo, on the development side you simply write (and document!) each piece, and when it comes the\ntime of deploying current state you distribute just the script collection (a single file,\nusually in `AXON`_, `JSON`_ or `YAML`_ format, or a ``pickle`` archive, see `storage formats`_\nbelow) to the end points where the database instances live, and execute ``patchdb`` against\neach one.\n\n.. _yaml: http://yaml.org/\n.. _json: http://json.org/\n.. _axon: http://intellimath.bitbucket.org/axon/\n\n\nScripts\n~~~~~~~\n\nThe basic building block is a `script`, an arbitrary sequence of statements written in some\nlanguage (currently, either ``Python``, ``SQL`` or ``Shell``), augmented with some metadata\nsuch as the `scriptid`, possibly a longer `description`, its `revision` and so on.\n\nAs a complete example of the syntax, consider the following::\n\n .. patchdb:script:: My first script\n :description: Full example of a script\n :revision: 2\n :depends: Other script@4\n :preceeds: Yet another\n :language: python\n :conditions: python_2_x\n\n print \"Yeah!\"\n\nThis will introduce a script globally identified by `My first script`, written in ``Python``:\nthis is its second release, and its execution must be constrained such that it happens\n**after** the execution of the fourth revision of `Other script` and **before** `Yet another`.\n\nThe sequence of statements may be specified either as the *content* of the directive **or**\nloaded from an external file, so the previous script could be written as::\n\n .. patchdb:script:: My first script\n :description: Full example of a script\n :revision: 2\n :depends: Other script@4\n :preceeds: Yet another\n :language: python\n :conditions: python_2_x\n :file: python_script.py\n\n``SQL`` scripts may be composed by multiple statements, separated by a standalone ``;;``\nmarker, as in::\n\n .. patchdb:script:: Create and populate\n\n CREATE TABLE foo (id integer, value varchar(20))\n ;;\n INSERT INTO foo (id, value) VALUES (1, 'bar')\n\nAnother special marker is ``;;INCLUDE:``, that can be used to include the content of an\nexternal file, more flexibly than with the ``file`` option above. The previous example could be\nwritten as::\n\n .. patchdb:script:: Create and populate\n\n ;;INCLUDE: create_table.sql\n ;;\n ;;INCLUDE: populate_table.sql\n\nwhere the two statements are loaded respectively from ``create_table.sql`` and\n``populate_table.sql``. The ``;;INCLUDE:`` marker is expanded recursively, so that another way\nto say the very same thing is::\n\n .. patchdb:script:: Create and populate\n\n ;;INCLUDE: create_and_populate.sql\n\nwith ``create_and_populate.sql`` containing::\n\n ;;INCLUDE: create_table.sql\n ;;\n ;;INCLUDE: populate_table.sql\n\nAs another concrete example where this can be very useful, consider the case when you need to\nreplace an existing function with one having a different signature for the output parameters,\nsomething that for example PostgreSQL does not allow. You could then say::\n\n .. patchdb:script:: Some function\n :revision: 2\n :file: some_function.sql\n\n .. patchdb:script:: Upgrade some function to revision 2\n :depends: Some function@1\n :brings: Some function@2\n\n DROP FUNCTION some_function(int, OUT int)\n ;;\n ;;INCLUDE: some_function.sql\n\n\nConditions\n++++++++++\n\nThe example shows also an usage of the conditions, allowing more than one variant of a script\nlike::\n\n .. patchdb:script:: My first script (py3)\n :description: Full example of a script\n :revision: 2\n :depends: Other script@4\n :preceeds: Yet another\n :language: python\n :conditions: python_3_x\n\n print(\"Yeah!\")\n\nThe value of the ``:conditions:`` option may be a single paragraph, containing a comma\nseparated list of conditions, or alternatively a `bullet list`_.\n\n.. _bullet list:\n http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#bullet-lists\n\nAs another use case of this feature, the following snippet declares the same table for two\ndifferent databases::\n\n .. patchdb:script:: Simple table (PostgreSQL)\n :language: sql\n :mimetype: text/x-postgresql\n :conditions: postgres\n :file: postgresql/simple.sql\n\n .. patchdb:script:: Simple table (MySQL)\n :language: sql\n :mimetype: text/x-mysql\n :conditions: mysql\n :file: mysql/simple.sql\n\nAs you can see, the content of the script can be conveniently stored in an external file, and\nthe particular dialect specified with the ``:mimetype:`` option, so it will be properly\nhighlighted by Pygments.\n\nSuch conditions may also be arbitrarily defined on the command line, so you can have for\nexample::\n\n .. patchdb:script:: Configure for production\n :language: sql\n :conditions: PRODUCTION\n\n UPDATE configuration SET is_production = true\n\nand then add the option ``--assert PRODUCTION`` when it is the case.\n\nA condition can be `negated`, prepending a ``!`` to its name::\n\n .. patchdb:script:: Configure for production\n :language: sql\n :conditions: !PRODUCTION\n\n UPDATE configuration SET is_production = false\n\n\nVariables\n+++++++++\n\nAnother way to influence a script effect is by using *variables*: a script may contain one or\nmore references to arbitrary variables using the syntax ``{{VARNAME}}``, that **must** be\ndefined at application time, using the ``--define VARNAME=VALUE`` command line option.\nAlternatively with the syntax ``{{name=default}}`` the reference can set the default value for\nthe variable, that can be overridden from the command line.\n\nAs an example, you can have the following script::\n\n .. patchdb:script:: Create table and give read-only rights to the web user\n :language: sql\n\n CREATE TABLE foo (id INTEGER)\n ;;\n GRANT SELECT ON TABLE foo TO {{WEB=www}}\n ;;\n GRANT ALL ON TABLE foo TO {{ADMIN}}\n\nTo apply it, you must specify the value for the ``ADMIN`` variable, with something like\n``--define ADMIN=$USER``.\n\nThe variable name must be an *identifier* (that is, at least an alphabetic letter possibly\nfollowed by alphanumerics or underscores), while its value may contain whitespaces, letters or\ndigits.\n\nIf the name starts with ``ENV_``, the value is looked up in the process `environment`. In the\nfollowing example, the name of the user is taken from the the ``USER`` environment variable\n(that must be present), while the password comes from the ``PASSWORD`` environment entry or, if\nnot set, from the specified default::\n\n .. patchdb:script:: Insert a default user name\n :language: sql\n\n INSERT INTO users (name, password) VALUES ('{{ENV_USER}}', '{{ENV_PASSWORD=password}}')\n\nNote that you can override the environment using an explicit ``--define`` option on the command\nline, for example with ``--define ENV_PASSWORD=foobar``.\n\n\nDependencies\n++++++++++++\n\n.. _master-table:\n\nThe dependencies (that is, the *options* ``:brings:``, ``:depends:``, ``:drops::`` and\n``:preceeds:``) may be a paragraph containing a comma separated list of script ids, such as::\n\n .. patchdb:script:: Create master table\n\n CREATE TABLE some_table (id INTEGER PRIMARY KEY, tt_id INTEGER)\n\n .. patchdb:script:: Create target table\n\n CREATE TABLE target_table (id INTEGER PRIMARY KEY)\n\n .. patchdb:script:: Add foreign key to some_table\n :depends: Create master table, Create target table\n\n ALTER TABLE some_table\n ADD CONSTRAINT fk_master_target\n FOREIGN KEY (tt_id) REFERENCES target_table (id)\n\n.. warning:: This implies that the referenced ``scriptid``\\ s **cannot** include a comma.\n\nAlternatively, they can be entered as a `bullet list`_, so the last script above can be written\nalso as::\n\n .. patchdb:script:: Add foreign key to some_table\n :depends:\n - Create master table\n - Create target table\n\n ALTER TABLE some_table\n ADD CONSTRAINT fk_master_target\n FOREIGN KEY (tt_id) REFERENCES target_table (id)\n\nWith this syntax you can reference a ``scriptid`` containing a comma.\n\nIndependently from the order these scripts appear in the documentation, the third script will\nexecute only after the first two are successfully applied to the database. As you can notice,\nmost of the options are optional: by default, ``:language:`` is ``sql``, ``:revision:`` is\n``1``, the ``:description:`` is taken from the title (that is, the script ID), while\n``:depends:`` and ``:preceeds:`` are empty.\n\nJust for illustration purposes, the same effect could be achieved with::\n\n .. patchdb:script:: Create master table\n :preceeds: Add foreign key to some_table\n\n CREATE TABLE some_table (id INTEGER PRIMARY KEY, tt_id INTEGER)\n\n .. patchdb:script:: Create target table\n\n CREATE TABLE target_table (id INTEGER PRIMARY KEY)\n\n .. patchdb:script:: Add foreign key to some_table\n :depends: Create target table\n\n ALTER TABLE some_table\n ADD CONSTRAINT fk_master_target\n FOREIGN KEY (tt_id) REFERENCES target_table (id)\n\n\nErrors handling\n+++++++++++++++\n\nBy default ``patchdb`` stops when it fails to apply one script. Some time you may want to relax\nthat rule, for example when operating on a database that was created with other methods so you\ncannot relay on the existence of a specific script to make the decision. In such cases, the\noption ``:onerror:`` may be used::\n\n .. patchdb:script:: Remove obsoleted tables and functions\n :onerror: ignore\n\n DROP TABLE foo\n ;;\n DROP FUNCTION initialize_record_foo()\n\nWhen ``:onerror:`` is set to `ignore`, each statement in the script is executed and if an error\noccurs it is ignored and ``patchdb`` proceeds with the next one. On good databases like\nPostgreSQL and SQLite where even DDL statements are transactional, each statement is executed\nin a nested subtransaction, so subsequent errors do not ruin the effect of correctly applied\nprevious statements.\n\nAnother possible setting of this option is `skip`: in this case, whenever an error occurs the\neffect of the whole script is undone and it is considered as applied. For example, assuming\nthat the old version of ``SomeProcedure`` accepted a single argument and the new one requires\ntwo of them, you could do something like the following::\n\n .. patchdb:script:: Fix stored procedure signature\n :onerror: skip\n\n SELECT somecol FROM SomeProcedure(NULL, NULL)\n ;;\n ALTER PROCEDURE SomeProcedure(p_first INTEGER, p_second INTEGER)\n RETURNS (somecol INTEGER) AS\n BEGIN\n somecol = p_first * p_second;\n SUSPEND;\n END\n\n\nPatches\n~~~~~~~\n\nA `patch` is a particular flavour of script, one that specifies a `brings` or a `drops`\ndependency list. Imagine that the `example above`__ was the first version of the database, and\nthat the current version looks like the following::\n\n .. patchdb:script:: Create master table\n :revision: 2\n\n CREATE TABLE some_table (\n id INTEGER PRIMARY KEY,\n description VARCHAR(80),\n tt_id INTEGER\n )\n\nthat is, ``some_table`` now contains one more field, ``description``.\n\nWe need an upgrade path from the first revision of the table to the second::\n\n .. patchdb:script:: Add a description to the master table\n :depends: Create master table@1\n :brings: Create master table@2\n\n ALTER TABLE some_table ADD COLUMN description VARCHAR(80)\n\nWhen ``patchdb`` examines the database status, it will execute one *or* the other. If the\nscript `Create master table` isn't executed yet (for example when operating on a new database),\nit will take the former script (the one that creates the table from scratch). Otherwise, if\nthe database \"contains\" revision 1 (and not higher than 1) of the script, it will execute the\nlatter, bumping up the revision number.\n\n__ master-table_\n\n\nObsoleted patches\n+++++++++++++++++\n\nAnother peculiarity of this kind of scripts is that they may references `non existing scripts`\nwithout producing warnings or errors.\n\nThe rationale is that in the database evolution a given script may be removed, possibly\nreplaced by a different one by some succeeding patch. Consider the case when you once had a\ntable called ``customers``::\n\n .. patchdb:script:: Create table customers\n :revision: 2\n\n CREATE TABLE customers (\n id SERIAL PRIMARY KEY,\n name VARCHAR(80),\n street_address VARCHAR(80),\n city VARCHAR(80),\n telephone_number VARCHAR(80)\n )\n\n .. patchdb:script:: Add telephone number to customers table\n :depends: Create table customers@1\n :brings: Create table customers@2\n\n ALTER TABLE customers ADD COLUMN telephone_number VARCHAR(80)\n\nand then the need for multiple addresses arose thus you decided to split it in two distinct\nrelations, a ``persons`` and a ``person_addresses``::\n\n .. patchdb:script:: Create table persons\n\n CREATE TABLE persons (\n id SERIAL PRIMARY KEY,\n name VARCHAR(80)\n )\n\n .. patchdb:script:: Create table person_addresses\n :depends: Create table persons\n\n CREATE TABLE person_addresses (\n id SERIAL PRIMARY KEY,\n person_id INTEGER REFERENCES persons (id),\n street_address VARCHAR(80),\n city VARCHAR(80),\n telephone_number VARCHAR(80)\n )\n\n .. patchdb:script:: Migrate from customers to persons and person_addresses\n :depends:\n - Create table customers@2\n - Create table persons\n - Create table person_addresses\n :drops:\n - Create table customers\n - Add telephone number to customers table\n\n INSERT INTO persons (id, name) SELECT id, name FROM customers\n ;;\n INSERT INTO person_addresses (person_id, street_address, city, telephone_number)\n SELECT id, street_address, city, telephone_number\n FROM customers\n ;;\n DROP TABLE customers\n\nAt that point the script that introduced the original ``customers`` table disappeared from the\ndocumentation, but you most probably want to keep the migration patch around for a while, at\nleast until you are sure all your production databases got upgraded.\n\n.. hint:: In the HTML output, missing dependencies such as the ``\"Create table customers\"``\n above are marked with a ``strike`` class. In order to actually get a visual effect\n you need to define the ``CSS`` style for that, for example putting the following in\n the Sphinx configuration::\n\n html_context = {\n 'css_files': [\n '_static/theme_overrides.css',\n ],\n }\n\n and something like\n\n ::\n\n span.strike {\n text-decoration: line-through;\n }\n\n in ``_static/theme_overrides.css``.\n\n\nRun-always scripts\n~~~~~~~~~~~~~~~~~~\n\nYet another variant of scripts, which get applied always, **every time** ``patchdb`` is\nexecuted. This kind may be used to perform arbitrary operations, either at the start or at the\nend of the ``patchdb`` session::\n\n .. patchdb:script:: Say hello\n :language: python\n :always: first\n\n print(\"Hello!\")\n\n .. patchdb:script:: Say goodbye\n :language: python\n :always: last\n\n print(\"Goodbye!\")\n\n\nFake data domains\n+++++++++++++++++\n\nAs a special case that uses this kind of script, the following example illustrate an\n`approximation` of the `data domains` with MySQL, that lacks them::\n\n .. patchdb:script:: Define data domains (MySQL)\n :language: sql\n :mimetype: text/x-mysql\n :conditions: mysql\n :always: first\n\n CREATE DOMAIN bigint_t bigint\n ;;\n CREATE DOMAIN `Boolean_t` char(1)\n\n .. patchdb:script:: Create some table (MySQL)\n :language: sql\n :mimetype: text/x-mysql\n :conditions: mysql\n :always: first\n\n CREATE TABLE `some_table` (\n `ID` bigint_t NOT NULL,\n , `FLAG` `Boolean_t`\n\n , PRIMARY KEY (`ID`)\n )\n\n.. warning:: This is just a dirty hack, based on relatively simple search and replace: don't\n take it seriously, use a better database if you really need `data domains`!\n\n.. note:: This works also with SQLite.\n\n\nPlaceholders\n~~~~~~~~~~~~\n\nAnother feature is that the definition of the database, that is the collection of the scripts\nthat actually define its schema, may be splitted on multiple Sphinx environments: the use case\nis when you have a complex application, composed by multiple modules, each of them requiring\nits own set of DB objects.\n\nA script is considered a `placeholder` when it has an empty body: it won't be ever applied, but\ninstead its presence in the database will be asserted. In this way, one Sphinx environment\ncould contain the following script::\n\n .. patchdb:script:: Create table a\n\n CREATE TABLE a (\n id INTEGER NOT NULL PRIMARY KEY\n , value INTEGER\n )\n\nand another documentation set could extend that with::\n\n .. patchdb:script:: Create table a\n :description: Place holder\n\n .. patchdb:script:: Create unique index on value\n :depends: Create table a\n\n CREATE UNIQUE INDEX on_value ON a (value)\n\nThe second set can be applied **only** after the former one is.\n\n\nUsage\n-----\n\nCollecting patches\n~~~~~~~~~~~~~~~~~~\n\nTo use it, first of all you must register the extension within the Sphinx environment, adding\nthe full name of the package to the ``extensions`` list in the file ``conf.py``, for example::\n\n # Add any Sphinx extension module names here, as strings.\n extensions = ['metapensiero.sphinx.patchdb']\n\nThe other required bit of customization is the location of the `on disk scripts storage`,\ni.e. the path of the file that will contain the information about every found script: this is\nkept separated from the documentation itself because you will probably deploy it on production\nservers just to update their database.\n\n.. _storage formats:\n\n.. topic:: Storage formats\n\n If the filename ends with ``.json`` it will contain a ``JSON`` formatted array, if it ends\n with ``.yaml`` the information will be dumped in ``YAML``, if it ends with ``.axon`` the\n dump will be formatted using ``AXON``, otherwise it will be a Python ``pickle``. I usually\n prefer ``AXON``, ``JSON`` or ``YAML``, because those formats are more VCs friendly and open\n to human inspection. These days I tend to use ``AXON`` for this kind of things as it is\n slightly more readable and more VCs friendly than ``JSON``, while ``YAML`` is very slow.\n\nThe location may be set in the same ``conf.py`` as above, like::\n\n # Location of the external storage\n patchdb_storage = '\u2026/dbname.json'\n\nOtherwise, you can set it using the ``-D`` option of the ``sphinx-build`` command, so that you\ncan easily share its definition with other rules in a ``Makefile``. I usually put the following\nsnippet at the beginning of the ``Makefile`` created by ``sphinx-quickstart``::\n\n TOPDIR ?= ..\n STORAGE ?= $(TOPDIR)/database.json\n\n SPHINXOPTS = -D patchdb_storage=$(STORAGE)\n\nAt this point, executing the usual ``make html`` will update the scripts archive: that file\ncontains everything is needed to update the database either local or remote; in other words,\nrunning Sphinx (or even having it installed) is **not** required to update a database.\n\n\nUpdating the database\n~~~~~~~~~~~~~~~~~~~~~\n\nThe other side of the coin is managed by the ``patchdb`` tool, that digests the scripts archive\nand is able to determine which of the scripts are not already applied and eventually does that,\nin the right order.\n\nWhen your database does already exist and you are just starting using ``patchdb`` you may need\nto force the initial state with the following command::\n\n patchdb --assume-already-applied --postgresql \"dbname=test\" database.json\n\nthat will just update the `patchdb` table registering current revision of all the missing\nscripts, without executing them.\n\nYou can inspect what will be done, that is obtain the list of not already applied patches, with\na command like::\n\n patchdb --dry-run --postgresql \"dbname=test\" database.json\n\nThe `database.json` archive can be sent to the production machines (in some cases I put it in a\n*production* branch of the repository and use the version control tool to update the remote\nmachines, in other I simply used ``scp`` or ``rsync`` based solutions). Another way is to\ninclude it in some package and then use the syntax ``some.package:path/database.json``.\n\nThe scripts may even come from several different archives (see `placeholders`_ above)::\n\n patchdb --postgresql \"dbname=test\" app.db.base:pdb.json app.db.auth:pdb.json\n\n\nAutomatic backup\n~~~~~~~~~~~~~~~~\n\nIn particular in development mode, I find it useful to have a simple way of going back to a\nprevious state and retry the upgrade, either to test different upgrade paths or to fix silly\ntypos in the new patches.\n\nSince version 2.3 ``patchdb`` has a new option, ``--backups-dir``, that controls an automatic\nbackup facility: at each execution, before proceeding with applying missing patches,\n*regardless* whether there are any, by default it takes a backup of the current database and\nkeeps a simple index of these snapshots.\n\nThe option defaults to the system-wide temporary directory (usually ``/tmp`` on POSIX systems):\nif you you don't need the automatic backup (a reasonable production system should have a\ndifferent approach to taking such snapshots), specify ``None`` as argument to the option.\n\nWith the ``patchdb-states`` tool you obtain a list of the available snapshots, or restore any\nprevious one::\n\n $ patchdb-states list\n [lun 18 apr 2016 08:24:48 CEST] bc5c5527ece6f11da529858d5ac735a8 \n [lun 18 apr 2016 10:27:11 CEST] 693fd245ad9e5f4de0e79549255fbd6e \n\n $ patchdb-states restore --sqlite /tmp/quicktest.sqlite 693fd245ad9e5f4de0e79549255fbd6e\n [I] Creating patchdb table\n [I] Restored SQLite database /tmp/quicktest.sqlite from /tmp/693fd245ad9e5f4de0e79549255fbd6e\n\n $ patchdb-states clean -k 1\n Removed /tmp/bc5c5527ece6f11da529858d5ac735a8\n Kept most recent 1 snapshot\n\n\nSupported databases\n~~~~~~~~~~~~~~~~~~~\n\nAs of version 2, ``patchdb`` can operate on the following databases:\n\n* Firebird (requires fdb_)\n* MySQL (requires PyMySQL_ by default, see option ``--driver`` to select a different one)\n* PostgreSQL (requires psycopg2_)\n* SQLite (uses the standard library ``sqlite3`` module)\n\n.. _fdb: https://pypi.python.org/pypi/fdb\n.. _PyMySQL: https://pypi.python.org/pypi/PyMySQL\n.. _psycopg2: https://pypi.python.org/pypi/psycopg2\n.. _SQLAlchemy: http://www.sqlalchemy.org/\n\n\nExample development Makefile snippet\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe following is a snippet that I usually put in my outer ``Makefile``::\n\n export TOPDIR := $(CURDIR)\n DBHOST := localhost\n DBPORT := 5432\n DBNAME := dbname\n DROPDB := dropdb --host=$(DBHOST) --port=$(DBPORT) --if-exists\n CREATEDB := createdb --host=$(DBHOST) --port=$(DBPORT) --encoding=UTF8\n STORAGE := $(TOPDIR)/$(DBNAME).json\n DSN := host=$(DBHOST) port=$(DBPORT) dbname=$(DBNAME)\n PUP := $(PATCHDB) --postgresql=\"$(DSN)\" --log-file=$(DBNAME).log $(STORAGE)\n\n # Build the Sphinx documentation\n doc:\n $(MAKE) -C doc STORAGE=$(STORAGE) html\n\n $(STORAGE): doc\n\n # Show what is missing\n missing-patches: $(STORAGE)\n $(PUP) --dry-run\n\n # Upgrade the database to the latest revision\n database: $(STORAGE)\n $(PUP)\n\n # Remove current database and start from scratch\n scratch-database:\n $(DROPDB) $(DBNAME)\n $(CREATEDB) $(DBNAME)\n $(MAKE) database\n\n\nQuick example\n-------------\n\nThe following shell session illustrates the basics:\n\n.. code-block:: shell\n\n python3 -m venv patchdb-session\n cd patchdb-session\n source bin/activate\n pip install metapensiero.sphinx.patchdb[dev]\n yes n | sphinx-quickstart --project PatchDB-Quick-Test \\\n --author JohnDoe \\\n -v 1 --release 1 \\\n --language en \\\n --master index --suffix .rst \\\n --makefile --no-batchfile \\\n pdb-qt\n cd pdb-qt\n echo \"extensions = ['metapensiero.sphinx.patchdb']\" >> conf.py\n echo \"patchdb_storage = 'pdb-qt.json'\" >> conf.py\n echo \"\n .. patchdb:script:: My first script\n :depends: Yet another\n :language: python\n\n print('world!')\n\n .. patchdb:script:: Yet another\n :language: python\n\n print('Hello')\n \" >> index.rst\n make html\n patchdb --sqlite /tmp/pdb-qt.sqlite --dry-run pdb-qt.json\n\nAt the end you should get something like::\n\n Would apply script \"yet another@1\"\n Would apply script \"my first script@1\"\n 100% (2 of 2) |########################################| Elapsed Time: 0:00:00 Time: 0:00:00\n\nRemoving the ``--dry-run``::\n\n $ patchdb --sqlite /tmp/pdb-qt.sqlite pdb-qt.json\n Hello\n world!\n\n Done, applied 2 scripts\n 100% (2 of 2) |########################################| Elapsed Time: 0:00:00 Time: 0:00:00\n\nOnce again::\n\n $ patchdb --sqlite /tmp/pdb-qt.sqlite pdb-qt.json\n Done, applied 0 scripts\n\n\nChanges\\ [#]_\n-------------\n\n3.5 (2019-06-21)\n~~~~~~~~~~~~~~~~\n\n* Now it's an hard error when a patch brings an unknown script: when it does, it's either\n obsoleted or there is a typo somewhere\n\n\n3.4 (2019-03-31)\n~~~~~~~~~~~~~~~~\n\n* Nothing new, minor glitch in the release procedure\n\n\n3.3 (2019-03-31)\n~~~~~~~~~~~~~~~~\n\n* Lift the constraint on sqlparse version, allow use of recently released 0.3.0.\n\n\n3.2 (2018-03-03)\n~~~~~~~~~~~~~~~~\n\n* Use `python-rapidjson`__ if available\n\n __ https://pypi.org/project/python-rapidjson/\n\n\n3.1 (2017-11-30)\n~~~~~~~~~~~~~~~~\n\n* Fix glitch in the logic that determine whether a patch script is still valid\n\n* Use enlighten__ to show the progress bar: the ``--verbose`` option is gone, now is the\n default mode\n\n __ https://pypi.org/project/enlighten/\n\n\n3.0 (2017-11-06)\n~~~~~~~~~~~~~~~~\n\n* Python 3 only\\ [#]_\n\n* New execution logic, hopefully fixing circular dependencies error in case of multiple non\n trivial pending migrations\n\n\n.. [#] Previous changes are here__.\n\n __ https://gitlab.com/metapensiero/metapensiero.sphinx.patchdb/blob/master/OLDERCHANGES.rst\n\n.. [#] If you are still using Python 2, either stick with version 2.27, or fetch `this\n commit`__ from the repository.\n\n __ https://gitlab.com/metapensiero/metapensiero.sphinx.patchdb/commit/f9fc5f5d50a381eaf9f003d7006cc46382842c18", "description_content_type": "text/x-rst", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://gitlab.com/metapensiero/metapensiero.sphinx.patchdb.git", "keywords": "", "license": "GPLv3+", "maintainer": "", "maintainer_email": "", "name": "metapensiero.sphinx.patchdb", "package_url": "https://pypi.org/project/metapensiero.sphinx.patchdb/", "platform": "", "project_url": "https://pypi.org/project/metapensiero.sphinx.patchdb/", "project_urls": { "Homepage": "https://gitlab.com/metapensiero/metapensiero.sphinx.patchdb.git" }, "release_url": "https://pypi.org/project/metapensiero.sphinx.patchdb/3.5/", "requires_dist": null, "requires_python": "", "summary": "Extract scripts from a reST document and apply them in order.", "version": "3.5" }, "last_serial": 5429918, "releases": { "1.1.0": [ { "comment_text": "", "digests": { "md5": "c42fd004de84d18fdfd8c96e8361174c", "sha256": "dcd104cb7c07cba9e86aba74f3e02ffe7bfcccd3f2c955b636585eb5d058063d" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.1.0.tar.gz", "has_sig": false, "md5_digest": "c42fd004de84d18fdfd8c96e8361174c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25850, "upload_time": "2014-06-03T16:01:42", "url": "https://files.pythonhosted.org/packages/2f/05/23a24da79d6ad904157cfe9c14e037ab6e50d395a648c73518b0c2f639d5/metapensiero.sphinx.patchdb-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "f2bd2260f06a56be91b6c666ac0da6fd", "sha256": "d9630463eff685929dfaec055c995d9e7a423da8dcf46b395d2181f030063de2" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.1.1.tar.gz", "has_sig": false, "md5_digest": "f2bd2260f06a56be91b6c666ac0da6fd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27548, "upload_time": "2014-06-03T16:07:11", "url": "https://files.pythonhosted.org/packages/99/ff/dd3f4ca20723475db73e218d890e2474d2eee0cde63868bdfadd188564df/metapensiero.sphinx.patchdb-1.1.1.tar.gz" } ], "1.1.2": [ { "comment_text": "", "digests": { "md5": "27ba537d07a851fb8360f512a9cf5d9a", "sha256": "553ca9d1fe66fc5e0cd946c239a7b5c476a7ffef9509a8d2a67b26c7b845ea66" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.1.2.tar.gz", "has_sig": false, "md5_digest": "27ba537d07a851fb8360f512a9cf5d9a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29315, "upload_time": "2014-06-05T07:29:37", "url": "https://files.pythonhosted.org/packages/c2/f2/4dbe734d3a49769c3e1c58122593bb21f4320b049d67c0078c760ec0570e/metapensiero.sphinx.patchdb-1.1.2.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "6e588c85e67e5e49ab0535c8336fe9d7", "sha256": "e09d3b6a8d9fee8ce4635224ae0d2045048f48a7dd32b0822c956b732adcd189" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.2.0.tar.gz", "has_sig": false, "md5_digest": "6e588c85e67e5e49ab0535c8336fe9d7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30896, "upload_time": "2014-06-18T22:40:15", "url": "https://files.pythonhosted.org/packages/77/d0/61bfe5054b2ffd06eb16269df17d1fe592bde1ef21a649831a9511afad54/metapensiero.sphinx.patchdb-1.2.0.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "ae917c0da4d36bfcdd8cefcbdbcf9d85", "sha256": "685d89a9d919de2b9df8200b712f0b67a19852b615dea71b39858bea7e12f7e6" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.2.1.tar.gz", "has_sig": false, "md5_digest": "ae917c0da4d36bfcdd8cefcbdbcf9d85", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 31418, "upload_time": "2014-07-02T07:28:08", "url": "https://files.pythonhosted.org/packages/5e/33/b77dbc1d5127c4814188e91523c9baa6de1159566bba29a48d7f9d92204c/metapensiero.sphinx.patchdb-1.2.1.tar.gz" } ], "1.3.0": [ { "comment_text": "", "digests": { "md5": "de8d4c02ef6b3f37867d7da1b64db712", "sha256": "e842ca56732c897de3afe40a61a77d6787dfb2010be54cbaf9f2de266201b359" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.3.0.tar.gz", "has_sig": false, "md5_digest": "de8d4c02ef6b3f37867d7da1b64db712", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 31814, "upload_time": "2015-06-21T11:36:20", "url": "https://files.pythonhosted.org/packages/3a/d7/e5a0e17819348b44a5ca0425e17def17acb97a6f26a77f419545fb8ced2a/metapensiero.sphinx.patchdb-1.3.0.tar.gz" } ], "1.3.1": [ { "comment_text": "", "digests": { "md5": "99ce2563db77c97a4f1ccd2e2ca8e766", "sha256": "c93a7e78d8e6d0d88edae828e1ab15f69f1a53d2de352bf23163686d6c803103" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.3.1.tar.gz", "has_sig": false, "md5_digest": "99ce2563db77c97a4f1ccd2e2ca8e766", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 31883, "upload_time": "2015-06-23T18:16:09", "url": "https://files.pythonhosted.org/packages/ea/82/41d756200b2661499fabc5bb78c87da952eb06a7e8d2faf52a9d1c7feea4/metapensiero.sphinx.patchdb-1.3.1.tar.gz" } ], "1.3.10": [ { "comment_text": "", "digests": { "md5": "1161a56736b039345a4a47617cf1123a", "sha256": "0a625b2c12d22293de8640c8e5d6e25ec4834623bfb78b77fa5534950a11ea96" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.3.10.tar.gz", "has_sig": false, "md5_digest": "1161a56736b039345a4a47617cf1123a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 33106, "upload_time": "2015-08-15T07:49:13", "url": "https://files.pythonhosted.org/packages/f0/bb/ae1f80c87cd303874d85349d4f6813c8ca161361542ca37ee95138b03522/metapensiero.sphinx.patchdb-1.3.10.tar.gz" } ], "1.3.11": [ { "comment_text": "", "digests": { "md5": "8650adb52235baf27190ef1e1c7e1d53", "sha256": "63120417ca78024b0d93343c810eff77977a72dd45dc5990b2780867e232d631" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.3.11.tar.gz", "has_sig": false, "md5_digest": "8650adb52235baf27190ef1e1c7e1d53", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 33232, "upload_time": "2015-08-16T15:21:29", "url": "https://files.pythonhosted.org/packages/10/74/03f6067997fbe58a8ec60c9656f31d8e1875a82af1edfa792f6450c3a162/metapensiero.sphinx.patchdb-1.3.11.tar.gz" } ], "1.3.2": [ { "comment_text": "", "digests": { "md5": "b6cf599d4ccb38af41b89543861fea52", "sha256": "0e309ae73f7f13410be93ce72b07a3aedfb8f9ab6f5e5be0c19e801e7818eb9c" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.3.2.tar.gz", "has_sig": false, "md5_digest": "b6cf599d4ccb38af41b89543861fea52", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32038, "upload_time": "2015-06-23T21:52:39", "url": "https://files.pythonhosted.org/packages/e1/1f/02799f206ee59f6e77a11e5585e1773f31f69399109992b4591173fe02e7/metapensiero.sphinx.patchdb-1.3.2.tar.gz" } ], "1.3.3": [ { "comment_text": "", "digests": { "md5": "0106eb9126efc250d19089b8a5552e19", "sha256": "ed40fa6268bcb5b4fc27813356239b4d44e4bf2f539fbdbafb12cd9038d2c344" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.3.3.tar.gz", "has_sig": false, "md5_digest": "0106eb9126efc250d19089b8a5552e19", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32162, "upload_time": "2015-06-24T21:19:08", "url": "https://files.pythonhosted.org/packages/47/9e/59b7f23a76920b764c3614fa78c2a0f3410218e61a68d37e50bfef2f9d09/metapensiero.sphinx.patchdb-1.3.3.tar.gz" } ], "1.3.4": [ { "comment_text": "", "digests": { "md5": "15f3162633960c81292a523a5d81c874", "sha256": "26ffc88a65b1491242cb37f655ed71e5cfe7951a13627143b118f0a28964568d" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.3.4.tar.gz", "has_sig": false, "md5_digest": "15f3162633960c81292a523a5d81c874", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32277, "upload_time": "2015-07-06T13:59:54", "url": "https://files.pythonhosted.org/packages/7d/da/1cb00ef37eb29ce3a69cef8e602cc946cd0ccb454751fa65d2d3b487d712/metapensiero.sphinx.patchdb-1.3.4.tar.gz" } ], "1.3.5": [ { "comment_text": "", "digests": { "md5": "163c82b233a10bc29c04b655a49e122b", "sha256": "51b22873c24cfa3f56a3054b7233130a1b3272104e29bf991dbb8feffbfa48e4" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.3.5.tar.gz", "has_sig": false, "md5_digest": "163c82b233a10bc29c04b655a49e122b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32333, "upload_time": "2015-07-06T14:09:30", "url": "https://files.pythonhosted.org/packages/52/02/f12db8faaebdf42e4ac475abe9e9ece688b063c7e492f1a8f25bb5437a7f/metapensiero.sphinx.patchdb-1.3.5.tar.gz" } ], "1.3.6": [ { "comment_text": "", "digests": { "md5": "6a0541a640520898b57d668fcd60dcbe", "sha256": "7e3c682463f6145c4f350843fa5f241f27b3c57caca2ac87be13e67849ac77f7" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.3.6.tar.gz", "has_sig": false, "md5_digest": "6a0541a640520898b57d668fcd60dcbe", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32383, "upload_time": "2015-07-06T14:29:06", "url": "https://files.pythonhosted.org/packages/aa/ea/d96c466b0a0c25402c0f12e95617be88823853096c011dbbf88e2d054be2/metapensiero.sphinx.patchdb-1.3.6.tar.gz" } ], "1.3.7": [ { "comment_text": "", "digests": { "md5": "d00121adfab235625f7c7d2e9288899f", "sha256": "06827787110d1bd0ed157814e52f909e8f43e89e627d970421c65b7f7e4dc861" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.3.7.tar.gz", "has_sig": false, "md5_digest": "d00121adfab235625f7c7d2e9288899f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32650, "upload_time": "2015-07-20T15:28:16", "url": "https://files.pythonhosted.org/packages/5b/d2/0f2d1f6bbda464e28eeb16e0c96bae0c53d6176b235c382ed2994454f0bf/metapensiero.sphinx.patchdb-1.3.7.tar.gz" } ], "1.3.8": [ { "comment_text": "", "digests": { "md5": "76c9eaf03c631a0569be52e5ef8ebc76", "sha256": "4a91d7392d3603229c1f11133f3f311f51e2f9685051e9ba9f82ecc60cad02d3" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.3.8.tar.gz", "has_sig": false, "md5_digest": "76c9eaf03c631a0569be52e5ef8ebc76", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32741, "upload_time": "2015-08-08T14:24:56", "url": "https://files.pythonhosted.org/packages/27/1d/674374e62f8301aae29d1f680336f02ba1183c0c75b7687b09acdf05b0fc/metapensiero.sphinx.patchdb-1.3.8.tar.gz" } ], "1.3.9": [ { "comment_text": "", "digests": { "md5": "255ca4f07b4fc60c515029cfe070e052", "sha256": "1024ddb9e74541ff12fbce32da1181f22160c246a5ae41adf7fb3a3d371db262" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.3.9.tar.gz", "has_sig": false, "md5_digest": "255ca4f07b4fc60c515029cfe070e052", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32830, "upload_time": "2015-08-08T16:59:58", "url": "https://files.pythonhosted.org/packages/23/e8/9a6ef52ff9dbdfe1a35f22c3429679399c6a62f0f4d4b382f536346028e3/metapensiero.sphinx.patchdb-1.3.9.tar.gz" } ], "1.4.0": [ { "comment_text": "", "digests": { "md5": "b4b942999451ede1f46e3a935cb6cdf6", "sha256": "58f9b53c9bc6716211d34f55be97bb6f4fb659b359169a3f018ccb58f8d4c1a1" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.4.0.tar.gz", "has_sig": false, "md5_digest": "b4b942999451ede1f46e3a935cb6cdf6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 35223, "upload_time": "2015-08-19T05:48:17", "url": "https://files.pythonhosted.org/packages/28/05/8b6d3ffe44e02cec89d76adac21b79192fa9a62b4b4343ec2798cf9619cc/metapensiero.sphinx.patchdb-1.4.0.tar.gz" } ], "1.4.1": [ { "comment_text": "", "digests": { "md5": "dca27eddbca909da4b2410e5ba2c0668", "sha256": "6fdd939794cd81b78a41060ac975486b8e97250220f45b4ca4c1b25b997b3708" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.4.1.tar.gz", "has_sig": false, "md5_digest": "dca27eddbca909da4b2410e5ba2c0668", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 36612, "upload_time": "2015-09-23T09:25:50", "url": "https://files.pythonhosted.org/packages/85/0a/903d3d4eb68b4572fc618aa574510715b0d16b24eb85d2e8924cf235a27e/metapensiero.sphinx.patchdb-1.4.1.tar.gz" } ], "1.4.2": [ { "comment_text": "", "digests": { "md5": "08698336506552c6cf72874e6a0705f1", "sha256": "77982ebc80381a71349949b1930a9a5047fbbf29a0118ab1eddf7f81346d0512" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.4.2.tar.gz", "has_sig": false, "md5_digest": "08698336506552c6cf72874e6a0705f1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 37401, "upload_time": "2015-10-22T19:56:56", "url": "https://files.pythonhosted.org/packages/5f/f6/4f85cb48e08f92df564130a8f30522b01e4ade9b803103dd883dd52c1021/metapensiero.sphinx.patchdb-1.4.2.tar.gz" } ], "1.5": [ { "comment_text": "", "digests": { "md5": "34267c7e3a2d4ca6019f4801288c4ec7", "sha256": "c9132abd89b62bf4b37c4fef4e0727e878d23917dee47292ded3de751b7e0373" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.5.tar.gz", "has_sig": false, "md5_digest": "34267c7e3a2d4ca6019f4801288c4ec7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 33037, "upload_time": "2016-01-07T11:49:13", "url": "https://files.pythonhosted.org/packages/c5/5e/19091167676c537ffc35aa644b14b847f06a7c286decf3b3fa93cb85c8ac/metapensiero.sphinx.patchdb-1.5.tar.gz" } ], "1.6": [ { "comment_text": "", "digests": { "md5": "3bd35f268b0cf896ba9eb32887943de9", "sha256": "c25ba74e30262cf8f60ff5a044a1bc64c6094d65a3b81319f1939647ed0bb1cf" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.6.tar.gz", "has_sig": false, "md5_digest": "3bd35f268b0cf896ba9eb32887943de9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 35594, "upload_time": "2016-02-10T09:37:25", "url": "https://files.pythonhosted.org/packages/f2/95/3dc11884fe4f4da726669c932826403146544a2d90f7d7d766a37a442930/metapensiero.sphinx.patchdb-1.6.tar.gz" } ], "1.7": [ { "comment_text": "", "digests": { "md5": "e587a8a8dd24279713776e3edbf25d69", "sha256": "548c42c089900e8779428f0bf42c98139d9e6f549b104903518c93ee6c2703fe" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-1.7.tar.gz", "has_sig": false, "md5_digest": "e587a8a8dd24279713776e3edbf25d69", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 35813, "upload_time": "2016-02-20T09:35:15", "url": "https://files.pythonhosted.org/packages/95/5d/d14af2ebc8232e24f4afba58f87bd239dbbd96be665ede9fb34a4c5fdbfe/metapensiero.sphinx.patchdb-1.7.tar.gz" } ], "2.0": [ { "comment_text": "", "digests": { "md5": "6e1fc090473304713325a3248683ae11", "sha256": "345663c0bcbeb90d327c0f5409287fec944f7367b9982a65a5d35812550a05e6" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.0.tar.gz", "has_sig": false, "md5_digest": "6e1fc090473304713325a3248683ae11", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 39257, "upload_time": "2016-02-29T23:09:39", "url": "https://files.pythonhosted.org/packages/83/86/1e5b13eee49c0ed3b45da3d7a1f9928ff6fd3927b6fe847d29d02eecf004/metapensiero.sphinx.patchdb-2.0.tar.gz" } ], "2.1": [ { "comment_text": "", "digests": { "md5": "691b7472c6ba9b5f69ab6dae5f18c8cd", "sha256": "459e66ac7ad91807d40850abaa3dc566c800590976913fccf6f6ed6cb6526896" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.1.tar.gz", "has_sig": false, "md5_digest": "691b7472c6ba9b5f69ab6dae5f18c8cd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 39634, "upload_time": "2016-03-03T23:23:10", "url": "https://files.pythonhosted.org/packages/c6/26/6da8ed9b7b84614b0c8acb32e7a4c8da02378c811384d6c5f33b723fd8e5/metapensiero.sphinx.patchdb-2.1.tar.gz" } ], "2.10": [ { "comment_text": "", "digests": { "md5": "5f5701177d5ee5f771d6661171f02211", "sha256": "5c2eb28f42c615db594260c3aaf607aea0eba2377423e84c7694043bd9ffb6f6" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.10.tar.gz", "has_sig": false, "md5_digest": "5f5701177d5ee5f771d6661171f02211", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 49828, "upload_time": "2016-09-29T16:25:13", "url": "https://files.pythonhosted.org/packages/97/f9/43828871cea4db90896bcdab748c9176ad0ef4da4d21cdcfc01d3c8190f4/metapensiero.sphinx.patchdb-2.10.tar.gz" } ], "2.11": [ { "comment_text": "", "digests": { "md5": "694ea2021a6d063151851bce073a6997", "sha256": "f7e1b723309ba86d24e4e400298b302cac4e468c0152dfd1f15705df39fb7d43" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.11.tar.gz", "has_sig": false, "md5_digest": "694ea2021a6d063151851bce073a6997", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 49924, "upload_time": "2016-10-14T11:07:45", "url": "https://files.pythonhosted.org/packages/5d/d6/ada3aad20f47a9a5c23854a3f5f81352a259bbf02cfe2bc49226ebad8ca2/metapensiero.sphinx.patchdb-2.11.tar.gz" } ], "2.12": [ { "comment_text": "", "digests": { "md5": "e53c995b56ed8becb0c30ba96410ef7f", "sha256": "da83fb59404518736cbb3ecac7c7bb9a391e2697db8b37107df8e6cd55e466ee" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.12.tar.gz", "has_sig": false, "md5_digest": "e53c995b56ed8becb0c30ba96410ef7f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50636, "upload_time": "2016-10-15T10:35:08", "url": "https://files.pythonhosted.org/packages/a8/01/9f7adf7824f9be06717e60da9ba412b3d2940a297a4a52a3d20504ae85f1/metapensiero.sphinx.patchdb-2.12.tar.gz" } ], "2.13": [ { "comment_text": "", "digests": { "md5": "4a833de45e37c27b412fc44ca6e5a67f", "sha256": "f1fb742fae1fbbb9126544605db8a5279fa956006aefd56a52e8d7bc42531e6c" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.13.tar.gz", "has_sig": false, "md5_digest": "4a833de45e37c27b412fc44ca6e5a67f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50813, "upload_time": "2016-10-25T07:44:13", "url": "https://files.pythonhosted.org/packages/ad/4e/8b704f5129e9105dba9e44cdcb714750409fc9b5435bf84b09cd5e7407ca/metapensiero.sphinx.patchdb-2.13.tar.gz" } ], "2.14": [ { "comment_text": "", "digests": { "md5": "f00d2e4f2f4959524aa729f2c3df7277", "sha256": "a5982bc7e0969f95e14ab4f0e934c1c1fab98b7deccce2e42e323930bc4bed3b" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.14.tar.gz", "has_sig": false, "md5_digest": "f00d2e4f2f4959524aa729f2c3df7277", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 51122, "upload_time": "2016-11-16T17:55:11", "url": "https://files.pythonhosted.org/packages/c0/7c/74c0282c1305f381d128e8fa1c0ce9a6c099b14e7d7288c53fb7fc5b0633/metapensiero.sphinx.patchdb-2.14.tar.gz" } ], "2.15": [ { "comment_text": "", "digests": { "md5": "e76c9c73c114f83cd975bf55061faa9d", "sha256": "173f67efbb0fba7f246813bdeb5da981dcdfa7dd88a42943c35141202de6d0e6" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.15.tar.gz", "has_sig": false, "md5_digest": "e76c9c73c114f83cd975bf55061faa9d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 66557, "upload_time": "2016-11-18T08:27:31", "url": "https://files.pythonhosted.org/packages/f8/e6/5d62d1b919b69b17c566186f77b7c50206e11ba7697d3f8c34f063e80462/metapensiero.sphinx.patchdb-2.15.tar.gz" } ], "2.16": [ { "comment_text": "", "digests": { "md5": "d1ebed55b2324780039eb91f8df9788a", "sha256": "f20a7735e93fe0e6a2bbf4a915d491b1089044ced3f1514539bf0c188af2eec2" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.16.tar.gz", "has_sig": false, "md5_digest": "d1ebed55b2324780039eb91f8df9788a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 67266, "upload_time": "2017-01-17T15:21:36", "url": "https://files.pythonhosted.org/packages/e4/05/869584d0ea5633f0fd1b4b44b816beab198ed1b5263df543a41ba0336c0a/metapensiero.sphinx.patchdb-2.16.tar.gz" } ], "2.17": [ { "comment_text": "", "digests": { "md5": "db985a4ffd37e57ec5bf74fd137ddbe2", "sha256": "05217fecb0c8107fc1369d23e38537fb4c1b8b272d8f88de78473b77b6bf7044" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.17.tar.gz", "has_sig": false, "md5_digest": "db985a4ffd37e57ec5bf74fd137ddbe2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 67474, "upload_time": "2017-02-28T08:47:39", "url": "https://files.pythonhosted.org/packages/87/41/986c689437a73d3ba9bdbd0ccc683914aca8918e04d0688cfee15aa02af1/metapensiero.sphinx.patchdb-2.17.tar.gz" } ], "2.18": [ { "comment_text": "", "digests": { "md5": "665698d729dbdab73a6c1d15e70985a1", "sha256": "9da3217336f0d8bc28007935711be02a6110dbfb25d09bb24610a7ea873d300a" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.18.tar.gz", "has_sig": false, "md5_digest": "665698d729dbdab73a6c1d15e70985a1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 67592, "upload_time": "2017-03-22T20:44:26", "url": "https://files.pythonhosted.org/packages/88/2b/e4225a09d160c7e58274d67af3590028d8c2f1ba55536306c289e83c4179/metapensiero.sphinx.patchdb-2.18.tar.gz" } ], "2.19": [ { "comment_text": "", "digests": { "md5": "2559ed7e9c7a22ab2917053aa9536d99", "sha256": "d2c96f66889b72a1799f5f87d58c00b6b0e8980aa59dcedffdb50284cd72ca37" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.19.tar.gz", "has_sig": false, "md5_digest": "2559ed7e9c7a22ab2917053aa9536d99", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 67753, "upload_time": "2017-04-06T00:30:44", "url": "https://files.pythonhosted.org/packages/37/9d/145ad6d860dbed9c3e5abb03d22bb98ad025ddfd938ac2db0153130d7d8b/metapensiero.sphinx.patchdb-2.19.tar.gz" } ], "2.2": [ { "comment_text": "", "digests": { "md5": "0581fd9c138b2fb73889dc6656e7b589", "sha256": "c6760356b808a271fbfecf0304ff8abae45b58ad370cae4cedf8cf717d8f2e8a" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.2.tar.gz", "has_sig": false, "md5_digest": "0581fd9c138b2fb73889dc6656e7b589", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40159, "upload_time": "2016-03-12T12:13:23", "url": "https://files.pythonhosted.org/packages/92/46/fdb9a3a0882b968514666fe899f2199b9986acbb35a0096b4c7a7013fdeb/metapensiero.sphinx.patchdb-2.2.tar.gz" } ], "2.20": [ { "comment_text": "", "digests": { "md5": "ed74b224f29b863ff3b354d9b33f20d9", "sha256": "4c23eb69944d532bb7eccd68f09e0a09cd2e5f82aebfde845e73e6156422162f" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.20.tar.gz", "has_sig": false, "md5_digest": "ed74b224f29b863ff3b354d9b33f20d9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 68042, "upload_time": "2017-05-02T15:10:03", "url": "https://files.pythonhosted.org/packages/fb/0b/ef18d21a1e2b388b9a35e9d85db34615014b1e4240e276ba7943c711c7ed/metapensiero.sphinx.patchdb-2.20.tar.gz" } ], "2.21": [ { "comment_text": "", "digests": { "md5": "dd372c3e269cb66f6d3e23d8a4d772bf", "sha256": "391e89234516f910248b3cc6af07fe63b440b9fbc41ad5f26f11c19cf106d1c8" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.21.tar.gz", "has_sig": false, "md5_digest": "dd372c3e269cb66f6d3e23d8a4d772bf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 68104, "upload_time": "2017-05-20T16:13:05", "url": "https://files.pythonhosted.org/packages/ac/ef/e55e505f89b23f358f16eadf484e924e77081d7cb84ede42b821106f69ce/metapensiero.sphinx.patchdb-2.21.tar.gz" } ], "2.22": [ { "comment_text": "", "digests": { "md5": "b3357d9674a908080b8f34c1b86ce93f", "sha256": "58cd3b996c03521869d7e1d925d98230ab1b8a44e10874fafd75d8b9cc567e15" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.22.tar.gz", "has_sig": false, "md5_digest": "b3357d9674a908080b8f34c1b86ce93f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 68313, "upload_time": "2017-05-23T01:11:08", "url": "https://files.pythonhosted.org/packages/7b/fa/0f2eae5c89f0e46ab1d30728f3333605f3abd79a3fe2d387a8c35ae5d73d/metapensiero.sphinx.patchdb-2.22.tar.gz" } ], "2.23": [ { "comment_text": "", "digests": { "md5": "7fb42f89d4bdc82fd55bb230c8bd72fd", "sha256": "da3c2988394af02b88c307a9e9e0dd92212cd2b4ce819af9017ea4efff477c9f" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.23.tar.gz", "has_sig": false, "md5_digest": "7fb42f89d4bdc82fd55bb230c8bd72fd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 70066, "upload_time": "2017-05-27T15:14:43", "url": "https://files.pythonhosted.org/packages/f6/a9/111fea83169f976a794a0026f4426748276fbfc754e55bdc9132e8b0b07e/metapensiero.sphinx.patchdb-2.23.tar.gz" } ], "2.24": [ { "comment_text": "", "digests": { "md5": "240bf97918e09d2c82fb4c4fb3d4fde0", "sha256": "5bf0dcf69a201f6e16569ae23f8c0105064d4edae5d2ce0abcd772958302867d" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.24.tar.gz", "has_sig": false, "md5_digest": "240bf97918e09d2c82fb4c4fb3d4fde0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 71181, "upload_time": "2017-06-08T18:35:13", "url": "https://files.pythonhosted.org/packages/14/c7/2912202b09117b93fbbc0f35317d72e27c946b5421b461e9bdd6ef60881a/metapensiero.sphinx.patchdb-2.24.tar.gz" } ], "2.25": [ { "comment_text": "", "digests": { "md5": "ced8231193081ef595875af8eacc49d7", "sha256": "e40ea49e7629582636d12e31384cfdb589564d18f1692295470a3894b296beed" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.25.tar.gz", "has_sig": false, "md5_digest": "ced8231193081ef595875af8eacc49d7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 71593, "upload_time": "2017-06-29T11:05:19", "url": "https://files.pythonhosted.org/packages/9c/3e/61100c65e399d9131fafac569dbfb93680002787533f7871f18a1e292bd6/metapensiero.sphinx.patchdb-2.25.tar.gz" } ], "2.26": [ { "comment_text": "", "digests": { "md5": "ef863a425b0a1a65dce4e4ed257a16b7", "sha256": "b632533236f4728688f789b09a695aed2f019ceb60c82bf1e2c3f2129569d1a3" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.26.tar.gz", "has_sig": false, "md5_digest": "ef863a425b0a1a65dce4e4ed257a16b7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 72223, "upload_time": "2017-09-27T22:10:09", "url": "https://files.pythonhosted.org/packages/64/f5/c5a403f0f4099af042d7a5db3401a05fee6dd7bb3c7a3673e64026bedee7/metapensiero.sphinx.patchdb-2.26.tar.gz" } ], "2.27": [ { "comment_text": "", "digests": { "md5": "e0c7e083e85eee4e225fb910ef29543e", "sha256": "9e119b7c43ddeb8cb830788f5c3c16133d43ff0d5c3a90d3f98a119c039bcbd6" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.27.tar.gz", "has_sig": false, "md5_digest": "e0c7e083e85eee4e225fb910ef29543e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 79358, "upload_time": "2017-11-02T16:23:31", "url": "https://files.pythonhosted.org/packages/0d/be/469c07cf44caeca73b116a80444d63c6ecc9a5dc5dd3c704aeb41eccf16f/metapensiero.sphinx.patchdb-2.27.tar.gz" } ], "2.3": [ { "comment_text": "", "digests": { "md5": "7e0552da734dac6374c0b52c6987c4ef", "sha256": "c368204e266b46754c716eec659a8c85241dda752250684746053ac0354f484f" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.3.tar.gz", "has_sig": false, "md5_digest": "7e0552da734dac6374c0b52c6987c4ef", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45428, "upload_time": "2016-04-19T06:21:04", "url": "https://files.pythonhosted.org/packages/83/bb/6de88b2d5a8e8bd286eb6f9b4f1c240af41f2f584feb25d7a94d87fa01d3/metapensiero.sphinx.patchdb-2.3.tar.gz" } ], "2.4": [ { "comment_text": "", "digests": { "md5": "8043654ad9da8a6f06a0151242b0692c", "sha256": "f58a641d49905c01169e97e7af0d116aef2d7e0ea69e7773faeb316702796388" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.4.tar.gz", "has_sig": false, "md5_digest": "8043654ad9da8a6f06a0151242b0692c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 47745, "upload_time": "2016-05-13T08:22:51", "url": "https://files.pythonhosted.org/packages/27/33/8abd76a5ffdc3508eb9249b6ab060d69f910308359e4be77d7d163d6705c/metapensiero.sphinx.patchdb-2.4.tar.gz" } ], "2.5": [ { "comment_text": "", "digests": { "md5": "cc31c17077254f52e03c485deeee224a", "sha256": "30e9a09ccaa0a35db345ea4799c0cbbe95b614172f4aaed04d5ace0b3f28e668" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.5.tar.gz", "has_sig": false, "md5_digest": "cc31c17077254f52e03c485deeee224a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 48145, "upload_time": "2016-05-17T21:12:54", "url": "https://files.pythonhosted.org/packages/b2/be/d49c2431843eea0c844733884eb24e1068be9bd875a7336da0dc784dc3ce/metapensiero.sphinx.patchdb-2.5.tar.gz" } ], "2.6": [ { "comment_text": "", "digests": { "md5": "b6dd95b101e017a46039ba4658b658c6", "sha256": "6b6bb12a9ad58383f3135cd0999a51d5a979a0c36122c13dcdbf3f3cd8427ba6" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.6.tar.gz", "has_sig": false, "md5_digest": "b6dd95b101e017a46039ba4658b658c6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 48226, "upload_time": "2016-05-28T11:53:09", "url": "https://files.pythonhosted.org/packages/9c/7d/0cc351e19a1893937a902943dc03e9add31f779d354a9df3b89f0cea736a/metapensiero.sphinx.patchdb-2.6.tar.gz" } ], "2.7": [ { "comment_text": "", "digests": { "md5": "3ac3ce9dbdde5b9e94e8bee4312d8397", "sha256": "4c67d939dec23231e5661afcec052d311760c74fb02af67c699dfe23b908a04e" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.7.tar.gz", "has_sig": false, "md5_digest": "3ac3ce9dbdde5b9e94e8bee4312d8397", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 48957, "upload_time": "2016-05-29T08:25:43", "url": "https://files.pythonhosted.org/packages/ee/fd/360c29c14dd4250420c3969f5990c78c5cd1e524efb86c7077f85aa12d0d/metapensiero.sphinx.patchdb-2.7.tar.gz" } ], "2.8": [ { "comment_text": "", "digests": { "md5": "14da1db902f945fa01427061ba271c2e", "sha256": "27e0e93e671b35213240802f9b692d2c86d10c4a1df1a4b3fc2cf0a22f05abe4" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.8.tar.gz", "has_sig": false, "md5_digest": "14da1db902f945fa01427061ba271c2e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 48787, "upload_time": "2016-06-07T18:21:22", "url": "https://files.pythonhosted.org/packages/5e/0e/0972a1e91fe8a58c9a326cea244639ace3e0f8619aef91e0594c730a7f45/metapensiero.sphinx.patchdb-2.8.tar.gz" } ], "2.9": [ { "comment_text": "", "digests": { "md5": "eefc2cd16bc409b047e135d6883d69f2", "sha256": "4997ef4aae92b518f5e64adcafa5a5e80be1268414e78b4cdd7c1418468540c4" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-2.9.tar.gz", "has_sig": false, "md5_digest": "eefc2cd16bc409b047e135d6883d69f2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 49758, "upload_time": "2016-06-11T18:38:51", "url": "https://files.pythonhosted.org/packages/46/37/200dacacba67abf2a9611e578e640570ed22b0ab87111a964c7eed4197ff/metapensiero.sphinx.patchdb-2.9.tar.gz" } ], "3.0": [ { "comment_text": "", "digests": { "md5": "0fb6d097f31eb15449983b45ba049f49", "sha256": "ed3357d2474d0484456fd96a66ab9995e09ad41ea349376cd92d83e417b6a837" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-3.0.tar.gz", "has_sig": false, "md5_digest": "0fb6d097f31eb15449983b45ba049f49", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 76240, "upload_time": "2017-11-06T11:52:58", "url": "https://files.pythonhosted.org/packages/ac/58/5127a7e13c8eb132062c5deab4070c0fde32494add87e2a6838fe1c60682/metapensiero.sphinx.patchdb-3.0.tar.gz" } ], "3.1": [ { "comment_text": "", "digests": { "md5": "8301609aca3a1fa2efa4c77765d9e8ec", "sha256": "c6896f289966e7253cc40ff53c3bbd87e7407e43c868efa09b35c1cf19a24d73" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-3.1.tar.gz", "has_sig": false, "md5_digest": "8301609aca3a1fa2efa4c77765d9e8ec", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 76202, "upload_time": "2017-11-30T10:09:49", "url": "https://files.pythonhosted.org/packages/74/42/5f75f92af3885e695f3a18135490414106a8b9531d865b64493a419ab94e/metapensiero.sphinx.patchdb-3.1.tar.gz" } ], "3.2": [ { "comment_text": "", "digests": { "md5": "d765faa02a7c0dd20a3dd4526c5d1791", "sha256": "f281cdf2e2a99fdc05e580a2bf282c5c0c763501683770130f742677fe1a04bf" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-3.2.tar.gz", "has_sig": false, "md5_digest": "d765faa02a7c0dd20a3dd4526c5d1791", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 76432, "upload_time": "2018-03-03T09:21:08", "url": "https://files.pythonhosted.org/packages/ca/7a/200cc5dcc29280ae5741de8b6a6869eefea173053c32012fb56d69a7a13e/metapensiero.sphinx.patchdb-3.2.tar.gz" } ], "3.4": [ { "comment_text": "", "digests": { "md5": "2d3517e18a1d21652a7d2bea7d0087b9", "sha256": "6a63e7070c2b3558ed8aa647a6b0d045a7590403ea756f85003ea198bb8490b6" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-3.4.tar.gz", "has_sig": false, "md5_digest": "2d3517e18a1d21652a7d2bea7d0087b9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 78325, "upload_time": "2019-03-31T08:14:29", "url": "https://files.pythonhosted.org/packages/e8/50/348bfded55d7317ffa391716c256f3d7c8b14dc10a0e537a6b347f0c3bba/metapensiero.sphinx.patchdb-3.4.tar.gz" } ], "3.5": [ { "comment_text": "", "digests": { "md5": "32d33ab3d1e72533b2623d3e5073cdff", "sha256": "d40fde9baa04763cfd1274b43995c85031e6d2034c3a317ea44b57ba43d5776a" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-3.5.tar.gz", "has_sig": false, "md5_digest": "32d33ab3d1e72533b2623d3e5073cdff", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 79821, "upload_time": "2019-06-21T09:26:25", "url": "https://files.pythonhosted.org/packages/11/15/b7b7dae667f0f8abdc5059feef5328cfab06d6b5e4a50a56728380457136/metapensiero.sphinx.patchdb-3.5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "32d33ab3d1e72533b2623d3e5073cdff", "sha256": "d40fde9baa04763cfd1274b43995c85031e6d2034c3a317ea44b57ba43d5776a" }, "downloads": -1, "filename": "metapensiero.sphinx.patchdb-3.5.tar.gz", "has_sig": false, "md5_digest": "32d33ab3d1e72533b2623d3e5073cdff", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 79821, "upload_time": "2019-06-21T09:26:25", "url": "https://files.pythonhosted.org/packages/11/15/b7b7dae667f0f8abdc5059feef5328cfab06d6b5e4a50a56728380457136/metapensiero.sphinx.patchdb-3.5.tar.gz" } ] }