{ "info": { "author": "Hardcoded Software", "author_email": "hsoft@hardcoded.net", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5" ], "description": "ObjP's goal is to create a two-way bridge between Python and Objective-C. Unlike PyObjC, which uses\ndynamic calls to methods on runtime, ObjP generates static code. It generates either Objective-C\ninterfaces to Python code or Python modules to interface Objective-C code.\n\nThe library is exceedingly simple and it's intended that way. Unlike PyObjC, there's no way ObjP\ncould possibly wrap the whole Cocoa framework, there's way too many things to support. ObjP is made\nto allow you to bridge your own code.\n\nAlso note that ObjP works on Python 3.2 and up.\n\nThe best way to learn how to use ObjP is, I think, to look at an example. There are many of them in\nthe 'demos' subfolder. These are built using ``waf`` (it's already included in here, no need to\ninstall it). For example, if you want to build the ``simple`` demo, do::\n\n $ cd demos/simple\n $ ./waf configure build\n $ cd build\n $ ./HelloWorld\n\nThat programs calls a simple Python script from Objective-C, and that python script itself calls\nan Objective-C class.\n\nUsage\n-----\n\nThere are two types of bridge: Objective-C class wrapping a Python class (o2p) and Python class\nwrapping an Objective-C class (p2o).\n\nTo generate an o2p wrapper, you need a target class. Moreover, for this class' methods to be\nwrapped, you need to have its arguments and return value correctly annotated (You can browse the\ndemos for good examples of how to do it). This is an example of a correctly annotated class::\n\n class Foo:\n def hello_(self, name: str) -> str:\n return \"Hello {}\".format(name)\n\nTo wrap this class, you'll use ``objp.o2p.generate_objc_code()`` in this fashion::\n\n import foo\n import objp.o2p\n objp.o2p.generate_objc_code(foo.Foo, 'destfolder')\n\nThis will generate \"Foo.h|m\" as well as \"ObjP.h|m\" in \"destfolder\". These source files directly\nuse the Python API and have no other dependencies.\n\nTo generate a p2o wrapper, you either need an Objective-C header file containing an interface or\nprotocol or a Python class describing that interface::\n\n @interface Foo: NSObject {}\n - (NSString *)hello:(NSString *)name;\n @end\n\nTo generate a python wrapper from this, you can do::\n\n import objp.p2o\n objp.p2o.generate_python_proxy_code(['Foo.h'], 'destfolder/Foo.m')\n\nThis will generate the code for a Python extension module wrapping ``Foo``. The name of the\nextension module is determined by the name of the destination source file. You can wrap more than\none class in the same unit::\n\n objp.p2o.generate_python_proxy_code(['Foo.h', 'Bar.h'], 'destfolder/mywrappers.m')\n\nMethod name conversion\n----------------------\n\nObjP follows PyObjC's convention for converting method names. The \":\" character being illegal in\nPython method names, they're replaced by underscores. Thus, a method\n``- (BOOL)foo:(NSInteger)arg1 bar:(NSString *)arg2;`` is converted to\n``def foo_bar_(self, arg1: int, arg2: str) -> bool:`` and vice versa.\n\nNote that if your method's argument count doesn't correspond to the number of underscores in your\nmethod name, objp will issue a warning and ignore the method.\n\nArgument Types\n--------------\n\nOnly a few argument types are supported by ObjP, the goal being to keep the project simple.\n\n* ``int/NSInteger``\n* ``float/CGFloat``\n* ``str/NSString*``\n* ``bool/BOOL``\n* ``list/NSArray*``\n* ``dict/NSDictionary*``\n* ``nspoint/NSPoint``\n* ``nssize/NSSize``\n* ``nsrect/NSRect``\n\nObjP also supports ``object`` which dynamically converts the argument depending on its type and\nreturns an ``NSObject`` subclass (which means that ``int``, ``float`` and ``bool`` convert to\n``NSNumber`` instead of converting to ``NSInteger``, ``CGFloat`` and ``BOOL``). This type of\nconversion is used to convert the contents of ``list`` and ``dict`` (it's impossible to have an\nNSArray directly containing ``BOOL``).\n\nAnother special argument type is ``pyref`` (which you must import from ``objp.util`` in your code)\nwhich simply passes the ``PyObject*`` instance around without converting it.\n\nThe structure arguments allow you to transform tuples to native objc structures and vice-versa.\nPython has no \"native\" structure for points, sizes and rects, so that's why we convert to/from\ntuples (``(x, y)``, ``(w, h)`` and ``(x, y, w, h)``). Like ``pyref``, the ``ns*`` signature\narguments have to be imported from ``objp.util``.\n\nUtilities\n---------\n\n``objp.util`` contains the ``pyref`` and ``ns*`` argument types, but it also contains two useful\nmethod decorators: ``dontwrap`` and ``objcname``. A method decorated with ``dontwrap`` will be\nignored by the code generator, and a method decorated with ``@objcname('some:selector:')`` will use\nthis name for generating objc code instead of the automatically generated name.\n\nConstant conversion\n-------------------\n\nWhen having code in two different languages, we sometimes have to share constants in between the\ntwo. To avoid having to manually maintain an Objective-C counterpart to your Python constants,\n``objp`` offers a small utility, ``objp.const.generate_objc_code(module, dest)``. This takes all\nelements in ``module``'s namespace and convert them to an Objective-C's constant unit at ``dest``.\n\n``int``, ``float`` and ``str`` types are going to be converted to ``#define ``\n(with ``@\"\"`` around ``str`` values). You can also have enum classes in your python constant\nmodule. A class is considered an enum if it has integer members. For example::\n\n class Foo:\n Bar = 1\n Baz = 2\n\nwill be converted to::\n\n typedef enum {\n FooBar=1,\n FooBaz=2\n } Foo;\n\nBecause this function will choke on any value that it can't convert, it is recommended that you use\nit on modules specifically written for that, for example a ``cocoa_const.py`` that imports from\nyour real const unit. Since constants in Objective-C often have prefixes, you can also add them in\nthat unit. It could look like that::\n\n from real_const import FOO as XZFOO, BAR as XZBAR, MyEnum as XZMyEnum\n\n\nChanges\n=======\n\nVersion 1.3.2 -- 2016/01/09\n---------------------------\n\n* Fix bug in ``generate_python_proxy_code_from_clsspec()``.\n* Fix compilation warning in ``ObjP_list_o2p()``.\n\nVersion 1.3.1 -- 2014/10/04\n---------------------------\n\n* Fixed a crash when converting a ``NSDictionary`` containing an unsupported type.\n\nVersion 1.3.0 -- 2012/09/27\n---------------------------\n\n* Added support for Python constant module conversion to Objective-C code.\n\nVersion 1.2.1 -- 2012/05/28\n---------------------------\n\n* Renamed proxy's target member name from ``py`` to ``_py`` to avoid name clash with local variables\n when an argument would be named ``y``.\n\nVersion 1.2.0 -- 2012/02/01\n---------------------------\n\n* Added support for ``NSPoint``, ``NSSize`` and ``NSRect`` structures.\n* In ``ObjP_str_o2p()``, when the string is ``nil``, return ``Py_None`` instead of crashing.\n\nVersion 1.1.0 -- 2012/01/23\n---------------------------\n\n* Allow null items (with ``[NSNull null]``) in p2o collection conversions.\n* Added support for floats.\n* p2o conversions returning ``NSObject`` subclasses can now convert ``None`` to ``nil``.\n\nVersion 1.0.0 -- 2012/01/16\n---------------------------\n\n* Added support for protocols.\n* Added support for __init__ method wrapping.\n* Added ``bool`` and ``pyref`` argument types.\n* Added support for creating a p2o instance that wraps a pre-existing objc instance.\n* Added exception checking.\n* Added GIL locking.\n* Added inheritance support.\n* Added multiple class wrapping in the same p2o module.\n\nVersion 0.1.1 -- 2012/01/08\n---------------------------\n\n* Fixed setup which was broken.\n* Fixed o2p which was broken.\n\nVersion 0.1.0 -- 2012/01/05\n---------------------------\n\n* Initial Release", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/hsoft/objp", "keywords": null, "license": "BSD License", "maintainer": null, "maintainer_email": null, "name": "objp", "package_url": "https://pypi.org/project/objp/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/objp/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/hsoft/objp" }, "release_url": "https://pypi.org/project/objp/1.3.2/", "requires_dist": null, "requires_python": null, "summary": "Python<-->Objective-C bridge with a code generation approach", "version": "1.3.2" }, "last_serial": 1905472, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "19bdc6d5d0fd740ac4b800339f26dcdb", "sha256": "221dc8f111ee9efe1add1fc8728cb1fa0c6b4a3c032fd3534fabde5c42d8d8ed" }, "downloads": -1, "filename": "objp-0.1.0.tar.gz", "has_sig": false, "md5_digest": "19bdc6d5d0fd740ac4b800339f26dcdb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5269, "upload_time": "2012-01-05T20:18:58", "url": "https://files.pythonhosted.org/packages/4e/41/bc3b8d794346727cd88f8ca2b093cacef5cc2cbaba010c39c5c6809e7e21/objp-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "84f0d751c420a3975d8132f44debf714", "sha256": "76f5c26f566412a17e6a24fa4fcaf393f823e0ab32b7f3a63dd9e76f6f2f7d99" }, "downloads": -1, "filename": "objp-0.1.1.tar.gz", "has_sig": false, "md5_digest": "84f0d751c420a3975d8132f44debf714", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6761, "upload_time": "2012-01-08T20:34:59", "url": "https://files.pythonhosted.org/packages/01/c8/ad511d0c0e4b5c8c6c392c4db1f843c33fcd62ed1d779db6e746e3380197/objp-0.1.1.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "b7ec4abfaf14bfdf9c589537db33cc5f", "sha256": "a6d11cc59625007e57f7c86ebd3b9c50e54372799c82f739e28425fc7b8f9f5e" }, "downloads": -1, "filename": "objp-1.0.0.tar.gz", "has_sig": false, "md5_digest": "b7ec4abfaf14bfdf9c589537db33cc5f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12265, "upload_time": "2012-01-16T17:27:13", "url": "https://files.pythonhosted.org/packages/60/58/e53c15ceb6fefcbd10d1be714521fae180597f7fc4dcd562bccff03dd4c1/objp-1.0.0.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "061f82985e0dd11b798ff55628d01005", "sha256": "22a4e244429c7d18923ee5675045d84c77f7212d1c73612418350e6c7d4d9951" }, "downloads": -1, "filename": "objp-1.1.0.tar.gz", "has_sig": false, "md5_digest": "061f82985e0dd11b798ff55628d01005", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12655, "upload_time": "2012-01-23T20:32:18", "url": "https://files.pythonhosted.org/packages/fe/4d/bc7a0a31cf1a219098baf0ff435d1ff06d584f5a4fdd0ab43f5d0a47a11c/objp-1.1.0.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "bdff818799309fb322ff010673e067a3", "sha256": "d83fee0c866548fd76b478bda9d4696d8071535524cd32c323186b23aaa476b8" }, "downloads": -1, "filename": "objp-1.2.0.tar.gz", "has_sig": false, "md5_digest": "bdff818799309fb322ff010673e067a3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13516, "upload_time": "2012-02-01T15:16:25", "url": "https://files.pythonhosted.org/packages/05/7b/7d87f00d89432af35a5f84dc4a065ca675d6c9ad28ac42627bb87e8b0100/objp-1.2.0.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "e97ac05b29bfec3806ab863036b34028", "sha256": "f4b15d6ed2f98b5c8e787e8ad6c420f8fb69600dc7965cda3ded750392a27416" }, "downloads": -1, "filename": "objp-1.2.1.tar.gz", "has_sig": false, "md5_digest": "e97ac05b29bfec3806ab863036b34028", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13685, "upload_time": "2012-05-28T15:46:51", "url": "https://files.pythonhosted.org/packages/a2/08/6671dafeecb01f8a3abbc160163ee1a33d3bd97391685c60a145fa0b37c8/objp-1.2.1.tar.gz" } ], "1.3.0": [ { "comment_text": "", "digests": { "md5": "785961ff259e587073eca075b94b14da", "sha256": "979019456a5eef3e1041536a5707eb8ffcd54d16aea43e0c9a097d2b35a023bb" }, "downloads": -1, "filename": "objp-1.3.0.tar.gz", "has_sig": false, "md5_digest": "785961ff259e587073eca075b94b14da", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14733, "upload_time": "2012-09-27T15:56:48", "url": "https://files.pythonhosted.org/packages/c0/22/c10b056537cf280084c19010cf66a7b6bde2388a0025ef8bbdeeda34d9dd/objp-1.3.0.tar.gz" } ], "1.3.1": [ { "comment_text": "", "digests": { "md5": "bad68d500bb74dfcfffa7ca8a7a4fab6", "sha256": "f01f9f18dd5c5746dfc7e7b2eededa2489022b4b06a41ab7262415697c501228" }, "downloads": -1, "filename": "objp-1.3.1.tar.gz", "has_sig": false, "md5_digest": "bad68d500bb74dfcfffa7ca8a7a4fab6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14818, "upload_time": "2014-10-04T20:26:29", "url": "https://files.pythonhosted.org/packages/d9/6b/3a22c3fb7779c6c2310882428b5e38e2687de583d5fa355775a4917f0cf5/objp-1.3.1.tar.gz" } ], "1.3.2": [ { "comment_text": "", "digests": { "md5": "8705f99f306abf264b4457440ae9e1ce", "sha256": "62dd7ea430f18790d2c823832ff76737a9175b8089b64e040a5b6816842af0e2" }, "downloads": -1, "filename": "objp-1.3.2-py3-none-any.whl", "has_sig": true, "md5_digest": "8705f99f306abf264b4457440ae9e1ce", "packagetype": "bdist_wheel", "python_version": "3.4", "requires_python": null, "size": 19154, "upload_time": "2016-01-15T02:03:27", "url": "https://files.pythonhosted.org/packages/3c/b6/f85265d83da1c32dfc6fb2540e3fb470b1dbe596b2ef62aabf533192412c/objp-1.3.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "aa11d944c3eb950ce1bac4b2fd4170c1", "sha256": "ff1d4a8db6ae326759a390b71659b8338e5bcf9302a54b401ae0891e73e32474" }, "downloads": -1, "filename": "objp-1.3.2.tar.gz", "has_sig": true, "md5_digest": "aa11d944c3eb950ce1bac4b2fd4170c1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17002, "upload_time": "2016-01-10T01:11:44", "url": "https://files.pythonhosted.org/packages/29/13/25cd0d3f8daf5919a8257db7958774b23cf234ad4c0e89672cee37b118d9/objp-1.3.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "8705f99f306abf264b4457440ae9e1ce", "sha256": "62dd7ea430f18790d2c823832ff76737a9175b8089b64e040a5b6816842af0e2" }, "downloads": -1, "filename": "objp-1.3.2-py3-none-any.whl", "has_sig": true, "md5_digest": "8705f99f306abf264b4457440ae9e1ce", "packagetype": "bdist_wheel", "python_version": "3.4", "requires_python": null, "size": 19154, "upload_time": "2016-01-15T02:03:27", "url": "https://files.pythonhosted.org/packages/3c/b6/f85265d83da1c32dfc6fb2540e3fb470b1dbe596b2ef62aabf533192412c/objp-1.3.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "aa11d944c3eb950ce1bac4b2fd4170c1", "sha256": "ff1d4a8db6ae326759a390b71659b8338e5bcf9302a54b401ae0891e73e32474" }, "downloads": -1, "filename": "objp-1.3.2.tar.gz", "has_sig": true, "md5_digest": "aa11d944c3eb950ce1bac4b2fd4170c1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17002, "upload_time": "2016-01-10T01:11:44", "url": "https://files.pythonhosted.org/packages/29/13/25cd0d3f8daf5919a8257db7958774b23cf234ad4c0e89672cee37b118d9/objp-1.3.2.tar.gz" } ] }