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

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
  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