{ "info": { "author": "", "author_email": "", "bugtrack_url": null, "classifiers": [], "description": "# pyctdev: python packaging common tasks for developers\n\nTools (and documentation) to support common tasks across many similar\nprojects, focusing on those making up [HoloViz.org](http://holoviz.org).\n\n**Note: documentation is draft/currently being written**\n\n## What is pyctdev?\n\nThe main part of pyctdev is a cross-platform, make-like tool plus library\nof common tasks to allow project admin tasks to be run equally well\nlocally or on various CI systems, on different platforms, or to support\ndifferent python package 'ecosystems' (pip and conda):\n\n```\n$ doit list\nbuild_docs build docs\ndevelop_install python develop install with specified optional groups of dependencies.\necosystem_setup Common pip setup\nenv_capture Report all information required to recreate current environment.\nenv_create TODO: create named environment if it doesn't already exist.\nenv_export TODO\nlist_envs\npackage_build Build pip package, then install and test all_quick (or other\npackage_upload Upload pip packages to pypi\ntest_all Run \"all\" tests\ntest_examples Run \"examples\" tests\ntest_flakes Run \"flakes\" tests\ntest_unit Run \"unit\" tests\n\n$ doit ecosystem=conda list\nbuild_docs build docs\ndevelop_install python develop install, with specified optional groups of dependencies (installed by conda only).\necosystem_setup Common conda setup (must be run in base env).\nenv_capture Report all information required to recreate current conda environment\nenv_create Create named environment if it doesn't already exist\nenv_export Generate a pinned environment.yaml from specified env, filtering against specified groups of deps.\nlist_envs\nminiconda_download Download Miniconda3-latest\nminiconda_install Install Miniconda3-latest to location if not already present\npackage_build Build and then test conda.recipe/ (or specified alternative).\npackage_upload Upload package built from conda.recipe/ (or specified alternative).\ntest_all Run \"all\" tests\ntest_examples Run \"examples\" tests\ntest_flakes Run \"flakes\" tests\ntest_unit Run \"unit\" tests\n```\n\nAlthough doit+pyctdev must be installed to run these tasks, the approach\nis trying to call standard python and/or conda tools where possible,\nso that people can run commands independently without installing\ndoit+pyctdev. This means pyctdev can be viewed as:\n\n * documentation of what all the common tasks are\n\n * documentation of the commands necessary to perform those tasks\n\n * a way to expose gaps in underlying tools that we might like to\n fill (or exposes our lack of knowledge of how to use them, so we\n can be corrected :) )\n\n * a way to map relatively unchanging \"high level tasks\" (e.g. \"run\n the unit tests\") to underlying specific commands that might change over\n time (e.g. as the python packaging ecosystem changes) or that vary\n between projects (e.g. run tests with nose or with pytest).\n\n * our current best understanding of how to perform the various tasks\n (balancing the best possible way with what's practically possible\n in general, given what tools are currently widely available).\n\nThe accompanying [background](background.md) document (even more draft\nthan this one!) contains more details, along with explanations for\nchoices. It's broken into the same sections, so can be read alongside\nthis document.\n\nThere's also an [instructions](instructions.md) document for setting\nup a new project (but it's only a placeholder right now...).\n\nIf you have a question, please feel free to open an issue (after first\nchecking the [FAQ](FAQ.md).\n\n\n## What does pyctdev cover?\n\npyctdev is a work in progress, and when it stabilizes we will need to\nexpand this description to include a clear mission statement about\nwhat is intended to be covered by pyctdev and which aspects of package\nmanagement are out of scope.\n\n### 0. What are all the tasks? How to run a task?\n\npyctdev shows what tasks there are, e.g. \"run unit tests\", \"build conda\npackage\", \"upload conda package\", \"install as a developer\", and so on.\n\npyctdev also documents how to perform those tasks, i.e. what the\nnecessary command(s) are for a task, or what tasks should be run\nbefore others.\n\nTo see all the tasks, you can type `doit list` in a project using pyctdev\nto get a list of the tasks with descriptions. `doit info` gives more\ndetail on any particular task. Alternatively, you can read the pyctdev\nsource code; most tasks are straightforward commands.\n\n\n### 1. Can run project admin tasks locally, on CI, and across platforms\n\ndoit/pyctdev are written in python so should work everywhere python's\navailable (not just on Unix-like systems, unlike many project\nconfiguration files). (And once any python's available, doit can be\nused to install other pythons if necessary - currently miniconda and\nanaconda.) Having the same command to run on each platform helps ensure\nthat testing, package building, and related tasks are done consistently\nacross platforms, which is particularly important when developers use\none platform but users will download packages for another.\n\nOther suggested tools used by pyctdev are also cross platform: tox,\nconda, pip, etc.\n\n\n### 2. support python and conda ecosystems\n\npyctdev supports performing most tasks with either the python/pip or the\nconda ecosystem. E.g. `doit develop_install` will typically run `pip\ninstall -e .[tests]`, which installs the dependencies using pip and\nthen does an editable install. Alternatively, `doit ecosystem=conda\ndevelop install` will install dependencies using conda, followed by an\neditable install. Projects can set a default ecosystem.\n\nThe ability to install with pip or conda, create reproducible/isolated\nenvironments with python tools (virtualenv+pip, or pipenv) or with\nconda tools (conda env), package for pip or conda, helps developers\nusing primarily one ecosystem to still support the other (e.g. via CI\nsystems).\n\n\n### 3. support multiple versions of python\n\nSimilarly to allowing developers to support both pip and conda\necosystems, pyctdev allows developers to support multiple versions of\npython. For python, doit uses tox to run same tests over multiple\nenvironments using tox. For conda, pyctdev runs conda build over multiple\nversions of python.\n\n\n### 4. dependencies in one place\n\npyctdev allows developers to express their project's \"abstract\"\ndependencies in one place. Currently this place is setup.py, as it's\nwidely supported by both python and conda tools. The dependencies\nlisted in setup.py are used for:\n\n * end-user pip packages\n\n * end-user conda packages\n\n * developers using conda\n\n * developers using pip\n\n * generating environment files (e.g. examples environment.yml)\n\nThe abstract dependencies may be transformed to more concrete ones,\ne.g. for a tutorial examples environment, versions of all dependencies\nmay be pinned to ensure reproducibility (see 10/environment files,\nbelow).\n\npyctdev supports transforming dependencies and generating environment.yml\n(and possibly pipenv or similar).\n\n\n### 5. dependencies labelled for different purposes\n\npyctdev supports expressing build and install/runtime dependencies, plus\nvarious optional groups of dependencies (e.g. for running examples,\nbuilding docs, etc).\n\npyctdev uses standard/generally supported python/pip/setuptools setup.py\narguments to do this (`install_requires` and `extras_require`). pip\nunderstands these, so the same optional dependency groups are\navailable to users (e.g. a user can run `pip install\npackage[examples]` to get package and the dependencies necessary to\nrun its examples.\n\nTo support 'options' in the conda ecosystem, multiple packages are\ngenerated - though typically our projects just have \"base\" and\n\"examples\" packages. `package-examples` depends on a specific pinned\n`package` (pinned at build time).\n\n\n### 6. testing of what users install\n\npyctdev encourages testing of the packages that users will install,\nrather than focusing only on testing what developers work with.\n\nIn the python ecosystem, tox is used to build a package, create a\nclean virtual environment, installs the package, and then run the\ntests. tox additionally supports running the same tests over multiple\nversions of python, in multiple environments (e.g. with different sets\nof dependencies installed), etc.\n\nIn the conda ecosystem, conda build is called multiple times to\nachieve the same.\n\n\n### 7. testing of what developers do\n\nIt's often difficult to contribute to a project, because setting it up\nto the point of being able to run the tests is difficult. Seasoned\nproject developers know what they are doing, but it's less obvious to\noccasional developers.\n\npyctdev ensures the dependencies required to develop a project are\nobvious, and encourages developers to keep them up to date (e.g. by\ntesting `doit develop_install` on neutral CI machines).\n\npyctdev also tries to capture how developers set up their environment.\nE.g. dependencies installed by conda, with a `python setup.py develop\n--no-deps` on top.\n\n\n### 8. Testing in different environments\n\nE.g. `doit package_build --test-python=py36 --test_requires=with_xarray --test-group=unit`\nwill build a package then install it into a python 3.6 environment,\nand will then further install `with_xarray` dependencies, and then\nwill run the unit tests. The dependencies for `with_xarray` are\nspecified in tox.ini (as are the unit test commands). This works with\necosystem=pip and ecosystem=conda. It's also possible to have extra\ntest commands that only run in a particular test environment\n(e.g. `with_xarray`).\n\n`doit test_unit` will run the unit tests in your current environment.\nIf there are extra commands for a particular environment, they will be\nrun if you select it. E.g. `doit test_unit --test-group\nwith_xarray`. However, your current environment is not altered by test\ncommands, so you would need to have installed `with_xarray`\ndependencies if necessary.\n\n\n### 9. packages on demand? simplify packaging recipes?\n\nAs well as specifying dependencies once, pyct attempts to express other\npackage metadata only once. Currently this is in setup.py. Templating\nis then used for conda build. This prevents the common situation where\ndescriptions, URLs, licenses, etc, are mismatched.\n\npyctdev expects project is being released first on pypi and on an\nanaconda.org channel. From these sources, conda-forge can be updated, followed by\nanaconda defaults (but we are not necessarily the maintainers of those\nchannels).\n\npyctdev is currently primarily supporting pure Python packages. While\nthey may often have complex, platform specific dependencies, the\npackages controlled by pyct are so far all pure Python. Therefore\nwe build noarch:python conda packages where possible. If we start\nmaintaining packages with binary code, pyct will be extended\nto support platform-specific packages, but for now none of our\npackages require that.\n\n\n### 10. Channels/sources of dependencies\n\nFor python/pip: typically just pypi.org. But other 'channels' can be\nspecified. E.g. test.pypi.org, or a private server.\n\nThe conda packages we maintain for HoloViz.org can usually be installed\non top of either anaconda defaults or conda-forge. We currently put\nthem on anaconda.org pyviz (releases) and pyviz/label/dev (dev\nversions), and only our specific packages are on this channel. For a\nvariety of reasons we recommend that any one install should not mix\nconda-forge and defaults. For a project with tricky requirements, we\nrecommend one above the other. Or if a project suffers in\nperformance on one or the other, we make a recommendation.\n\nOur dev builds and dev package releases of projects on Travis CI use\npyviz/label/dev to get other packages, while release package builds\njust use pyviz. And then if devs are happy with those packages,\nconda-forge and defaults should be updated.\n\n### 11. How to structure project\n\nAlthough it's not necessary, a common structure simplifies things\nacross multiple similar projects. HoloViz projects typically have\nrepositories that look like:\n\n```\npackage/\npackage/tests\npackage/tests/data\npackage/examples/\npackage/examples/data\npackage/examples/assets\nexamples -> package/examples\n\ndoc/ # minimal nbsite skeleton only\ndoc/assets # e.g. favicon - not relevant to notebooks\n```\n\nWe try to limit differences between what's in the repository and\nwhat's in the package shipped to users, to avoid creating custom\npackage building code.\n\n\n### 12. Unify how various tools are run\n\nOften, it's not clear how to run the tests for a project. Pyct already\nhelps with this by having high level tasks such as \"run unit\ntests\". However, pyctdev also encourages internal command definitions to\nappear only once.\n\nCurrently, setup.cfg is used to store global options for commands\n(e.g. flake8 rules), while tox.ini is used to store the various actual\ncommands used for different things (e.g. running unit tests, running\ntests in different environments, etc). (TODO: what is shared across\nprojects, and how? Would rather not have a config file for pyctdev...)\n\n\n### 13. What's tested, and how.\n\nThere are various tools for running tests (e.g. pytest, nose). An aim\nof pyctdev is for our HoloViz projects to all end up using the same\ndeveloper tools where possible. And to configure those tools in the\nsame kind of way.\n\n* unit tests: pytest\n\n* flakes: pyflakes\n\n* examples:\n\n * notebooks run without error: pytest plugin nbsmoke\n\n * notebooks flakes: pytest plugin nbsmoke\n\n * notebooks \"data tests\": pytest plugin nbva\n\n* performance/benchmark tests: (pytest-benchmark, custom stuff,\n airspeed velocity, ??)\n\n* ...?\n\npytest has features for defining (\"marking\") and then selecting groups\nof tests to run. So pyctdev expects there to be:\n\n * \"slow tests\" (`pytest -m slow`)\n\n * ...?\n\n\n### 14. docs\n\n#### website\n\n * nbsite for examples -> website\n\n#### live docs\n\n * Live/browser way for users to try examples: mybinder\n\n\n### 15. versioning\n\nVersion via git tag. Version is stored only in one place in the\nrepository (a git tag), and is written into packages. Every place that\nneeds to know version (`__init__.py`; packaging: `setup.py`,\n`meta.yaml`; docs) reads it from the single source.\n\nStoring in one place, and it being the tag rather than in the git repo\nsource code, makes it easier to automate various other 'release time'\ntasks. Our projects generally use\n[autover](https://github.com/pyviz/autover) (via param).\n\nVersioning scheme:\n\n * we use `vX.Y.Z`\n\n * post 1.0, (TODO: copy hv's scheme?)\n\n\n### 16. automate release type tasks on travis\n\nAs far as possible, just by running one or a couple of doit commands,\nwe avoid CI-provided magic except where it's truly unavoidable or very\nuseful (e.g. parallelizing builds, etc), because we need to support\nmultiple CI systems (Travis CI for Linux and Mac, plus Appveyor for\nWindows).\n\n#### automatically generated packages\n\nEvery (dev) release:\n\n * conda packages are built and uploaded to anaconda.org\n (pyviz/label/dev) pyviz/label/main\n\n * pip packages (sdist zip, universal wheel) are built and uploaded\n to (test.pypi.org) pypi.org\n\nA release happens when a `vX.Y.Z` tag is pushed. Dev releases can\neither be defined as \"every merge to master\" (e.g. for a mature\nproject), or \"every time a `vX.Y.ZaN` style tag is pushed (for a\nrapidly changing project).\n\nNote: \"package build\" means generate package, install package into\nclean environment, run tests.\n\n\n#### automatically generated website\n\nTwo main options:\n\n 1. for young, fast-moving projects: a single main website (default:\n https://package.github.io/) updated on releases (plus maybe also\n special post-release tags where we're fixing minor docs issues\n without changing code, which presumably must be tagged\n specially), with a separate dev website (default:\n https://pyviz-docs.github.io/package-master) updated on every\n push to master (or every time an alpha/beta/rc format tag is\n pushed ?).\n\n 2. Same as 1, but also archiving websites for each major release\n (i.e. one copy for X.Y, updated for each new .Z) over time until\n we eventually delete them. Presumably could actually just make 2\n the default, with the definition that only versions 1.0 or\n greater count as a major release, in which case it would follow\n policy 1 until reaching 1.0, then policy 2, thereby acting as\n appropriate for a young, fast-moving project until release 1.0,\n then archiving each x.y version.\n\nNote: for e.g. datashader, using Travis CI isn't currently feasible\n(build takes too long/uses too much memory/requires too-large\ndata). But Travis is just using doit commands, so same can be run\nlocally at release time.\n\n\n### 17. Extra CI things\n\n#### platforms\n\n* Ubuntu (Travis CI)\n\n* MacOS (Travis CI)\n\n* Windows (appveyor)\n\n\n#### caching\n\nInstalling miniconda and dependencies from scratch every time takes up\nquite a lot of build time for some projects.\n\nCaching of miniconda/conda environments is therefore\nsupported. (Supported also for python/pip, although speed is not an\nissue there).\n\nIn many ways, this could be a better test than installing from\nscratch, since many devs/users will be updating existing conda\ninstallations/environments rather than starting from scratch.\n\n\n#### build stages/parallelization of builds\n\nRather than running tasks sequentially (wall clock time consuming; a\ntask might affect subsequent ones), tasks can be run independently in\nparallel.\n\n### To add to docs\n\n* generating pinned conda package\n* generating environment.yml\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/pyviz/pyctdev", "keywords": "", "license": "BSD-3", "maintainer": "", "maintainer_email": "", "name": "pyctdev", "package_url": "https://pypi.org/project/pyctdev/", "platform": "", "project_url": "https://pypi.org/project/pyctdev/", "project_urls": { "Homepage": "http://github.com/pyviz/pyctdev" }, "release_url": "https://pypi.org/project/pyctdev/0.5.5/", "requires_dist": [ "doit", "cloudpickle", "pluggy", "py", "pip (>=19.1.1)", "conda (>=4.4) ; extra == 'ecosystem_conda'", "conda-build (>=3.10.1) ; extra == 'ecosystem_conda'", "tox ; extra == 'ecosystem_pip'", "twine ; extra == 'ecosystem_pip'", "wheel ; extra == 'ecosystem_pip'", "flake8 ; extra == 'tests'" ], "requires_python": ">=2.7", "summary": "python packaging common tasks for developers", "version": "0.5.5" }, "last_serial": 5511311, "releases": { "0.4.0": [ { "comment_text": "", "digests": { "md5": "1996dc5afb5b6ecac84f813697839cf6", "sha256": "303ae13d5e167b2993990bf6af184903b31e6870678258753f995df9f61e92dd" }, "downloads": -1, "filename": "pyctdev-0.4.0-py2-none-any.whl", "has_sig": false, "md5_digest": "1996dc5afb5b6ecac84f813697839cf6", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 94994, "upload_time": "2018-05-04T12:15:19", "url": "https://files.pythonhosted.org/packages/ff/df/4bcf9adb30227505673e76bc1f7eb5926724e5822526450969f980631c2e/pyctdev-0.4.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d36a4f187778131e7b4882bb677126b8", "sha256": "0226efe243948bf1682ecb3aa1cf6348619c388ac8b843cc06dfc9714abd5401" }, "downloads": -1, "filename": "pyctdev-0.4.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d36a4f187778131e7b4882bb677126b8", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7", "size": 94989, "upload_time": "2018-05-04T12:14:45", "url": "https://files.pythonhosted.org/packages/38/2e/2cb33f91c684c407be593b6eaa05526da06e7c8c4a54d0ac51d2b9a41f29/pyctdev-0.4.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2ee4372fc6fd9d335564d814c6bd776d", "sha256": "fd1d68319db89ab4c69a437c840165322ad9ba65ef97397756a0e339b049f9fa" }, "downloads": -1, "filename": "pyctdev-0.4.0.zip", "has_sig": false, "md5_digest": "2ee4372fc6fd9d335564d814c6bd776d", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 119927, "upload_time": "2018-05-04T12:14:46", "url": "https://files.pythonhosted.org/packages/06/96/5042b59d78e5967467e693b998a64cb33376bbfeb7dbf7ed5887921fd70a/pyctdev-0.4.0.zip" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "950b1bbebf1ad9d6c4a30b0b2229f99f", "sha256": "8810848cdee0b322dce42baa0cbf0306a569075e37a030489cf802b4b9f07461" }, "downloads": -1, "filename": "pyctdev-0.4.1-py2-none-any.whl", "has_sig": false, "md5_digest": "950b1bbebf1ad9d6c4a30b0b2229f99f", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 94995, "upload_time": "2018-05-04T12:40:49", "url": "https://files.pythonhosted.org/packages/45/80/c9e008f8b59631df4ea52d75e2f1eaddac74a86881805ced13a13ee9151f/pyctdev-0.4.1-py2-none-any.whl" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "ab96343a4317d5d1d396b02a290bb1cc", "sha256": "86ed122191e4ce7ca2d0e230c45507928f87204c99529afee3355788181322b2" }, "downloads": -1, "filename": "pyctdev-0.4.2-py2-none-any.whl", "has_sig": false, "md5_digest": "ab96343a4317d5d1d396b02a290bb1cc", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 94995, "upload_time": "2018-05-04T13:06:57", "url": "https://files.pythonhosted.org/packages/ad/30/3bdc38a76670c16d060d7f5a6f3a933d0bfb753f5a2682e37e79d797f8d0/pyctdev-0.4.2-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "59275d5129a82561942b1afe760ef036", "sha256": "deab301c808d9a760aeff680743bcad37b95912b586c8dbe3950e2b7f68b88a9" }, "downloads": -1, "filename": "pyctdev-0.4.2-py3-none-any.whl", "has_sig": false, "md5_digest": "59275d5129a82561942b1afe760ef036", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 94987, "upload_time": "2018-05-04T13:07:18", "url": "https://files.pythonhosted.org/packages/37/82/9d7fb2d0a21649d2a18a4b7e7cfb9fbddad12eff862d7b819174f4c3647c/pyctdev-0.4.2-py3-none-any.whl" } ], "0.4.3": [ { "comment_text": "", "digests": { "md5": "18771df027c40e4b59fa59c94cee9d3a", "sha256": "d228e8c94e5ddcb33b0d86a4715d643c6f4105ee338810eacb91dfcae30e58cf" }, "downloads": -1, "filename": "pyctdev-0.4.3-py2-none-any.whl", "has_sig": false, "md5_digest": "18771df027c40e4b59fa59c94cee9d3a", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 95050, "upload_time": "2018-05-04T20:04:18", "url": "https://files.pythonhosted.org/packages/94/4b/81849668be47f2e2c46ecf2b5d575404f94a767909ece56fdc36b011f92c/pyctdev-0.4.3-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "07f9534cf102f53fd9e41acd1ba33a96", "sha256": "63dff9b09c24ca4b883606d434363b3187edd5ff8f7ee679a3f7fa9fce260e9c" }, "downloads": -1, "filename": "pyctdev-0.4.3-py3-none-any.whl", "has_sig": false, "md5_digest": "07f9534cf102f53fd9e41acd1ba33a96", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 95041, "upload_time": "2018-05-04T20:03:38", "url": "https://files.pythonhosted.org/packages/70/0d/f5c06a4b4f8cb3a7a42551c472435d6919c32540fcd2f0044f5043941754/pyctdev-0.4.3-py3-none-any.whl" } ], "0.4.4": [ { "comment_text": "", "digests": { "md5": "dc34b95dc2b40b154e0adf3a5fddc10d", "sha256": "9a910a3bfd75c2ee5b740dd704e6d77afe171174eadfe6f24fca6ca72e9703da" }, "downloads": -1, "filename": "pyctdev-0.4.4-py2-none-any.whl", "has_sig": false, "md5_digest": "dc34b95dc2b40b154e0adf3a5fddc10d", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 95021, "upload_time": "2018-05-05T18:23:49", "url": "https://files.pythonhosted.org/packages/96/36/862901d563ddc1dcf27318d1fdca30cedcfede8b43f531aa348adaf7dd4d/pyctdev-0.4.4-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "971624a2e3d1815a5e224f11c9da7760", "sha256": "386a0312a63233bfe666e6a69a54997e95cd25f59be26f93d12c23244922726b" }, "downloads": -1, "filename": "pyctdev-0.4.4-py3-none-any.whl", "has_sig": false, "md5_digest": "971624a2e3d1815a5e224f11c9da7760", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 95012, "upload_time": "2018-05-05T18:23:50", "url": "https://files.pythonhosted.org/packages/22/8c/20960817063f67e8eb778f4c39f74a3b664265b3c60d5419571ae51458d2/pyctdev-0.4.4-py3-none-any.whl" } ], "0.4.6": [ { "comment_text": "", "digests": { "md5": "8f72d9f993a62f66845c1e03243ebb8c", "sha256": "bbb95fad5f97e025bedd6a23b0239a63c1ac7f07d03b5b914cec423efbf75e3a" }, "downloads": -1, "filename": "pyctdev-0.4.6-py2-none-any.whl", "has_sig": false, "md5_digest": "8f72d9f993a62f66845c1e03243ebb8c", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 102429, "upload_time": "2018-06-11T19:40:36", "url": "https://files.pythonhosted.org/packages/30/91/278d94f6b22c6cdf4445a0de6c9aaf41fd521dc215f0ecd5cc8fe042bdb3/pyctdev-0.4.6-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ae9d0ef9f0239fc55de53d31379b6a34", "sha256": "c5644d6a272220008cd3909f2d26b36b7a27b5410d8b4948694f7efdff35094d" }, "downloads": -1, "filename": "pyctdev-0.4.6-py3-none-any.whl", "has_sig": false, "md5_digest": "ae9d0ef9f0239fc55de53d31379b6a34", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 102423, "upload_time": "2018-06-11T19:40:19", "url": "https://files.pythonhosted.org/packages/3b/77/83b299d5aec0815737860c3f0a464f03dce6d533163ed0ac463af5075f2a/pyctdev-0.4.6-py3-none-any.whl" } ], "0.4.7": [ { "comment_text": "", "digests": { "md5": "fc7285eb7c3a3bac1648a44ab7eaeb59", "sha256": "4338ce4293ec7801bfd738d83f812ca63488569b853d40f6b28e1a89298ecf34" }, "downloads": -1, "filename": "pyctdev-0.4.7-py2-none-any.whl", "has_sig": false, "md5_digest": "fc7285eb7c3a3bac1648a44ab7eaeb59", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 147702, "upload_time": "2018-06-23T10:08:09", "url": "https://files.pythonhosted.org/packages/a7/dc/804ad790f0f800e0ff067d83498beada150d85db64e7cf460370a8de8b41/pyctdev-0.4.7-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6bd7e7851935e6f3ee98eaff1677b6c6", "sha256": "912886c6e4a78dbf60c14e0dab8c44073cdb1f95e587fa95202a46e6283dc2c5" }, "downloads": -1, "filename": "pyctdev-0.4.7-py3-none-any.whl", "has_sig": false, "md5_digest": "6bd7e7851935e6f3ee98eaff1677b6c6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 147695, "upload_time": "2018-06-23T10:08:32", "url": "https://files.pythonhosted.org/packages/96/2c/1455dd37c60316abc00966f51173f09de5183e05f4e4a754191bdf8b11cd/pyctdev-0.4.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "34978245e15ac10e420b2bc59cda2828", "sha256": "3b90d65979acf492b5e8ea4c8e0b74f0db8781851eeedb1d23affcb2d8726ce2" }, "downloads": -1, "filename": "pyctdev-0.4.7.tar.gz", "has_sig": false, "md5_digest": "34978245e15ac10e420b2bc59cda2828", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 170610, "upload_time": "2018-06-23T10:08:33", "url": "https://files.pythonhosted.org/packages/32/96/2d3da9a855e22235f8b09128856ff8b74464cad1721397164bfe9f0b7d7e/pyctdev-0.4.7.tar.gz" } ], "0.4.8": [ { "comment_text": "", "digests": { "md5": "29445892af0821aab22a5e2a3341c02c", "sha256": "9d298e6a02dc5747d15932e32bc8cca757cb526a71faa8f56db54c62f065762d" }, "downloads": -1, "filename": "pyctdev-0.4.8-py2-none-any.whl", "has_sig": false, "md5_digest": "29445892af0821aab22a5e2a3341c02c", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 148745, "upload_time": "2018-06-23T11:27:16", "url": "https://files.pythonhosted.org/packages/e8/3c/f60e437582457cd7588ddfd82e659d74c634fd90d6767428acec89710736/pyctdev-0.4.8-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6d5c099539a5a965651cb7741889c86e", "sha256": "09e01a025e6e73e7e27143c393e496731d027cf58fd71d43d08eb5c1bf6b6cfb" }, "downloads": -1, "filename": "pyctdev-0.4.8-py3-none-any.whl", "has_sig": false, "md5_digest": "6d5c099539a5a965651cb7741889c86e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 148483, "upload_time": "2018-06-23T11:26:49", "url": "https://files.pythonhosted.org/packages/4c/a3/815e1f46bf859c20541f0d316683b61ab93de332219ae858972b7e56791c/pyctdev-0.4.8-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "16311cd8c07fd32c58c988d33ae5d1f1", "sha256": "e9407568f093756157be20399650dbbe19e3f2b09728ff310e15daf1c8892ad0" }, "downloads": -1, "filename": "pyctdev-0.4.8.tar.gz", "has_sig": false, "md5_digest": "16311cd8c07fd32c58c988d33ae5d1f1", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 170993, "upload_time": "2018-06-23T11:26:50", "url": "https://files.pythonhosted.org/packages/98/7b/f8c2d416c1fca582d108d3417287748fe7a2564f0bb1b19b49c430731bea/pyctdev-0.4.8.tar.gz" } ], "0.4.9": [ { "comment_text": "", "digests": { "md5": "9d651dac5babd15a3b28a80027a0aa66", "sha256": "845b19dd7d1dbb94c629be19d5de9896bd6c477859fd181d44305070bb8a44d7" }, "downloads": -1, "filename": "pyctdev-0.4.9-py2-none-any.whl", "has_sig": false, "md5_digest": "9d651dac5babd15a3b28a80027a0aa66", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 149217, "upload_time": "2018-07-06T13:58:26", "url": "https://files.pythonhosted.org/packages/bd/84/86166dae9fc00e5a9a558350e0d23ab91f3907e23f6bae05d54a8c6d4117/pyctdev-0.4.9-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "525488da594ee6c5f6f250e5a91790dc", "sha256": "9b3b874590faee54041a2499bf21c209eae491694b971ae69e723e0abea18f78" }, "downloads": -1, "filename": "pyctdev-0.4.9-py3-none-any.whl", "has_sig": false, "md5_digest": "525488da594ee6c5f6f250e5a91790dc", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 148957, "upload_time": "2018-07-06T13:58:19", "url": "https://files.pythonhosted.org/packages/4d/71/78b8be9fe90a57129069300e7353481e1c441757c318144719544387dcb7/pyctdev-0.4.9-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "12fba52b702b72ad7f1cd489abb211db", "sha256": "63cc8146ece653aee8aa98fc2c4e1dc6cd2bd1278b9b5b32438c536504df90c6" }, "downloads": -1, "filename": "pyctdev-0.4.9.tar.gz", "has_sig": false, "md5_digest": "12fba52b702b72ad7f1cd489abb211db", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 171541, "upload_time": "2018-07-06T13:58:21", "url": "https://files.pythonhosted.org/packages/d4/16/f050481f73b37666ba9acc6dc6771ceb5844fca86bb35c89baaa00935572/pyctdev-0.4.9.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "e46f9a09a9c60a43218a446dab6d9479", "sha256": "acfec774212aca0c289b083abce9d9632da107386f573fe5d4bceccb1a2ff223" }, "downloads": -1, "filename": "pyctdev-0.5.0-py2-none-any.whl", "has_sig": false, "md5_digest": "e46f9a09a9c60a43218a446dab6d9479", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 149586, "upload_time": "2018-07-08T15:03:45", "url": "https://files.pythonhosted.org/packages/46/97/18fe4f73d4ea5f59dc93a91524177eb7c24982b065fd6821384d3c89329f/pyctdev-0.5.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ae8088f7501a28f44beb7166a2d3d8d9", "sha256": "3c19da87c333990daadc0e2f423b532b39f58cdc137563e69d9347ff2132975f" }, "downloads": -1, "filename": "pyctdev-0.5.0-py3-none-any.whl", "has_sig": false, "md5_digest": "ae8088f7501a28f44beb7166a2d3d8d9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 149324, "upload_time": "2018-07-08T15:03:00", "url": "https://files.pythonhosted.org/packages/08/e9/311f283874ce17372aa4d6f4e5b31cc13667595995217f83b08cbf3575e6/pyctdev-0.5.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2369c1262cd601a8bf43b422cdf44ee2", "sha256": "ecfbef8676031ba3ffd8c8214cf84ff0dec27b7b9ab31854e254dc83f10249b5" }, "downloads": -1, "filename": "pyctdev-0.5.0.tar.gz", "has_sig": false, "md5_digest": "2369c1262cd601a8bf43b422cdf44ee2", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 171892, "upload_time": "2018-07-08T15:03:02", "url": "https://files.pythonhosted.org/packages/5e/ea/03b1753a0fae4bcb552035bdcac462f89be1db4e5d9dbbadc8ca2f09972b/pyctdev-0.5.0.tar.gz" } ], "0.5.1": [ { "comment_text": "", "digests": { "md5": "49893b82488882779ddc73703fcbd48c", "sha256": "d0121c62198f41f7a0e6eacdf7bfd9a8f4e9019bc27b450a3916398c289c4933" }, "downloads": -1, "filename": "pyctdev-0.5.1-py2-none-any.whl", "has_sig": false, "md5_digest": "49893b82488882779ddc73703fcbd48c", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 149762, "upload_time": "2018-09-21T14:02:49", "url": "https://files.pythonhosted.org/packages/ca/4d/bee83fe559db8c7f0c112825a8d5903a0663034654d88869418da9ba17d1/pyctdev-0.5.1-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5b61efb7700367180fc34c8c50651236", "sha256": "9b7195a21771d74556bc7ce4128b74f15c19b5c2c48063ec6876d694a1267545" }, "downloads": -1, "filename": "pyctdev-0.5.1-py3-none-any.whl", "has_sig": false, "md5_digest": "5b61efb7700367180fc34c8c50651236", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 149501, "upload_time": "2018-09-21T14:03:22", "url": "https://files.pythonhosted.org/packages/bf/2d/b4a9e8295cb1d8a895a05c4406aabe224488504c9dcc9626ded54880b46d/pyctdev-0.5.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "387e7fc71d4ed950c96881cba37d3df2", "sha256": "f70ab4d515ba3373c3f5e3317cfe26ae07dcd0b72e7b88b3fd460233ac1b7808" }, "downloads": -1, "filename": "pyctdev-0.5.1.tar.gz", "has_sig": false, "md5_digest": "387e7fc71d4ed950c96881cba37d3df2", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 172085, "upload_time": "2018-09-21T14:03:23", "url": "https://files.pythonhosted.org/packages/96/36/bc0339d44d74e95c4143e630482f070f5f5b9264de197461026e001151b0/pyctdev-0.5.1.tar.gz" } ], "0.5.2": [ { "comment_text": "", "digests": { "md5": "a445cccfe0bf1dd0099795b7b24d9fe7", "sha256": "af3ca0010c3c7908c71ebb24326967730c595e42582f1e70d2384b2e9b80ce8b" }, "downloads": -1, "filename": "pyctdev-0.5.2-py2-none-any.whl", "has_sig": false, "md5_digest": "a445cccfe0bf1dd0099795b7b24d9fe7", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 149706, "upload_time": "2019-04-25T15:41:08", "url": "https://files.pythonhosted.org/packages/cc/5e/9fa464957f156edb3328bf598affc256f2b91b5e40f48e8bf7f6939be216/pyctdev-0.5.2-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "fcb7beb6296d80415dba19219e205aad", "sha256": "569ce5d1d86e75b922ad4e54d2510e0a2556f2214a27536633c0cd0b72f63d48" }, "downloads": -1, "filename": "pyctdev-0.5.2-py3-none-any.whl", "has_sig": false, "md5_digest": "fcb7beb6296d80415dba19219e205aad", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 149441, "upload_time": "2019-04-25T15:41:06", "url": "https://files.pythonhosted.org/packages/66/8e/6117c0a2e4de52361eb2bea71e2c949110c51a369ed9dc331f67c106f6e9/pyctdev-0.5.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7df9e9d38f523b2cfe8efc43f179de79", "sha256": "be191d82e09d80ee0456fca83d138ae5745428ba8d9c8150717094bc61f319c5" }, "downloads": -1, "filename": "pyctdev-0.5.2.tar.gz", "has_sig": false, "md5_digest": "7df9e9d38f523b2cfe8efc43f179de79", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 178066, "upload_time": "2019-04-25T15:41:10", "url": "https://files.pythonhosted.org/packages/26/33/d9ad164d38165788aace85c2975408c35e04af39956d10ffb7be48bbd857/pyctdev-0.5.2.tar.gz" } ], "0.5.3": [ { "comment_text": "", "digests": { "md5": "5d503368a6557abf388887968354139b", "sha256": "0f7cdc3e04d1ccac926b6c684b5d6217b4f89c42f78802501ff8d7bfcd890cf7" }, "downloads": -1, "filename": "pyctdev-0.5.3-py2-none-any.whl", "has_sig": false, "md5_digest": "5d503368a6557abf388887968354139b", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 149636, "upload_time": "2019-04-30T18:24:00", "url": "https://files.pythonhosted.org/packages/c8/08/ab836533b9a94e604d6f106d0bb8bdf3cb1be5d1a3454825bbce5a37c989/pyctdev-0.5.3-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "569253953757398b44fe59a3b9bae16c", "sha256": "b4b8a78be04298d3314a3e33d0c7c7e3d310d3130a8e6abc16cd5081d20f6370" }, "downloads": -1, "filename": "pyctdev-0.5.3-py3-none-any.whl", "has_sig": false, "md5_digest": "569253953757398b44fe59a3b9bae16c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 149372, "upload_time": "2019-04-30T18:24:43", "url": "https://files.pythonhosted.org/packages/a2/46/71256bffaf8f8abb1494fcdedf376aa8248b5b20c4b3685ca7a895258439/pyctdev-0.5.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0b8279f962f2444d19234e6c75c84056", "sha256": "999300ac81678dd4939b843813670d745974cf57f607f8de915509710760ed36" }, "downloads": -1, "filename": "pyctdev-0.5.3.tar.gz", "has_sig": false, "md5_digest": "0b8279f962f2444d19234e6c75c84056", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 178021, "upload_time": "2019-04-30T18:24:46", "url": "https://files.pythonhosted.org/packages/92/82/5e2911a5362d5754b34be1043a198de81b5a96d9966615697399d9ddd74d/pyctdev-0.5.3.tar.gz" } ], "0.5.4": [ { "comment_text": "", "digests": { "md5": "e7c39e12a14ae786161201762b1d525b", "sha256": "0b3b938591a496f32015e81f5e977ce6868b4fbfef534f142c4e4d7600f28ff6" }, "downloads": -1, "filename": "pyctdev-0.5.4-py2-none-any.whl", "has_sig": false, "md5_digest": "e7c39e12a14ae786161201762b1d525b", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 149637, "upload_time": "2019-07-09T20:03:44", "url": "https://files.pythonhosted.org/packages/9b/70/efc4ff0ab63a863cf56fb752245c7b64c7edd25604df1f92fe368bc6d5c1/pyctdev-0.5.4-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ded63618e8bc6a30ea3ba296a83e12b2", "sha256": "050f9c880be5154d2dfaa9a9051e12890491d355cec9132fdb361a2472c028b4" }, "downloads": -1, "filename": "pyctdev-0.5.4-py3-none-any.whl", "has_sig": false, "md5_digest": "ded63618e8bc6a30ea3ba296a83e12b2", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 149370, "upload_time": "2019-07-09T20:03:51", "url": "https://files.pythonhosted.org/packages/6e/23/fee2e2e2ee71654f05a41fb69b4fd172375b6bde0817191d1571c3c2c235/pyctdev-0.5.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8ffe46e065540590cbc7706794085a19", "sha256": "0785739ca9650be2ed3c4d1b7b1b6b3d9dcd1d6d8e94aaeb3732a20fc7cf8bde" }, "downloads": -1, "filename": "pyctdev-0.5.4.tar.gz", "has_sig": false, "md5_digest": "8ffe46e065540590cbc7706794085a19", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 177956, "upload_time": "2019-07-09T20:03:53", "url": "https://files.pythonhosted.org/packages/7b/d8/3cf37ec089b7215a28902d0830b21a7bf6d970da28ebdb9cbae4f2c641fb/pyctdev-0.5.4.tar.gz" } ], "0.5.5": [ { "comment_text": "", "digests": { "md5": "4633ce840a84e3ba6627fbcfb0017541", "sha256": "9fda181a87f8d2277638f9f1fb2682c8aab2821b5d57c5067bf034e7d48e17be" }, "downloads": -1, "filename": "pyctdev-0.5.5-py2-none-any.whl", "has_sig": false, "md5_digest": "4633ce840a84e3ba6627fbcfb0017541", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 149647, "upload_time": "2019-07-10T10:35:44", "url": "https://files.pythonhosted.org/packages/24/f0/3a0e0a8989782ee859964bbb991841acfa5bcd3238980ce8c45a920b36b9/pyctdev-0.5.5-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d23e12fbd5033650ed473cb402a7ffe0", "sha256": "d5ec2f3d255f3a372880b9217ea3320838c768508d45ecfa3a08051c506d0947" }, "downloads": -1, "filename": "pyctdev-0.5.5-py3-none-any.whl", "has_sig": false, "md5_digest": "d23e12fbd5033650ed473cb402a7ffe0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 149380, "upload_time": "2019-07-10T10:33:55", "url": "https://files.pythonhosted.org/packages/a1/79/4d61167d10a8876cc16b0a7e558bd720bbcb7d32fae5fd5dd6cefbf5013d/pyctdev-0.5.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ad4ea35afbebfb93afd8d28ee7ea0698", "sha256": "a2db7e21c60515f3111bcf45fcd24624f852e7abfb1c11d44fc2e210c65a88af" }, "downloads": -1, "filename": "pyctdev-0.5.5.tar.gz", "has_sig": false, "md5_digest": "ad4ea35afbebfb93afd8d28ee7ea0698", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 177989, "upload_time": "2019-07-10T10:33:57", "url": "https://files.pythonhosted.org/packages/e7/70/652a83ba8536a1e95870a7637d372d6cc0828564c80f53df924611122644/pyctdev-0.5.5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "4633ce840a84e3ba6627fbcfb0017541", "sha256": "9fda181a87f8d2277638f9f1fb2682c8aab2821b5d57c5067bf034e7d48e17be" }, "downloads": -1, "filename": "pyctdev-0.5.5-py2-none-any.whl", "has_sig": false, "md5_digest": "4633ce840a84e3ba6627fbcfb0017541", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": ">=2.7", "size": 149647, "upload_time": "2019-07-10T10:35:44", "url": "https://files.pythonhosted.org/packages/24/f0/3a0e0a8989782ee859964bbb991841acfa5bcd3238980ce8c45a920b36b9/pyctdev-0.5.5-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d23e12fbd5033650ed473cb402a7ffe0", "sha256": "d5ec2f3d255f3a372880b9217ea3320838c768508d45ecfa3a08051c506d0947" }, "downloads": -1, "filename": "pyctdev-0.5.5-py3-none-any.whl", "has_sig": false, "md5_digest": "d23e12fbd5033650ed473cb402a7ffe0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 149380, "upload_time": "2019-07-10T10:33:55", "url": "https://files.pythonhosted.org/packages/a1/79/4d61167d10a8876cc16b0a7e558bd720bbcb7d32fae5fd5dd6cefbf5013d/pyctdev-0.5.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ad4ea35afbebfb93afd8d28ee7ea0698", "sha256": "a2db7e21c60515f3111bcf45fcd24624f852e7abfb1c11d44fc2e210c65a88af" }, "downloads": -1, "filename": "pyctdev-0.5.5.tar.gz", "has_sig": false, "md5_digest": "ad4ea35afbebfb93afd8d28ee7ea0698", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 177989, "upload_time": "2019-07-10T10:33:57", "url": "https://files.pythonhosted.org/packages/e7/70/652a83ba8536a1e95870a7637d372d6cc0828564c80f53df924611122644/pyctdev-0.5.5.tar.gz" } ] }