Disable code inspection with Cython and compilation

Viewed 48

I have a python script which I have transformed into a pyd file using Cython and Gcc. I would like it to be a black box, so that people cannot inspect it easily.

The source code after cythonization and compilation is hidden. However, it seems like you can still inspect it quite easily when you import the module in a python console and use the dir magic method. Is there a way to prevent code inspection from happening?

1 Answers

The first thing to emphasise is that Cython isn't really designed to help you hide your code - it's more an unintentional consequence. If Cython could get a 1% speed-up by making the source code for a compiled module completely visible then it'd probably choose to do that rather than hide it (however that's pretty unlikely... I can't see a mechanism that'd happen by).

Having some things visible by dir is pretty unavoidable. Cython is trying to make things behave like Python as far as possible and Python works by looking names up in a module dictionary. All dir does is print the keys from the module dictionary. However there are some things you can try:

  • use cdef functions rather than def functions. cdef functions are only not callable (or visible) from Python. They have some limitations though - you can't use *args or **kwds as arguments for example. Some sub-notes:
    • you will probably need one entry-point that can be called from Python.
    • if you need to share cdef functions between modules then you will need to create a pxd file. shared cdef functions will appear in the __pyx_capi__ special attribute of your module where their name, C signature, and possibly function pointer will be able to anyone that looks.
  • Turning off the binding and embedsignature compiler directives will make regular def functions a little less easily introspected.
  • You can tag a cdef class with the cython.internal decorator. This makes it only easily accessible from within your module. Notes:
    • cdef classes aren't quite a substitute for Python classes (for example, all attributes must be pre-declared at compile-time),
    • If you return one of these classes to Python then the user can introspect it,
    • The class will leave some evidence that it exists in the names automatically generated pickle functions (visible in your module). You can turn that off with the auto_pickle compiler directive.
Related