Repository: nltk/nltk

Issue:
RegexpTagger fails to handle exception.
There is a bug in the RegexpTagger. It fails to handle exception in case of missing tag or regular expression. 

```
    def __init__(self, regexps, backoff=None):
        """ """
        super().__init__(backoff)
        try:
            self._regexps = [
                (
                    re.compile(regexp),
                    tag,
                )
                for regexp, tag in regexps
            ]
        except Exception as e:
            raise Exception(
                "Invalid RegexpTagger regexp:", str(e), "regexp:", regexp, "tag:", tag
            ) from e
```

The problem that both regexp and tag are not defined anywhere in the class, which is weird because it implies that the user should be notified with the missing tag or regular expression which is missing!. 

The possible solutions from POV are: 

- Simply remove the regexp and tag variables from the exception messae. 
- Check for the length of each tuple in the list and throw exception if length of one tuple is not two.

Maybe the Exception should be more meaningful like, "RegexpTagger expects tuple of size two(regexp, tag). 




Discussion:
I think it is useful to catch regexp compilation errors and report them in this way. I think the situation you describe can only happen if an empty list of regexps is passed to the initialiser.

We do not systematically check the type or internal structure arguments passed to NLTK functions.
I completely agree, but it is irrelevant to use un-defined variables. Also there is different cases where this behaviour can happens. For example, regexps = [(r'^-?[0-]', 'CD'), (r'(The|the|A|a|An|an)$', 'AT'), (r'.*able$',)], where the list contains a tuple that does not have a corresponding tag or vice versa.


Resolving patch:
diff --git a/nltk/tag/sequential.py b/nltk/tag/sequential.py
--- a/nltk/tag/sequential.py
+++ b/nltk/tag/sequential.py
@@ -20,6 +20,7 @@ class for all the taggers in this module.  Tagging of individual words
 import ast
 import re
 from abc import abstractmethod
+from typing import List, Optional, Tuple
 
 from nltk import jsontags
 from nltk.classify import NaiveBayesClassifier
@@ -533,21 +534,18 @@ class RegexpTagger(SequentialBackoffTagger):
 
     json_tag = "nltk.tag.sequential.RegexpTagger"
 
-    def __init__(self, regexps, backoff=None):
-        """ """
+    def __init__(
+        self, regexps: List[Tuple[str, str]], backoff: Optional[TaggerI] = None
+    ):
         super().__init__(backoff)
-        try:
-            self._regexps = [
-                (
-                    re.compile(regexp),
-                    tag,
-                )
-                for regexp, tag in regexps
-            ]
-        except Exception as e:
-            raise Exception(
-                "Invalid RegexpTagger regexp:", str(e), "regexp:", regexp, "tag:", tag
-            ) from e
+        self._regexps = []
+        for regexp, tag in regexps:
+            try:
+                self._regexps.append((re.compile(regexp), tag))
+            except Exception as e:
+                raise Exception(
+                    f"Invalid RegexpTagger regexp: {e}\n- regexp: {regexp!r}\n- tag: {tag!r}"
+                ) from e
 
     def encode_json_obj(self):
         return [(regexp.pattern, tag) for regexp, tag in self._regexps], self.backoff


Test patch: