Repository: facebookresearch/ParlAI

Issue:
Help incorrectly shows when flag isn't recognized
**Bug description**
```
$ parlai i -mf /checkpoint/parlai/zoo/
q_function/generative2.7B_bst_0331/model --display-fi 1
usage: parlai [-h] [--helpall] [--version] COMMAND ...

       _
      /")
     //)
  ==//'=== ParlAI
   /

optional arguments:
  -h, --help               show this help message and exit
  --helpall                List all commands, including advanced ones.
  --version                Prints version info and exit.

Commands:
  
  display_data (dd)        Display data from a task
  display_model (dm)       Display model predictions.
  eval_model (em, eval)    Evaluate a model
  train_model (tm, train)  Train a model
  interactive (i)          Interactive chat with a model on the command line
  safe_interactive         Like interactive, but adds a safety filter
  self_chat                Generate self-chats of a model

Parse Error: unrecognized arguments: --display-fi 1
```

Note that the parlai supercommand help shows, and not the interactive.



Discussion:

Resolving patch:
diff --git a/parlai/core/script.py b/parlai/core/script.py
--- a/parlai/core/script.py
+++ b/parlai/core/script.py
@@ -126,6 +126,9 @@ class _SupercommandParser(ParlaiParser):
     """
 
     def __init__(self, *args, **kwargs):
+        # used to target help messages more correctly, see GH #3182
+        self._help_subparser = None
+
         from parlai.utils.strings import colorize
 
         logo = ""
@@ -147,6 +150,22 @@ def add_extra_args(self, args):
         for _, v in sa.choices.items():
             v.add_extra_args(args)
 
+    def parse_known_args(self, args=None, namespace=None, nohelp=False):
+        known, unused = super().parse_known_args(args, namespace, nohelp)
+        if hasattr(known, '_subparser'):
+            # keep this around to keep the print message more in tune
+            self._help_subparser = known._subparser
+        return known, unused
+
+    def print_help(self):
+        """
+        Print help, possibly deferring to the appropriate subcommand.
+        """
+        if self._help_subparser:
+            self._help_subparser.print_help()
+        else:
+            return super().print_help()
+
     def add_subparsers(self, **kwargs):
         return super().add_subparsers(**kwargs)
 


Test patch:
diff --git a/tests/test_script.py b/tests/test_script.py
--- a/tests/test_script.py
+++ b/tests/test_script.py
@@ -92,8 +92,17 @@ def test_help(self):
             script.superscript_main(args=['help'])
             assert 'test_script' in output.getvalue()
             assert 'hidden_script' not in output.getvalue()
+            # showing help for the super command, not the subcommand
+            assert '--foo' not in output.getvalue()
 
         with testing_utils.capture_output() as output:
             script.superscript_main(args=['helpall'])
             assert 'test_script' in output.getvalue()
             assert 'hidden_script' in output.getvalue()
+
+    def test_subcommand_help(self):
+        with testing_utils.capture_output() as output:
+            with self.assertRaises(SystemExit):
+                script.superscript_main(args=['test_script', 'foo'])
+                assert 'parlai test_script' in output.getvalue()
+                assert '--foo' in output.getvalue()