pycall 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba0b7938e482d87e6a6eb540b92b2e581974fc6e894e674c7da00b4b68807b15
4
- data.tar.gz: ad5ce0352f59744abf9193e69cf33719f9314aad45e9c24fd6584fe73873330e
3
+ metadata.gz: 79fa29a4fd735c0741f03e74aadce297273cd2d64c0813b9ee2e20ad5fa321b9
4
+ data.tar.gz: 108942ac4b4d45324644fe90af4e56e239f7ce3b2f27fa0d98d5defa439da8db
5
5
  SHA512:
6
- metadata.gz: cc2eb8963c91d69086eccab17cb06ebea072908f77f3e4f85a23f328f858f7cda29ebec70c519fa70f3fc88eaf5e37b61b88136515f2326e0c239467a522067b
7
- data.tar.gz: cfb14589abee3741fcec45f31d8d94dc076341ae425ee0302e50628e6ffafdfff665a6e90c67a80ce10df6a8866282bc221ecddf198d0049ee85d1055bb50255
6
+ metadata.gz: eb899c3e9c353622945df3b816df4588cd3b4606f723c53973a2f8d77d8eb9edf94b7dbcf15ff4d33f65430fd6d38a8bc2ccc2fda2a1f8f274dc769b0280e42a
7
+ data.tar.gz: ff84eb82b4e10d1a2f699abd32cfcdcc6159cba6b83f2258bc4100c7229bb49ca1c7593b5a6629ef2081007728bc3be5e266b65c2967c49c043fb3dfe0bf3835
@@ -1,67 +1,150 @@
1
1
  name: CI
2
2
 
3
3
  on:
4
- - push
4
+ push:
5
+ branches:
6
+ - master
7
+ - "check/ci/**"
8
+ - "check/unix/**"
9
+ pull_request:
10
+ types:
11
+ - opened
12
+ - synchronize
13
+ - reopened
5
14
 
6
15
  jobs:
7
16
  test:
8
- name: Test
17
+ name: ${{ matrix.venv }}${{ matrix.os }}/${{ matrix.ruby }}/${{ matrix.python }}-${{ matrix.python_architecture }}
9
18
  runs-on: ${{ matrix.os }}
10
19
 
11
20
  strategy:
12
21
  fail-fast: false
13
22
  matrix:
14
23
  os:
15
- - ubuntu-18.04
24
+ - ubuntu-20.04
16
25
  - macos-latest
17
- ruby_version:
18
- - 2.7.x
19
- - 2.6.x
20
- - 2.5.x
21
- - 2.4.x
22
- python_version:
23
- - 3.8.x
24
- - 3.7.x
25
- - 3.6.x
26
- - 2.7.x
26
+ ruby:
27
+ - "3.0"
28
+ - 2.7
29
+ - 2.6
30
+ python:
31
+ - 3.x
32
+ - 2.x
27
33
  python_architecture:
28
34
  - x64
35
+ venv:
36
+ - ""
37
+ include:
38
+ - { os: ubuntu-20.04 , ruby: 2.5 , python: 3.x , python_architecture: x64 , venv: "" }
39
+ - { os: ubuntu-20.04 , ruby: 2.4 , python: 3.x , python_architecture: x64 , venv: "" }
40
+ - { os: ubuntu-20.04 , ruby: 2.5 , python: 2.x , python_architecture: x64 , venv: "" }
41
+ - { os: ubuntu-20.04 , ruby: 2.4 , python: 2.x , python_architecture: x64 , venv: "" }
42
+ - { os: ubuntu-20.04 , ruby: 2.7 , python: 3.8 , python_architecture: x64 , venv: "" }
43
+ - { os: ubuntu-20.04 , ruby: 2.7 , python: 3.7 , python_architecture: x64 , venv: "" }
44
+ - { os: ubuntu-20.04 , ruby: 2.7 , python: 3.6 , python_architecture: x64 , venv: "" }
45
+ - { os: ubuntu-18.04 , ruby: 2.7 , python: 3.8 , python_architecture: x64 , venv: "" }
46
+ - { os: ubuntu-20.04 , ruby: debug , python: 3.x , python_architecture: x64 , venv: "" }
47
+ - { os: ubuntu-20.04 , ruby: "3.0" , python: 3.x , python_architecture: x64 , venv: "venv:" }
48
+ - { os: ubuntu-18.04 , ruby: "3.0" , python: 3.x , python_architecture: x64 , venv: "venv:" }
49
+ - { os: ubuntu-18.04 , ruby: "3.0" , python: 3.8 , python_architecture: x64 , venv: "venv:" }
50
+ - { os: macos-latest , ruby: "3.0" , python: 3.x , python_architecture: x64 , venv: "venv:" }
51
+ - { os: macos-latest , ruby: "3.0" , python: 3.8 , python_architecture: x64 , venv: "venv:" }
52
+ #- { os: macos-latest , ruby: debug , python: 3.x , python_architecture: x64 , venv: "" }
29
53
 
30
54
  steps:
31
- - name: Setup Ruby
32
- if: matrix.ruby_version != 'master-nightly'
33
- uses: actions/setup-ruby@v1
34
- with:
35
- ruby-version: ${{ matrix.ruby_version }}
36
-
37
- - name: Setup Python
38
- uses: actions/setup-python@v1
39
- with:
40
- python-version: ${{ matrix.python_version }}
41
- architecture: ${{ matrix.python_architecture }}
42
-
43
- - name: Checkout
44
- uses: actions/checkout@v1
45
- with:
46
- fetch-depth: 1
47
-
48
- - name: Prepare environment
49
- run: |
50
- gem install bundler
51
-
52
- - name: Install requirements
53
- run: |
54
- pip install --user numpy
55
- bundle install
56
-
57
- - name: Compile pycall.so
58
- run: |
59
- bundle exec rake compile
60
-
61
- - name: Python investigator
62
- run: |
63
- python lib/pycall/python/investigator.py
64
-
65
- - name: Test
66
- run: |
67
- PYTHON=python bundle exec rake
55
+ - uses: actions/checkout@v2
56
+ with:
57
+ fetch-depth: 1
58
+
59
+ - uses: ruby/setup-ruby@v1
60
+ if: matrix.ruby_version != 'master-nightly'
61
+ with:
62
+ ruby-version: ${{ matrix.ruby }}
63
+
64
+ - uses: actions/setup-python@v2
65
+ with:
66
+ python-version: ${{ matrix.python }}
67
+ architecture: ${{ matrix.python_architecture }}
68
+
69
+ - run: pip install --user numpy
70
+
71
+ - run: bundle install
72
+
73
+ - run: rake compile
74
+
75
+ - run: python lib/pycall/python/investigator.py
76
+
77
+ - name: venv examination
78
+ run: |
79
+ python -m venv ~/test-venv
80
+ source ~/test-venv/bin/activate
81
+ ruby -Ilib -Iext/pycall -rpycall -ePyCall.builtins
82
+ env:
83
+ PYCALL_DEBUG_FIND_LIBPYTHON: 1
84
+ if: ${{ matrix.venv != '' }}
85
+
86
+ - run: rake
87
+ env:
88
+ PYTHON: python
89
+
90
+ conda:
91
+ name: conda:${{ matrix.os }}/${{ matrix. ruby }}/${{ matrix.python }}
92
+ runs-on: ${{ matrix.os }}
93
+
94
+ strategy:
95
+ fail-fast: false
96
+ matrix:
97
+ os:
98
+ - ubuntu-20.04
99
+ - macos-latest
100
+ ruby:
101
+ - "3.0"
102
+ python:
103
+ - 3.8
104
+
105
+ steps:
106
+ - uses: actions/checkout@v2
107
+ with:
108
+ fetch-depth: 1
109
+
110
+ - uses: conda-incubator/setup-miniconda@v2
111
+ with:
112
+ activate-environment: test
113
+ python-version: ${{ matrix.python }}
114
+
115
+ - uses: ruby/setup-ruby@v1
116
+ if: matrix.ruby_version != 'master-nightly'
117
+ with:
118
+ ruby-version: ${{ matrix.ruby }}
119
+
120
+ - name: Add Ruby path
121
+ run: |
122
+ echo >> ~/.profile
123
+ echo >> ~/.profile
124
+ IFS=:
125
+ for p in $PATH; do
126
+ case $p in
127
+ */Ruby/*)
128
+ echo "export PATH=$p:\$PATH" >> ~/.profile
129
+ ;;
130
+ esac
131
+ done
132
+
133
+ - run: cat ~/.profile
134
+
135
+ - run: bash -xe ~/.profile
136
+
137
+ - run: conda install numpy
138
+ shell: bash -l {0}
139
+
140
+ - run: bundle install
141
+
142
+ - run: rake compile
143
+
144
+ - run: python lib/pycall/python/investigator.py
145
+ shell: bash -l {0}
146
+
147
+ - run: rake
148
+ env:
149
+ PYTHON: python
150
+ shell: bash -l {0}
@@ -0,0 +1,127 @@
1
+ name: Windows
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ - "check/ci/**"
8
+ - "check/windows/**"
9
+ pull_request:
10
+ types:
11
+ - opened
12
+ - synchronize
13
+ - reopened
14
+
15
+ jobs:
16
+ test:
17
+ name: ruby-${{ matrix.ruby }}/python-${{ matrix.python }}-${{ matrix.python_architecture }}
18
+ runs-on: windows-latest
19
+
20
+ strategy:
21
+ fail-fast: false
22
+ matrix:
23
+ ruby:
24
+ - "3.0"
25
+ - 2.7
26
+ - 2.6
27
+ python:
28
+ - 3.x
29
+ - 2.x
30
+ python_architecture:
31
+ - x64
32
+ include:
33
+ - { os: windows-latest , ruby: mingw , python: 3.x , python_architecture: x64 }
34
+ #- { os: windows-latest , ruby: mswin , python: 3.x , python_architecture: x64 }
35
+
36
+ steps:
37
+ - uses: actions/checkout@v2
38
+ with:
39
+ fetch-depth: 1
40
+
41
+ - uses: ruby/setup-ruby@v1
42
+ if: matrix.ruby_version != 'master-nightly'
43
+ with:
44
+ ruby-version: ${{ matrix.ruby }}
45
+
46
+ - uses: actions/setup-python@v2
47
+ with:
48
+ python-version: ${{ matrix.python }}
49
+ architecture: ${{ matrix.python_architecture }}
50
+
51
+ - run: pip install --user numpy
52
+
53
+ - run: bundle install
54
+
55
+ - run: rake compile
56
+
57
+ - run: python lib/pycall/python/investigator.py
58
+
59
+ - run: rake
60
+ env:
61
+ PYTHON: python
62
+
63
+ conda:
64
+ name: conda:ruby-${{ matrix. ruby }}/python-${{ matrix.python }}
65
+ runs-on: windows-latest
66
+
67
+ strategy:
68
+ fail-fast: false
69
+ matrix:
70
+ ruby:
71
+ - "3.0"
72
+ python:
73
+ - 3.8
74
+
75
+ defaults:
76
+ run:
77
+ shell: pwsh
78
+
79
+ steps:
80
+ - uses: actions/checkout@v2
81
+ with:
82
+ fetch-depth: 1
83
+
84
+ - uses: conda-incubator/setup-miniconda@v2
85
+ with:
86
+ activate-environment: test
87
+ python-version: ${{ matrix.python }}
88
+
89
+ - run: set
90
+ shell: cmd
91
+
92
+ - name: Add conda's DLL path
93
+ run: |
94
+ echo $env:CONDA\Library\bin >> $GITHUB_PATH
95
+ echo $env:CONDA_PREFIX\Library\bin >> $GITHUB_PATH
96
+
97
+ - uses: ruby/setup-ruby@v1
98
+ if: matrix.ruby_version != 'master-nightly'
99
+ with:
100
+ ruby-version: ${{ matrix.ruby }}
101
+
102
+ - run: conda install numpy
103
+
104
+ - run: python -c 'import numpy; print(numpy)'
105
+
106
+ - run: python -c 'import os; print(os.environ)'
107
+
108
+ - run: bundle install
109
+
110
+ - run: rake compile
111
+
112
+ - run: python lib/pycall/python/investigator.py
113
+
114
+ - run: |
115
+ ruby -Ilib -Iext/pycall -rpycall -e "p PyCall.sys.version"
116
+ ruby -Ilib -Iext/pycall -rpycall -e "PyCall.import_module(:numpy)"
117
+ env:
118
+ PYTHON: python
119
+ continue-on-error: true
120
+
121
+ - run: |
122
+ echo $env:PATH
123
+ rake
124
+ env:
125
+ PYTHON: python
126
+ CONDA_DLL_SEARCH_MODIFICATION_ENABLE: 1
127
+ continue-on-error: true
data/.gitignore CHANGED
@@ -10,6 +10,8 @@
10
10
 
11
11
  __pycache__/
12
12
  .ipynb_checkpoints/
13
+ /ext/**/Makefile
14
+ /ext/**/mkmf.log
13
15
  *.bundle
14
16
  *.so
15
17
  *.o
data/CHANGES.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # The change history of PyCall
2
2
 
3
+ ## 1.4.0
4
+
5
+ * Explicitly states that Windows is not supported yet in README
6
+ * Add PyCall.same?
7
+ * Improve conda support
8
+ * Fat gem is no longer supported
9
+ * Use WeakMap for caching PyPtr instances
10
+
3
11
  ## 1.3.1
4
12
 
5
13
  * Stop using `&proc` idiom to prevent warnings
data/README.md CHANGED
@@ -6,7 +6,6 @@
6
6
  # PyCall: Calling Python functions from the Ruby language
7
7
 
8
8
  [![Build Status](https://github.com/mrkn/pycall.rb/workflows/CI/badge.svg)](https://github.com/mrkn/pycall.rb/actions?query=workflow%3ACI)
9
- [![Build Status](https://travis-ci.org/mrkn/pycall.rb.svg?branch=master)](https://travis-ci.org/mrkn/pycall.rb)
10
9
  [![Build status](https://ci.appveyor.com/api/projects/status/0fad23u4qj1yr49e/branch/master?svg=true)](https://ci.appveyor.com/project/mrkn/pycall-rb/branch/master)
11
10
 
12
11
  This library provides the features to directly call and partially interoperate
@@ -16,7 +15,7 @@ Ruby to Python.
16
15
 
17
16
  ## Supported Ruby versions
18
17
 
19
- pycall.rb supports Ruby version 2.3 or higher.
18
+ pycall.rb supports Ruby version 2.4 or higher.
20
19
 
21
20
  ## Supported Python versions
22
21
 
@@ -33,6 +32,12 @@ pyenv does not build the shared library in default, so you need to specify `--en
33
32
  $ env PYTHON_CONFIGURE_OPTS='--enable-shared' pyenv install 3.7.2
34
33
  ```
35
34
 
35
+ ## Note for Windows users
36
+
37
+ Currently, pycall.rb does not support Windows. Please try to use pycall.rb on WSL2 environment.
38
+
39
+ On Windows, the error "[BUG] object allocation during garbage collection phase" is occurred at unpredictable timings.
40
+
36
41
  ## Installation
37
42
 
38
43
  Add this line to your application's Gemfile:
@@ -62,6 +67,33 @@ the `Math.sin` in Ruby:
62
67
  Type conversions from Ruby to Python are automatically performed for numeric,
63
68
  boolean, string, arrays, and hashes.
64
69
 
70
+ ### Calling a constructor
71
+
72
+ In Python, we call the constructor of a class by `classname(x, y, z)` syntax. Pycall.rb maps this syntax to `classname.new(x, y, z)`.
73
+
74
+ ### Calling a callable object
75
+
76
+ In Python, we can call the callable object by `obj(x, y, z)` syntax. PyCall.rb maps this syntax to `obj.(x, y, z)`.
77
+
78
+ ### Passing keyword arguments
79
+
80
+ In Python, we can pass keyword arguments by `func(x=1, y=2, z=3)` syntax. In pycallrb, we should rewrite `x=1` to `x: 1`.
81
+
82
+ ### The callable attribute of an object
83
+
84
+ Pycall.rb maps the callable attribute of an object to the instance method of the corresponding wrapper object. So, we can write a Python expression `obj.meth(x, y, z=1)` as `obj.meth(x, y, z: 1)` in Ruby. This mapping allows us to call these attributes naturally as Ruby's manner.
85
+
86
+ But, unfortunately, this mapping prohibits us to get the callable attributes. We need to write `PyCall.getattr(obj, :meth)` in Ruby to get `obj.meth` object while we can write `obj.meth` in Python.
87
+
88
+ ### Specifying the Python version
89
+
90
+ If you want to use a specific version of Python instead of the default,
91
+ you can change the Python version by setting the `PYTHON` environment variable
92
+ to the path of the `python` executable.
93
+
94
+ When `PYTHON` is not specified, pycall.rb tries to use `python3` first,
95
+ and then tries to use `python`.
96
+
65
97
  ### Releasing the RubyVM GVL during Python function calls
66
98
 
67
99
  You may want to release the RubyVM GVL when you call a Python function that takes very long runtime.
@@ -101,6 +133,20 @@ DEBUG(find_libpython) Unable to find /opt/brew/opt/python/lib/darwin/Python.fram
101
133
  DEBUG(find_libpython) dlopen("/opt/brew/opt/python/Frameworks/Python.framework/Versions/3.7/Python") = #<Fiddle::Handle:0x00007fc012048650>
102
134
  ```
103
135
 
136
+ ## Special notes for specific libraries
137
+
138
+ ### matplotlib
139
+
140
+ Use [mrkn/matplotlib.rb](https://github.com/mrkn/matplotlib.rb) instead of just importing it by `PyCall.import_module("matplotlib")`.
141
+
142
+ ### numpy
143
+
144
+ Use [mrkn/numpy.rb](https://github.com/mrkn/numpy.rb) instead of just importing it by `PyCall.import_module("numpy")`.
145
+
146
+ ### pandas
147
+
148
+ Use [mrkn/pandas.rb](https://github.com/mrkn/pandas.rb) instead of just importing it by `PyCall.import_module("pandas")`.
149
+
104
150
  ## PyCall object system
105
151
 
106
152
  PyCall wraps pointers of Python objects in `PyCall::PyPtr` objects.
@@ -120,11 +166,71 @@ variable `@__pyptr__`. `PyCall::PyObjectWrapper` assumes the existance of
120
166
  system and Python object system. For example, `PyCall::PyObjectWrapper`
121
167
  translates Ruby's coerce system into Python's swapped operation protocol.
122
168
 
123
- ### Specifying the Python version
169
+ ## Deploying on Heroku
124
170
 
125
- If you want to use a specific version of Python instead of the default,
126
- you can change the Python version by setting the `PYTHON` environment variable
127
- to the path of the `python` executable.
171
+ Heroku's default version of Python is not compiled with the `--enabled-shared`
172
+ option and can't be accessed by PyCall. Alternative [buildpacks](https://devcenter.heroku.com/articles/buildpacks) are available,
173
+ including these that have been reported to work with PyCall:
174
+
175
+ https://github.com/richgong/heroku-buildpack-python
176
+ https://github.com/dsounded/heroku-buildpack-python
177
+ https://github.com/ReforgeHQ/heroku-buildpack-python
178
+
179
+ These community-developed buildpacks are not supported by Heroku, so it's
180
+ worth examining the source to make sure the buildpack you use suits your
181
+ needs. For instance, 'ReforgeHQ' works well with Python 3.8.1, but has not
182
+ been configured to work with other versions and may not be as generally
183
+ useful as the 'dsounded' or 'richgong' buildpacks.
184
+
185
+ The buildpack will expect to find both a `runtime.txt` and a `requirements.txt`
186
+ file in the root of your project. You will need to add these to specify the
187
+ version of Python and any packages to be installed via `pip`, _e.g_ to use
188
+ version Python 3.8.1 and version 2.5 of the 'networkx' package:
189
+
190
+ $ echo "python-3.8.1" >> runtime.txt
191
+ $ echo "networkx==2.5" >> requirements.txt
192
+
193
+ Commit these two files into project's repository. You'll use these to manage
194
+ your Python environment in much the same way you use the `Gemfile` to manage
195
+ Ruby.
196
+
197
+ Heroku normally detects which buildpacks to use, but you will want to override
198
+ this behavior. It's probably best to clear out existing buildpacks and specify
199
+ exactly which buildpacks from scratch.
200
+
201
+ First, take stock of your existing buildpacks:
202
+
203
+ $ heroku buildpack [-a YOUR_APP_NAME]
204
+
205
+ For a Ruby/Rails application this will typically report the stock `heroku/ruby`
206
+ buildpack, or possibly both `heroku/ruby` and `heroku/nodejs`.
207
+
208
+ Clear the list and progressively add back your buildpacks, starting with the Python
209
+ community-developed buildpack. For example, if `ruby` and `nodejs` buildpacks were
210
+ previously installed, and chosing the 'ReforgeHQ' buildback, your setup process will
211
+ be similar to this:
212
+
213
+ $ heroku buildpacks:clear
214
+ $ heroku buildpacks:add https://github.com/ReforgeHQ/heroku-buildpack-python -i 1
215
+ $ heroku buildpacks:add heroku/nodejs -i 2
216
+ # heroku buildpacks:add heroku/ruby -i 3
217
+
218
+ If you have multiple applications on Heroku you will need to append each of these
219
+ with application's identifier (_e.g._ `heroku buildpacks:clear -a YOUR_APP_NAME`).
220
+
221
+ With each buildpack we are registering its index (the `-i` switch) in order to
222
+ specify the order Heroku will load runtimes and execute bootstrapping code. It's
223
+ important for the Python environment to be engaged first, as PyCall will need to
224
+ be able to find it when Ruby-based processes start.
225
+
226
+ Once you have set up your buildpacks, and have commited both `requirements.txt` and
227
+ `runtime.txt` files to git, deploy your Heroku application as your normally would.
228
+ The Python bootstrapping process will appear in the log first, followed by the Ruby
229
+ and so on. PyCall should now be able to successfully call Python functions from
230
+ within the Heroku environment.
231
+
232
+ NB It is also possible to specify buildpacks within Docker images on Heroku.
233
+ See Heroku's [documentation on using Docker Images](https://devcenter.heroku.com/articles/build-docker-images-heroku-yml).
128
234
 
129
235
  ## Development
130
236