pycall 0.1.0.alpha.20170302 → 0.1.0.alpha.20170307

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f8c5abd1327e908691a79a42fdc536826e48d208
4
- data.tar.gz: 4dd793ea028f6b9e47c9e74266d043de5751a74a
3
+ metadata.gz: bff90008a927b2cb383fe47fa5b7c9e4447c01ec
4
+ data.tar.gz: 4de66d04dad27fc929fe5071bc9ce8bcf06019cd
5
5
  SHA512:
6
- metadata.gz: 6a75c2f1a5df62a881f8eee78fc72f5896bbc30d912610afc4f7b6bc719b43015cdddd03f87b6202a5ab782c4a182fd6fef181923e270cd1299bc9b738ff2709
7
- data.tar.gz: 6fa5f34b243181d4340c3c265eb3c68b430c971976ba8a2ee8649d77a3df5ce547afa69b86d9e253cca7eb801f06e78647bc39ab2343198ebfb667f5e78f1a23
6
+ metadata.gz: 9fbb882c47f5a771f58b83e56e92deae332b5ca5348bc205594c0bbc5f4c3141d13bb121459b320790d1bdda2e98134323bd70498a94cf7650bb71d377be8128
7
+ data.tar.gz: de2fd8a4eceaa84b3ce58918f4fd15cd19b5f3f8256ab1e44abdb32c3e48eeed8527ee853f08b828aadb78635fb0c3b2552a75a1da297b3f45c52a3399fd0226
@@ -8,8 +8,17 @@ module PyCall
8
8
  end
9
9
  end
10
10
 
11
+ def self.each_type_pair
12
+ i, n = 1, @python_type_map.length
13
+ while i <= n
14
+ yield @python_type_map[n - i]
15
+ i += 1
16
+ end
17
+ self
18
+ end
19
+
11
20
  def self.python_type_mapping(pytype, rbtype)
12
- @python_type_map.each_with_index do |type_pair, index|
21
+ each_type_pair do |type_pair|
13
22
  next unless pytype == type_pair.pytype
14
23
  type_pair.rbtype = rbtype
15
24
  return
@@ -21,7 +30,7 @@ module PyCall
21
30
  unless pyobj.kind_of? PyObject
22
31
  raise
23
32
  end
24
- @python_type_map.each do |tp|
33
+ each_type_pair do |tp|
25
34
  pytype, rbtype = tp.to_a
26
35
  next unless pyobj.kind_of?(pytype)
27
36
  case
@@ -61,7 +70,7 @@ module PyCall
61
70
  when Array
62
71
  PyCall::List.new(obj).__pyobj__
63
72
  else
64
- LibPython.Py_None
73
+ PyCall.None
65
74
  end
66
75
  end
67
76
 
data/lib/pycall/dict.rb CHANGED
@@ -25,10 +25,17 @@ module PyCall
25
25
 
26
26
  def [](key)
27
27
  key = key.to_s if key.is_a? Symbol
28
- if key.is_a? String
29
- LibPython.PyDict_GetItemString(__pyobj__, key).to_ruby
30
- else
31
- LibPython.PyDict_GetItem(__pyobj__, key).to_ruby
28
+ value = if key.is_a? String
29
+ LibPython.PyDict_GetItemString(__pyobj__, key).to_ruby
30
+ else
31
+ LibPython.PyDict_GetItem(__pyobj__, key).to_ruby
32
+ end
33
+ ensure
34
+ case value
35
+ when PyObject
36
+ PyCall.incref(value)
37
+ when PyObjectWrapper
38
+ PyCall.incref(value.__pyobj__)
32
39
  end
33
40
  end
34
41
 
data/lib/pycall/eval.rb CHANGED
@@ -3,8 +3,8 @@ module PyCall
3
3
  Py_eval_input = 258
4
4
 
5
5
  def self.eval(str, filename: "pycall")
6
- globals_ptr = maindict_ptr
7
- locals_ptr = maindict_ptr
6
+ globals_ptr = main_dict
7
+ locals_ptr = main_dict
8
8
  defer_sigint do
9
9
  py_code_ptr = LibPython.Py_CompileString(str, filename, Py_eval_input)
10
10
  raise PyError.fetch if py_code_ptr.null?
@@ -15,12 +15,10 @@ module PyCall
15
15
  class << self
16
16
  private
17
17
 
18
- def main_module
19
- @main_module ||= PyCall.import_module("__main__")
20
- end
21
-
22
- def maindict_ptr
23
- @maindict_ptr ||= LibPython.PyModule_GetDict(main_module)
18
+ def main_dict
19
+ @main_dict ||= PyCall.import_module("__main__") do |main_module|
20
+ PyCall.incref(LibPython.PyModule_GetDict(main_module))
21
+ end
24
22
  end
25
23
 
26
24
  def defer_sigint
@@ -34,11 +32,18 @@ module PyCall
34
32
  name = name.to_s if name.kind_of? Symbol
35
33
  raise TypeError, "name must be a String" unless name.kind_of? String
36
34
  value = LibPython.PyImport_ImportModule(name)
37
- return value.to_ruby unless value.null?
38
- raise PyError.fetch
35
+ raise PyError.fetch if value.null?
36
+ value = value.to_ruby
37
+ return value unless block_given?
38
+ begin
39
+ yield value
40
+ ensure
41
+ PyCall.decref(value)
42
+ end
39
43
  end
40
44
 
41
- def self.eval(str)
42
- Eval.eval(str).to_ruby
45
+ def self.eval(str, conversion: true)
46
+ result = Eval.eval(str)
47
+ conversion ? result.to_ruby : result
43
48
  end
44
49
  end
@@ -137,6 +137,11 @@ module PyCall
137
137
  attach_function :Py_InitializeEx, [:int], :void
138
138
  attach_function :Py_IsInitialized, [], :int
139
139
 
140
+ # Reference count
141
+
142
+ attach_function :Py_IncRef, [PyObject.by_ref], :void
143
+ attach_function :Py_DecRef, [PyObject.by_ref], :void
144
+
140
145
  # Object
141
146
 
142
147
  attach_function :PyObject_RichCompare, [PyObject.by_ref, PyObject.by_ref, :int], PyObject.by_ref
@@ -34,7 +34,7 @@ module PyCall
34
34
  end
35
35
 
36
36
  def py_none?
37
- to_ptr == LibPython.Py_None.to_ptr
37
+ to_ptr == PyCall.None.to_ptr
38
38
  end
39
39
 
40
40
  def kind_of?(klass)
@@ -107,7 +107,7 @@ module PyCall
107
107
 
108
108
  def **(other)
109
109
  other = Conversions.from_ruby(other)
110
- value = LibPython.PyNumber_Power(self, other, LibPython.Py_None)
110
+ value = LibPython.PyNumber_Power(self, other, PyCall.None)
111
111
  return value.to_ruby unless value.null?
112
112
  raise PyError.fetch
113
113
  end
@@ -1,5 +1,36 @@
1
1
  module PyCall
2
2
  module PyObjectWrapper
3
+ module ClassMethods
4
+ private
5
+
6
+ def wrap_class(pyobj)
7
+ define_singleton_method(:__pyobj__) { pyobj }
8
+
9
+ PyCall.dir(__pyobj__).each do |name|
10
+ obj = PyCall.getattr(__pyobj__, name)
11
+ next unless obj.kind_of?(PyCall::PyObject) || obj.kind_of?(PyCall::PyObjectWrapper)
12
+ next unless PyCall.callable?(obj)
13
+
14
+ define_method(name) do |*args, **kwargs|
15
+ PyCall.getattr(__pyobj__, name).(*args, **kwargs)
16
+ end
17
+ end
18
+
19
+ class << self
20
+ def method_missing(name, *args, **kwargs)
21
+ return super unless PyCall.hasattr?(__pyobj__, name)
22
+ PyCall.getattr(__pyobj__, name)
23
+ end
24
+ end
25
+
26
+ PyCall::Conversions.python_type_mapping(__pyobj__, self)
27
+ end
28
+ end
29
+
30
+ def self.included(mod)
31
+ mod.extend ClassMethods
32
+ end
33
+
3
34
  def initialize(pyobj, pytype=nil)
4
35
  check_type pyobj, pytype
5
36
  pytype ||= LibPython.PyObject_Type(pyobj)
data/lib/pycall/utils.rb CHANGED
@@ -1,5 +1,10 @@
1
1
  module PyCall
2
2
  module Utils
3
+ def append_sys_path(path_str)
4
+ pyobj = LibPython.PyUnicode_DecodeUTF8(path_str, path_str.bytesize, nil)
5
+ sys.path.append.(pyobj)
6
+ end
7
+
3
8
  def callable?(pyobj)
4
9
  case pyobj
5
10
  when PyObject
@@ -19,6 +24,17 @@ module PyCall
19
24
  raise PyError.fetch
20
25
  end
21
26
 
27
+ def incref(pyobj)
28
+ LibPython.Py_IncRef(pyobj)
29
+ pyobj
30
+ end
31
+
32
+ def decref(pyobj)
33
+ LibPython.Py_DecRef(pyobj)
34
+ pyobj.send :pointer=, FFI::Pointer::NULL
35
+ pyobj
36
+ end
37
+
22
38
  def int(pyobj)
23
39
  @int ||= PyCall.eval('int')
24
40
  @int.(pyobj)
@@ -29,6 +45,10 @@ module PyCall
29
45
  @len.(pyobj)
30
46
  end
31
47
 
48
+ def None
49
+ LibPython.Py_None
50
+ end
51
+
32
52
  def slice(*args)
33
53
  Slice.new(*args)
34
54
  end
@@ -38,6 +58,10 @@ module PyCall
38
58
  @str.(pyobj)
39
59
  end
40
60
 
61
+ def sys
62
+ @sys ||= PyCall.import_module('sys')
63
+ end
64
+
41
65
  def tuple(*args)
42
66
  PyCall::Tuple[*args]
43
67
  end
@@ -1,3 +1,3 @@
1
1
  module PyCall
2
- VERSION = "0.1.0.alpha.20170302"
2
+ VERSION = "0.1.0.alpha.20170307"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pycall
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.alpha.20170302
4
+ version: 0.1.0.alpha.20170307
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenta Murata
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-03-02 00:00:00.000000000 Z
11
+ date: 2017-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi