Metadata-Version: 2.1
Name: c2f
Version: 1.0.4
Summary: UNKNOWN
Home-page: UNKNOWN
Author: UNKNOWN
Author-email: UNKNOWN
License: UNKNOWN
Platform: UNKNOWN

Cython for All with GitHub Actions
==================================

Is Python an interpreted or compiled language? Trick question. Itâ€™s actually
both. With tools like Cython, we can take the compilation step further and
remove the interpreter loop almost entirely. Cython produces binaries much like
C++, Go, and Rust do. Now with GitHub Actions the cross-platform build and
release process can be automated for free for Open Source projects. This is an
enormous opportunity to make the Python ecosystem 20-50% faster with a single
pull request. This lightning talk walks through a GitHub workflow that
publishes Cython-optimized wheels to PyPI. Discover how Cython can turbo-charge
your Python code and GitHub Actions can simplify your cross-platform release
process for free.


SF Python Holiday Party 2019
----------------------------

| Grant Jenks
| Dec. 4, 2019
| `grantjenks.com/docs/cython-for-all`_
| `github.com/grantjenks/python-c2f`_
| `pypi.org/project/c2f/#files`_


Is Python interpreted or compiled?
----------------------------------

| .
| .
| .
| ?
| .
| .
| .
| ?
| .
| .
| .
| ?


c2f.py
------

.. code-block:: python

   "Celsius to Fahrenheit Library"

   def convert(celsius: float) -> float:
       "Convert Celsius to Fahrenheit"
       fahrenheit = celsius * 1.8 + 32
       return fahrenheit


c2f.cpython-38.pyc
------------------

.. code-block:: pycon

   >>> import c2f
   >>> dis.dis(c2f.convert)
     6           0 LOAD_FAST                0 (celsius)
                 2 LOAD_CONST               1 (1.8)
                 4 BINARY_MULTIPLY
                 6 LOAD_CONST               2 (32)
                 8 BINARY_ADD
                10 STORE_FAST               1 (fahrenheit)
     7          12 LOAD_FAST                1 (fahrenheit)
                14 RETURN_VALUE


setup.py
--------

.. code-block:: python

   from setuptools import setup
   from Cython.Build import cythonize

   setup(
       name='c2f',
       version='0.0.0',
       py_modules=['c2f'],
       ext_modules=cythonize('c2f.py'),
   )


c2f.c
-----

.. code-block:: shell

   $ cython c2f.py

.. code-block:: c

   static PyObject * __pyx_convert(double __pyx_v_celsius)
   {
     double __pyx_v_fahrenheit;
     PyObject *__pyx_r = NULL;
     __pyx_v_fahrenheit = ((__pyx_v_celsius * 1.8) + 32.0);
     __pyx_r = PyFloat_FromDouble(__pyx_v_fahrenheit);
     return __pyx_r;
   }


c2f.so
------

.. code-block:: shell

   $ python setup.py bdist_wheel

.. code-block:: nasm

   ___pyx_convert:
   push	  rbp
   mov	  rbp, rsp
   sub	  rsp, 16
   movsd  xmm0, qword ptr [rbp - 8]
   mulsd  xmm0, qword ptr [rip + 1379]
   addsd  xmm0, qword ptr [rip + 1379]
   call	  502 <PyFloat_FromDouble ...>
   add	  rsp, 16
   pop	  rbp
   ret


.github/workflows/release.yml
-----------------------------

.. code-block:: yaml

   name: release
   on:
     push:
       tags:
         - v*
   jobs:
     build-linux-cp38:
       runs-on: ubuntu-latest
       container: quay.io/pypa/manylinux2014_x86_64
       steps:
       ...


Matrix Build
------------

.. code-block:: yaml

   build-macos:
     runs-on: macos-latest
     strategy:
       max-parallel: 4
       matrix:
         python-version: [3.5, 3.6, 3.7, 3.8]
     steps:
     ...


Mac Build Steps
---------------

.. code-block:: yaml

   - name: Set up Python ${{ matrix.python-version }} x64
     uses: actions/setup-python@v1
     with:
       python-version: ${{ matrix.python-version }}
       architecture: x64

   - name: Install package dependencies
     run: pip install cython wheel

   - name: Build binary wheel
     run: python setup.py bdist_wheel


Linux auditwheel Tool
---------------------

.. code-block:: yaml

   - name: Build binary wheel
     run: /opt/python/cp38-cp38/bin/python setup.py bdist_wheel

   - name: Apply auditwheel for manylinux wheel
     run: auditwheel repair -w dist dist/*

   - name: Remove linux wheel
     run: rm dist/*-linux_x86_64.whl


Windows Build Steps
-------------------

.. code-block:: yaml

   - name: Download Build Tools for Visual Studio 2019
     run: Invoke-WebRequest -Uri https://aka.ms/vs/16/rel...

   - name: Run vs_buildtools.exe install
     run: ./vs_buildtools.exe --quiet --wait --norestart ...


Store Build Artifacts
---------------------

.. code-block:: yaml

   - name: Archive dist artifacts
     uses: actions/upload-artifact@v1
     with:
       name: dist-macos-${{ matrix.python-version }}
       path: dist


Source Distribution
-------------------

.. code-block:: yaml

   upload:
     needs: [build-linux-cp35, ...]
     runs-on: ubuntu-latest
     steps:
     ...
     - name: Install dependencies
       run: pip install -r requirements.txt

     - name: Create source dist
       run: python setup.py sdist


Stage Binary Wheels
-------------------

.. code-block:: yaml

   - name: Stage linux 3.8
     uses: actions/download-artifact@v1
     with:
       name: dist-linux-3.8
   - run: mv -v dist-linux-3.8/* dist/

   - name: Stage macos 3.8
     uses: actions/download-artifact@v1
     with:
       name: dist-macos-3.8
   - run: mv -v dist-macos-3.8/* dist/
   ...


Upload with Twine
-----------------

.. code-block:: yaml

   - name: Upload with twine
     env:
       TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }}
       TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }}
     run: |
       ls -l dist/*
       pip install twine
       twine upload dist/*


Cythonize all the Things!
-------------------------

PLEASE STEAL THE CODE!

| `grantjenks.com/docs/cython-for-all`_
| `github.com/grantjenks/python-c2f`_
| `pypi.org/project/c2f/#files`_

*Cythonize all the Things!*

*Cythonize all the Things!*

*Cythonize all the Things!*

*Cythonize all the Things!*

*Cythonize all the Things!*

*Cythonize all the Things!*

.. _grantjenks.com/docs/cython-for-all: http://grantjenks.com/docs/cython-for-all/
.. _github.com/grantjenks/python-c2f: https://github.com/grantjenks/python-c2f/
.. _pypi.org/project/c2f/#files: https://pypi.org/project/c2f/#files


Appendix
--------

Dumping Assembly
................

.. code-block:: shell

   $ gcc -g -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/Library/Frameworks/Python.framework/Versions/3.8/include/python3.8 -L/Library/Frameworks/Python.framework/Versions/3.8/lib -o c2f.so c2f.c -lpython3.8
   $ objdump -S -df=___pyx_pw_3c2f_1convert c2f.so


Git Tagging
...........

.. code-block:: shell

   $ git tag -a v0.0.2 -m v0.0.2
   $ git push
   $ git push --tags


