python-pickle 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +3 -0
- data/.github/workflows/ruby.yml +27 -0
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +14 -0
- data/Gemfile +15 -0
- data/LICENSE.txt +20 -0
- data/README.md +149 -0
- data/Rakefile +13 -0
- data/gemspec.yml +25 -0
- data/lib/python/pickle/byte_array.rb +40 -0
- data/lib/python/pickle/deserializer.rb +595 -0
- data/lib/python/pickle/exceptions.rb +12 -0
- data/lib/python/pickle/instruction.rb +52 -0
- data/lib/python/pickle/instructions/add_items.rb +26 -0
- data/lib/python/pickle/instructions/append.rb +24 -0
- data/lib/python/pickle/instructions/appends.rb +26 -0
- data/lib/python/pickle/instructions/bin_bytes.rb +32 -0
- data/lib/python/pickle/instructions/bin_bytes8.rb +32 -0
- data/lib/python/pickle/instructions/bin_float.rb +29 -0
- data/lib/python/pickle/instructions/bin_get.rb +27 -0
- data/lib/python/pickle/instructions/bin_int1.rb +29 -0
- data/lib/python/pickle/instructions/bin_put.rb +29 -0
- data/lib/python/pickle/instructions/bin_string.rb +32 -0
- data/lib/python/pickle/instructions/bin_unicode.rb +32 -0
- data/lib/python/pickle/instructions/bin_unicode8.rb +32 -0
- data/lib/python/pickle/instructions/build.rb +24 -0
- data/lib/python/pickle/instructions/byte_array8.rb +32 -0
- data/lib/python/pickle/instructions/dict.rb +17 -0
- data/lib/python/pickle/instructions/dup.rb +24 -0
- data/lib/python/pickle/instructions/empty_dict.rb +26 -0
- data/lib/python/pickle/instructions/empty_list.rb +26 -0
- data/lib/python/pickle/instructions/empty_set.rb +26 -0
- data/lib/python/pickle/instructions/empty_tuple.rb +26 -0
- data/lib/python/pickle/instructions/ext1.rb +29 -0
- data/lib/python/pickle/instructions/ext2.rb +29 -0
- data/lib/python/pickle/instructions/ext4.rb +29 -0
- data/lib/python/pickle/instructions/float.rb +24 -0
- data/lib/python/pickle/instructions/frame.rb +29 -0
- data/lib/python/pickle/instructions/frozen_set.rb +26 -0
- data/lib/python/pickle/instructions/get.rb +27 -0
- data/lib/python/pickle/instructions/global.rb +62 -0
- data/lib/python/pickle/instructions/has_length_and_value.rb +58 -0
- data/lib/python/pickle/instructions/has_value.rb +50 -0
- data/lib/python/pickle/instructions/int.rb +24 -0
- data/lib/python/pickle/instructions/list.rb +24 -0
- data/lib/python/pickle/instructions/long.rb +24 -0
- data/lib/python/pickle/instructions/long1.rb +32 -0
- data/lib/python/pickle/instructions/long4.rb +32 -0
- data/lib/python/pickle/instructions/long_bin_get.rb +27 -0
- data/lib/python/pickle/instructions/mark.rb +24 -0
- data/lib/python/pickle/instructions/memoize.rb +26 -0
- data/lib/python/pickle/instructions/new_false.rb +24 -0
- data/lib/python/pickle/instructions/new_obj.rb +26 -0
- data/lib/python/pickle/instructions/new_obj_ex.rb +26 -0
- data/lib/python/pickle/instructions/new_true.rb +24 -0
- data/lib/python/pickle/instructions/next_buffer.rb +26 -0
- data/lib/python/pickle/instructions/none.rb +24 -0
- data/lib/python/pickle/instructions/pop.rb +24 -0
- data/lib/python/pickle/instructions/pop_mark.rb +24 -0
- data/lib/python/pickle/instructions/proto.rb +29 -0
- data/lib/python/pickle/instructions/put.rb +24 -0
- data/lib/python/pickle/instructions/readonly_buffer.rb +26 -0
- data/lib/python/pickle/instructions/reduce.rb +24 -0
- data/lib/python/pickle/instructions/set_item.rb +24 -0
- data/lib/python/pickle/instructions/set_items.rb +26 -0
- data/lib/python/pickle/instructions/short_bin_bytes.rb +32 -0
- data/lib/python/pickle/instructions/short_bin_string.rb +32 -0
- data/lib/python/pickle/instructions/short_bin_unicode.rb +32 -0
- data/lib/python/pickle/instructions/stack_global.rb +26 -0
- data/lib/python/pickle/instructions/stop.rb +24 -0
- data/lib/python/pickle/instructions/string.rb +24 -0
- data/lib/python/pickle/instructions/tuple.rb +24 -0
- data/lib/python/pickle/instructions/tuple1.rb +24 -0
- data/lib/python/pickle/instructions/tuple2.rb +24 -0
- data/lib/python/pickle/instructions/tuple3.rb +24 -0
- data/lib/python/pickle/protocol.rb +56 -0
- data/lib/python/pickle/protocol0.rb +399 -0
- data/lib/python/pickle/protocol1.rb +183 -0
- data/lib/python/pickle/protocol2.rb +229 -0
- data/lib/python/pickle/protocol3.rb +163 -0
- data/lib/python/pickle/protocol4.rb +285 -0
- data/lib/python/pickle/protocol5.rb +218 -0
- data/lib/python/pickle/py_class.rb +75 -0
- data/lib/python/pickle/py_object.rb +141 -0
- data/lib/python/pickle/tuple.rb +19 -0
- data/lib/python/pickle/version.rb +6 -0
- data/lib/python/pickle.rb +226 -0
- data/python-pickle.gemspec +62 -0
- data/spec/byte_array_spec.rb +54 -0
- data/spec/deserializer_spec.rb +1201 -0
- data/spec/fixtures/ascii_str_v3.pkl +0 -0
- data/spec/fixtures/ascii_str_v4.pkl +0 -0
- data/spec/fixtures/ascii_str_v5.pkl +0 -0
- data/spec/fixtures/bin_str_v0.pkl +3 -0
- data/spec/fixtures/bin_str_v1.pkl +0 -0
- data/spec/fixtures/bin_str_v2.pkl +0 -0
- data/spec/fixtures/bin_str_v3.pkl +0 -0
- data/spec/fixtures/bin_str_v4.pkl +0 -0
- data/spec/fixtures/bin_str_v5.pkl +0 -0
- data/spec/fixtures/bytearray_v0.pkl +10 -0
- data/spec/fixtures/bytearray_v1.pkl +0 -0
- data/spec/fixtures/bytearray_v2.pkl +0 -0
- data/spec/fixtures/bytearray_v3.pkl +0 -0
- data/spec/fixtures/bytearray_v4.pkl +0 -0
- data/spec/fixtures/bytearray_v5.pkl +0 -0
- data/spec/fixtures/class_v0.pkl +4 -0
- data/spec/fixtures/class_v1.pkl +0 -0
- data/spec/fixtures/class_v2.pkl +0 -0
- data/spec/fixtures/class_v3.pkl +0 -0
- data/spec/fixtures/class_v4.pkl +0 -0
- data/spec/fixtures/class_v5.pkl +0 -0
- data/spec/fixtures/dict_v0.pkl +6 -0
- data/spec/fixtures/dict_v1.pkl +0 -0
- data/spec/fixtures/dict_v2.pkl +0 -0
- data/spec/fixtures/dict_v3.pkl +0 -0
- data/spec/fixtures/dict_v4.pkl +0 -0
- data/spec/fixtures/dict_v5.pkl +0 -0
- data/spec/fixtures/escaped_str_v0.pkl +3 -0
- data/spec/fixtures/escaped_str_v1.pkl +0 -0
- data/spec/fixtures/escaped_str_v2.pkl +0 -0
- data/spec/fixtures/false_v0.pkl +2 -0
- data/spec/fixtures/false_v1.pkl +2 -0
- data/spec/fixtures/false_v2.pkl +1 -0
- data/spec/fixtures/false_v3.pkl +1 -0
- data/spec/fixtures/false_v4.pkl +1 -0
- data/spec/fixtures/false_v5.pkl +1 -0
- data/spec/fixtures/float_v0.pkl +2 -0
- data/spec/fixtures/float_v1.pkl +1 -0
- data/spec/fixtures/float_v2.pkl +1 -0
- data/spec/fixtures/float_v3.pkl +1 -0
- data/spec/fixtures/float_v4.pkl +0 -0
- data/spec/fixtures/float_v5.pkl +0 -0
- data/spec/fixtures/function_v0.pkl +4 -0
- data/spec/fixtures/function_v1.pkl +0 -0
- data/spec/fixtures/function_v2.pkl +0 -0
- data/spec/fixtures/function_v3.pkl +0 -0
- data/spec/fixtures/function_v4.pkl +0 -0
- data/spec/fixtures/function_v5.pkl +0 -0
- data/spec/fixtures/hex_str_v0.pkl +3 -0
- data/spec/fixtures/hex_str_v1.pkl +0 -0
- data/spec/fixtures/hex_str_v2.pkl +0 -0
- data/spec/fixtures/int_v0.pkl +2 -0
- data/spec/fixtures/int_v1.pkl +1 -0
- data/spec/fixtures/int_v2.pkl +1 -0
- data/spec/fixtures/int_v3.pkl +1 -0
- data/spec/fixtures/int_v4.pkl +1 -0
- data/spec/fixtures/int_v5.pkl +1 -0
- data/spec/fixtures/list_v0.pkl +7 -0
- data/spec/fixtures/list_v1.pkl +0 -0
- data/spec/fixtures/list_v2.pkl +0 -0
- data/spec/fixtures/list_v3.pkl +0 -0
- data/spec/fixtures/list_v4.pkl +0 -0
- data/spec/fixtures/list_v5.pkl +0 -0
- data/spec/fixtures/long_v0.pkl +2 -0
- data/spec/fixtures/long_v1.pkl +2 -0
- data/spec/fixtures/long_v2.pkl +0 -0
- data/spec/fixtures/long_v3.pkl +0 -0
- data/spec/fixtures/long_v4.pkl +0 -0
- data/spec/fixtures/long_v5.pkl +0 -0
- data/spec/fixtures/nested_dict_v0.pkl +12 -0
- data/spec/fixtures/nested_dict_v1.pkl +0 -0
- data/spec/fixtures/nested_dict_v2.pkl +0 -0
- data/spec/fixtures/nested_dict_v3.pkl +0 -0
- data/spec/fixtures/nested_dict_v4.pkl +0 -0
- data/spec/fixtures/nested_dict_v5.pkl +0 -0
- data/spec/fixtures/nested_list_v0.pkl +9 -0
- data/spec/fixtures/nested_list_v1.pkl +0 -0
- data/spec/fixtures/nested_list_v2.pkl +0 -0
- data/spec/fixtures/nested_list_v3.pkl +0 -0
- data/spec/fixtures/nested_list_v4.pkl +0 -0
- data/spec/fixtures/nested_list_v5.pkl +0 -0
- data/spec/fixtures/none_v0.pkl +1 -0
- data/spec/fixtures/none_v1.pkl +1 -0
- data/spec/fixtures/none_v2.pkl +1 -0
- data/spec/fixtures/none_v3.pkl +1 -0
- data/spec/fixtures/none_v4.pkl +1 -0
- data/spec/fixtures/none_v5.pkl +1 -0
- data/spec/fixtures/object_v0.pkl +19 -0
- data/spec/fixtures/object_v1.pkl +0 -0
- data/spec/fixtures/object_v2.pkl +0 -0
- data/spec/fixtures/object_v3.pkl +0 -0
- data/spec/fixtures/object_v4.pkl +0 -0
- data/spec/fixtures/object_v5.pkl +0 -0
- data/spec/fixtures/str_v0.pkl +3 -0
- data/spec/fixtures/str_v1.pkl +0 -0
- data/spec/fixtures/str_v2.pkl +0 -0
- data/spec/fixtures/str_v3.pkl +0 -0
- data/spec/fixtures/str_v4.pkl +0 -0
- data/spec/fixtures/str_v5.pkl +0 -0
- data/spec/fixtures/true_v0.pkl +2 -0
- data/spec/fixtures/true_v1.pkl +2 -0
- data/spec/fixtures/true_v2.pkl +1 -0
- data/spec/fixtures/true_v3.pkl +1 -0
- data/spec/fixtures/true_v4.pkl +1 -0
- data/spec/fixtures/true_v5.pkl +1 -0
- data/spec/fixtures/unicode_str_v0.pkl +3 -0
- data/spec/fixtures/unicode_str_v1.pkl +0 -0
- data/spec/fixtures/unicode_str_v2.pkl +0 -0
- data/spec/fixtures/unicode_str_v3.pkl +0 -0
- data/spec/fixtures/unicode_str_v4.pkl +0 -0
- data/spec/fixtures/unicode_str_v5.pkl +0 -0
- data/spec/generate_pickles2.py +41 -0
- data/spec/generate_pickles3.py +40 -0
- data/spec/integration/load/protocol0_spec.rb +258 -0
- data/spec/integration/load/protocol1_spec.rb +258 -0
- data/spec/integration/load/protocol2_spec.rb +258 -0
- data/spec/integration/load/protocol3_spec.rb +258 -0
- data/spec/integration/load/protocol4_spec.rb +258 -0
- data/spec/integration/load/protocol5_spec.rb +258 -0
- data/spec/integration/parse/protocol0_spec.rb +467 -0
- data/spec/integration/parse/protocol1_spec.rb +459 -0
- data/spec/integration/parse/protocol2_spec.rb +471 -0
- data/spec/integration/parse/protocol3_spec.rb +407 -0
- data/spec/integration/parse/protocol4_spec.rb +439 -0
- data/spec/integration/parse/protocol5_spec.rb +419 -0
- data/spec/pickle_spec.rb +163 -0
- data/spec/protocol0_read_instruction_examples.rb +211 -0
- data/spec/protocol0_spec.rb +445 -0
- data/spec/protocol1_read_instruction_examples.rb +156 -0
- data/spec/protocol1_spec.rb +59 -0
- data/spec/protocol2_read_instruction_examples.rb +135 -0
- data/spec/protocol2_spec.rb +128 -0
- data/spec/protocol3_read_instruction_examples.rb +29 -0
- data/spec/protocol3_spec.rb +32 -0
- data/spec/protocol4_read_instruction_examples.rb +142 -0
- data/spec/protocol4_spec.rb +58 -0
- data/spec/protocol5_spec.rb +68 -0
- data/spec/py_class_spec.rb +62 -0
- data/spec/py_object_spec.rb +149 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/tuple_spec.rb +18 -0
- metadata +325 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ea86f43e4b83bacac94635b88e2c9deeb6eb4aaa553f1770e4943554389422fc
|
4
|
+
data.tar.gz: 973327ecbd8f2c1df7d0ac10f37d76628745e00da9317ab655a9f12644fef441
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8b95a73ff2ebfba7c9ca97648df7c7b3b6be14df61e0e6f4943e3e263a5f300696e79d8cf57aacc7bd9d572bcf3c00a5ec88162e1dd8cc627617afe01414499d
|
7
|
+
data.tar.gz: 73a9a106cfa346d3d74835cf9369732f041fdb2faafdb8a030f1e9ec6b58831e8b7c8aee3a05bec687d11d2d4ea9d48a00d4fcf164f0c686eb84c1248b15f056
|
data/.document
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: [ push, pull_request ]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
tests:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
strategy:
|
9
|
+
fail-fast: false
|
10
|
+
matrix:
|
11
|
+
ruby:
|
12
|
+
- 3.0
|
13
|
+
- 3.1
|
14
|
+
- 3.2
|
15
|
+
- jruby
|
16
|
+
# - truffleruby
|
17
|
+
name: Ruby ${{ matrix.ruby }}
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v2
|
20
|
+
- name: Set up Ruby
|
21
|
+
uses: ruby/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: ${{ matrix.ruby }}
|
24
|
+
- name: Install dependencies
|
25
|
+
run: bundle install --jobs 4 --retry 3
|
26
|
+
- name: Run tests
|
27
|
+
run: bundle exec rake test
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour --format documentation
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown --title "Python::Pickle Documentation" --protected --quiet
|
data/ChangeLog.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
### 0.1.0 / 2023-02-18
|
2
|
+
|
3
|
+
* Initial release:
|
4
|
+
* Supports deserializing Python Pickle data into Ruby objects.
|
5
|
+
* Supports serializing Ruby objects into Python Pickle data.
|
6
|
+
* Optionally supports only parsing Python Pickle data streams for debugging
|
7
|
+
purposes.
|
8
|
+
* Supports Pickle protocol 0, protocol 1, protocol 2, protocol 3, protocol 4,
|
9
|
+
and protocol 5.
|
10
|
+
* Can parse both Python 2 and Python 3 Pickled data.
|
11
|
+
* Supports deserializing Python `tuple` and `bytearray` objects.
|
12
|
+
* Supports mapping Python functions to Ruby methods.
|
13
|
+
* Supports mapping Python classes to Ruby classes.
|
14
|
+
|
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
group :development do
|
6
|
+
gem 'rake'
|
7
|
+
gem 'rubygems-tasks', '~> 0.2'
|
8
|
+
gem 'rspec', '~> 3.0'
|
9
|
+
gem 'simplecov', '~> 0.20'
|
10
|
+
gem 'kramdown'
|
11
|
+
gem 'redcarpet', platform: :mri
|
12
|
+
gem 'yard', '~> 0.9'
|
13
|
+
gem 'yard-spellcheck', require: false
|
14
|
+
gem 'dead_end', require: false
|
15
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2023 Hal Brodigan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
# python-pickle.rb
|
2
|
+
|
3
|
+
[![CI](https://github.com/postmodern/python-pickle.rb/actions/workflows/ruby.yml/badge.svg)](https://github.com/postmodern/python-pickle.rb/actions/workflows/ruby.yml)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/python-pickle.svg)](https://badge.fury.io/rb/python-pickle)
|
5
|
+
|
6
|
+
* [Source](https://github.com/postmodern/python-pickle.rb)
|
7
|
+
* [Issues](https://github.com/postmodern/python-pickle.rb/issues)
|
8
|
+
* [Documentation](https://rubydoc.info/gems/python-pickle)
|
9
|
+
|
10
|
+
## Description
|
11
|
+
|
12
|
+
python-pickle is a modern Ruby implementation of the Python Pickle serialization
|
13
|
+
format.
|
14
|
+
|
15
|
+
## Features
|
16
|
+
|
17
|
+
* Supports deserializing Python Pickle data into Ruby objects.
|
18
|
+
* Optionally supports only parsing Python Pickle data streams for debugging
|
19
|
+
purposes.
|
20
|
+
* Supports Pickle protocol 0, protocol 1, protocol 2, protocol 3, protocol 4,
|
21
|
+
and protocol 5.
|
22
|
+
* Can parse both Python 2 and Python 3 Pickled data.
|
23
|
+
* Supports deserializing Python `tuple` and `bytearray` objects.
|
24
|
+
* Supports mapping Python functions to Ruby methods.
|
25
|
+
* Supports mapping Python classes to Ruby classes.
|
26
|
+
|
27
|
+
## TODO
|
28
|
+
|
29
|
+
* Add support for writing Python Pickle data.
|
30
|
+
* Add support for serializing Ruby objects to Python Pickle data.
|
31
|
+
|
32
|
+
## Requirements
|
33
|
+
|
34
|
+
* [Ruby] >= 3.0.0
|
35
|
+
|
36
|
+
[Ruby]: https://www.ruby-lang.org/
|
37
|
+
|
38
|
+
## Install
|
39
|
+
|
40
|
+
```shell
|
41
|
+
$ gem install python-pickle
|
42
|
+
```
|
43
|
+
|
44
|
+
### gemspec
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
gem.add_dependency 'python-pickle', '~> 1.0'
|
48
|
+
```
|
49
|
+
|
50
|
+
### Gemfile
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
gem 'python-pickle', '~> 1.0'
|
54
|
+
```
|
55
|
+
|
56
|
+
## Examples
|
57
|
+
|
58
|
+
Load a Python Pickle string:
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
Python::Pickle.load("\x80\x04\x95\x10\x00\x00\x00\x00\x00\x00\x00}\x94\x8C\x03foo\x94\x8C\x03bar\x94s.")
|
62
|
+
# => {"foo"=>"bar"}
|
63
|
+
```
|
64
|
+
|
65
|
+
Load a Python Pickle stream:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
Python::Pickle.load(io)
|
69
|
+
# => ...
|
70
|
+
```
|
71
|
+
|
72
|
+
Loading a Python Pickle file:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
Python::Pickle.load_file('dict.pkl')
|
76
|
+
# => {"foo"=>"bar"}
|
77
|
+
```
|
78
|
+
|
79
|
+
Loading Python `bytearray` objects:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
pickle = "\x80\x05\x95\x0E\x00\x00\x00\x00\x00\x00\x00\x96\x03\x00\x00\x00\x00\x00\x00\x00ABC\x94."
|
83
|
+
|
84
|
+
Python::Pickle.load(pickle)
|
85
|
+
# => #<Python::Pickle::ByteArray: "ABC">
|
86
|
+
```
|
87
|
+
|
88
|
+
Loading Python objects:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
ickle = "\x80\x04\x95,\x00\x00\x00\x00\x00\x00\x00\x8C\b__main__\x94\x8C\aMyClass\x94\x93\x94)\x81\x94}\x94(\x8C\x01x\x94KA\x8C\x01y\x94KBub."
|
92
|
+
|
93
|
+
Python::Pickle.load(pickle)
|
94
|
+
# =>
|
95
|
+
# #<Python::Pickle::PyObject:0x00007f48c9ba7598
|
96
|
+
# @attributes={"y"=>66, "x"=>65},
|
97
|
+
# @init_args=[],
|
98
|
+
# @init_kwargs={},
|
99
|
+
# @py_class=#<Python::Pickle::PyClass: __main__.MyClass>>
|
100
|
+
```
|
101
|
+
|
102
|
+
Mapping Python classes to Ruby classes:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
class MyClass
|
106
|
+
|
107
|
+
attr_reader :x
|
108
|
+
attr_reader :y
|
109
|
+
|
110
|
+
def __setstate__(attributes)
|
111
|
+
@x = attributes['x']
|
112
|
+
@y = attributes['y']
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
pickle = "\x80\x04\x95,\x00\x00\x00\x00\x00\x00\x00\x8C\b__main__\x94\x8C\aMyClass\x94\x93\x94)\x81\x94}\x94(\x8C\x01x\x94KA\x8C\x01y\x94KBub."
|
118
|
+
|
119
|
+
Python::Pickle.load(pickle, constants: {
|
120
|
+
'__main__' => {
|
121
|
+
'MyClass' => MyClass
|
122
|
+
}
|
123
|
+
})
|
124
|
+
# => #<MyClass:0x00007f48c5c28980 @x=65, @y=66>
|
125
|
+
```
|
126
|
+
|
127
|
+
Parsing and inspecting a pickle file:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
require 'python/pickle'
|
131
|
+
|
132
|
+
Python::Pickle.parse(File.open('dict.pkl'))
|
133
|
+
# =>
|
134
|
+
# [#<Python::Pickle::Instructions::Mark: MARK>,
|
135
|
+
# #<Python::Pickle::Instructions::Dict: DICT>,
|
136
|
+
# #<Python::Pickle::Instructions::Put: PUT 0>,
|
137
|
+
# #<Python::Pickle::Instructions::String: STRING "foo">,
|
138
|
+
# #<Python::Pickle::Instructions::Put: PUT 1>,
|
139
|
+
# #<Python::Pickle::Instructions::String: STRING "bar">,
|
140
|
+
# #<Python::Pickle::Instructions::Put: PUT 2>,
|
141
|
+
# #<Python::Pickle::Instructions::SetItem: SETITEM>,
|
142
|
+
# #<Python::Pickle::Instructions::Stop: STOP>]
|
143
|
+
```
|
144
|
+
|
145
|
+
## Copyright
|
146
|
+
|
147
|
+
Copyright (c) 2023 Hal Brodigan
|
148
|
+
|
149
|
+
See {file:LICENSE.txt} for details.
|
data/Rakefile
ADDED
data/gemspec.yml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
name: python-pickle
|
2
|
+
summary: A modern Ruby implementation of the Python Pickle serialization format.
|
3
|
+
description: |
|
4
|
+
python-pickle is a modern Ruby implementation of the Python Pickle
|
5
|
+
serialization format. It supports protocol 0, protocol 1, protocol 2,
|
6
|
+
protocol 3, protocol 4, and protocol 5, allowing it to parse both Python 2
|
7
|
+
and Python 3 pickle data.
|
8
|
+
|
9
|
+
license: MIT
|
10
|
+
authors: Postmodern
|
11
|
+
email: postmodern.mod3@gmail.com
|
12
|
+
homepage: https://github.com/postmodern/python-pickle.rb#readme
|
13
|
+
has_yard: true
|
14
|
+
|
15
|
+
metadata:
|
16
|
+
documentation_uri: https://rubydoc.info/gems/python-pickle
|
17
|
+
source_code_uri: https://github.com/postmodern/python-pickle.rb
|
18
|
+
bug_tracker_uri: https://github.com/postmodern/python-pickle.rb/issues
|
19
|
+
changelog_uri: https://github.com/postmodern/python-pickle.rb/blob/master/ChangeLog.md
|
20
|
+
rubygems_mfa_required: 'true'
|
21
|
+
|
22
|
+
required_ruby_version: ">= 3.0.0"
|
23
|
+
|
24
|
+
development_dependencies:
|
25
|
+
bundler: ~> 2.0
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Python
|
2
|
+
module Pickle
|
3
|
+
#
|
4
|
+
# Represents a Python `bytearray` object.
|
5
|
+
#
|
6
|
+
class ByteArray < String
|
7
|
+
|
8
|
+
# Mapping of python `codecs` encoding names and their Ruby equivalents.
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
ENCODINGS = {
|
12
|
+
nil => Encoding::ASCII_8BIT,
|
13
|
+
'latin-1' => Encoding::ISO_8859_1
|
14
|
+
}
|
15
|
+
|
16
|
+
#
|
17
|
+
# Initializes the byte array.
|
18
|
+
#
|
19
|
+
# @param [String] string
|
20
|
+
# The contents of the byte array.
|
21
|
+
#
|
22
|
+
# @param [String, nil] encoding
|
23
|
+
# The optional encoding name.
|
24
|
+
#
|
25
|
+
def initialize(string='', encoding=nil)
|
26
|
+
super(string, encoding: ENCODINGS.fetch(encoding))
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Inspects the byte array object.
|
31
|
+
#
|
32
|
+
# @return [String]
|
33
|
+
#
|
34
|
+
def inspect
|
35
|
+
"#<#{self.class}: #{super}>"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|