How to use Ruby's PyCall to enable pyenv Python

Assumed environment

Problems encountered

Write a Ruby script like this [^ 1]

test.rb


require 'pycall/import'

puts "ok"

Once executed,

$ ruby test.rb
ImportError: No module named site

Error appears.

Solution

When installing Python with pyenv, specify an option to create a shared library.

$ CONFIGURE_OPTS="--enable-shared" pyenv install 3.6.1

This will generate libpython3.6m.dylib under ~ / .pyenv / versions / 3.6.1. [^ 2]

Tracking

Find the site module

$ cd $(pyenv prefix)
$ find . -name site.py
./lib/python3.6/site-packages/jedi/evaluate/site.py
./lib/python3.6/site.py

There is site.py. I guess it's just that the path doesn't pass.

Try through PYTHONPATH

PYTHONPATH=$HOME/.pyenv/versions/3.6.1/lib/python3.6 ruby test.rb
  File "/Users/cesare/.pyenv/versions/3.6.1/lib/python3.6/site.py", line 177
    file=sys.stderr)
        ^
SyntaxError: invalid syntax

The module was successfully found, but this time I got a syntax error. Apparently, I suspect that the processing system that loaded this module is not Python3.x system.

I took a quick look at the PyCall source and seemed to be using FFI, so I expected the processing system to be a shared library.

Find a shared library for processing

On Mac, the extension of the shared library is often .dylib, so for the time being, try searching for it like this.

$ find . -name '*.dylib'
./lib/python3.6/site-packages/matplotlib/.dylibs/libpng16.16.dylib
./lib/python3.6/site-packages/matplotlib/.dylibs/libz.1.2.10.dylib
./lib/python3.6/site-packages/scipy/.dylibs/libgcc_s.1.dylib
./lib/python3.6/site-packages/scipy/.dylibs/libgfortran.3.dylib
./lib/python3.6/site-packages/scipy/.dylibs/libquadmath.0.dylib

There are some, but they are different because they are from packages that I installed later. If you look under .pyenv / versions / 3.6.1 / lib, you can see that the file libpython3.6m.a is rolling, but .a is not a shared library and what you are looking for is not this. I guess it's probably necessary that a file called libpython3.6m.dylib exists.

Allow pyenv to create a shared library for processing

When I fetched the source of the Python processing system and examined the option of configure, I found that it seems that --enable-shared can be specified. It seems that you can use the environment variable CONFIGURE_OPTS to specify the configure option when installing pyenv.

So

$ CONFIGURE_OPTS="--enable-shared" pyenv install 3.6.1

This generated libpython3.6m.dylib. When I rerun the test Ruby script,

$ ruby test.rb
ok

It worked safely.

Supplement

libpython search order

You can observe PyCall looking for libpython using the environment variable DEBUG_FIND_LIBPYTHON.

$ DEBUG_FIND_LIBPYTHON=1 ruby -e 'require "pycall"'

By doing so, the searched paths will be listed in the standard output.


[^ 1]: I got this code after cutting extra things to minimize it to find the cause of the error. Since "ok" does not appear in the standard output, it can be seen that it is moss with require'pycall / import'. [^ 2]: When --enable-shared was not specified, .dylib was not generated and only .a files with the same name were placed.

Recommended Posts

How to use Ruby's PyCall to enable pyenv Python
How to use Pyenv
How to use python put in pyenv on macOS with PyCall
How to use tkinter with python in pyenv
python3: How to use bottle (2)
How to use Python argparse
[Python] How to use checkio
[Python] How to use input ()
How to use Python lambda
[Python] How to use virtualenv
python3: How to use bottle (3)
python3: How to use bottle
How to use Python bytes
[Python] How to use Pandas Series
How to use Requests (Python Library)
How to use SQLite in Python
[Python] How to use list 3 Added
How to use Mysql in python
How to use OpenPose's Python API
How to use ChemSpider in Python
How to use FTP with Python
Python: How to use pydub (playback)
How to use PubChem in Python
How to use python zip function
[Python] How to use Typetalk API
[Python] Summary of how to use pandas
[Introduction to Python] How to use class in Python?
How to install and use pandas_datareader [Python]
[python] How to use __command__, function explanation
[Python] How to use import sys sys.argv
[Python] Organizing how to use for statements
Memorandum on how to use gremlin python
[Python2.7] Summary of how to use unittest
How to use __slots__ in Python class
How to use "deque" for Python data
[Python] Understand how to use recursive functions
Summary of how to use Python list
How to use regular expressions in Python
[Python2.7] Summary of how to use subprocess
How to use is and == in Python
[Blender x Python] How to use modifiers
[Question] How to use plot_surface of python
How to use xml.etree.ElementTree
How to use Python-shell
How to use the C library in Python
How to use tf.data
How to use virtualenv
How to use Seaboan
How to use image-match
How to use shogun
[Introduction to Udemy Python3 + Application] 23. How to use tuples
How to install Python
How to use Virtualenv
How to use numpy.vectorize
How to use Raspberry Pi pie camera Python
How to use pytest_report_header
How to use Python Image Library in python3 series
How to use Python Kivy ④ ~ Execution on Android ~
How to use partial
How to use Bio.Phylo
Summary of how to use MNIST in Python