RubyMarshal
===========
Read and write Ruby-marshalled data.
Only basics Ruby data types can be directly read and written, but you can use any custom Python and Ruby types:
* `float`,
* `bool`,
* `int`,
* `str` (mapped to `rubymarshal.classes.RubyString` if dumped with instance variables),
* `nil` (mapped to `None` in Python),
* `array` (mapped to `list`),
* `hash` (mapped to `dict`),
* symbols and other classes are mapped to specific Python classes.
Installation
------------
```python3
pip install rubymarshal
```
Usage
-----
```python3
from rubymarshal.reader import loads, load
from rubymarshal.writer import writes, write
with open('my_file', 'rb') as fd:
content = load(fd)
with open('my_file', 'wb') as fd:
write(fd, content)
loads(b"\x04\bi\xfe\x00\xff")
writes(-256)
```
You can map custom Ruby types to Python ones:
```python3
from rubymarshal.reader import loads
from rubymarshal.classes import RubyObject, registry
class DomainError(RubyObject):
ruby_class_name = "Math::DomainError"
registry.register(DomainError)
loads(b'\x04\x08c\x16Math::DomainError')
```
You can use custom registries instead of the global one:
```python3
from rubymarshal.reader import loads
from rubymarshal.classes import RubyObject, ClassRegistry
class DomainError(RubyObject):
ruby_class_name = "Math::DomainError"
registry = ClassRegistry()
registry.register(DomainError)
loads(b'\x04\x08c\x16Math::DomainError', registry=registry)
```
You can use Ruby's symbols:
```python3
from rubymarshal.reader import loads
from rubymarshal.writer import writes
from rubymarshal.classes import Symbol
x = Symbol("test")
dump = writes(Symbol("test"))
y = loads(dump)
assert y is x
```
The default Writer class is customizable to write custom Python classes:
```python3
from rubymarshal.writer import writes, Writer
from rubymarshal.classes import Symbol
class Constant:
def __init__(self, name):
self.name = name
class ConstantWriter(Writer):
def write_python_object(self, obj):
if isinstance(obj, Constant):
return self.write(Symbol(obj.name))
super().write_python_object(obj)
dump = writes([Constant("test")], cls=ConstantWriter)
print(dump)
```
Infos
-----
* Code is on github: https://github.com/d9pouces/RubyMarshal
* Documentation is on readthedocs: http://rubymarshal.readthedocs.org/en/latest/
* Tests are on travis-ci: https://travis-ci.org/d9pouces/RubyMarshal
Raw data
{
"_id": null,
"home_page": "https://github.com/interdiode/interdiode-logo",
"name": "rubymarshal",
"maintainer": "Matthieu Gallet",
"docs_url": null,
"requires_python": "<4.0,>=3.8",
"maintainer_email": "github@19pouces.net",
"keywords": null,
"author": "Matthieu Gallet",
"author_email": "github@19pouces.net",
"download_url": "https://files.pythonhosted.org/packages/19/83/a067992eeaad935ba51a3ee565e997310aed8ac2f960f689571eea1b60be/rubymarshal-1.2.8.tar.gz",
"platform": null,
"description": "RubyMarshal\n===========\n\nRead and write Ruby-marshalled data.\nOnly basics Ruby data types can be directly read and written, but you can use any custom Python and Ruby types: \n\n * `float`,\n * `bool`,\n * `int`,\n * `str` (mapped to `rubymarshal.classes.RubyString` if dumped with instance variables),\n * `nil` (mapped to `None` in Python),\n * `array` (mapped to `list`),\n * `hash` (mapped to `dict`),\n * symbols and other classes are mapped to specific Python classes.\n\nInstallation\n------------\n\n```python3\n pip install rubymarshal\n```\n\nUsage\n-----\n\n```python3\n from rubymarshal.reader import loads, load\n from rubymarshal.writer import writes, write\n with open('my_file', 'rb') as fd:\n content = load(fd)\n with open('my_file', 'wb') as fd:\n write(fd, content)\n loads(b\"\\x04\\bi\\xfe\\x00\\xff\")\n writes(-256)\n```\n\nYou can map custom Ruby types to Python ones:\n\n```python3\n from rubymarshal.reader import loads\n from rubymarshal.classes import RubyObject, registry\n\n class DomainError(RubyObject):\n ruby_class_name = \"Math::DomainError\"\n \n registry.register(DomainError)\n\n loads(b'\\x04\\x08c\\x16Math::DomainError')\n```\n\n\nYou can use custom registries instead of the global one:\n\n\n```python3\n from rubymarshal.reader import loads\n from rubymarshal.classes import RubyObject, ClassRegistry\n\n class DomainError(RubyObject):\n ruby_class_name = \"Math::DomainError\"\n \n registry = ClassRegistry()\n registry.register(DomainError)\n\n loads(b'\\x04\\x08c\\x16Math::DomainError', registry=registry)\n```\n\nYou can use Ruby's symbols:\n\n```python3\n from rubymarshal.reader import loads\n from rubymarshal.writer import writes\n from rubymarshal.classes import Symbol\n \n x = Symbol(\"test\")\n dump = writes(Symbol(\"test\"))\n y = loads(dump)\n assert y is x\n```\n\n\nThe default Writer class is customizable to write custom Python classes:\n\n```python3\n from rubymarshal.writer import writes, Writer\n from rubymarshal.classes import Symbol\n \n class Constant:\n def __init__(self, name):\n self.name = name\n \n class ConstantWriter(Writer):\n def write_python_object(self, obj):\n if isinstance(obj, Constant):\n return self.write(Symbol(obj.name))\n super().write_python_object(obj)\n \n dump = writes([Constant(\"test\")], cls=ConstantWriter)\n print(dump)\n\n```\n\nInfos\n-----\n\n * Code is on github: https://github.com/d9pouces/RubyMarshal \n * Documentation is on readthedocs: http://rubymarshal.readthedocs.org/en/latest/ \n * Tests are on travis-ci: https://travis-ci.org/d9pouces/RubyMarshal\n",
"bugtrack_url": null,
"license": "WTFPL",
"summary": "Read and write Ruby-marshalled data",
"version": "1.2.8",
"project_urls": {
"Documentation": "https://github.com/d9pouces/RubyMarshal",
"Homepage": "https://github.com/interdiode/interdiode-logo",
"Repository": "https://github.com/interdiode/interdiode-logo"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "9d8b8fbc24d576ac406fdd2d5f3e53c4cd0da0d5d6a048e2a27bd3f2a3056153",
"md5": "6bcbc55ebbef7613184fa9d66bec4f62",
"sha256": "be58785c2c07cf5d5a31aaa6172f8c6905655cba9c1b13961da4dce2547221d8"
},
"downloads": -1,
"filename": "rubymarshal-1.2.8-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6bcbc55ebbef7613184fa9d66bec4f62",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8",
"size": 18781,
"upload_time": "2025-01-11T20:47:40",
"upload_time_iso_8601": "2025-01-11T20:47:40.427287Z",
"url": "https://files.pythonhosted.org/packages/9d/8b/8fbc24d576ac406fdd2d5f3e53c4cd0da0d5d6a048e2a27bd3f2a3056153/rubymarshal-1.2.8-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "1983a067992eeaad935ba51a3ee565e997310aed8ac2f960f689571eea1b60be",
"md5": "47be1f9e83186f358c00bbd63d19250b",
"sha256": "f3ef0ac428ec6b09455ddd4182affc8d8d13481f65f141da34c91ca9fa33ee1b"
},
"downloads": -1,
"filename": "rubymarshal-1.2.8.tar.gz",
"has_sig": false,
"md5_digest": "47be1f9e83186f358c00bbd63d19250b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8",
"size": 14567,
"upload_time": "2025-01-11T20:47:42",
"upload_time_iso_8601": "2025-01-11T20:47:42.665304Z",
"url": "https://files.pythonhosted.org/packages/19/83/a067992eeaad935ba51a3ee565e997310aed8ac2f960f689571eea1b60be/rubymarshal-1.2.8.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-11 20:47:42",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "interdiode",
"github_project": "interdiode-logo",
"github_not_found": true,
"lcname": "rubymarshal"
}