Repository: biolab/orange3-text

Issue:
Copying corpus sometimes fails
<!--
This is an issue template. Please fill in the relevant details in the
sections below.
-->

##### Text version
Current (~**0.2.5**) and older


##### Orange version
master


##### Expected behavior
```python
corpus = Corpus(...)
new_corpus = corpus.copy()
```
That should work and not raise an error.

##### Actual behavior

> orangecontrib.text.corpus in set_text_features at line 90
>    raise ValueError('Feature "{}" not found.'.format(f))
> orangecontrib.text.corpus in __init__ at line 73
>    self.set_text_features(text_features)
> orangecontrib.text.corpus in copy at line 321
>    self.W.copy(), copy(self.text_features))
> orangecontrib.text.widgets.owpreprocess in set_data at line 598
>    self.corpus = data.copy() if data is not None else None

https://sentry.io/biolab/orange3-text-bl/issues/399242697/


##### Steps to reproduce the behavior



##### Additional info (worksheets, data, screenshots, ...)





Discussion:
`data.transform(new_domain)` does not update `text_features`.
Could you fix `transform` on `Corpus` to retain them?
Yes.

Resolving patch:
diff --git a/orangecontrib/text/corpus.py b/orangecontrib/text/corpus.py
--- a/orangecontrib/text/corpus.py
+++ b/orangecontrib/text/corpus.py
@@ -58,7 +58,7 @@ def __init__(self, domain=None, X=None, Y=None, metas=None, W=None,
         self.metas = metas if metas is not None else np.zeros((n_doc, 0))
         self.W = W if W is not None else np.zeros((n_doc, 0))
         self.domain = domain
-        self.text_features = None    # list of text features for mining
+        self.text_features = []    # list of text features for mining
         self._tokens = None
         self._dictionary = None
         self._ngrams_corpus = None
@@ -434,8 +434,8 @@ def retain_preprocessing(orig, new, key=...):
                 else:
                     raise TypeError('Indexing by type {} not supported.'.format(type(key)))
                 new._dictionary = orig._dictionary
-
-            new.text_features = orig.text_features
+            new_domain_metas = set(new.domain.metas)
+            new.text_features = [tf for tf in orig.text_features if tf in new_domain_metas]
             new.ngram_range = orig.ngram_range
             new.attributes = orig.attributes
             new.used_preprocessor = orig.used_preprocessor


Test patch:
diff --git a/orangecontrib/text/tests/test_corpus.py b/orangecontrib/text/tests/test_corpus.py
--- a/orangecontrib/text/tests/test_corpus.py
+++ b/orangecontrib/text/tests/test_corpus.py
@@ -389,3 +389,15 @@ def test_from_documents(self):
         self.assertEqual([engine_dv.repr_val(v) for v in c.X[:, 0]],
                          [d['engine'] for d in documents])
 
+    def test_corpus_remove_text_features(self):
+        """
+        Remove those text features which do not have a column in metas.
+        GH-324
+        GH-325
+        """
+        c = Corpus.from_file('deerwester')
+        domain = Domain(attributes=c.domain.attributes, class_vars=c.domain.class_vars)
+        d = c.transform(domain)
+        self.assertFalse(len(d.text_features))
+        # Make sure that copying works.
+        d.copy()