diff --git a/docs/_templates/sidebarintro.html b/docs/_templates/sidebarintro.html index 65ca51e..883572b 100644 --- a/docs/_templates/sidebarintro.html +++ b/docs/_templates/sidebarintro.html @@ -8,16 +8,6 @@

Subscribe to Newsletter

-

Donate

-

- If you enjoy this guide, consider supporting the author on Gittip: -

-

- -

-

Contributors

This guide is the result of the collaboration of diff --git a/docs/_templates/sidebarlogo.html b/docs/_templates/sidebarlogo.html index 67650e8..6372b3f 100644 --- a/docs/_templates/sidebarlogo.html +++ b/docs/_templates/sidebarlogo.html @@ -7,13 +7,3 @@

Receive updates on new releases and upcoming projects.

Subscribe to Newsletter

- -

Donate

-

- If you enjoy this guide, consider supporting the author on Gittip: -

-

- -

\ No newline at end of file diff --git a/docs/contents.rst.inc b/docs/contents.rst.inc index bf04003..59bc39a 100644 --- a/docs/contents.rst.inc +++ b/docs/contents.rst.inc @@ -63,6 +63,7 @@ different scenarios. scenarios/xml scenarios/json scenarios/crypto + scenarios/clibs Shipping Great Code diff --git a/docs/dev/virtualenvs.rst b/docs/dev/virtualenvs.rst index 266faeb..bb3f948 100644 --- a/docs/dev/virtualenvs.rst +++ b/docs/dev/virtualenvs.rst @@ -1,3 +1,5 @@ +.. _virtualenvironments-ref: + Virtual Environments ==================== diff --git a/docs/scenarios/clibs.rst b/docs/scenarios/clibs.rst new file mode 100644 index 0000000..290638e --- /dev/null +++ b/docs/scenarios/clibs.rst @@ -0,0 +1,129 @@ +Interfacing with C/C++ Libraries +================================ + +C Foreign Function Interface +---------------------------- + +`CFFI `_ provides a simple to use +mechanism for interfacing with C from both CPython and PyPy. It supports two +modes: an inline ABI compatibility mode (example provided below), which allows +you to dynamically load and run functions from executable modules (essentially +exposing the same functionality as LoadLibrary or dlopen), and an API mode, +which allows you to build C extension modules. + +ABI Interaction +~~~~~~~~~~~~~~~ + +.. code-block:: python + :linenos: + + from cffi import FFI + ffi = FFI() + ffi.cdef("size_t strlen(const char*);") + clib = ffi.dlopen(None) + length = clib.strlen("String to be evaluated.") + # prints: 23 + print("{}".format(length)) + +ctypes +------ + +`ctypes `_ is the de facto +library for interfacing with C/C++ from CPython, and it provides not only +full access to the native C interface of most major operating systems (e.g., +kernel32 on Windows, or libc on \*nix), but also provides support for loading +and interfacing with dynamic libraries, such as DLLs or shared objects at +runtime. It does bring along with it a whole host of types for interacting +with system APIs, and allows you to rather easily define your own complex +types, such as structs and unions, and allows you to modify things such as +padding and alignment, if needed. It can be a bit crufty to use, but in +conjunction with the `struct `_ +module, you are essentially provided full control over how your data types get +translated into something something usable by a pure C(++) method. + +Struct Equivalents +~~~~~~~~~~~~~~~~~~ + +:file:`MyStruct.h` + +.. code-block:: c + :linenos: + + struct my_struct { + int a; + int b; + }; + +:file:`MyStruct.py` + +.. code-block:: python + :linenos: + + import ctypes + class my_struct(ctypes.Structure): + _fields_ = [("a", c_int), + ("b", c_int)] + +SWIG +---- + +`SWIG `_, though not strictly Python focused (it supports a +large number of scripting languages), is a tool for generating bindings for +interpreted languages from C/C++ header files. It is extremely simple to use: +the consumer simply needs to define an interface file (detailed in the +tutorial and documentations), include the requisite C/C++ headers, and run +the build tool against them. While it does have some limits, (it currently +seems to have issues with a small subset of newer C++ features, and getting +template-heavy code to work can be a bit verbose), it provides a great deal +of power and exposes lots of features to Python with little effort. +Additionally, you can easily extend the bindings SWIG creates (in the +interface file) to overload operators and built-in methods, effectively re- +cast C++ exceptions to be catchable by Python, etc. + +Example: Overloading __repr__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:file:`MyClass.h` + +.. code-block:: c++ + :linenos: + + #include + class MyClass { + private: + std::string name; + public: + std::string getName(); + }; + +:file:`myclass.i` + +.. code-block:: c++ + :linenos: + + %include "string.i" + + %module myclass + %{ + #include + #include "MyClass.h" + %} + + %extend MyClass { + std::string __repr__() + { + return $self->getName(); + } + } + + %include "MyClass.h" + + +Boost.Python +------------ + +`Boost.Python `_ +requires a bit more manual work to expose C++ object functionality, but +it is capable of providing all the same features SWIG does and then some, +to include providing wrappers to access PyObjects in C++, extracting SWIG- +wrapper objects, and even embedding bits of Python into your C++ code. diff --git a/docs/scenarios/scrape.rst b/docs/scenarios/scrape.rst index 65560d3..0728d25 100644 --- a/docs/scenarios/scrape.rst +++ b/docs/scenarios/scrape.rst @@ -38,7 +38,10 @@ parse it using the ``html`` module and save the results in ``tree``: .. code-block:: python page = requests.get('http://econpy.pythonanywhere.com/ex/001.html') - tree = html.fromstring(page.text) + tree = html.fromstring(page.content) + +(We need to use ``page.content`` rather than ``page.text`` because +``html.fromstring`` implicitly expects ``bytes`` as input.) ``tree`` now contains the whole HTML file in a nice tree structure which we can go over two different ways: XPath and CSSSelect. In this example, we diff --git a/docs/starting/install/linux.rst b/docs/starting/install/linux.rst index a42106d..e68c5d0 100644 --- a/docs/starting/install/linux.rst +++ b/docs/starting/install/linux.rst @@ -58,7 +58,7 @@ your global site-packages directory clean and manageable. For example, you can work on a project which requires Django 1.3 while also maintaining a project which requires Django 1.0. -To start using and see more information: `Virtual Environments `_ docs. +To start using this and see more information: :ref:`Virtual Environments ` docs. You can also use :ref:`virtualenvwrapper ` to make it easier to manage your virtual environments. diff --git a/docs/starting/install/osx.rst b/docs/starting/install/osx.rst index 0de724f..cb0062c 100644 --- a/docs/starting/install/osx.rst +++ b/docs/starting/install/osx.rst @@ -92,7 +92,7 @@ your global site-packages directory clean and manageable. For example, you can work on a project which requires Django 1.3 while also maintaining a project which requires Django 1.0. -To start using and see more information: `Virtual Environments `_ docs. +To start using this and see more information: :ref:`Virtual Environments ` docs. -------------------------------- diff --git a/docs/starting/install/win.rst b/docs/starting/install/win.rst index a0f37c5..140c842 100644 --- a/docs/starting/install/win.rst +++ b/docs/starting/install/win.rst @@ -77,7 +77,7 @@ your global site-packages directory clean and manageable. For example, you can work on a project which requires Django 1.3 while also maintaining a project which requires Django 1.0. -To start using and see more information: `Virtual Environments `_ docs. +To start using this and see more information: :ref:`Virtual Environments ` docs. --------------------------------