Skip to content

Commit

Permalink
Merge pull request #4388 from lanzagar/pickle-protocol
Browse files Browse the repository at this point in the history
[FIX] Explicitly define the protocol version for pickling
  • Loading branch information
janezd authored Feb 1, 2020
2 parents 796bd26 + 2335aa8 commit 8cd240f
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 9 deletions.
1 change: 0 additions & 1 deletion Orange/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from .domain import *
from .storage import *
from .table import *
from .io_base import *
from .io_util import *
from .io import *
from .filter import *
4 changes: 2 additions & 2 deletions Orange/data/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
import openpyxl

from Orange.data import _io, Table, Domain, ContinuousVariable
from Orange.data import Flags, FileFormatBase, DataTableMixin
from Orange.data import Compression, open_compressed, detect_encoding, \
isnastr, guess_data_type, sanitize_variable
from Orange.data.io_base import FileFormatBase, Flags, DataTableMixin, PICKLE_PROTOCOL

from Orange.util import flatten

Expand Down Expand Up @@ -218,7 +218,7 @@ def read(self):
@classmethod
def write_file(cls, filename, data):
with cls.open(filename, 'wb') as f:
pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)
pickle.dump(data, f, protocol=PICKLE_PROTOCOL)


class BasketReader(FileFormat):
Expand Down
7 changes: 5 additions & 2 deletions Orange/data/io_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@
from Orange.data.variable import VariableMeta
from Orange.util import Registry, flatten, namegen

__all__ = ["FileFormatBase", "Flags", "DataTableMixin"]
__all__ = ["FileFormatBase", "Flags", "DataTableMixin", "PICKLE_PROTOCOL"]


PICKLE_PROTOCOL = 4


class Flags:
Expand Down Expand Up @@ -605,7 +608,7 @@ def write_file(fn):
for kv in data.attributes.items()))
else:
with open(fn, 'wb') as f:
pickle.dump(data.attributes, f, pickle.HIGHEST_PROTOCOL)
pickle.dump(data.attributes, f, protocol=PICKLE_PROTOCOL)

if isinstance(filename, str):
metafile = filename + '.metadata'
Expand Down
24 changes: 20 additions & 4 deletions Orange/tests/test_io.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
# Test methods with long descriptive names can omit docstrings
# pylint: disable=missing-docstring

import unittest
from unittest.mock import Mock, patch
import io
import os
import tempfile
import pickle
import shutil
import io
import tempfile
import unittest
from unittest.mock import Mock, patch

from Orange import data

from Orange.data.io import FileFormat, TabReader, CSVReader, PickleReader
from Orange.data.io_base import PICKLE_PROTOCOL
from Orange.data.table import get_sample_datasets_dir
from Orange.data import Table, Variable
from Orange.tests import test_dirname
Expand Down Expand Up @@ -180,3 +182,17 @@ def test_load_pickle(self):
self.assertEqual(attributes_count, len(data2.domain.attributes))
self.assertEqual(attributes_count, len(data3.domain.attributes))
self.assertEqual(attributes_count, len(data4.domain.attributes))

def test_pickle_version(self):
"""
Orange uses a fixed PICKLE_PROTOCOL (currently set to 4)
for pickling data files and possibly elsewhere for consistent
behaviour across different python versions (e.g. 3.6 - 3.8).
When the default protocol is increased in a future version of python
we should consider increasing this constant to match it as well.
"""
# we should use a version that is at least as high as the default.
# it could be higher for older (but supported) python versions
self.assertGreaterEqual(PICKLE_PROTOCOL, pickle.DEFAULT_PROTOCOL)
# we should not use a version that is not supported
self.assertLessEqual(PICKLE_PROTOCOL, pickle.HIGHEST_PROTOCOL)

0 comments on commit 8cd240f

Please sign in to comment.