Compiling Python extensions inside a virtualenv created inside a snap

Yes, it’s complicated.

I’m running fades after installing it from the Snap Store, and it creates a virtualenv and installs a dependency inside.

The command issued is simple:

fades -v -d git+https://github.com/fginther/PyGithub.git@add-reviews#egg=PyGithub

If fades was installed from a .deb, all works fine.

But if fades was installed from a snap, it fails to compile the dependency properly, see the produced logs (when fades executes pip install git+https://github.com/fginther/PyGithub.git@add-reviews#egg=PyGithub inside the venv):

Collecting PyGithub from git+https://github.com/fginther/PyGithub.git@add-reviews#egg=PyGithub
  Cloning https://github.com/fginther/PyGithub.git (to add-reviews) to /tmp/pip-build-_ynrv8_7/PyGithub
Collecting python-jose (from PyGithub)
  Using cached python_jose-1.3.2-py2.py3-none-any.whl
Collecting six<2.0 (from python-jose->PyGithub)
  Using cached six-1.10.0-py2.py3-none-any.whl
Collecting future<1.0 (from python-jose->PyGithub)
Collecting ecdsa<1.0 (from python-jose->PyGithub)
  Using cached ecdsa-0.13-py2.py3-none-any.whl
Collecting pycrypto<2.7.0,>=2.6.0 (from python-jose->PyGithub)
  Using cached pycrypto-2.6.1.tar.gz
Building wheels for collected packages: pycrypto
  Running setup.py bdist_wheel for pycrypto: started
  Running setup.py bdist_wheel for pycrypto: finished with status 'error'
  Complete output from command /root/snap/fades/common/data/b7c0d40b-dd4d-4f57-ab40-cf1656111949/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-_ynrv8_7/pycrypto/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/tmpbqtf5tirpip-wheel- --python-tag cp35:
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.linux-x86_64-3.5
  creating build/lib.linux-x86_64-3.5/Crypto
  copying lib/Crypto/__init__.py -> build/lib.linux-x86_64-3.5/Crypto
  copying lib/Crypto/pct_warnings.py -> build/lib.linux-x86_64-3.5/Crypto
  creating build/lib.linux-x86_64-3.5/Crypto/Hash
  copying lib/Crypto/Hash/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/Hash
  copying lib/Crypto/Hash/SHA.py -> build/lib.linux-x86_64-3.5/Crypto/Hash
  copying lib/Crypto/Hash/SHA224.py -> build/lib.linux-x86_64-3.5/Crypto/Hash
  copying lib/Crypto/Hash/MD2.py -> build/lib.linux-x86_64-3.5/Crypto/Hash
  copying lib/Crypto/Hash/SHA256.py -> build/lib.linux-x86_64-3.5/Crypto/Hash
  copying lib/Crypto/Hash/SHA512.py -> build/lib.linux-x86_64-3.5/Crypto/Hash
  copying lib/Crypto/Hash/SHA384.py -> build/lib.linux-x86_64-3.5/Crypto/Hash
  copying lib/Crypto/Hash/RIPEMD.py -> build/lib.linux-x86_64-3.5/Crypto/Hash
  copying lib/Crypto/Hash/HMAC.py -> build/lib.linux-x86_64-3.5/Crypto/Hash
  copying lib/Crypto/Hash/hashalgo.py -> build/lib.linux-x86_64-3.5/Crypto/Hash
  copying lib/Crypto/Hash/MD4.py -> build/lib.linux-x86_64-3.5/Crypto/Hash
  copying lib/Crypto/Hash/MD5.py -> build/lib.linux-x86_64-3.5/Crypto/Hash
  creating build/lib.linux-x86_64-3.5/Crypto/Cipher
  copying lib/Crypto/Cipher/PKCS1_v1_5.py -> build/lib.linux-x86_64-3.5/Crypto/Cipher
  copying lib/Crypto/Cipher/ARC4.py -> build/lib.linux-x86_64-3.5/Crypto/Cipher
  copying lib/Crypto/Cipher/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/Cipher
  copying lib/Crypto/Cipher/AES.py -> build/lib.linux-x86_64-3.5/Crypto/Cipher
  copying lib/Crypto/Cipher/DES3.py -> build/lib.linux-x86_64-3.5/Crypto/Cipher
  copying lib/Crypto/Cipher/Blowfish.py -> build/lib.linux-x86_64-3.5/Crypto/Cipher
  copying lib/Crypto/Cipher/blockalgo.py -> build/lib.linux-x86_64-3.5/Crypto/Cipher
  copying lib/Crypto/Cipher/XOR.py -> build/lib.linux-x86_64-3.5/Crypto/Cipher
  copying lib/Crypto/Cipher/DES.py -> build/lib.linux-x86_64-3.5/Crypto/Cipher
  copying lib/Crypto/Cipher/ARC2.py -> build/lib.linux-x86_64-3.5/Crypto/Cipher
  copying lib/Crypto/Cipher/PKCS1_OAEP.py -> build/lib.linux-x86_64-3.5/Crypto/Cipher
  copying lib/Crypto/Cipher/CAST.py -> build/lib.linux-x86_64-3.5/Crypto/Cipher
  creating build/lib.linux-x86_64-3.5/Crypto/Util
  copying lib/Crypto/Util/py3compat.py -> build/lib.linux-x86_64-3.5/Crypto/Util
  copying lib/Crypto/Util/Counter.py -> build/lib.linux-x86_64-3.5/Crypto/Util
  copying lib/Crypto/Util/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/Util
  copying lib/Crypto/Util/asn1.py -> build/lib.linux-x86_64-3.5/Crypto/Util
  copying lib/Crypto/Util/number.py -> build/lib.linux-x86_64-3.5/Crypto/Util
  copying lib/Crypto/Util/randpool.py -> build/lib.linux-x86_64-3.5/Crypto/Util
  copying lib/Crypto/Util/winrandom.py -> build/lib.linux-x86_64-3.5/Crypto/Util
  copying lib/Crypto/Util/_number_new.py -> build/lib.linux-x86_64-3.5/Crypto/Util
  copying lib/Crypto/Util/RFC1751.py -> build/lib.linux-x86_64-3.5/Crypto/Util
  creating build/lib.linux-x86_64-3.5/Crypto/Random
  copying lib/Crypto/Random/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/Random
  copying lib/Crypto/Random/random.py -> build/lib.linux-x86_64-3.5/Crypto/Random
  copying lib/Crypto/Random/_UserFriendlyRNG.py -> build/lib.linux-x86_64-3.5/Crypto/Random
  creating build/lib.linux-x86_64-3.5/Crypto/Random/Fortuna
  copying lib/Crypto/Random/Fortuna/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/Random/Fortuna
  copying lib/Crypto/Random/Fortuna/SHAd256.py -> build/lib.linux-x86_64-3.5/Crypto/Random/Fortuna
  copying lib/Crypto/Random/Fortuna/FortunaAccumulator.py -> build/lib.linux-x86_64-3.5/Crypto/Random/Fortuna
  copying lib/Crypto/Random/Fortuna/FortunaGenerator.py -> build/lib.linux-x86_64-3.5/Crypto/Random/Fortuna
  creating build/lib.linux-x86_64-3.5/Crypto/Random/OSRNG
  copying lib/Crypto/Random/OSRNG/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/Random/OSRNG
  copying lib/Crypto/Random/OSRNG/rng_base.py -> build/lib.linux-x86_64-3.5/Crypto/Random/OSRNG
  copying lib/Crypto/Random/OSRNG/posix.py -> build/lib.linux-x86_64-3.5/Crypto/Random/OSRNG
  copying lib/Crypto/Random/OSRNG/fallback.py -> build/lib.linux-x86_64-3.5/Crypto/Random/OSRNG
  creating build/lib.linux-x86_64-3.5/Crypto/SelfTest
  copying lib/Crypto/SelfTest/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest
  copying lib/Crypto/SelfTest/st_common.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest
  creating build/lib.linux-x86_64-3.5/Crypto/SelfTest/Cipher
  copying lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Cipher
  copying lib/Crypto/SelfTest/Cipher/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Cipher
  copying lib/Crypto/SelfTest/Cipher/test_DES3.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Cipher
  copying lib/Crypto/SelfTest/Cipher/test_ARC2.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Cipher
  copying lib/Crypto/SelfTest/Cipher/test_Blowfish.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Cipher
  copying lib/Crypto/SelfTest/Cipher/test_XOR.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Cipher
  copying lib/Crypto/SelfTest/Cipher/test_CAST.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Cipher
  copying lib/Crypto/SelfTest/Cipher/test_ARC4.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Cipher
  copying lib/Crypto/SelfTest/Cipher/test_pkcs1_15.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Cipher
  copying lib/Crypto/SelfTest/Cipher/test_AES.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Cipher
  copying lib/Crypto/SelfTest/Cipher/common.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Cipher
  copying lib/Crypto/SelfTest/Cipher/test_DES.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Cipher
  creating build/lib.linux-x86_64-3.5/Crypto/SelfTest/Hash
  copying lib/Crypto/SelfTest/Hash/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Hash
  copying lib/Crypto/SelfTest/Hash/test_HMAC.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Hash
  copying lib/Crypto/SelfTest/Hash/test_MD2.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Hash
  copying lib/Crypto/SelfTest/Hash/test_MD5.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Hash
  copying lib/Crypto/SelfTest/Hash/test_MD4.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Hash
  copying lib/Crypto/SelfTest/Hash/test_SHA224.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Hash
  copying lib/Crypto/SelfTest/Hash/test_SHA256.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Hash
  copying lib/Crypto/SelfTest/Hash/test_RIPEMD.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Hash
  copying lib/Crypto/SelfTest/Hash/common.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Hash
  copying lib/Crypto/SelfTest/Hash/test_SHA.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Hash
  copying lib/Crypto/SelfTest/Hash/test_SHA384.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Hash
  copying lib/Crypto/SelfTest/Hash/test_SHA512.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Hash
  creating build/lib.linux-x86_64-3.5/Crypto/SelfTest/Protocol
  copying lib/Crypto/SelfTest/Protocol/test_AllOrNothing.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Protocol
  copying lib/Crypto/SelfTest/Protocol/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Protocol
  copying lib/Crypto/SelfTest/Protocol/test_chaffing.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Protocol
  copying lib/Crypto/SelfTest/Protocol/test_rfc1751.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Protocol
  copying lib/Crypto/SelfTest/Protocol/test_KDF.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Protocol
  creating build/lib.linux-x86_64-3.5/Crypto/SelfTest/PublicKey
  copying lib/Crypto/SelfTest/PublicKey/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/PublicKey
  copying lib/Crypto/SelfTest/PublicKey/test_DSA.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/PublicKey
  copying lib/Crypto/SelfTest/PublicKey/test_importKey.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/PublicKey
  copying lib/Crypto/SelfTest/PublicKey/test_ElGamal.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/PublicKey
  copying lib/Crypto/SelfTest/PublicKey/test_RSA.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/PublicKey
  creating build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random
  copying lib/Crypto/SelfTest/Random/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random
  copying lib/Crypto/SelfTest/Random/test__UserFriendlyRNG.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random
  copying lib/Crypto/SelfTest/Random/test_random.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random
  copying lib/Crypto/SelfTest/Random/test_rpoolcompat.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random
  creating build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random/Fortuna
  copying lib/Crypto/SelfTest/Random/Fortuna/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random/Fortuna
  copying lib/Crypto/SelfTest/Random/Fortuna/test_SHAd256.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random/Fortuna
  copying lib/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random/Fortuna
  copying lib/Crypto/SelfTest/Random/Fortuna/test_FortunaGenerator.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random/Fortuna
  creating build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random/OSRNG
  copying lib/Crypto/SelfTest/Random/OSRNG/test_nt.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random/OSRNG
  copying lib/Crypto/SelfTest/Random/OSRNG/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random/OSRNG
  copying lib/Crypto/SelfTest/Random/OSRNG/test_winrandom.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random/OSRNG
  copying lib/Crypto/SelfTest/Random/OSRNG/test_fallback.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random/OSRNG
  copying lib/Crypto/SelfTest/Random/OSRNG/test_posix.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random/OSRNG
  copying lib/Crypto/SelfTest/Random/OSRNG/test_generic.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Random/OSRNG
  creating build/lib.linux-x86_64-3.5/Crypto/SelfTest/Util
  copying lib/Crypto/SelfTest/Util/test_Counter.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Util
  copying lib/Crypto/SelfTest/Util/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Util
  copying lib/Crypto/SelfTest/Util/test_number.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Util
  copying lib/Crypto/SelfTest/Util/test_winrandom.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Util
  copying lib/Crypto/SelfTest/Util/test_asn1.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Util
  creating build/lib.linux-x86_64-3.5/Crypto/SelfTest/Signature
  copying lib/Crypto/SelfTest/Signature/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Signature
  copying lib/Crypto/SelfTest/Signature/test_pkcs1_15.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Signature
  copying lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py -> build/lib.linux-x86_64-3.5/Crypto/SelfTest/Signature
  creating build/lib.linux-x86_64-3.5/Crypto/Protocol
  copying lib/Crypto/Protocol/Chaffing.py -> build/lib.linux-x86_64-3.5/Crypto/Protocol
  copying lib/Crypto/Protocol/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/Protocol
  copying lib/Crypto/Protocol/KDF.py -> build/lib.linux-x86_64-3.5/Crypto/Protocol
  copying lib/Crypto/Protocol/AllOrNothing.py -> build/lib.linux-x86_64-3.5/Crypto/Protocol
  creating build/lib.linux-x86_64-3.5/Crypto/PublicKey
  copying lib/Crypto/PublicKey/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/PublicKey
  copying lib/Crypto/PublicKey/_slowmath.py -> build/lib.linux-x86_64-3.5/Crypto/PublicKey
  copying lib/Crypto/PublicKey/_RSA.py -> build/lib.linux-x86_64-3.5/Crypto/PublicKey
  copying lib/Crypto/PublicKey/DSA.py -> build/lib.linux-x86_64-3.5/Crypto/PublicKey
  copying lib/Crypto/PublicKey/_DSA.py -> build/lib.linux-x86_64-3.5/Crypto/PublicKey
  copying lib/Crypto/PublicKey/pubkey.py -> build/lib.linux-x86_64-3.5/Crypto/PublicKey
  copying lib/Crypto/PublicKey/ElGamal.py -> build/lib.linux-x86_64-3.5/Crypto/PublicKey
  copying lib/Crypto/PublicKey/RSA.py -> build/lib.linux-x86_64-3.5/Crypto/PublicKey
  creating build/lib.linux-x86_64-3.5/Crypto/Signature
  copying lib/Crypto/Signature/PKCS1_v1_5.py -> build/lib.linux-x86_64-3.5/Crypto/Signature
  copying lib/Crypto/Signature/__init__.py -> build/lib.linux-x86_64-3.5/Crypto/Signature
  copying lib/Crypto/Signature/PKCS1_PSS.py -> build/lib.linux-x86_64-3.5/Crypto/Signature
  Skipping optional fixer: buffer
  Skipping optional fixer: idioms
  Skipping optional fixer: set_literal
  Skipping optional fixer: ws_comma
  running build_ext
  running build_configure
  checking for gcc... gcc
  checking whether the C compiler works... yes
  checking for C compiler default output file name... a.out
  checking for suffix of executables...
  checking whether we are cross compiling... no
  checking for suffix of object files... o
  checking whether we are using the GNU C compiler... yes
  checking whether gcc accepts -g... yes
  checking for gcc option to accept ISO C89... none needed
  checking for __gmpz_init in -lgmp... no
  checking for __gmpz_init in -lmpir... no
  checking whether mpz_powm is declared... no
  checking whether mpz_powm_sec is declared... no
  checking how to run the C preprocessor... gcc -E
  checking for grep that handles long lines and -e... /bin/grep
  checking for egrep... /bin/grep -E
  checking for ANSI C header files... yes
  checking for sys/types.h... yes
  checking for sys/stat.h... yes
  checking for stdlib.h... yes
  checking for string.h... yes
  checking for memory.h... yes
  checking for strings.h... yes
  checking for inttypes.h... yes
  checking for stdint.h... yes
  checking for unistd.h... yes
  checking for inttypes.h... (cached) yes
  checking limits.h usability... yes
  checking limits.h presence... yes
  checking for limits.h... yes
  checking stddef.h usability... yes
  checking stddef.h presence... yes
  checking for stddef.h... yes
  checking for stdint.h... (cached) yes
  checking for stdlib.h... (cached) yes
  checking for string.h... (cached) yes
  checking wchar.h usability... yes
  checking wchar.h presence... yes
  checking for wchar.h... yes
  checking for inline... inline
  checking for int16_t... yes
  checking for int32_t... yes
  checking for int64_t... yes
  checking for int8_t... yes
  checking for size_t... yes
  checking for uint16_t... yes
  checking for uint32_t... yes
  checking for uint64_t... yes
  checking for uint8_t... yes
  checking for stdlib.h... (cached) yes
  checking for GNU libc compatible malloc... yes
  checking for memmove... yes
  checking for memset... yes
  configure: creating ./config.status
  config.status: creating src/config.h
  warning: GMP or MPIR library not found; Not building Crypto.PublicKey._fastmath.
  building 'Crypto.Hash._MD2' extension
  creating build/temp.linux-x86_64-3.5
  creating build/temp.linux-x86_64-3.5/src
  x86_64-linux-gnu-gcc -pthread -fwrapv -Wall -Wstrict-prototypes -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -std=c99 -O3 -fomit-frame-pointer -Isrc/ -I/root/snap/fades/common/data/b7c0d40b-dd4d-4f57-ab40-cf1656111949/include -I/snap/fades/22/usr/include/python3.5m -c src/MD2.c -o build/temp.linux-x86_64-3.5/src/MD2.o
  src/MD2.c:31:20: fatal error: Python.h: No such file or directory
   #include "Python.h"
                      ^
  compilation terminated.
  error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
  
  ----------------------------------------
  Failed building wheel for pycrypto
  Running setup.py clean for pycrypto
Failed to build pycrypto

Note that I do have the python development dependencies installed:

# locate Python.h
/usr/include/python2.7/Python.h
/usr/include/python3.5m/Python.h

It looks like the compiling process triggered inside a snap is not finding the library installed in the system.

Do I need to include these libraries inside the snap? Or enable some interface(s)?

Thanks!!

Looking at your fades snap, it bundles its own copy of Python. So presumably it is searching for the headers and other development files associated with that installation. They’re not included in your snap, so the build fails.

Note that Python extension code generally uses #include <Python.h>, so the copies of the header under /usr/include/python2.7 and /usr/include/python3.5m would not be found without the use of an appropriate -I flag to the compiler. Your bundled Python is probably expecting to find the header at /snap/fades/current/usr/include/python3.5m instead.

Thanks jamesh for the info!

What I don’t understand is: can I NOT include its own copy of Python? fades only needs Python >= 3.3, if the system already guarantees that, is there a point in including its own copy? How do I stop including it?

OTOH, if including its own copy of Python is the only way forward, is there also a way to include the development headers?

Thanks again!!

As a classic snap, there’s no reason why you couldn’t use the system version of Python. What you can’t do is require that the system have a particular version installed, or that it has the development headers installed. I’m not sure if that is a problem for you or not.

I don’t know how to do this with the python Snapcraft part plugin, but you can almost certainly do it using the nil plugin with your own build and install commands.

As for including the development headers for the packed in version of Python in your snap, you can probably do this via stage-packages.