python-pickle 0.1.0 → 0.1.1

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: ea86f43e4b83bacac94635b88e2c9deeb6eb4aaa553f1770e4943554389422fc
4
- data.tar.gz: 973327ecbd8f2c1df7d0ac10f37d76628745e00da9317ab655a9f12644fef441
3
+ metadata.gz: c18d8d36ae1a85dd7dbdbe13bf136de10bd2d30ddaab523bace2042f1ab3c784
4
+ data.tar.gz: ad04252dfd4cbcb7e8d80b61e92a1d7439ce256ccfda97b9b3a202e8b3225415
5
5
  SHA512:
6
- metadata.gz: 8b95a73ff2ebfba7c9ca97648df7c7b3b6be14df61e0e6f4943e3e263a5f300696e79d8cf57aacc7bd9d572bcf3c00a5ec88162e1dd8cc627617afe01414499d
7
- data.tar.gz: 73a9a106cfa346d3d74835cf9369732f041fdb2faafdb8a030f1e9ec6b58831e8b7c8aee3a05bec687d11d2d4ea9d48a00d4fcf164f0c686eb84c1248b15f056
6
+ metadata.gz: 4f64f303012885b2acb6b3ee56527a10a109cac5a9b5f938fea2817552b43bbefad6b5d460f299bb5909388b4eeff722d69b2cba9342e1e8a1c460e3c070a08b
7
+ data.tar.gz: cc598296cf863810512869805f53b17d2a16bffc9bc09afcb8e35e21fcf1d50b53026151bbd28b687820523618e5dc66a52b42e416281d79ab95a0d6fd636d2a
data/ChangeLog.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ### 0.1.0 / 2023-02-18
2
2
 
3
+ * Changed {Python::Pickle.dump} to raise a `NotImplementedError` exception.
4
+ * Fixed a typo in the method signature of {Python::Pickle.dump}.
5
+
6
+ ### 0.1.0 / 2023-02-18
7
+
3
8
  * Initial release:
4
9
  * Supports deserializing Python Pickle data into Ruby objects.
5
10
  * Supports serializing Ruby objects into Python Pickle data.
data/README.md CHANGED
@@ -20,7 +20,9 @@ format.
20
20
  * Supports Pickle protocol 0, protocol 1, protocol 2, protocol 3, protocol 4,
21
21
  and protocol 5.
22
22
  * Can parse both Python 2 and Python 3 Pickled data.
23
- * Supports deserializing Python `tuple` and `bytearray` objects.
23
+ * Supports deserializing Python `None`, `True`, `False`, `int`, `str`, `tuple`,
24
+ `list`, `bytearray`, and other objects.
25
+ * Supports mapping Python extension codes to Ruby classes.
24
26
  * Supports mapping Python functions to Ruby methods.
25
27
  * Supports mapping Python classes to Ruby classes.
26
28
 
@@ -1,6 +1,6 @@
1
1
  module Python
2
2
  module Pickle
3
3
  # python-pickle version
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
5
5
  end
6
6
  end
data/lib/python/pickle.rb CHANGED
@@ -28,7 +28,7 @@ module Python
28
28
  # The default protocol version to use.
29
29
  #
30
30
  # @api public
31
- DEFAULT_PROTCOL = 4
31
+ DEFAULT_PROTOCOL = 4
32
32
 
33
33
  # The highest protocol version supported.
34
34
  #
@@ -88,12 +88,22 @@ module Python
88
88
  # The explicit protocol version to use. If `nil` the protocol version will
89
89
  # be inferred by inspecting the first two bytes of the stream.
90
90
  #
91
+ # @param [Hash{Symbol => Object}] kwargs
92
+ # Additional keyword arguments.
93
+ #
94
+ # @option kwargs [Hash{Integer => Object}] :extensions
95
+ # A Hash of registered extension IDs and their Objects.
96
+ #
97
+ # @option kwargs [Hash{String => Hash{String => Class,Method}}] :constants
98
+ # An optional mapping of custom Python constant names to Ruby classes
99
+ # or methods.
100
+ #
91
101
  # @api public
92
102
  #
93
- def self.load(data,**kwargs)
103
+ def self.load(data, protocol: nil, **kwargs)
94
104
  deserializer = Deserializer.new(**kwargs)
95
105
 
96
- parse(data) do |instruction|
106
+ parse(data, protocol: protocol) do |instruction|
97
107
  status, object = deserializer.execute(instruction)
98
108
 
99
109
  if status == :halt
@@ -110,11 +120,27 @@ module Python
110
120
  # @param [String] path
111
121
  # The path of the file.
112
122
  #
123
+ # @param [Hash{Symbol => Object}] kwargs
124
+ # Additional keyword arguments.
125
+ #
126
+ # @option kwargs [Hash{Integer => Object}] :extensions
127
+ # A Hash of registered extension IDs and their Objects.
128
+ #
129
+ # @option kwargs [Hash{String => Hash{String => Class,Method}}] :constants
130
+ # An optional mapping of custom Python constant names to Ruby classes
131
+ # or methods.
132
+ #
113
133
  # @return [Object]
114
134
  # The deserialized object.
115
135
  #
116
136
  def self.load_file(path,**kwargs)
117
- load(File.open(path,'rb'),**kwargs)
137
+ result = nil
138
+
139
+ File.open(path,'rb') do |file|
140
+ result = load(file,**kwargs)
141
+ end
142
+
143
+ return result
118
144
  end
119
145
 
120
146
  #
@@ -129,12 +155,12 @@ module Python
129
155
  # @param [Integer] protocol
130
156
  # The desired Python Pickle protocol to use.
131
157
  #
158
+ # @note serializing is currently not supported.
159
+ #
132
160
  # @api public
133
161
  #
134
162
  def self.dump(object,output=nil, protocol: DEFAULT_PROTOCOL)
135
- if (protocol < 0) || (protocol > HIGHEST_PROTOCOL)
136
- raise(ArgumentError,"protocol must be between 0 or #{HIGHEST_PROTOCOL}, but was #{protocol.inspect}")
137
- end
163
+ raise(NotImplementedError,"pickle serializing is currently not supported")
138
164
  end
139
165
 
140
166
  #
@@ -2,6 +2,11 @@ require 'spec_helper'
2
2
  require 'python/pickle/deserializer'
3
3
 
4
4
  describe Python::Pickle::Deserializer do
5
+ module TestDeserializer
6
+ class MyClass
7
+ end
8
+ end
9
+
5
10
  describe "#initialize" do
6
11
  it "must initialize #meta_stack to an empty Array" do
7
12
  expect(subject.meta_stack).to eq([])
@@ -44,9 +49,55 @@ describe Python::Pickle::Deserializer do
44
49
  end
45
50
 
46
51
  context "when initialized with the `extensions:` keyword argument" do
52
+ let(:extensions) do
53
+ {
54
+ 0x41 => Object.new,
55
+ 0x42 => Object.new,
56
+ 0x43 => Object.new
57
+ }
58
+ end
59
+
60
+ subject { described_class.new(extensions: extensions) }
61
+
62
+ it "must add the extensions: values to #extensions" do
63
+ expect(subject.extensions).to eq(extensions)
64
+ end
47
65
  end
48
66
 
49
67
  context "when initialized with the `constants:` keyword argument" do
68
+ let(:constants) do
69
+ {
70
+ '__main__' => {
71
+ 'MyClass' => TestDeserializer::MyClass
72
+ }
73
+ }
74
+ end
75
+
76
+ subject { described_class.new(constants: constants) }
77
+
78
+ it "must merge the constants: keyword argument with the default constants" do
79
+ expect(subject.constants).to eq(
80
+ {
81
+ 'copy_reg' => {
82
+ '_reconstructor' => subject.method(:copyreg_reconstructor)
83
+ },
84
+
85
+ '__builtin__' => {
86
+ 'object' => described_class::OBJECT_CLASS,
87
+ 'bytearray' => Python::Pickle::ByteArray
88
+ },
89
+
90
+ 'builtins' => {
91
+ 'object' => described_class::OBJECT_CLASS,
92
+ 'bytearray' => Python::Pickle::ByteArray
93
+ },
94
+
95
+ '__main__' => {
96
+ 'MyClass' => TestDeserializer::MyClass
97
+ }
98
+ }
99
+ )
100
+ end
50
101
  end
51
102
  end
52
103
 
data/spec/pickle_spec.rb CHANGED
@@ -52,6 +52,33 @@ describe Python::Pickle do
52
52
  it "must deserialize the Python Pickle data in the given file" do
53
53
  expect(subject.load(data)).to eq({"foo" => "bar"})
54
54
  end
55
+
56
+ context "when the constants: keyword argument is given" do
57
+ let(:path) { File.join(fixtures_dir,'object_v4.pkl') }
58
+
59
+ module TestLoad
60
+ class MyClass
61
+ attr_reader :x, :y
62
+
63
+ def __setstate__(attributes)
64
+ @x = attributes['x']
65
+ @y = attributes['y']
66
+ end
67
+ end
68
+ end
69
+
70
+ let(:constants) do
71
+ {
72
+ '__main__' => {
73
+ 'MyClass' => TestLoad::MyClass
74
+ }
75
+ }
76
+ end
77
+
78
+ it "must map the Python classes to the Ruby classes" do
79
+ expect(subject.load(data, constants: constants)).to be_kind_of(TestLoad::MyClass)
80
+ end
81
+ end
55
82
  end
56
83
 
57
84
  describe ".load_file" do
@@ -60,9 +87,43 @@ describe Python::Pickle do
60
87
  it "must deserialize the Python Pickle data in the given file" do
61
88
  expect(subject.load_file(path)).to eq({"foo" => "bar"})
62
89
  end
90
+
91
+ context "when the constants: keyword argument is given" do
92
+ let(:path) { File.join(fixtures_dir,'object_v4.pkl') }
93
+
94
+ module TestLoad
95
+ class MyClass
96
+ attr_reader :x, :y
97
+
98
+ def __setstate__(attributes)
99
+ @x = attributes['x']
100
+ @y = attributes['y']
101
+ end
102
+ end
103
+ end
104
+
105
+ let(:constants) do
106
+ {
107
+ '__main__' => {
108
+ 'MyClass' => TestLoad::MyClass
109
+ }
110
+ }
111
+ end
112
+
113
+ it "must map the Python classes to the Ruby classes" do
114
+ expect(subject.load_file(path, constants: constants)).to be_kind_of(TestLoad::MyClass)
115
+ end
116
+ end
63
117
  end
64
118
 
65
119
  describe ".dump" do
120
+ let(:object) { Object.new }
121
+
122
+ it do
123
+ expect {
124
+ subject.dump(object)
125
+ }.to raise_error(NotImplementedError,"pickle serializing is currently not supported")
126
+ end
66
127
  end
67
128
 
68
129
  describe ".infer_protocol_version" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: python-pickle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Postmodern