internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: facebookresearch/fairscale

Issue:
the main branch is not compatible with python 3.6, but setup.py only requires ">=3.6"
python 3.6 can pip install latest fairscale
https://github.com/facebookresearch/fairscale/blob/1bc96fa8c69def6d990e42bfbd75f86146ce29bd/setup.py#L67

but, some code is not compatible with python 3.6
https://github.com/facebookresearch/fairscale/blob/1bc96fa8c69def6d990e42bfbd75f86146ce29bd/fairscale/experimental/nn/ssd_offload.py#L6
and python<3.7 has no dataclasses
https://github.com/facebookresearch/fairscale/blob/1bc96fa8c69def6d990e42bfbd75f86146ce29bd/fairscale/nn/data_parallel/fully_sharded_data_parallel.py#L8





Discussion:
I think this is a bug where we need to update setup.py to say python >= 3.7 which is what we [support right now](https://github.com/facebookresearch/fairscale/blob/main/.circleci/config.yml). Thank you for raising this! Happy to accept a PR if you want to fix this.

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -64,7 +64,7 @@ def find_version(version_file_path) -> str:
         packages=setuptools.find_packages(exclude=("tests", "tests.*")),
         ext_modules=extensions,
         cmdclass=cmdclass,
-        python_requires=">=3.6",
+        python_requires=">=3.7",
         author="Facebook AI Research",
         author_email="todo@fb.com",
         long_description="FairScale is a PyTorch extension library for high performance and large scale training on one or multiple machines/nodes. This library extends basic PyTorch capabilities while adding new experimental ones.",


Test patch:
Repository: facebookresearch/fairscale

Issue:
Lots of Commandline Output from this line.

https://github.com/facebookresearch/fairscale/blob/2350968ee61a6f9ca6ecd24aba9db536e814a24c/fairscale/internal/version.py#L27

this warning appears a LOT in the commandline output when training. Can we remove it or place it in a place where it gets only shown once at the start?



Discussion:
yeah, indeed. Will fix.

Resolving patch:
diff --git a/fairscale/internal/version.py b/fairscale/internal/version.py
--- a/fairscale/internal/version.py
+++ b/fairscale/internal/version.py
@@ -11,13 +11,15 @@
 
 __all__: List[str] = ["torch_version"]
 
+_logged = False
 
 def torch_version(version: str = torch.__version__) -> Tuple[int, ...]:
     numbering = re.search(r"^(\d+).(\d+).(\d+)([^\+]*)(\+\S*)?$", version)
     if not numbering:
         return tuple()
     # Catch torch version if run against internal pre-releases, like `1.8.0a0fb`,
-    if numbering.group(4):
+    global _logged
+    if numbering.group(4) and not _logged:
         # Two options here:
         # - either skip this version (minor number check is not relevant)
         # - or check that our codebase is not broken by this ongoing development.
@@ -25,5 +27,6 @@ def torch_version(version: str = torch.__version__) -> Tuple[int, ...]:
         # Assuming that we're interested in the second use-case more than the first,
         # return the pre-release or dev numbering
         logging.warning(f"Pytorch pre-release version {version} - assuming intent to test it")
+        _logged = True
 
     return tuple(int(numbering.group(n)) for n in range(1, 4))


Test patch:
Repository: nyu-mll/jiant

Issue:
ELMo scalar parameters not saved (!)
The scalar parameters for ELMo...

07/12 01:59:56 PM:    _text_field_embedder.token_embedder_elmo._elmo.scalar_mix_0.gamma
07/12 01:59:56 PM:    _text_field_embedder.token_embedder_elmo._elmo.scalar_mix_0.scalar_parameters.0
07/12 01:59:56 PM:    _text_field_embedder.token_embedder_elmo._elmo.scalar_mix_0.scalar_parameters.1
07/12 01:59:56 PM:    _text_field_embedder.token_embedder_elmo._elmo.scalar_mix_0.scalar_parameters.2

...aren't saved in our checkpoints. There's no logic in the code to save them, and tests with demo.conf confirm that they aren't the same after reloading.

This is a problem: ELMo-based models aren't guaranteed to behave correctly if they're saved then restored in a different Python run. Our dev set results are mostly fine, since they come from single runs without restarts, but our test set and probing results with ELMo may be artificially bad. We'll need to retrain any ELMo models that we want to probe after this is fixed.



Discussion:
May have to be fixed _again_ once as part of #118 on that branch. 

Resolving patch:
diff --git a/src/trainer.py b/src/trainer.py
--- a/src/trainer.py
+++ b/src/trainer.py
@@ -741,11 +741,10 @@ def _save_checkpoint(self, training_state, phase="main", new_best_macro=False, k
 
         model_state = self._model.state_dict()
 
-        # Don't save embeddings here.
-        # TODO: There has to be a prettier way to do this.
-        keys_to_skip = [key for key in model_state if dont_save(key)]
-        for key in keys_to_skip:
-            del model_state[key]
+        # Skip non-trainable params, like the main ELMo params.
+        for name, param in self._model.named_parameters():
+            if not param.requires_grad:
+                del model_state[name]
         torch.save(model_state, model_path)
 
         if phase != "eval":
@@ -936,8 +935,3 @@ def from_params(cls, model, serialization_dir, params):
                                         keep_all_checkpoints=keep_all_checkpoints,
                                         val_data_limit=val_data_limit,
                                         training_data_fraction=training_data_fraction)
-
-
-def dont_save(key):
-    ''' Filter out strings with some bad words '''
-    return 'elmo' in key or 'text_field_embedder' in key


Test patch:
Repository: nyu-mll/jiant

Issue:
Error in CBOW training
python main.py --config config/demo.conf --overrides "max_vals = 1, sst+={max_vals = 1}, train_tasks=sst, eval_tasks = cola, cola+={max_vals=10, val_interval = 100}, val_interval = 10, write_preds = \"val,test\", write_strict_glue_format = 1, do_train = 1, load_model = 1, sent_enc = bow"

```
08/22 06:34:50 PM: Beginning training. Stopping metric: sst_accuracy
08/22 06:34:51 PM: Fatal error in main():
Traceback (most recent call last):
  File "main.py", line 316, in <module>
    main(sys.argv[1:])
  File "main.py", line 209, in main
    args.shared_optimizer, args.load_model, phase="main")
  File "/Users/Bowman/Drive/JSALT/jiant/src/trainer.py", line 437, in train
    output_dict = self._forward(batch, task=task, for_training=True)
  File "/Users/Bowman/Drive/JSALT/jiant/src/trainer.py", line 737, in _forward
    model_out = self._model.forward(task, tensor_batch)
  File "/Users/Bowman/Drive/JSALT/jiant/src/models.py", line 551, in forward
    out = self._single_sentence_forward(batch, task, predict)
  File "/Users/Bowman/Drive/JSALT/jiant/src/models.py", line 599, in _single_sentence_forward
    sent_embs, sent_mask = self.sent_encoder(batch['input1'], task)
  File "/Users/Bowman/anaconda3/envs/jiant/lib/python3.6/site-packages/torch/nn/modules/module.py", line 491, in __call__
    result = self.forward(*input, **kwargs)
TypeError: forward() takes 2 positional arguments but 3 were given

```


Discussion:

Resolving patch:
diff --git a/src/models.py b/src/models.py
--- a/src/models.py
+++ b/src/models.py
@@ -105,6 +105,7 @@ def build_model(args, vocab, pretrained_embs, tasks):
     elif args.sent_enc == 'bow':
         sent_encoder = BoWSentEncoder(vocab, embedder)
         log.info("Using BoW architecture for shared encoder!")
+        assert_for_log(not args.skip_embs, "Skip connection not currently supported with `bow` encoder.")
         d_sent = d_emb
     elif args.sent_enc == 'rnn':
         sent_rnn = s2s_e.by_name('lstm').from_params(copy.deepcopy(rnn_params))
diff --git a/src/modules.py b/src/modules.py
--- a/src/modules.py
+++ b/src/modules.py
@@ -161,11 +161,12 @@ def __init__(self, vocab, text_field_embedder, initializer=InitializerApplicator
         self.output_dim = text_field_embedder.get_output_dim()
         initializer(self)
 
-    def forward(self, sent):
+    def forward(self, sent, task):
         # pylint: disable=arguments-differ
         """
         Args:
             - sent (Dict[str, torch.LongTensor]): From a ``TextField``.
+            - task: Ignored.
 
         Returns
             - word_embs (torch.FloatTensor): (b_size, seq_len, d_emb)


Test patch:
Repository: nyu-mll/jiant

Issue:
Sigmoid warning
/home/sbowman/miniconda3/envs/jiant/lib/python3.6/site-packages/torch/nn/functional.py:1006: UserWarning: nn.functional.sigmoid is deprecated. Use torch.sigmoid instead.
  warnings.warn("nn.functional.sigmoid is deprecated. Use torch.sigmoid instead.")



Discussion:
Related to this (or maybe a separate issue?) -- should we hide/soften these error messages (if they still exist):

* qqp loading errors during preproc (e.g. `list index out of range  file: /nfs/jsalt/share/glue_data/QQP/train.tsv, row: 36732`)
* math error that gets thrown when calculating matthews (?)

I'll update this comment with examples when I find them.
QQP issues are real, and worth warning about.
Not sure about the math error.

The sigmoid warning should be fixable—just stop using that name for the function.
Another warning that comes up (but harmless?)
```
08/02 04:16:05 PM: Your label namespace was 'idxs'. We recommend you use a namespace ending with 'labels' or 'tags', so we don't add UNK and PAD tokens by default to your vocabulary.
  See documentation for `non_padded_namespaces` parameter in Vocabulary.
```

Resolving patch:
diff --git a/src/edge_probing.py b/src/edge_probing.py
--- a/src/edge_probing.py
+++ b/src/edge_probing.py
@@ -187,7 +187,7 @@ def get_predictions(self, logits: torch.Tensor):
             raise NotImplementedError("Softmax loss not fully supported.")
             return F.softmax(logits, dim=2)
         elif self.loss_type == 'sigmoid':
-            return F.sigmoid(logits)
+            return torch.sigmoid(logits)
         else:
             raise ValueError("Unsupported loss type '%s' "
                              "for edge probing." % loss_type)
@@ -223,7 +223,7 @@ def compute_loss(self, logits: torch.Tensor,
             assert labels.shape[1] == 1  # expect a single target
             return F.cross_entropy(logits, labels)
         elif self.loss_type == 'sigmoid':
-            return F.binary_cross_entropy(F.sigmoid(logits),
+            return F.binary_cross_entropy(torch.sigmoid(logits),
                                           labels.float())
         else:
             raise ValueError("Unsupported loss type '%s' "
diff --git a/src/models.py b/src/models.py
--- a/src/models.py
+++ b/src/models.py
@@ -807,7 +807,7 @@ def _ranking_forward(self, batch, task, predict):
             total_loss = torch.nn.BCEWithLogitsLoss()(cos_simi, labels)
             out['loss'] = total_loss
 
-            pred = F.sigmoid(cos_simi).round()
+            pred = torch.sigmoid(cos_simi).round()
 
         total_correct = torch.sum(pred == labels)
         batch_acc = total_correct.item()/len(labels)
@@ -1021,7 +1021,7 @@ def _grounded_ranking_bce_forward(self, batch, task, predict):
 
         mat_mul = mat_mul.view(-1)
         labels = labels.view(-1).cuda()
-        pred = F.sigmoid(mat_mul).round()
+        pred = torch.sigmoid(mat_mul).round()
 
         out['loss'] = loss_fn(mat_mul, labels)
         total_correct = torch.sum(pred == labels)


Test patch:
Repository: nyu-mll/jiant

Issue:
Problems with new PATH_TO_COVE var
https://github.com/jsalt18-sentence-repl/jiant/pull/349

- Demo is broken because the user_config script doesn't contain this variable. 
- README should be updated to match. (See pending comment on the closed README PR).


Discussion:

Resolving patch:
diff --git a/src/models.py b/src/models.py
--- a/src/models.py
+++ b/src/models.py
@@ -220,8 +220,7 @@ def build_embeddings(args, vocab, tasks, pretrained_embs=None):
         assert args.word_embs == "glove", "CoVe requires GloVe embeddings."
         assert d_word == 300, "CoVe expects 300-dimensional GloVe embeddings."
         try:
-            sys.path.append(args.path_to_cove)
-            from cove import MTLSTM as cove_lstm
+            from .cove.cove import MTLSTM as cove_lstm
             # Have CoVe do an internal GloVe lookup, but don't add residual.
             # We'll do this manually in modules.py; see
             # SentenceEncoder.forward().


Test patch:
Repository: nyu-mll/jiant

Issue:
Add timestamps to log file
^ The timestamps are formatted the same as in the printed messages. Fixes #577 and #89 .


Discussion:

Resolving patch:
diff --git a/main.py b/main.py
--- a/main.py
+++ b/main.py
@@ -5,10 +5,12 @@
     python -m ipdb main.py --config_file ...
 """
 # pylint: disable=no-member
+import logging as log
+log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO)  # noqa # nopep8
+
 import argparse
 import glob
 import io
-import logging as log
 import os
 import random
 import subprocess
@@ -24,7 +26,6 @@
 from src.utils import config
 from src.utils.utils import assert_for_log, check_arg_name, load_model_state, maybe_make_dir
 
-log.basicConfig(format="%(asctime)s: %(message)s", datefmt="%m/%d %I:%M:%S %p", level=log.INFO)
 
 
 # Global notification handler, can be accessed outside main() during exception handling.
@@ -309,9 +310,14 @@ def initial_setup(args, cl_args):
     """
     output = io.StringIO()
     maybe_make_dir(args.project_dir)  # e.g. /nfs/jsalt/exp/$HOSTNAME
-    maybe_make_dir(args.exp_dir)  # e.g. <project_dir>/jiant-demo
-    maybe_make_dir(args.run_dir)  # e.g. <project_dir>/jiant-demo/sst
-    log.getLogger().addHandler(log.FileHandler(args.local_log_path))
+    maybe_make_dir(args.exp_dir)      # e.g. <project_dir>/jiant-demo
+    maybe_make_dir(args.run_dir)      # e.g. <project_dir>/jiant-demo/sst
+    log_fh = log.FileHandler(args.local_log_path)
+    log_fmt = log.Formatter('%(asctime)s: %(message)s',
+                            datefmt='%m/%d %I:%M:%S %p')
+    log_fh.setFormatter(log_fmt)
+    log.getLogger().addHandler(log_fh)
+
 
     if cl_args.remote_log:
         from src.utils import gcp


Test patch:
Repository: nyu-mll/jiant

Issue:
${NFS_PROJECT_PREFIX} and ${JIANT_PROJECT_PREFIX}
Do we need two separate set of environment variables?
We also have ${NFS_DATA_DIR} and ${JIANT_DATA_DIR}. I don't know about potential users of jiant, at least for me, it's pretty confusing.




Discussion:
+1

Resolving patch:
diff --git a/main.py b/main.py
--- a/main.py
+++ b/main.py
@@ -39,6 +39,7 @@ def handle_arguments(cl_arguments):
         "-c",
         type=str,
         nargs="+",
+        default="config/defaults.conf",
         help="Config file(s) (.conf) for model parameters.",
     )
     parser.add_argument(


Test patch:
Repository: nyu-mll/jiant

Issue:
Broken support for multiple target tasks with fine-tuning and no pretraining
If you want to evaluate BERT on a set of target tasks (no extra pretraining, paradigm = finetune), the pre_target_train doesn't kick in, and the model crashes when it tries to restore after finishing a target task.


Discussion:

Resolving patch:
diff --git a/main.py b/main.py
--- a/main.py
+++ b/main.py
@@ -265,7 +265,7 @@ def get_best_checkpoint_path(run_dir, phase):
         target training
         3) nothing found (empty string) """
     checkpoint = glob.glob(os.path.join(run_dir, "model_state_%s_epoch_*.best_macro.th" % phase))
-    if len(checkpoint) == 0 and phase == "target_train":
+    if len(checkpoint) == 0:
         checkpoint = glob.glob(os.path.join(run_dir, "model_state_untrained_pre_target_train.th"))
     if len(checkpoint) > 0:
         assert_for_log(len(checkpoint) == 1, "Too many best checkpoints. Something is wrong.")


Test patch:
Repository: nyu-mll/jiant

Issue:
write_preds = "val,test", write_strict_glue_format = 1 fails
It looks like 'write_strict_glue_format = 1' uses the standard SuperGLUE filenames, even for the dev results, so the test results jut overwrite the test results. 

'write_strict_glue_format = 1' probably shouldn't determine the filename for dev results, since the SuperGLUE server doesn't accept dev output files.


Discussion:

Resolving patch:
diff --git a/jiant/evaluate.py b/jiant/evaluate.py
--- a/jiant/evaluate.py
+++ b/jiant/evaluate.py
@@ -246,9 +246,15 @@ def write_preds(
 
 def _get_pred_filename(task_name, pred_dir, split_name, strict_glue_format):
     if strict_glue_format and task_name in GLUE_NAME_MAP:
-        file = GLUE_NAME_MAP[task_name] + ".tsv"
+        if split_name == "test":
+            file = "%s.tsv" % (GLUE_NAME_MAP[task_name])
+        else:
+            file = "%s_%s.tsv" % (GLUE_NAME_MAP[task_name], split_name)
     elif strict_glue_format and task_name in SUPERGLUE_NAME_MAP:
-        file = SUPERGLUE_NAME_MAP[task_name] + ".jsonl"
+        if split_name == "test":
+            file = "%s.jsonl" % (SUPERGLUE_NAME_MAP[task_name])
+        else:
+            file = "%s_%s.jsonl" % (SUPERGLUE_NAME_MAP[task_name], split_name)
     else:
         file = "%s_%s.tsv" % (task_name, split_name)
     return os.path.join(pred_dir, file)


Test patch:
Repository: nyu-mll/jiant

Issue:
Make `delete_checkpoint_if_done` default behavior



Discussion:

Resolving patch:
diff --git a/jiant/proj/main/runscript.py b/jiant/proj/main/runscript.py
--- a/jiant/proj/main/runscript.py
+++ b/jiant/proj/main/runscript.py
@@ -39,7 +39,7 @@ class RunConfiguration(zconf.RunConfig):
     save_every_steps = zconf.attr(type=int, default=0)
     save_checkpoint_every_steps = zconf.attr(type=int, default=0)
     no_improvements_for_n_evals = zconf.attr(type=int, default=0)
-    delete_checkpoint_if_done = zconf.attr(action="store_true")
+    keep_checkpoint_when_done = zconf.attr(action="store_true")
     force_overwrite = zconf.attr(action="store_true")
     seed = zconf.attr(type=int, default=-1)
 
@@ -201,7 +201,7 @@ def run_loop(args: RunConfiguration, checkpoint=None):
             )
 
     if (
-        args.delete_checkpoint_if_done
+        not args.keep_checkpoint_when_done
         and args.save_checkpoint_every_steps
         and os.path.exists(os.path.join(args.output_dir, "checkpoint.p"))
     ):
diff --git a/jiant/proj/simple/runscript.py b/jiant/proj/simple/runscript.py
--- a/jiant/proj/simple/runscript.py
+++ b/jiant/proj/simple/runscript.py
@@ -48,7 +48,7 @@ class RunConfiguration(zconf.RunConfig):
     save_every_steps = zconf.attr(type=int, default=0)
     save_checkpoint_every_steps = zconf.attr(type=int, default=0)
     no_improvements_for_n_evals = zconf.attr(type=int, default=0)
-    delete_checkpoint_if_done = zconf.attr(action="store_true")
+    keep_checkpoint_when_done = zconf.attr(action="store_true")
     force_overwrite = zconf.attr(action="store_true")
     seed = zconf.attr(type=int, default=-1)
 
@@ -231,7 +231,7 @@ def run_simple(args: RunConfiguration, with_continue: bool = False):
             save_every_steps=args.save_every_steps,
             save_checkpoint_every_steps=args.save_checkpoint_every_steps,
             no_improvements_for_n_evals=args.no_improvements_for_n_evals,
-            delete_checkpoint_if_done=args.delete_checkpoint_if_done,
+            keep_checkpoint_when_done=args.keep_checkpoint_when_done,
             force_overwrite=args.force_overwrite,
             seed=args.seed,
             # === Training Learning Parameters === #


Test patch:
Repository: tournesol-app/tournesol

Issue:
Create a docker image instead of using a `setup.sh` bash file that clutters dev's system
While the python packages necessary to run tournesol are installed in a separate `venv`, the same is not the case for `apt` and `nodejs` dependencies. The latter could clash with the requirements for other projects that a dev is working on, causing the terrible _dependency headache_. Thus, Sergei suggested using docker instead.

I view this as low-priority, but I lack the experience and holisitic view of the project to reliably assess the priority.


Discussion:

Resolving patch:
diff --git a/backend/django_react/settings.py b/backend/django_react/settings.py
--- a/backend/django_react/settings.py
+++ b/backend/django_react/settings.py
@@ -321,6 +321,7 @@ def DIRECTORY_ACCESS_FUNCTION(request): return request.user.is_superuser
     '--port=8899',
     # disables the browser
     '--no-browser',
+    '--allow-root',
 ]
 
 # configurable email backend
@@ -342,8 +343,9 @@ def DIRECTORY_ACCESS_FUNCTION(request): return request.user.is_superuser
 # Outlook 365 config
 EMAIL_SERVER = os.environ.get('DJANGO_EMAIL_SERVER', '127.0.0.1')
 EMAIL_HOST = EMAIL_SERVER
-EMAIL_PORT = 587
-EMAIL_USE_TLS = True
+EMAIL_PORT = int(os.environ.get('DJANGO_EMAIL_PORT', 25))
+EMAIL_USE_TLS = os.environ.get('DJANGO_EMAIL_USE_TLS', '') == 'True'
+EMAIL_USE_SSL = os.environ.get('DJANGO_EMAIL_USE_SSL', '') == 'True'
 EMAIL_HOST_USER = os.environ.get('DJANGO_EMAIL_HOST_USER', 'noreply@tournesol.app')
 EMAIL_HOST_PASSWORD = os.environ.get('DJANGO_EMAIL_HOST_PASSWORD',
                                      'password_from_email_hosting')


Test patch:
diff --git a/tests.sh b/tests.sh
--- a/tests.sh
+++ b/tests.sh
@@ -72,6 +72,12 @@ then
         export DISPLAY=:99
         screen -Sdm "xvfb_test" Xvfb $DISPLAY -screen 0 1920x1080x24
         export XDG_SESSION_TYPE=x11
+	sleep 3
+	if [ "X$(which x11vnc)" != "X" ]
+	then
+		echo "Launching x11vnc"
+		screen -Sdm "xvfb_vnc" x11vnc -display $DISPLAY -loop -shared -forever
+	fi
 fi
 
 # enabling basic auth for the API
Repository: tournesol-app/tournesol

Issue:
Hourly caching for public dataset download
Add caching the the public dataset download (it take ~5sec to return a result and overloads the server if asked 20 times in a minute)

Another improvement may be to temporarily disable the public download button when it is clicked.


Discussion:

Resolving patch:
diff --git a/backend/settings/settings.py b/backend/settings/settings.py
--- a/backend/settings/settings.py
+++ b/backend/settings/settings.py
@@ -306,3 +306,10 @@
         'level': os.environ.get("DJANGO_LOG_LEVEL", "DEBUG"),
     },
 }
+
+CACHES = {
+    'default': {
+        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
+        'LOCATION': 'default_cache_table',
+    }
+}
diff --git a/backend/tournesol/views/exports.py b/backend/tournesol/views/exports.py
--- a/backend/tournesol/views/exports.py
+++ b/backend/tournesol/views/exports.py
@@ -3,6 +3,8 @@
 from io import StringIO
 
 from django.http import HttpResponse
+from django.utils.decorators import method_decorator
+from django.views.decorators.cache import cache_page
 from rest_framework.views import APIView
 from rest_framework.permissions import IsAuthenticated, AllowAny
 from drf_spectacular.utils import extend_schema, OpenApiTypes
@@ -84,6 +86,7 @@ def get(self, request):
 class ExportPublicComparisonsView(APIView):
     permission_classes = [AllowAny]
 
+    @method_decorator(cache_page(60*10))  # 10 minutes cache
     @extend_schema(
         description="Download public data in .csv file",
         responses={200: OpenApiTypes.BINARY}


Test patch:
diff --git a/backend/tournesol/tests/test_exports.py b/backend/tournesol/tests/test_exports.py
--- a/backend/tournesol/tests/test_exports.py
+++ b/backend/tournesol/tests/test_exports.py
@@ -2,12 +2,14 @@
 import io
 
 from django.test import TestCase
+from django.core.cache import cache
 from rest_framework import status
 from rest_framework.test import APIClient
 
 from core.models import User
 from tournesol.models import Comparison, Video, ComparisonCriteriaScore, ContributorRating
 
+
 class ExportTest(TestCase):
     def setUp(self) -> None:
         self.user_with_comparisons = User.objects.create_user(username="user_with", email="user_with@example.com")
@@ -31,6 +33,7 @@ def setUp(self) -> None:
         ComparisonCriteriaScore.objects.create(comparison=self.comparison_private,score=5,criteria="largely_recommended")
 
         self.client = APIClient()
+        cache.clear()
 
     def test_not_authenticated_cannot_download_comparisons(self):
         resp = self.client.get("/users/me/exports/comparisons/")