Python, PyPy and CFFI: what am I supposed to use? - python-3.x

I need to call C libraries with python, and after some consideration it seemed CFFI would be most adequate for the kind of job. By now, however, I am thouroughly confused if I'm using it right, because some things seem to work as intended only on PyPy, while others seem to work only on Python3 (which PyPy doesn't support, as far as I know).
Here's the most basic code sample from the CFFI documentation:
>>> from cffi import FFI
>>> ffi = FFI()
>>> ffi.cdef("""
... int printf(const char *format, ...); // copy-pasted from the man page
... """)
>>> C = ffi.dlopen(None) # loads the entire C namespace
>>> arg = ffi.new("char[]", "world") # equivalent to C code: char arg[] = "world";
>>> C.printf("hi there, %s.\n", arg) # call printf
hi there, world.
17 # this is the return value
>>>
When running this code with Python3, I get the following error:
TypeError: initializer for ctype 'char[]' must be a bytes or list or tuple, not str
Looking for the error, I found it as an issue that was fixed in January last year in PyPy. So I see if the thing runs with PyPy, and it does. Hooray!
However, already in the second example, I'm getting the problem in reverse:
# file "simple_example_build.py"
# Note: this particular example fails before version 1.0.2
# because it combines variadic function and ABI level.
from cffi import FFI
ffi = FFI()
ffi.set_source("_simple_example", None)
ffi.cdef("""
int printf(const char *format, ...);
""")
if __name__ == "__main__":
ffi.compile()
Running this in PyPy throws another error at me:
AttributeError: 'FFI' object has no attribute 'set_source'
Since the example states helpfully that it won't work on older versions, I checked my CFFI version: 1.2.1, everything's alright.
Finally I run the second example with Python3 instead of PyPy, and who would have thought, it does exactly what it's supposed to do.
Being new to Python, by now I don't really have a clue anymore what I am supposed to use, and why the examples from the same documentation only run on different versions of the language. And there's of course still the problem that I might just have configured something wrong (what with being new to Linux too), or that I should use another python version altogether. Could somebody shed some light on this?

When running this code with Python3, I get the following error: TypeError: initializer for ctype 'char[]' must be a bytes or list or tuple, not str
Yes, because for Python 3 you need to use the 'b' prefix to make sure you are handling bytes. The example in the docs states this clearly just below.
AttributeError: 'FFI' object has no attribute 'set_source'
This means that you have an old version of PyPy. The version of CFFI cannot be upgraded in a given version of PyPy; you need to upgrade PyPy itself. Check which CFFI version your particular PyPy comes with like this:
$ pypy
Python 2.7.9 (295ee98b6928, May 31 2015, 07:29:04)
[PyPy 2.6.0 with GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>> import cffi
>>>> cffi.__version__
'1.1.0'
I'm pretty sure you're using an older version of PyPy that comes with an older version of CFFI, not 1.2.1.

you can modify it as below:
from cffi import FFI
ffi = FFI()
ffi.cdef("""int printf(const char *format, ...);""")
C = ffi.dlopen(None) # loads the entire C namespace
arg = ffi.new("char[]", b"world") # equivalent to C code: char arg[] = "world";
C.printf(b"hi there, %s.\n", arg) # call printf

Related

SAFELY Installing Python 3.6 on Ubuntu with Python 3.8 already available

I am using this package, and one of its prerequisites is bcolz, which in turn [apparently] needs Pandas < 0.23. The Pandas version I have is 1.2, and I get this exception:
BRs1 = self.convertToBroad(dui=dui1)
File "/usr/local/lib/python3.8/dist-packages/pyMeSHSim-0.0.1-py3.8.egg/pyMeSHSim/Sim/MeSHProcess.py", line 374, in convertToBroad
return self._convertToBroadOrNarrowConceptID(dui=dui, rel="RB")
File "/usr/local/lib/python3.8/dist-packages/pyMeSHSim-0.0.1-py3.8.egg/pyMeSHSim/Sim/MeSHProcess.py", line 348, in _convertToBroadOrNarrowConceptID
df = self.getRelData(data="RNandRBRel")
File "/usr/local/lib/python3.8/dist-packages/pyMeSHSim-0.0.1-py3.8.egg/pyMeSHSim/data/dataInterface.py", line 99, in getRelData
df1 = bz1.todataframe()
File "/usr/lib/python3/dist-packages/bcolz/ctable.py", line 806, in todataframe
df = pd.DataFrame.from_items(
AttributeError: type object 'DataFrame' has no attribute 'from_items'
I tried to downgrade Pandas from 1.2 to 0.22 by python3 -m pip install pandas==0.22.0, but I got an error again (a long long error I can't make much sense of).
The documentation for Pandas 0.22.0 says that it officially supports Python 3.6, Python 3.8, and Python 2.7, but I am quite worried about messing with Python on Ubuntu since my OS is doomed if I put a foot wrong. Does anyone know how I can safely install another Python version on Ubuntu? There's this answer on askubuntu, but then it has strongly warned against changing the symlink, and I don't understand what exactly I should avoid doing. I did something similar once, and from then on I had to use python3 -m pip instead of pip3 in order for Ubuntu to not confuse my two Python versions. Somebody suggested using synaptic on Ubuntu, but I wonder which of the following I should check here:
enter image description here
Another solution (that I think is more safe but needs more space) is using virtualenvs. I couldn't find any link that thoroughly explains working with them, except for perhaps pyenv, but I am new to it and as I said I need to be very careful. Does anyone know how good pyenv is, or what other solutions there are for maintaining more than one Python3 version on a single Ubuntu OS?

In sys.version is Clang as compiler, not python, What can I do?

I'm using python 3.8.3 with vim and MacOs Mojave, I was making a common script in python and when I tried run it, it shows a syntax error with += operator, this have never happened before, when I checked sys.version in both vim and the console with the python3 command it says that I'm using Clang to compile code, yesterday I modified my .vimrc a lot and no more and I don't now if that's related.
I tried running other programms with the same += operator and it works.
This is the python3 console result:
Python 3.8.3 (v3.8.3:6f8c8320e9, May 13 2020, 16:29:34)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.version
'3.8.3 (v3.8.3:6f8c8320e9, May 13 2020, 16:29:34) \n[Clang 6.0 (clang-600.0.57)]'
>>>
This is the code with the problem:
#coding=utf-8
def sum_user(user, times, operator):
counter=0
for i in times:
contar+=1
if counter<times:
resultado=user+=1
else:
break
return result
The sys.version field contains information about the version of Python and the C compiler used to build it. The python binary and the corresponding shared libraries are written in C, so some C compiler must be used to compile it.
On some platforms, such as Windows, the compiler used may contain relevant information, since it's possible to build for either the Microsoft runtime or the GNU runtime and any extension modules must be compiled against the same runtime.
Your Python code is not compiled with the C compiler, but the Python runtime. The C compiler is simply there for informative reasons, and if you don't care about which one was used, then you can just ignore it.

How to link openCv with Python3 in mac Os

I have two versions of python in my mac os, the first python2.7 which is the default that came with the system. Later I installed python3.7 that I use most of the time.
I have recently installed openCV using homebrew.
When I'm using openCV with python2.7, it's working normally.
But the problem is when I try to use it with python3. Importing cv2 in python3 gives error: ModuleNotFoundError: No module named 'cv2'
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 03:03:55)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "copyright", "credits" or "license()" for more information.
>>> WARNING: The version of Tcl/Tk (8.5.9) in use may be unstable.
Visit http://www.python.org/download/mac/tcltk/ for current
information.
>>> import cv2
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
import cv2
ModuleNotFoundError: No module named 'cv2'
>>>
Is there anything I can do so that I can link the installed openCV with python3 ??
Thanks for the help
Sorry I cannot give you specifics because your setup is not identical to mine, but I am sure we can get you sorted out.
Firstly, when you install packages, such as OpenCV, they tend to create a directory somewhere called lib which contains the C/C++ functions you can call from that package. Inside that directory, you normally find "shared object libraries" which traditionally end in "XXX.so" on macOS. More interestingly, they also contain a sub-directory called site-packages which contains the Python bindings (links). So, on my system, which is likely different from yours, I can find all those site-packages directories with:
find / -type d -name site-packages 2>/dev/null
Sample Output
/usr/local/lib/python3.7/site-packages
/usr/local/lib/python2.7/site-packages
...
...
/usr/local/Cellar/tbb/2018_U5/lib/python2.7/site-packages
/usr/local/Cellar/vips/8.6.5/lib/python3.7/site-packages
Hopefully, you can see that /usr/local/lib/python3.7/site-packages is looking a very likely candidate for where all the Python v3.7 bindings for OpenCV should be.
Good, so now we know how to find the Python bindings, we need to tell Python that information. How? Well, not unreasonably, Python looks at an environment variable called PYTHONPATH to find its stuff. So, using our skill and judgement we need to marry up what we found in the first step with what we now know from the second step. So we do:
export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3.7/site-packages
And everything should work. All we need to do is put that in our login profile (probably $HOME/.profile) and we will be ready to go every time we log in.

Get Python 3.4, Pygame, and Wing 101 all working on OSX (yosemite)

I have successfully installed Python3 and Pygame using the homebrew methods found here: Installing Pygame on Mac OS X with Python 3
After it was all done, I ran IDLE3, and the Import Pygame command ran successfully.
However now my goal is to get Wing IDE (specifically wing 101 for now) running and have it import pygame as well, but it does not seem to recognize pygame.
2.7.10 (default, Jul 13 2015, 12:05:58)
[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)]
Python Type "help", "copyright", "credits" or "license" for more information.
[evaluate untitled-2.py]
Traceback (most recent call last):
Python Shell, prompt 2, line 1
ImportError: No module named pygame
Then when i try to do the Edit < Configure Python < (change the path) method, all I get is this error
Some values are invalid:
Python executable '/usr/local/Cellar/python3/3.4.3_2/IDLE 3.app' is not a file. It should be the name of a Python interpreter that is on
your PATH (such as python, python3.4, python.exe) or the full path to
the Python interpreter you wish to use.
Please correct the values and try again.
I've tried looking everywhere for a solution, I'm pretty new at all of this as the only language i currently know is VB6 (basically caveman talk), but i really just want to get everything running smoothly so I can really get started learning.
Thanks :)
I'm not on Mac right now, so I can't test this, but it looks like it can't find the correct Python interpreter. Fortunately, IDLE can find the correct python interpreter. Open IDLE and use:
import sys
sys.executable
to find the correct python path to use. In your WingIDE settings, use that path.
Basically Running This "import sys; print(sys.executable)" in the IDLE i already had working gave me the correct path to plug into Wing.
Everything runs beautifully now, Big thankyou to everyone who provided input to my problem and solution. Haken Lid & Ben

Python 3.4 pip install wheel fails on Yosemite - "not a supported wheel on this platform"

I've been trying to install numpy, pysci etc on a MacBook Pro with Yosemite and fresh installation of ActiveState Python 3.4. I have tried many wheel files and they all fail with "not a supported wheel on this platform". For example, using the latest wheel file for Python 3.4 from https://pypi.python.org/pypi/numpy:
...$ sudo pip3 install numpy-1.9.1-cp34-cp34m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl
numpy-1.9.1-cp34-cp34m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl is not a supported wheel on this platform.
I traced my way through wheel.py, req.py and pep425tags.py to try to understand why it failed.
In pep425tags.py it uses
distutils.util.get_platform().replace('.', '_').replace('-', '_')
which, presumably, is then compared to tags in the filename of the wheel file.
Since I have upgraded to Yosemite, I was expecting that my computer would return something like: "macosx_10_10_intel" or "macosx_10_10_x86_64" - but instead it returns "macosx_10_6_x86_64"
>>> import distutils.util
>>> distutils.util.get_platform().replace('.', '_').replace('-', '_')
'macosx_10_6_x86_64'
>>>
Am I correct that Yosemite is apparently reporting that it is Snow Leopard? Or is Python 3.4 getting it wrong? Is this my problem with wheel files? If so, is there a fix?
Updating to Python 3.4.2 corrected the problem and I was able to install the numpy wheel file.
Please note however, that distutils.util.get_platform() still reports "macosx_10_6_intel" but that does not affect the installation.
Python 3.4.2 (v3.4.2:ab2c023a9432, Oct 5 2014, 20:42:22)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "copyright", "credits" or "license()" for more information.
>>> import distutils.util
>>> distutils.util.get_platform().replace('.', '_').replace('-', '_')
'macosx_10_6_intel'
Take into account that distutils.util.get_platform() returns the minimal version on which the binary will run:
For Mac OS X systems the OS version reflects the minimal version on which
binaries will run (that is, the value of MACOSX_DEPLOYMENT_TARGET
during the build of Python), not the OS version of the current system.
Emphasis mine. That said, for Python 3.4 you can reasonably expect the value to be 10.10 if you built Python on that platform.
For Python to handle MACOSX_DEPLOYMENT_TARGET to work correctly throughout, you need to upgrade to Python 3.4.2; 3.4.1 is not ready for Mac OS X 10.10 or higher. See issue #21811:
There are a number of places within the cpython code base where decisions are made based on either the running system version or the OS X ABI (e.g. the value of MACOSX_DEPLOYMENT_TARGET) that the interpreter was built with or is being built with. Most of the current tests do string comparisons of these values which will not work properly with a two-digit version number ('10.10' < '10.9' --> True).
3.4.2 includes the required fixes. The same applies to Python 2.7 up to version 2.7.7; if you see this same problem in Python 2.7 upgrade to 2.7.8 or up.
Without the fixes, intel is mixed up with x86_64, as is the case with your setup:
When running current 3.4.1 and 2.7.7 binary installers on 10.10, building C extension modules will likely result in an incorrect universal platform name, for example, "x86_64" instead of "intel", and that could affect extension module file names and wheel or egg names.
For reference, on my OS X 10.10 system, on Python 3.4.2 the result of get_platform() is:
>>> import distutils.util
>>> distutils.util.get_platform()
'macosx-10.10-x86_64'
and for Python 2.7.8 I get:
>>> import distutils.util
>>> distutils.util.get_platform()
'macosx-10.4-x86_64'

Resources