Repository: voxel51/fiftyone
Issue: [BUG] COCO Sample Parser Inheritance

Loading COCO from the zoo using torch raises an error:
```
Uncaught exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/lambertw/anaconda3/envs/fiftyone/lib/python3.7/site-packages/fiftyone/zoo/__init__.py", line 180, in load_zoo_dataset
    name, splits=splits, dataset_dir=dataset_dir
  File "/Users/lambertw/anaconda3/envs/fiftyone/lib/python3.7/site-packages/fiftyone/zoo/__init__.py", line 121, in download_zoo_dataset
    cleanup=cleanup,
  File "/Users/lambertw/anaconda3/envs/fiftyone/lib/python3.7/site-packages/fiftyone/zoo/__init__.py", line 805, in download_and_prepare
    ) = self._download_and_prepare(split_dir, scratch_dir, split)
  File "/Users/lambertw/anaconda3/envs/fiftyone/lib/python3.7/site-packages/fiftyone/zoo/torch.py", line 375, in _download_and_prepare
    sample_parser,
  File "/Users/lambertw/anaconda3/envs/fiftyone/lib/python3.7/site-packages/fiftyone/zoo/torch.py", line 516, in _download_and_prepare
    raise ValueError("Unsupported SampleParser %s" % type(sample_parser))
ValueError: Unsupported SampleParser <class 'fiftyone.utils.coco.COCODetectionSampleParser'>
```

This is likely an inheritance issue due to the [`COCODetectionSampleParser`](https://github.com/voxel51/fiftyone/blob/0415d1fce56bf610c34204358ac79d3cfcda0d2a/fiftyone/utils/coco.py#L38)  and the [`ImageLabelsSampleParser`](https://github.com/voxel51/fiftyone/blob/0415d1fce56bf610c34204358ac79d3cfcda0d2a/fiftyone/zoo/torch.py#L496) both inheriting from `LabeledImageTupleSampleParser`.

Changed files:
fiftyone/zoo/torch.py, fiftyone/zoo/tf.py

diff --git a/fiftyone/zoo/tf.py b/fiftyone/zoo/tf.py
index 90096c9f8..232bd7ceb 100644
--- a/fiftyone/zoo/tf.py
+++ b/fiftyone/zoo/tf.py
@@ -5,6 +5,7 @@ FiftyOne Zoo Datasets provided by ``tensorflow_datasets``.
 | `voxel51.com <https://voxel51.com/>`_
 |
 """
+import fiftyone.core.labels as fol
 import fiftyone.core.utils as fou
 import fiftyone.types as fot
 import fiftyone.utils.imagenet as foui
@@ -725,22 +726,20 @@ def _download_and_prepare(
     classes = get_class_labels_fcn(info)
     num_samples = get_num_samples_fcn(info)
     sample_parser.classes = classes
+    label_cls = sample_parser.label_cls
 
-    if isinstance(sample_parser, foud.ImageClassificationSampleParser):
+    if label_cls is fol.Classification:
         dataset_type = fot.FiftyOneImageClassificationDataset()
         dataset_exporter = foud.FiftyOneImageClassificationDatasetExporter(
             dataset_dir, classes=classes
         )
-    elif isinstance(sample_parser, foud.ImageDetectionSampleParser):
+    elif label_cls is fol.Detections:
         dataset_type = fot.FiftyOneImageDetectionDataset()
         dataset_exporter = foud.FiftyOneImageDetectionDatasetExporter(
             dataset_dir, classes=classes
         )
-    elif isinstance(sample_parser, foud.ImageLabelsSampleParser):
-        dataset_type = fot.FiftyOneImageLabelsDataset()
-        dataset_exporter = foud.FiftyOneImageLabelsDatasetExporter(dataset_dir)
     else:
-        raise ValueError("Unsupported SampleParser %s" % type(sample_parser))
+        raise ValueError("Unsupported label class %s" % label_cls)
 
     try:
         samples = dataset.as_numpy_iterator()
diff --git a/fiftyone/zoo/torch.py b/fiftyone/zoo/torch.py
index 88d0a8955..9978df8c4 100644
--- a/fiftyone/zoo/torch.py
+++ b/fiftyone/zoo/torch.py
@@ -5,6 +5,7 @@ FiftyOne Zoo Datasets provided by ``torchvision.datasets``.
 | `voxel51.com <https://voxel51.com/>`_
 |
 """
+import fiftyone.core.labels as fol
 import fiftyone.core.utils as fou
 import fiftyone.types as fot
 import fiftyone.utils.coco as fouc
@@ -498,22 +499,20 @@ def _download_and_prepare(
     classes = get_class_labels_fcn(dataset)
     num_samples = len(dataset)
     sample_parser.classes = classes
+    label_cls = sample_parser.label_cls
 
-    if isinstance(sample_parser, foud.ImageClassificationSampleParser):
+    if label_cls is fol.Classification:
         dataset_type = fot.FiftyOneImageClassificationDataset()
         dataset_exporter = foud.FiftyOneImageClassificationDatasetExporter(
             dataset_dir, classes=classes
         )
-    elif isinstance(sample_parser, foud.ImageDetectionSampleParser):
+    elif label_cls is fol.Detections:
         dataset_type = fot.FiftyOneImageDetectionDataset()
         dataset_exporter = foud.FiftyOneImageDetectionDatasetExporter(
             dataset_dir, classes=classes
         )
-    elif isinstance(sample_parser, foud.ImageLabelsSampleParser):
-        dataset_type = fot.FiftyOneImageLabelsDataset()
-        dataset_exporter = foud.FiftyOneImageLabelsDatasetExporter(dataset_dir)
     else:
-        raise ValueError("Unsupported SampleParser %s" % type(sample_parser))
+        raise ValueError("Unsupported label class %s" % label_cls)
 
     # Write the formatted dataset to `dataset_dir`
     foud.write_dataset(