{ "info": { "author": "Niall Douglas and David Beazley", "author_email": "", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Topic :: Software Development :: Build Tools" ], "description": "A C99 preprocessor written in pure Python\n=========================================\n.. role:: c(code)\n :language: c\n\n.. |travis| image:: https://travis-ci.org/ned14/pcpp.svg?branch=master\n :align: middle\n :target: https://travis-ci.org/ned14/pcpp\n\n\\(C) 2018-2019 Niall Douglas http://www.nedproductions.biz/ and (C) 2007-2019 David Beazley http://www.dabeaz.com/\n\nPyPI: https://pypi.python.org/pypi/pcpp Github: https://github.com/ned14/pcpp API reference docs: https://ned14.github.io/pcpp/\n\nTravis master branch all tests passing for Python v2 and v3: |travis|\n\nA pure universal Python C (pre-)preprocessor implementation very useful for pre-preprocessing header only\nC++ libraries into single file includes and other such build or packaging stage malarky.\nThe implementation can be used as a Python module (`see API reference `_)\nor as a command line tool ``pcpp`` which\ncan stand in for a conventional C preprocessor (i.e. it'll accept similar arguments).\n\nYour includes can be benchmarked for heft in order to improve your build times! See\nthe ``--times`` and ``--filetimes`` options.\n\nA very unique facility of this C preprocessor is *partial* preprocessing so you can\nprogrammatically control how much preprocessing is done by ``pcpp`` and how much is\ndone by the C or C++ compiler's preprocessor. The ultimate control is by subclassing\nthe :c:`Preprocessor` class in Python from which you can do anything you like, however\nfor your convenience the ``pcpp`` command line tool comes with the following canned\npartial preprocessing algorithms:\n\n**passthru-defines**\n Pass through but still execute #defines and #undefs if not always removed by\n preprocessor logic. This ensures that including the output sets exactly the same\n macros as if you included the original, plus include guards work.\n\n**passthru-unfound-includes**\n If an :c:`#include` is not found, pass it through unmodified. This is very useful\n for passing through includes of system headers.\n\n**passthru-undefined-exprs**\n This is one of the most powerful pass through algorithms. If an expression passed to\n :c:`#if` (or its brethern) contains an unknown macro, expand the expression with\n known macros and pass through *unexecuted*, and then pass through the remaining block.\n Each :c:`#elif` is evaluated in turn and if it does not contain unknown macros, it will be\n executed immediately. Finally, any :c:`#else` clause is always passed through *unexecuted*.\n Note that include guards normally defeat this algorithm, so those are specially detected and\n ignored.\n\n**passthru-comments**\n A major use case for ``pcpp`` is as a preprocessor for the `doxygen `_\n reference documentation tool whose preprocessor is unable to handle any preprocessing\n of any complexity. ``pcpp`` can partially execute the preprocessing which doxygen\n is incapable of, thus generating output which produces good results with doxygen.\n Hence the ability to pass through comments containing doxygen markup is very useful.\n\n**passthru-magic-macros**\n Don't expand ``__DATE__``, ``__TIME__``, ``__FILE__``, ``__LINE__`` nor ``__COUNTER__``.\n\nStandards (non-)compliance\n--------------------------\n``pcpp`` passes a modified edition of the `mcpp `_ unit\ntest suite. Modifications done were to clarify ternary operators with extra brackets,\nplus those testing the unusual special quirks in expression evaluation (see detailed\ndescription below). It also passes the list of \"preprocessor torture\" expansion fragments\nin the C11 standard, correctly expanding some very complex recursive macro expansions\nwhere expansions cause new macro expansions to be formed. In this, it handily beats\nthe MSVC preprocessor and ought to handle most C99 preprocessor metaprogramming.\nIf you compare its output side-by-side to that of GCC or clang's preprocessor, results\nare extremely close indeed with blank line collapsing being the only difference.\n\nThe most non-conforming part is :c:`#if` expression\nparsing (donations of a proper yacc based parser for executing :c:`#if` expressions based on\nhttp://www.dabeaz.com/ply/ are welcome). In practice, in most real world code, you\nwon't notice the departures and if you do, the application of extra brackets to\ngroup subexpressions so Python's :c:`eval()` executes right will fix it.\n\nA full, detailed list of known non-conformance with the C99 standard is below. We have\nbeen told that ``pcpp`` does not pass the Boost.Wave preprocessor test suite, but\nthe chances of that biting most people is low. If it does, pull requests with bug\nfixes and new unit tests for the fix are welcome.\n\nNote that most of this preprocessor was written originally by David Beazley to show\noff his excellent Python Lex-Yacc library PLY (http://www.dabeaz.com/ply/) and is\nhidden in there without being at all obvious given the number of Stackoverflow\nquestions which have asked for a pure Python C preprocessor implementation. This\nimplementation fixes a lot of conformance bugs (the original was never intended to\nrigidly adhere to the C standard) and adds in a test suite based on the C11 preprocessor\ntorture samples plus the mcpp preprocessor test suite. Still, this project would\nnot be possible without David's work, so please take off your hat and give a bow towards him.\n\nCommand line tool ``pcpp``:\n---------------------------\nThe help from the command line tool ``pcpp``::\n\n usage: pcpp [-h] [-o [path]] [-D macro[=val]] [-U macro] [-N macro] [-I path]\n [--passthru-defines] [--passthru-unfound-includes]\n [--passthru-unknown-exprs] [--passthru-comments]\n [--disable-auto-pragma-once] [--line-directive [form]] [--debug]\n [--time] [--filetimes [path]] [--version]\n [input [input ...]]\n\n A pure universal Python C (pre-)preprocessor implementation very useful for\n pre-preprocessing header only C++ libraries into single file includes and\n other such build or packaging stage malarky.\n\n positional arguments:\n input Files to preprocess\n\n optional arguments:\n -h, --help show this help message and exit\n -o [path] Output to a file instead of stdout\n -D macro[=val] Predefine name as a macro [with value]\n -U macro Pre-undefine name as a macro\n -N macro Never define name as a macro, even if defined during\n the preprocessing.\n -I path Path to search for unfound #include's\n --passthru-defines Pass through but still execute #defines and #undefs if\n not always removed by preprocessor logic\n --passthru-unfound-includes\n Pass through #includes not found without execution\n --passthru-unknown-exprs\n Unknown macros in expressions cause preprocessor logic\n to be passed through instead of executed by treating\n unknown macros as 0L\n --passthru-comments Pass through comments unmodified\n --passthru-magic-macros\n Pass through double underscore magic macros unmodified\n --disable-auto-pragma-once\n Disable the heuristics which auto apply #pragma once\n to #include files wholly wrapped in an obvious include\n guard macro\n --line-directive [form]\n Form of line directive to use, defaults to #line,\n specify nothing to disable output of line directives\n --debug Generate a pcpp_debug.log file logging execution\n --time Print the time it took to #include each file\n --filetimes [path] Write CSV file with time spent inside each included\n file, inclusive and exclusive\n --compress Make output as small as possible\n --version show program's version number and exit\n\n Note that so pcpp can stand in for other preprocessor tooling, it ignores any\n arguments it does not understand.\n\nQuick demo of pass through mode\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nLet us look at an example for pass through mode. Here is the original:\n\n.. code-block:: c\n\n #if !defined(__cpp_constexpr)\n #if __cplusplus >= 201402L\n #define __cpp_constexpr 201304 // relaxed constexpr\n #else\n #define __cpp_constexpr 190000\n #endif\n #endif\n #ifndef BOOSTLITE_CONSTEXPR\n #if __cpp_constexpr >= 201304\n #define BOOSTLITE_CONSTEXPR constexpr\n #endif\n #endif\n #ifndef BOOSTLITE_CONSTEXPR\n #define BOOSTLITE_CONSTEXPR\n #endif\n\n``pcpp test.h --passthru-defines --passthru-unknown-exprs`` will output:\n\n.. code-block:: c\n\n #if !defined(__cpp_constexpr)\n #if __cplusplus >= 201402\n #define __cpp_constexpr 201304\n #else\n #define __cpp_constexpr 190000\n #endif\n #endif\n #ifndef BOOSTLITE_CONSTEXPR\n #if __cpp_constexpr >= 201304\n #define BOOSTLITE_CONSTEXPR constexpr\n #endif\n #endif\n #ifndef BOOSTLITE_CONSTEXPR\n #define BOOSTLITE_CONSTEXPR\n #endif\n\nThis is because ``__cpp_constexpr`` was not defined, so because of the ``--passthru-unknown-exprs`` flag\nwe pass through everything inside that if block **unexecuted** i.e. defines and undefs are NOT executed by\n``pcpp``. Let's define ``__cpp_constexpr``:\n\n``pcpp test.h --passthru-defines --passthru-unknown-exprs -D __cpp_constexpr``\n\n.. code-block:: c\n\n #line 8 \"test.h\"\n #ifndef BOOSTLITE_CONSTEXPR\n\n\n\n #endif\n #ifndef BOOSTLITE_CONSTEXPR\n #define BOOSTLITE_CONSTEXPR\n #endif\n\nSo, big difference now. We execute the entire first if block as ``__cpp_constexpr`` is now defined, thus\nleaving whitespace. Let's try setting ``__cpp_constexpr`` a bit higher:\n\n``pcpp test.h --passthru-defines --passthru-unknown-exprs -D __cpp_constexpr=201304``\n\n.. code-block:: c\n\n #line 8 \"test.h\"\n #ifndef BOOSTLITE_CONSTEXPR\n\n #define BOOSTLITE_CONSTEXPR constexpr\n\n #endif\n\nAs you can see, the lines related to the known ``__cpp_constexpr`` are executed and removed, passing through\nany if blocks with unknown macros in the expression.\n\nWhat if you want a macro to be known but undefined? The -U (to undefine) flag has an obvious meaning in pass\nthrough mode in that it makes a macro no longer unknown, but known to be undefined.\n\n``pcpp test.h --passthru-defines --passthru-unknown-exprs -U __cpp_constexpr``\n\n.. code-block:: c\n\n #if __cplusplus >= 201402\n #define __cpp_constexpr 201304\n #else\n #define __cpp_constexpr 190000\n #endif\n\n #ifndef BOOSTLITE_CONSTEXPR\n\n\n\n #endif\n #ifndef BOOSTLITE_CONSTEXPR\n #define BOOSTLITE_CONSTEXPR\n #endif\n\nHere ``__cpp_constexpr`` is known to be undefined so the first clause executes, but ``__cplusplus`` is\nunknown so that entire block is passed through unexecuted. In the next test comparing ``__cpp_constexpr``\nto 201304 it is still known to be undefined, and so 0 >= 201304 is the expressions tested which is false,\nhence the following stanza is removed entirely.\n\nHelping ``pcpp`` using source code annotation\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nYou can achieve a great deal using -D (define), -U (undefine) and -N (never define) on the command line,\nbut for more complex preprocessing it gets hard to pass through the correct logic without some source code\nannotation.\n\n``pcpp`` lets you annotate which part of an if block being passed through due to use of unknown macros\nto also be executed in addition to the pass through. For this use ``__PCPP_ALWAYS_FALSE__`` or\n``__PCPP_ALWAYS_TRUE__`` which tells ``pcpp`` to temporarily start executing the passed through\npreprocessor commands e.g.\n\n.. code-block:: c\n\n #if !defined(__cpp_constexpr)\n #if __cplusplus >= 201402L \n #define __cpp_constexpr 201304\n #elif !__PCPP_ALWAYS_FALSE__ // pcpp please execute this next block\n #define __cpp_constexpr 190000\n #endif\n #endif\n #ifndef BOOSTLITE_CONSTEXPR\n #if __cpp_constexpr >= 201304\n #define BOOSTLITE_CONSTEXPR constexpr\n #endif\n #endif\n #ifndef BOOSTLITE_CONSTEXPR\n #define BOOSTLITE_CONSTEXPR\n #endif\n\nNote that ``__PCPP_ALWAYS_FALSE__`` will always be false in any other preprocessor, and it is also\nfalse in ``pcpp``. However it causes ``pcpp`` to execute the define of ``__cpp_constexpr`` to 190000:\n\n``pcpp test.h --passthru-defines --passthru-unknown-exprs``\n\n.. code-block:: c\n\n #if !defined(__cpp_constexpr)\n #if __cplusplus >= 201402\n #define __cpp_constexpr 201304\n #elif 1\n #define __cpp_constexpr 190000\n #endif\n #endif\n #ifndef BOOSTLITE_CONSTEXPR\n\n\n\n #endif\n #ifndef BOOSTLITE_CONSTEXPR\n #define BOOSTLITE_CONSTEXPR\n #endif\n\nThis is one way of marking up ``#else`` clauses so they always execute in a normal preprocessor\nand also pass through with execution with ``pcpp``. You can, of course, also place ``|| __PCPP_ALWAYS_FALSE__``\nin any ``#if`` stanza to cause it to be passed through with execution, but not affect the\npreprocessing logic otherwise.\n\nWhat's implemented by the ``Preprocessor`` class:\n=================================================\n- Digraphs and Trigraphs\n- line continuation operator '``\\``'\n- C99 correct elimination of comments and maintenance of whitespace in output.\n- :c:`__DATE__`, :c:`__TIME__`, :c:`__FILE__`, :c:`__LINE__`. Note that :c:`__STDC__` et al are NOT defined by\n default, you need to define those manually before starting preprocessing.\n- :c:`__COUNTER__`, a very common extension\n- Object :c:`#define`\n- Function :c:`#define macro(...)`\n\n - Retokenisation and reexpansion after expansion is C99 compliant.\n\n- :c:`#undef`\n- :c:`#include \"path\"`, :c:`` and :c:`PATH`\n- :c:`defined` operator\n- C operators:\n\n - :c:`+, -, !, ~`\n - :c:`*, /, %`\n - :c:`+, -`\n - :c:`<<, >>`\n - :c:`<, <=, >, >=`\n - :c:`==, !=`\n - :c:`&`\n - :c:`^`\n - :c:`|`\n - :c:`&&`\n - :c:`||`\n - :c:`x ? y : z` (partial support, see known bugs)\n\n- :c:`#if`, :c:`#ifdef`, :c:`#ifndef`, :c:`#elif`, :c:`#else`, :c:`#endif`\n- Stringizing operator #\n- Token pasting operator ##\n- :c:`#pragma once`, a very common extension\n\nAdditionally implemented by ``pcpp`` command line tool:\n-------------------------------------------------------\n- :c:`#error` (default implementation prints to stderr and increments the exit code)\n- :c:`#warning` (default implementation prints to stderr)\n\nNot implemented yet (donations of code welcome):\n------------------------------------------------\n- :c:`#pragma` anything other than :c:`once`.\n- :c:`_Pragma` used to emit preprocessor calculated #pragma.\n- :c:`#line num`, :c:`num \"file\"` and :c:`NUMBER FILE`.\n\nKnown bugs (ordered from worst to least worst):\n-----------------------------------------------\n**Expression evaluation is a bit broken**\n Currently :c:`#if` expressions are evaluated by converting them into Python\n expressions and calling :c:`eval()` on them. This works surprisingly well\n most of the time, but because Python is not C, corner cases break.\n These are the known such broken corner cases:\n\n - Unary operator evaluation will break for evil expressions such as :c:`-!+!9`\n because logical NOT in Python results in a boolean, not an integer, and\n a unary plus or negative boolean is invalid syntax in Python\n - Similarly expressions which assume that boolean operations output either\n a zero or a one will fail e.g. :c:`(2 || 3) == 0`\n - Python has no concept of an unsigned integer and C expressions relying\n on unsigned integer semantics will fail badly e.g. :c:`-1 <= 0U`\n is supposed to be evaluated as false in the C preprocessor, but it will be\n evaluated as true under this implementation. To be honest\n if your preprocessor logic is relying on those sorts of behaviours, you should rewrite it.\n - Without a back tracking parser, the C ternary operator is hard to accurately\n convert into a Python ternary operation, so you need to help it by using one\n of these two forms:\n\n - :c:`(x) ? y : z` (z gets evaluated according to Python not C precedence)\n - :c:`(x ? y : z)` (preferred, evaluates correctly, we inject brackets\n around the subexpessions before sending to Python)\n\n A proper lexing parser based on http://www.dabeaz.com/ply/'s yacc module has\n been started and can be found in the https://github.com/ned14/pcpp/tree/yacc_expression_evaluator\n branch. Time to complete it, is the problem, and any pull requests helping with\n that are welcome.\n\n**We do not pass the Boost.Wave preprocessor test suite**\n A lot of bugs have been fixed since this was reported, however the chances are\n that ``pcpp`` still doesn't pass it. A TODO is to port the Wave test suite to\n Python and find out how bad things are. We suspect that any failures will be\n in highly estoric use cases i.e. known illegal input. If you only use valid\n input then we expect you generally won't have trouble.\n\nCustomising your own preprocessor:\n==================================\nSee the API reference docs at https://ned14.github.io/pcpp/\n\nYou can find an example of overriding the ``on_*()`` processing hooks at https://github.com/ned14/pcpp/blob/master/pcpp/pcpp_cmd.py\n\nHistory:\n========\nv1.21 (30th September 2019):\n----------------------------\n- Fix bug where token pasting two numeric tokens did not yield a numeric token. Thanks\n to Sei-Lisa for reporting this.\n- BREAKING CHANGE: Paths emitted by pcpp into ``#line`` directives now are relative to the\n working directory of the process when ``Preprocessor`` is initialised. This includes\n added search paths - files included from those locations will be emitted with a sequence\n of ``../`` to relativise the path emitted. If no path exists between the working\n directory and the path of the file being emitted, an absolute path is emitted instead.\n\n If you wish to disable this new behaviour, or use different behaviour, you can\n customise the new `rewrite_paths` member variable of ``Preprocessor``.\n- Fix bug where ``__LINE__`` was expanding into the line number of its definition instead\n of its use. Thanks to Sei-Lisa for reporting this.\n- Add ``--passthru-magic-macros`` command line option.\n- BREAKING CHANGE: The ``PreprocessorHooks`` and ``OutputDirective`` interface has\n changed. One now must specify the kind of ``OutputDirective`` abort one wants, and one\n can now both ignore AND remove directives. ``on_directive_handle()`` and\n ``on_directive_unknown()`` now take an extra parameter ``precedingtoks``, these are the\n tokens from the ``#`` up to the directive.\n- Fix a corner case where ``FUNC(void)foo()`` expanded to ``voidfoo()`` and not\n ``void foo()`` which is a very common non-conforming extension of the C preprocessor.\n Thanks to OmegaDoom for reporting this.\n- Add tokens for all the C operators, to help implementation of an expression evaluator.\n- Updated embedded ply to HEAD (2019-04-25)\n- Fix ``#include`` not working if no ``-I`` parameters were supplied. Thanks to csm10495\n for reporting this.\n\nv1.20 (7th January 2019):\n-------------------------\n- Now supports character literals in expressions. Thanks to untaugh for the pull request\n adding this.\n- Stopped the default collapsing of whitespace in output, and made it optional via a\n new command line option ``--compress``.\n- Fixed extraneous whitespace in ``--passthru-comments`` caused by multiline comments.\n Thanks to p2k for reporting this.\n- Fixed bug where defining a macro via string did not set the source attribute in the\n token. Thanks to ZedThree for reporting this.\n- Stop triggering an exception when no arguments are supplied to pcpp. Thanks to\n virtuald for reporting this.\n- Rebase onto PLY latest from Dec 28th 2018 (https://github.com/dabeaz/ply/commit/a37e0839583d683d95e70ce1445c0063c7d4bd21). Latest\n PLY no longer works using pypi packaging, David wants people to include the source of\n PLY directly. pcpp does this via a git submodule, and has setuptools bundle the submodule.\n- Add a formal LICENSE.txt file, as requested by Sei-Lisa.\n- Fix failure to issue ``#line`` directive for first include file in a file. Thanks to\n Sei-Lisa for reporting this.\n\nv1.1 (19th June 2018):\n----------------------\n- Added the ``--times`` and ``--filetimes`` features.\n- Fix bug where macros containing operator `defined` were not being expanded properly.\n- Added the ability to accept multiple inputs, they are concatenated into the output.\n- Fix bug where lines beginning with `#` and no contents caused an internal preprocessor error.\n- Fix bug where the macro expansion ``par par##ext`` was expanding into ``parext parext``.\n\nv1.01 (21st Feb 2018):\n----------------------\n- Fix bug where in pass through mode, an #elif in an #if block inside an #if block in ifpassthru was failing to be passed through.\n- Downgraded failure to evaluate an expression to a warning.\n- Fix missing Readme.rst in pypi package.\n\nv1.00 (13th Mar 2017):\n----------------------\nFirst release\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://pypi.python.org/pypi/pcpp", "keywords": "", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "pcpp", "package_url": "https://pypi.org/project/pcpp/", "platform": "", "project_url": "https://pypi.org/project/pcpp/", "project_urls": { "Homepage": "http://pypi.python.org/pypi/pcpp" }, "release_url": "https://pypi.org/project/pcpp/1.21/", "requires_dist": null, "requires_python": "", "summary": "A C99 preprocessor written in pure Python", "version": "1.21" }, "last_serial": 5906391, "releases": { "1.0.1": [ { "comment_text": "", "digests": { "md5": "f307eeb5425e7d24dd1c69c1cb6ab598", "sha256": "dd454d3e30e7f735d4ca09fbc90ec400fbf5cb774af986c5a4601e010579e6b2" }, "downloads": -1, "filename": "pcpp-1.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "f307eeb5425e7d24dd1c69c1cb6ab598", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 29945, "upload_time": "2018-02-21T18:57:49", "url": "https://files.pythonhosted.org/packages/1b/1d/d144fe46b71eaba087baa9c6e757b76504e2ea41bf54bd70db05c8a152d1/pcpp-1.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a549ed8b69154d083db82521ea317df6", "sha256": "e67bc62a391d5c252f3498b1434374483c3cb3b11a3be7b51fea40ea61b057fc" }, "downloads": -1, "filename": "pcpp-1.0.1.tar.gz", "has_sig": false, "md5_digest": "a549ed8b69154d083db82521ea317df6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23569, "upload_time": "2018-02-21T18:57:51", "url": "https://files.pythonhosted.org/packages/b1/f7/38c3d61e9303a67af208a9a6f2941f4feafccac9a04ffc56fd32238f6657/pcpp-1.0.1.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "0b638858e8605492cf678f0cfc5a0fa4", "sha256": "5a0fd5a71a0c11afb519669e0555080796a92170474ccc74335cbf0ac1aaa2c2" }, "downloads": -1, "filename": "pcpp-1.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "0b638858e8605492cf678f0cfc5a0fa4", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 24864, "upload_time": "2018-06-20T08:11:30", "url": "https://files.pythonhosted.org/packages/f0/1f/f28cabe90eb9557dc0354709ebcec666f3ecf3dd6b0ae3b176ac6c10c54a/pcpp-1.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c6609f4eeb57d569da6a8bed33b79c05", "sha256": "765bdd8002889615fb23d5205f26b14f78768577e5d3883775218924a5f8e494" }, "downloads": -1, "filename": "pcpp-1.1.0.tar.gz", "has_sig": false, "md5_digest": "c6609f4eeb57d569da6a8bed33b79c05", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25154, "upload_time": "2018-06-20T08:07:01", "url": "https://files.pythonhosted.org/packages/39/a9/c7478af528a235cf88dabe583bc6651243c0531efc6f9967eafc33f4d151/pcpp-1.1.0.tar.gz" } ], "1.20.1": [ { "comment_text": "", "digests": { "md5": "b021c78abeba7f938216fa9feb197603", "sha256": "d4c2b208d3788a188b07f2865d51d4ea7ebc677ddf856554203c476ec7716755" }, "downloads": -1, "filename": "pcpp-1.20.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "b021c78abeba7f938216fa9feb197603", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 76216, "upload_time": "2019-01-07T20:31:50", "url": "https://files.pythonhosted.org/packages/33/7b/e8ca3707a86a21685214cbe8d7d77a71a2964dfef01c1fe9bbfad9ff6b39/pcpp-1.20.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0e5e8b330a3a0290aca50d226d40ea96", "sha256": "701955f95d25518f77a07563e69b478d6258241cf85946497721c629b0d8aab9" }, "downloads": -1, "filename": "pcpp-1.20.1.tar.gz", "has_sig": false, "md5_digest": "0e5e8b330a3a0290aca50d226d40ea96", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 72359, "upload_time": "2019-01-07T20:31:51", "url": "https://files.pythonhosted.org/packages/0b/b3/2b0fb36c4cb5dc075da0953be3a027a20de4f1fecbb2870f841c972e72b7/pcpp-1.20.1.tar.gz" } ], "1.21": [ { "comment_text": "", "digests": { "md5": "7124ac0c6cc2c544163600cda8818c41", "sha256": "6f455b2296b6cd0353d3746b0b75a5445fbc1792ac20c15c559e1506a48bb047" }, "downloads": -1, "filename": "pcpp-1.21-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "7124ac0c6cc2c544163600cda8818c41", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 80731, "upload_time": "2019-09-30T10:26:35", "url": "https://files.pythonhosted.org/packages/af/e3/b2d081ba1222a6bb43ccbb448c59039cc36f21481101f4091fc185683ff2/pcpp-1.21-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3bb95325c77bd878ce8d39c4526c3ee8", "sha256": "ecc45588bb6f1d4f6e5af713be437f43114bbc3461ca07d2454e2049e2f7d502" }, "downloads": -1, "filename": "pcpp-1.21.tar.gz", "has_sig": false, "md5_digest": "3bb95325c77bd878ce8d39c4526c3ee8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 84066, "upload_time": "2019-09-30T10:26:37", "url": "https://files.pythonhosted.org/packages/b5/9d/e3afe1b6afb47a9062502a50cf729d6d651754e9d1171bb598083acda73b/pcpp-1.21.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7124ac0c6cc2c544163600cda8818c41", "sha256": "6f455b2296b6cd0353d3746b0b75a5445fbc1792ac20c15c559e1506a48bb047" }, "downloads": -1, "filename": "pcpp-1.21-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "7124ac0c6cc2c544163600cda8818c41", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 80731, "upload_time": "2019-09-30T10:26:35", "url": "https://files.pythonhosted.org/packages/af/e3/b2d081ba1222a6bb43ccbb448c59039cc36f21481101f4091fc185683ff2/pcpp-1.21-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3bb95325c77bd878ce8d39c4526c3ee8", "sha256": "ecc45588bb6f1d4f6e5af713be437f43114bbc3461ca07d2454e2049e2f7d502" }, "downloads": -1, "filename": "pcpp-1.21.tar.gz", "has_sig": false, "md5_digest": "3bb95325c77bd878ce8d39c4526c3ee8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 84066, "upload_time": "2019-09-30T10:26:37", "url": "https://files.pythonhosted.org/packages/b5/9d/e3afe1b6afb47a9062502a50cf729d6d651754e9d1171bb598083acda73b/pcpp-1.21.tar.gz" } ] }