Repository: cython/cython
Pull request: Document cython.compile
Fixes #2770.


Problem statement:
Document @cython.compile
Hi,

I was wondering whethter there is a way, or it is possible to add a way, to do something like:
```python
from cython import cythonize, other, cython, magics

@cythonize  # Decorator of interest
@other 
@cython
@magics
def slow_function_at_work():
      # omg so slow

# slow function is fast at this point
```
I dug a bit inside some cython files, and saw there's a `pyx_to_dll` function, and a `cython_inline` function. 

Is it perhaps possible to - 
- Make `pyx_to_dll` read `StringIO` objects (probably not since I saw that path is formed into a command string)
- Somehow work with `cython_inline(inspect.getsource(slow_function))`
- Use some other method

So that one can @cythonize his functions in pure mode?

I think this is the epitome of pure mode - the ability to decorate and move along, and let cython hook in the sped up code.


Thanks,
Eli

Hints from issue discussion:
Looks like `@cython.compile` is undocumented, that's what you want. It should be mentioned [here](https://github.com/cython/cython/blob/master/docs/src/userguide/source_files_and_compilation.rst), preferably somewhere close to `@cython.inline`.
Sweet, thanks!

It looks like `RuntimeCompiledFunction` in fact uses `cython_inline`.  
Are you aware of - 
https://github.com/AlanCristhian/statically

This package also seems to use a similar technique, but has more meat to it - 
https://github.com/AlanCristhian/statically/blob/master/statically.py

Edit:
Does `@cython.compile` take into account the other magics, eg `locals`, `returns`, `cfunc`, `nogil` etc?
> Does @cython.compile take into account the other magics, eg locals, returns, cfunc, nogil etc?

I would hope so, but since it's undocumented, you'd better try it out. If it does not, then that's probably just an easy to fix bug.
Sorry if it's silly, but how can I see in runtime what @compile generated?

Commit message: Document cython.compile

Patch to review:
diff --git a/docs/src/userguide/source_files_and_compilation.rst b/docs/src/userguide/source_files_and_compilation.rst
index b5855609772..e61bae7a0d6 100644
--- a/docs/src/userguide/source_files_and_compilation.rst
+++ b/docs/src/userguide/source_files_and_compilation.rst
@@ -605,6 +605,34 @@ Unbound variables are automatically pulled from the surrounding local
 and global scopes, and the result of the compilation is cached for
 efficient re-use.
 
+Compiling with ``cython.compile``
+=================================
+
+Cython supports transpartent compiling of the cython code within function using
+``@cython.compile`` dedorator::
+
+    @cython.compile
+    def plus(a, b):
+        return a + b
+
+Parameters of the decorated function cannot have types. Their types are
+automaticaly determined based on values passed to a function.
+Executing example::
+
+    import cython
+
+    @cython.compile
+    def plus(a, b):
+        return a + b
+
+    print(plus('3', '5'))
+    print(plus(3, 5))
+
+will produce following output::
+
+    35
+    8
+
 .. _compiling_with_sage:
 
 Compiling with Sage


Code review comments:
diff_hunk: @@ -605,6 +605,34 @@ Unbound variables are automatically pulled from the surrounding local
 and global scopes, and the result of the compilation is cached for
 efficient re-use.
 
+Compiling with ``cython.compile``
+=================================
+
+Cython supports transpartent compiling of the cython code within function using
+``@cython.compile`` dedorator::
+
+    @cython.compile
+    def plus(a, b):
+        return a + b
+
+Parameters of the decorated function cannot have types. Their types are
+automaticaly determined based on values passed to a function.
path: docs/src/userguide/source_files_and_compilation.rst
text: @user1:
```suggestion
set to be a normal Python object.
```

The way you've written it implies JIT compilation specialized for whatever type you've passed (which I don't think is what happens)

@author:
> The way you've written it implies JIT compilation specialized for whatever type you've passed 

Well Cython does kind of specialisation if I understand it correctly - see the generated .pyx files by the decorator below. Cython generates two versions of function (`_cython_inline_4528cbcb5eb32c44847d2ed113ddee648d7485d6.pyx` and `_cython_inline_3e54f923a152621eae433e8eb5c2eb8559332453.pyx`) - one with python string and other with C long type. 


```
$ python test.py
Compiling /Users/matus/Library/Caches/cython/inline/_cython_inline_4528cbcb5eb32c44847d2ed113ddee648d7485d6.pyx because it changed.
[1/1] Cythonizing /Users/matus/Library/Caches/cython/inline/_cython_inline_4528cbcb5eb32c44847d2ed113ddee648d7485d6.pyx
warning: /Users/matus/Library/Caches/cython/inline/_cython_inline_4528cbcb5eb32c44847d2ed113ddee648d7485d6.pyx:7:4: Unreachable code
35
Compiling /Users/matus/Library/Caches/cython/inline/_cython_inline_3e54f923a152621eae433e8eb5c2eb8559332453.pyx because it changed.
[1/1] Cythonizing /Users/matus/Library/Caches/cython/inline/_cython_inline_3e54f923a152621eae433e8eb5c2eb8559332453.pyx
warning: /Users/matus/Library/Caches/cython/inline/_cython_inline_3e54f923a152621eae433e8eb5c2eb8559332453.pyx:7:4: Unreachable code
8
(cython39) matus@user2-Pro:~/dev/cython/test$ cat /Users/matus/Library/Caches/cython/inline/_cython_inline_4528cbcb5eb32c44847d2ed113ddee648d7485d6.pyx



def __invoke(str a, str b):

    return a + b
    return locals()

(cython39) matus@user2-Pro:~/dev/cytho/Users/matus/Library/Caches/cython/inline/_cython_inline_3e54f923a152621eae433e8eb5c2eb8559332453.pyx59332453.pyx



def __invoke(long a, long b):

    return a + b
    return locals()
```

@user1:
Oh OK I didn't know that. What you've written is correct then. Sorry!

@author:
No worries. It was surprising also for me :-D

diff_hunk: @@ -605,6 +605,34 @@ Unbound variables are automatically pulled from the surrounding local
 and global scopes, and the result of the compilation is cached for
 efficient re-use.
 
+Compiling with ``cython.compile``
+=================================
+
+Cython supports transpartent compiling of the cython code within function using
+``@cython.compile`` dedorator::
+
+    @cython.compile
+    def plus(a, b):
+        return a + b
+
+Parameters of the decorated function cannot have types. Their types are
+automaticaly determined based on values passed to a function.
path: docs/src/userguide/source_files_and_compilation.rst
text: @user1:
```suggestion
Parameters of the decorated function cannot have type declarations. Their types are
automatically determined from values passed to the function, thus leading to one or more
specialised compiled functions for the respective argument types.
```