Repository: biolab/orange3

Issue:
Orange.data.Table's is_view and is_copy do not work for sparse matrices: deprecate them
`Table.is_view` and `Table.is_copy` do not work for sparse matrices.

I do not think they are that useful because they are a conjunction of so many conditions. I think we should deprecate them instead of fixing them. PyCharm only finds one usage in the Orange3 repo, and even that in the tests.

So, I would deprecate and remove in Orange 3.33.




Discussion:
I support removing stuff that nobody uses, in particular if it's a method of `Table`.

Resolving patch:
diff --git a/Orange/data/table.py b/Orange/data/table.py
--- a/Orange/data/table.py
+++ b/Orange/data/table.py
@@ -32,7 +32,7 @@
 from Orange.statistics.util import bincount, countnans, contingency, \
     stats as fast_stats, sparse_has_implicit_zeros, sparse_count_implicit_zeros, \
     sparse_implicit_zero_weights
-from Orange.util import OrangeDeprecationWarning, dummy_callback
+from Orange.util import deprecated, OrangeDeprecationWarning, dummy_callback
 if TYPE_CHECKING:
     # import just for type checking - avoid circular import
     from Orange.data.aggregate import OrangeTableGroupBy
@@ -1428,6 +1428,7 @@ def add_column(self, variable, data, to_metas=None):
             new_table.get_column_view(variable)[0][:] = data
         return new_table
 
+    @deprecated("array.base is not None for each subarray of Orange.data.Table (i.e. X, Y, W, metas)")
     def is_view(self):
         """
         Return `True` if all arrays represent a view referring to another table
@@ -1437,6 +1438,7 @@ def is_view(self):
                 (not self._metas.shape[-1] or self._metas.base is not None) and
                 (not self._W.shape[-1] or self._W.base is not None))
 
+    @deprecated("array.base is None for each subarray of Orange.data.Table (i.e. X, Y, W, metas)")
     def is_copy(self):
         """
         Return `True` if the table owns its data


Test patch:
diff --git a/Orange/data/tests/test_table.py b/Orange/data/tests/test_table.py
--- a/Orange/data/tests/test_table.py
+++ b/Orange/data/tests/test_table.py
@@ -1,10 +1,12 @@
 import pickle
 import unittest
 import os
+from distutils.version import LooseVersion
 
 import numpy as np
 import scipy.sparse as sp
 
+import Orange
 from Orange.data import (
     ContinuousVariable, DiscreteVariable, StringVariable,
     Domain, Table, IsDefined, FilterContinuous, Values, FilterString,
@@ -13,6 +15,18 @@
 
 
 class TestTableInit(unittest.TestCase):
+
+    def test_is_view_is_copy_deprecated(self):
+        """This test is to be included in the 3.32 release and will fail in
+        version 3.34. This serves as a reminder to remove the deprecated methods
+        and this test."""
+        if LooseVersion(Orange.__version__) >= LooseVersion("3.34"):
+            self.fail(
+                "`Orange.data.Table.is_view` and `Orange.data.Table.is_copy` "
+                "were deprecated in version 3.32, and there have been two minor "
+                "versions in between. Please remove the deprecated methods."
+            )
+
     def test_empty_table(self):
         t = Table()
         self.assertEqual(t.domain.attributes, ())
@@ -40,7 +54,7 @@ def test_from_numpy(self):
         Y = np.arange(5) % 2
         metas = np.array(list("abcde")).reshape(5, 1)
         W = np.arange(5) / 5
-        ids = np.arange(100, 105, dtype=np.int)
+        ids = np.arange(100, 105, dtype=int)
         attributes = dict(a=5, b="foo")
 
         dom = Domain([ContinuousVariable(x) for x in "abcd"],
@@ -380,8 +394,8 @@ def test_unpickled_owns_data(self):
             Table.LOCKING = default
 
         unpickled = pickle.loads(pickle.dumps(table))
-        self.assertFalse(unpickled.is_view())
-        self.assertTrue(unpickled.is_copy())
+        self.assertTrue(all(ar.base is None
+                            for ar in (unpickled.X, unpickled.Y, unpickled.W, unpickled.metas)))
         with unpickled.unlocked():
             unpickled.X[0, 0] = 42