1

I would like to compare Python with Cython in term of time execution, so I wrote two files:

fac.py

def factorial(n):
    if n >= 1:
        return n*factorial(n - 1)
    return 1

fastfac.pyx

cpdef long fastfactorial(long n):
    if n>= 1:
        return n*fastfactorial(n - 1)
    return 1

Then I wrote a setup file:

setup.py

from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize('fastfac.pyx'))

From the Powershell I executed the two commands:

pip install Cython
python setup.py build_ext --inplace

From the second command I get the following message:

Compiling fastfac.pyx because it changed.
[1/1] Cythonizing fastfac.pyx
C:\Users\.....\venv\lib\site-packages\Cython\Compiler\Main.py:369: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: C:\Users\.....\fastfac.pyx
  tree = Parsing.p_module(s, pxd, full_module_name)
running build_ext
building 'fastfac' extension
error: Unable to find vcvarsall.bat

However I tried to make a comparison, so I wrote the file:

comparison.py

from fastfac import fastfactorial
from fac import factorial
from timeit import timeit

print(timeit('fastfactorial(20)', globals = globals(), number = 10000))
print(timeit('factorial(20)', globals = globals(), number = 10000))

When I run it, I get this error message:

Traceback (most recent call last):
  File "C:/Users/...../comparison.py", line 1, in <module>
    from fastfac import fastfactorial
ModuleNotFoundError: No module named 'fastfac'

It seems that in the file python.pyx the definition cpdef long fastfactorial(long n) is not recognized as a regular function definition but as a syntax error; in fact, if I try to run that file I get the error message:

  File "C:/Users/...../fastfac.pyx", line 1
    cpdef long fastfactorial(long n):
             ^
SyntaxError: invalid syntax

How can I solve? How can I correctly define a cpdef inside a .pyx file? what am I missing?

Zephyr
  • 11,891
  • 53
  • 45
  • 80
  • 1
    Cythonizing fastfac.pyx, failed: `error: Unable to find vcvarsall.bat`, you should fix that first – Maurice Meyer May 29 '20 at 08:20
  • Does this answer your question? [error: Unable to find vcvarsall.bat](https://stackoverflow.com/questions/2817869/error-unable-to-find-vcvarsall-bat) – ead May 29 '20 at 08:27
  • Duplicate assumes you have visual studio installed. That might not be the case for you. Then you need to install it. – ead May 29 '20 at 08:28

1 Answers1

1

The problem is not your definition of fastfactorial, it is the fact that your setup.py exited with an error and, presumably, without compiling fastfac into a c library. In general, you should always fix such errors.

Your error appears to be happening because you don't have a Microsoft Visual C++ compiler installed. You can follow the instructions in this answer to choose a version of Visual C++ to install.

You also have a warning about the language_level not being set. You shouldn't ignore warnings either so it is worth explicitly stating the level in your setup.py.

setup(ext_modules=cythonize('fastfac.pyx'), language_level=3)
FiddleStix
  • 3,016
  • 20
  • 21
  • I modified the setup line as you indicated, now I get the error: `C:\Users\.....\Python37-32\lib\distutils\dist.py:274: UserWarning: Unknown distribution option: 'language_level' warnings.warn(msg) running build_ext building 'fastfac' extension error: Unable to find vcvarsall.bat` – Zephyr May 29 '20 at 09:05
  • I went to the link you indicated and followed the bulleted list; on this machine I am running: `Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)] on win32` so I downloaded and installed the appropriate version of Visual Studio C++ 2017 (15.7). Then I run the command `C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat` and I got the answer `C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat` without any further information. – Zephyr May 29 '20 at 09:06
  • The command `python setup.py build_ext --inplace` still throws me the same error as before. – Zephyr May 29 '20 at 09:07
  • Apparently, you should have got a message like "Setting environment for using Microsoft Visual Studio..." when you ran the vsvars.bat. Did you run it from a cmd prompt? – FiddleStix May 29 '20 at 11:10
  • Even tough I installed the required VC++ version ([link](https://i.ibb.co/vY5N8rY/panel.png)), in my `Program Files (x86)` there is no `Microsoft Visual Studio 9.0` folder, neither a `vsvars32.bat` or a `vsvars64.bat`, as you can see here [link](https://i.ibb.co/80NtvPG/folder.png); so the cmd prompt fails to run a file that it cannot find – Zephyr May 31 '20 at 12:57
  • 1
    Years after I switched to linux, it seems there is no issue with C++ compilers in this OS, so everything runs properly. Thanks – Zephyr Jan 16 '22 at 09:50