We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Validating optional columns with a pandera type causes TypeError in SchemaModel
**Describe the bug**
When I use the class-based API with an optional column of type `pandera.typing.*`, I get the following TypeError:

```
TypeError: type of `pandas_dtype` argument not recognized: typing_extensions.Literal. 
Please specify a pandera PandasDtype enum, legal pandas data type, pandas data type 
string alias, or numpy data type string alias
```

If a Python type is used instead or when the column is not optional, it works as expected.

#### Code Sample

```python
import pandas as pd
import pandera as pa
from pandera.typing import DataFrame, DateTime, Series

class Schema(pa.SchemaModel):
    date : Optional[Series[DateTime]]

df = pd.DataFrame({ 
    'date': pd.date_range('2015-02-24', periods=5, freq='T')
 })
Schema.validate(df)
```

```
TypeError                                 Traceback (most recent call last)
<ipython-input-10-1d3df28d227a> in <module>
----> 1 Schema.validate(df)

/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/model.py in validate(cls, check_obj, head, tail, sample, random_state, lazy)
    146     ) -> pd.DataFrame:
    147         """%(validate_doc)s"""
--> 148         return cls.to_schema().validate(
    149             check_obj, head, tail, sample, random_state, lazy
    150         )

/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/model.py in to_schema(cls)
    119         }
    120         columns, index = cls._build_columns_index(
--> 121             cls.__fields__, cls.__checks__, **mi_kwargs
    122         )
    123         cls.__schema__ = DataFrameSchema(

/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/model.py in _build_columns_index(cls, fields, checks, **multiindex_kwargs)
    199                     required=not annotation.optional,
    200                     checks=field_checks,
--> 201                     name=field_name,
    202                 )
    203             elif annotation.origin is Index:

/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/schema_components.py in __init__(self, pandas_dtype, checks, nullable, allow_duplicates, coerce, required, name, regex)
     77         """
     78         super().__init__(
---> 79             pandas_dtype, checks, nullable, allow_duplicates, coerce
     80         )
     81         if (

/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/schemas.py in __init__(self, pandas_dtype, checks, nullable, allow_duplicates, coerce, name)
   1453
   1454         # make sure pandas dtype is valid
-> 1455         self.dtype  # pylint: disable=pointless-statement
   1456
   1457         # this attribute is not meant to be accessed by users and is explicitly

/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/schemas.py in dtype(self)
   1526     def dtype(self) -> Optional[str]:
   1527         """String representation of the dtype."""
-> 1528         return PandasDtype.get_str_dtype(self._pandas_dtype)
   1529
   1530     @property

/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/dtypes.py in get_str_dtype(cls, pandas_dtype_arg)
    310             return dtype_.str_alias
    311         raise TypeError(
--> 312             "type of `pandas_dtype` argument not recognized: "
    313             f"{type(pandas_dtype_arg)}. Please specify a pandera PandasDtype "
    314             "enum, legal pandas data type, pandas data type string alias, or "

TypeError: type of `pandas_dtype` argument not recognized: typing_extensions.Literal. Please specify a pandera PandasDtype enum, legal pandas data type, pandas data type string alias, or numpy data type string alias
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pandera/typing.py`
Content:
```
1 """Typing definitions and helpers."""
2 # pylint:disable=abstract-method,disable=too-many-ancestors
3 import sys
4 from typing import TYPE_CHECKING, Generic, Type, TypeVar
5 
6 import pandas as pd
7 import typing_inspect
8 
9 from .dtypes import PandasDtype, PandasExtensionType
10 
11 if sys.version_info < (3, 8):  # pragma: no cover
12     from typing_extensions import Literal
13 else:  # pragma: no cover
14     from typing import Literal  # pylint:disable=no-name-in-module
15 
16 
17 _LEGACY_TYPING = sys.version_info[:3] < (3, 7, 0)
18 
19 GenericDtype = TypeVar(  # type: ignore
20     "GenericDtype",
21     PandasDtype,
22     PandasExtensionType,
23     bool,
24     int,
25     str,
26     float,
27     Literal[PandasDtype.Bool],
28     Literal[PandasDtype.DateTime],
29     Literal[PandasDtype.Category],
30     Literal[PandasDtype.Float],
31     Literal[PandasDtype.Float16],
32     Literal[PandasDtype.Float32],
33     Literal[PandasDtype.Float64],
34     Literal[PandasDtype.Int],
35     Literal[PandasDtype.Int8],
36     Literal[PandasDtype.Int16],
37     Literal[PandasDtype.Int32],
38     Literal[PandasDtype.Int64],
39     Literal[PandasDtype.UInt8],
40     Literal[PandasDtype.UInt16],
41     Literal[PandasDtype.UInt32],
42     Literal[PandasDtype.UInt64],
43     Literal[PandasDtype.INT8],
44     Literal[PandasDtype.INT16],
45     Literal[PandasDtype.INT32],
46     Literal[PandasDtype.INT64],
47     Literal[PandasDtype.UINT8],
48     Literal[PandasDtype.UINT16],
49     Literal[PandasDtype.UINT32],
50     Literal[PandasDtype.UINT64],
51     Literal[PandasDtype.Object],
52     Literal[PandasDtype.String],
53     Literal[PandasDtype.STRING],
54     Literal[PandasDtype.Timedelta],
55     covariant=True,
56 )
57 Schema = TypeVar("Schema", bound="SchemaModel")  # type: ignore
58 
59 
60 # pylint:disable=too-few-public-methods
61 class Index(pd.Index, Generic[GenericDtype]):
62     """Representation of pandas.Index, only used for type annotation.
63 
64     *new in 0.5.0*
65     """
66 
67 
68 # pylint:disable=too-few-public-methods
69 class Series(pd.Series, Generic[GenericDtype]):  # type: ignore
70     """Representation of pandas.Series, only used for type annotation.
71 
72     *new in 0.5.0*
73     """
74 
75 
76 if TYPE_CHECKING:  # pragma: no cover
77     # pylint:disable=too-few-public-methods,invalid-name
78     T = TypeVar("T")
79 
80     class DataFrame(pd.DataFrame, Generic[T]):
81         """
82         Representation of pandas.DataFrame, only used for type annotation.
83 
84         *new in 0.5.0*
85         """
86 
87 
88 else:
89     # pylint:disable=too-few-public-methods
90     class DataFrame(pd.DataFrame, Generic[Schema]):
91         """
92         Representation of pandas.DataFrame, only used for type annotation.
93 
94         *new in 0.5.0*
95         """
96 
97 
98 class AnnotationInfo:  # pylint:disable=too-few-public-methods
99     """Captures extra information about an annotation.
100 
101     Attributes:
102         origin: The non-parameterized generic class.
103         arg: The first generic type (SchemaModel does not support more than 1 argument).
104         literal: Whether the annotation is a literal.
105         optional: Whether the annotation is optional.
106         raw_annotation: The raw annotation.
107     """
108 
109     def __init__(self, raw_annotation: Type) -> None:
110         self._parse_annotation(raw_annotation)
111 
112     @property
113     def is_generic_df(self) -> bool:
114         """True if the annotation is a pandera.typing.DataFrame."""
115         return self.origin is not None and issubclass(self.origin, DataFrame)
116 
117     def _parse_annotation(self, raw_annotation: Type) -> None:
118         """Parse key information from annotation.
119 
120         :param annotation: A subscripted type.
121         :returns: Annotation
122         """
123         self.raw_annotation = raw_annotation
124 
125         self.optional = typing_inspect.is_optional_type(raw_annotation)
126         if self.optional:
127             # e.g: Typing.Union[pandera.typing.Index[str], NoneType]
128             if _LEGACY_TYPING:  # pragma: no cover
129                 # get_args -> ((pandera.typing.Index, <class 'str'>), <class 'NoneType'>)
130                 self.origin, self.arg = typing_inspect.get_args(
131                     raw_annotation
132                 )[0]
133                 return
134             # get_args -> (pandera.typing.Index[str], <class 'NoneType'>)
135             raw_annotation = typing_inspect.get_args(raw_annotation)[0]
136 
137         self.origin = typing_inspect.get_origin(raw_annotation)
138         args = typing_inspect.get_args(raw_annotation)
139         self.arg = args[0] if args else args
140 
141         self.literal = typing_inspect.is_literal_type(self.arg)
142         if self.literal:
143             self.arg = typing_inspect.get_args(self.arg)[0]
144 
145 
146 Bool = Literal[PandasDtype.Bool]  #: ``"bool"`` numpy dtype
147 DateTime = Literal[PandasDtype.DateTime]  #: ``"datetime64[ns]"`` numpy dtype
148 Timedelta = Literal[
149     PandasDtype.Timedelta
150 ]  #: ``"timedelta64[ns]"`` numpy dtype
151 Category = Literal[PandasDtype.Category]  #: pandas ``"categorical"`` datatype
152 Float = Literal[PandasDtype.Float]  #: ``"float"`` numpy dtype
153 Float16 = Literal[PandasDtype.Float16]  #: ``"float16"`` numpy dtype
154 Float32 = Literal[PandasDtype.Float32]  #: ``"float32"`` numpy dtype
155 Float64 = Literal[PandasDtype.Float64]  #: ``"float64"`` numpy dtype
156 Int = Literal[PandasDtype.Int]  #: ``"int"`` numpy dtype
157 Int8 = Literal[PandasDtype.Int8]  #: ``"int8"`` numpy dtype
158 Int16 = Literal[PandasDtype.Int16]  #: ``"int16"`` numpy dtype
159 Int32 = Literal[PandasDtype.Int32]  #: ``"int32"`` numpy dtype
160 Int64 = Literal[PandasDtype.Int64]  #: ``"int64"`` numpy dtype
161 UInt8 = Literal[PandasDtype.UInt8]  #: ``"uint8"`` numpy dtype
162 UInt16 = Literal[PandasDtype.UInt16]  #: ``"uint16"`` numpy dtype
163 UInt32 = Literal[PandasDtype.UInt32]  #: ``"uint32"`` numpy dtype
164 UInt64 = Literal[PandasDtype.UInt64]  #: ``"uint64"`` numpy dtype
165 INT8 = Literal[PandasDtype.INT8]  #: ``"Int8"`` pandas dtype:: pandas 0.24.0+
166 INT16 = Literal[PandasDtype.INT16]  #: ``"Int16"`` pandas dtype: pandas 0.24.0+
167 INT32 = Literal[PandasDtype.INT32]  #: ``"Int32"`` pandas dtype: pandas 0.24.0+
168 INT64 = Literal[PandasDtype.INT64]  #: ``"Int64"`` pandas dtype: pandas 0.24.0+
169 UINT8 = Literal[
170     PandasDtype.UINT8
171 ]  #: ``"UInt8"`` pandas dtype:: pandas 0.24.0+
172 UINT16 = Literal[
173     PandasDtype.UINT16
174 ]  #: ``"UInt16"`` pandas dtype: pandas 0.24.0+
175 UINT32 = Literal[
176     PandasDtype.UINT32
177 ]  #: ``"UInt32"`` pandas dtype: pandas 0.24.0+
178 UINT64 = Literal[
179     PandasDtype.UINT64
180 ]  #: ``"UInt64"`` pandas dtype: pandas 0.24.0+
181 Object = Literal[PandasDtype.Object]  #: ``"object"`` numpy dtype
182 
183 String = Literal[PandasDtype.String]  #: ``"str"`` numpy dtype
184 
185 #: ``"string"`` pandas dtypes: pandas 1.0.0+. For <1.0.0, this enum will
186 #: fall back on the str-as-object-array representation.
187 STRING = Literal[PandasDtype.STRING]  #: ``"str"`` numpy dtype
188
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pandera/typing.py b/pandera/typing.py
--- a/pandera/typing.py
+++ b/pandera/typing.py
@@ -130,13 +130,13 @@
                 self.origin, self.arg = typing_inspect.get_args(
                     raw_annotation
                 )[0]
-                return
             # get_args -> (pandera.typing.Index[str], <class 'NoneType'>)
             raw_annotation = typing_inspect.get_args(raw_annotation)[0]
 
-        self.origin = typing_inspect.get_origin(raw_annotation)
-        args = typing_inspect.get_args(raw_annotation)
-        self.arg = args[0] if args else args
+        if not (self.optional and _LEGACY_TYPING):
+            self.origin = typing_inspect.get_origin(raw_annotation)
+            args = typing_inspect.get_args(raw_annotation)
+            self.arg = args[0] if args else args
 
         self.literal = typing_inspect.is_literal_type(self.arg)
         if self.literal:

{"golden_diff": "diff --git a/pandera/typing.py b/pandera/typing.py\n--- a/pandera/typing.py\n+++ b/pandera/typing.py\n@@ -130,13 +130,13 @@\n                 self.origin, self.arg = typing_inspect.get_args(\n                     raw_annotation\n                 )[0]\n-                return\n             # get_args -> (pandera.typing.Index[str], <class 'NoneType'>)\n             raw_annotation = typing_inspect.get_args(raw_annotation)[0]\n \n-        self.origin = typing_inspect.get_origin(raw_annotation)\n-        args = typing_inspect.get_args(raw_annotation)\n-        self.arg = args[0] if args else args\n+        if not (self.optional and _LEGACY_TYPING):\n+            self.origin = typing_inspect.get_origin(raw_annotation)\n+            args = typing_inspect.get_args(raw_annotation)\n+            self.arg = args[0] if args else args\n \n         self.literal = typing_inspect.is_literal_type(self.arg)\n         if self.literal:\n", "issue": "Validating optional columns with a pandera type causes TypeError in SchemaModel\n**Describe the bug**\r\nWhen I use the class-based API with an optional column of type `pandera.typing.*`, I get the following TypeError:\r\n\r\n```\r\nTypeError: type of `pandas_dtype` argument not recognized: typing_extensions.Literal. \r\nPlease specify a pandera PandasDtype enum, legal pandas data type, pandas data type \r\nstring alias, or numpy data type string alias\r\n```\r\n\r\nIf a Python type is used instead or when the column is not optional, it works as expected.\r\n\r\n#### Code Sample\r\n\r\n```python\r\nimport pandas as pd\r\nimport pandera as pa\r\nfrom pandera.typing import DataFrame, DateTime, Series\r\n\r\nclass Schema(pa.SchemaModel):\r\n    date : Optional[Series[DateTime]]\r\n\r\ndf = pd.DataFrame({ \r\n    'date': pd.date_range('2015-02-24', periods=5, freq='T')\r\n })\r\nSchema.validate(df)\r\n```\r\n\r\n```\r\nTypeError                                 Traceback (most recent call last)\r\n<ipython-input-10-1d3df28d227a> in <module>\r\n----> 1 Schema.validate(df)\r\n\r\n/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/model.py in validate(cls, check_obj, head, tail, sample, random_state, lazy)\r\n    146     ) -> pd.DataFrame:\r\n    147         \"\"\"%(validate_doc)s\"\"\"\r\n--> 148         return cls.to_schema().validate(\r\n    149             check_obj, head, tail, sample, random_state, lazy\r\n    150         )\r\n\r\n/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/model.py in to_schema(cls)\r\n    119         }\r\n    120         columns, index = cls._build_columns_index(\r\n--> 121             cls.__fields__, cls.__checks__, **mi_kwargs\r\n    122         )\r\n    123         cls.__schema__ = DataFrameSchema(\r\n\r\n/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/model.py in _build_columns_index(cls, fields, checks, **multiindex_kwargs)\r\n    199                     required=not annotation.optional,\r\n    200                     checks=field_checks,\r\n--> 201                     name=field_name,\r\n    202                 )\r\n    203             elif annotation.origin is Index:\r\n\r\n/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/schema_components.py in __init__(self, pandas_dtype, checks, nullable, allow_duplicates, coerce, required, name, regex)\r\n     77         \"\"\"\r\n     78         super().__init__(\r\n---> 79             pandas_dtype, checks, nullable, allow_duplicates, coerce\r\n     80         )\r\n     81         if (\r\n\r\n/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/schemas.py in __init__(self, pandas_dtype, checks, nullable, allow_duplicates, coerce, name)\r\n   1453\r\n   1454         # make sure pandas dtype is valid\r\n-> 1455         self.dtype  # pylint: disable=pointless-statement\r\n   1456\r\n   1457         # this attribute is not meant to be accessed by users and is explicitly\r\n\r\n/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/schemas.py in dtype(self)\r\n   1526     def dtype(self) -> Optional[str]:\r\n   1527         \"\"\"String representation of the dtype.\"\"\"\r\n-> 1528         return PandasDtype.get_str_dtype(self._pandas_dtype)\r\n   1529\r\n   1530     @property\r\n\r\n/cw/dtaijupiter/NoCsBack/dtai/pieterr/Projects/socceraction/.venv/lib/python3.6/site-packages/pandera/dtypes.py in get_str_dtype(cls, pandas_dtype_arg)\r\n    310             return dtype_.str_alias\r\n    311         raise TypeError(\r\n--> 312             \"type of `pandas_dtype` argument not recognized: \"\r\n    313             f\"{type(pandas_dtype_arg)}. Please specify a pandera PandasDtype \"\r\n    314             \"enum, legal pandas data type, pandas data type string alias, or \"\r\n\r\nTypeError: type of `pandas_dtype` argument not recognized: typing_extensions.Literal. Please specify a pandera PandasDtype enum, legal pandas data type, pandas data type string alias, or numpy data type string alias\r\n```\r\n\n", "before_files": [{"content": "\"\"\"Typing definitions and helpers.\"\"\"\n# pylint:disable=abstract-method,disable=too-many-ancestors\nimport sys\nfrom typing import TYPE_CHECKING, Generic, Type, TypeVar\n\nimport pandas as pd\nimport typing_inspect\n\nfrom .dtypes import PandasDtype, PandasExtensionType\n\nif sys.version_info < (3, 8):  # pragma: no cover\n    from typing_extensions import Literal\nelse:  # pragma: no cover\n    from typing import Literal  # pylint:disable=no-name-in-module\n\n\n_LEGACY_TYPING = sys.version_info[:3] < (3, 7, 0)\n\nGenericDtype = TypeVar(  # type: ignore\n    \"GenericDtype\",\n    PandasDtype,\n    PandasExtensionType,\n    bool,\n    int,\n    str,\n    float,\n    Literal[PandasDtype.Bool],\n    Literal[PandasDtype.DateTime],\n    Literal[PandasDtype.Category],\n    Literal[PandasDtype.Float],\n    Literal[PandasDtype.Float16],\n    Literal[PandasDtype.Float32],\n    Literal[PandasDtype.Float64],\n    Literal[PandasDtype.Int],\n    Literal[PandasDtype.Int8],\n    Literal[PandasDtype.Int16],\n    Literal[PandasDtype.Int32],\n    Literal[PandasDtype.Int64],\n    Literal[PandasDtype.UInt8],\n    Literal[PandasDtype.UInt16],\n    Literal[PandasDtype.UInt32],\n    Literal[PandasDtype.UInt64],\n    Literal[PandasDtype.INT8],\n    Literal[PandasDtype.INT16],\n    Literal[PandasDtype.INT32],\n    Literal[PandasDtype.INT64],\n    Literal[PandasDtype.UINT8],\n    Literal[PandasDtype.UINT16],\n    Literal[PandasDtype.UINT32],\n    Literal[PandasDtype.UINT64],\n    Literal[PandasDtype.Object],\n    Literal[PandasDtype.String],\n    Literal[PandasDtype.STRING],\n    Literal[PandasDtype.Timedelta],\n    covariant=True,\n)\nSchema = TypeVar(\"Schema\", bound=\"SchemaModel\")  # type: ignore\n\n\n# pylint:disable=too-few-public-methods\nclass Index(pd.Index, Generic[GenericDtype]):\n    \"\"\"Representation of pandas.Index, only used for type annotation.\n\n    *new in 0.5.0*\n    \"\"\"\n\n\n# pylint:disable=too-few-public-methods\nclass Series(pd.Series, Generic[GenericDtype]):  # type: ignore\n    \"\"\"Representation of pandas.Series, only used for type annotation.\n\n    *new in 0.5.0*\n    \"\"\"\n\n\nif TYPE_CHECKING:  # pragma: no cover\n    # pylint:disable=too-few-public-methods,invalid-name\n    T = TypeVar(\"T\")\n\n    class DataFrame(pd.DataFrame, Generic[T]):\n        \"\"\"\n        Representation of pandas.DataFrame, only used for type annotation.\n\n        *new in 0.5.0*\n        \"\"\"\n\n\nelse:\n    # pylint:disable=too-few-public-methods\n    class DataFrame(pd.DataFrame, Generic[Schema]):\n        \"\"\"\n        Representation of pandas.DataFrame, only used for type annotation.\n\n        *new in 0.5.0*\n        \"\"\"\n\n\nclass AnnotationInfo:  # pylint:disable=too-few-public-methods\n    \"\"\"Captures extra information about an annotation.\n\n    Attributes:\n        origin: The non-parameterized generic class.\n        arg: The first generic type (SchemaModel does not support more than 1 argument).\n        literal: Whether the annotation is a literal.\n        optional: Whether the annotation is optional.\n        raw_annotation: The raw annotation.\n    \"\"\"\n\n    def __init__(self, raw_annotation: Type) -> None:\n        self._parse_annotation(raw_annotation)\n\n    @property\n    def is_generic_df(self) -> bool:\n        \"\"\"True if the annotation is a pandera.typing.DataFrame.\"\"\"\n        return self.origin is not None and issubclass(self.origin, DataFrame)\n\n    def _parse_annotation(self, raw_annotation: Type) -> None:\n        \"\"\"Parse key information from annotation.\n\n        :param annotation: A subscripted type.\n        :returns: Annotation\n        \"\"\"\n        self.raw_annotation = raw_annotation\n\n        self.optional = typing_inspect.is_optional_type(raw_annotation)\n        if self.optional:\n            # e.g: Typing.Union[pandera.typing.Index[str], NoneType]\n            if _LEGACY_TYPING:  # pragma: no cover\n                # get_args -> ((pandera.typing.Index, <class 'str'>), <class 'NoneType'>)\n                self.origin, self.arg = typing_inspect.get_args(\n                    raw_annotation\n                )[0]\n                return\n            # get_args -> (pandera.typing.Index[str], <class 'NoneType'>)\n            raw_annotation = typing_inspect.get_args(raw_annotation)[0]\n\n        self.origin = typing_inspect.get_origin(raw_annotation)\n        args = typing_inspect.get_args(raw_annotation)\n        self.arg = args[0] if args else args\n\n        self.literal = typing_inspect.is_literal_type(self.arg)\n        if self.literal:\n            self.arg = typing_inspect.get_args(self.arg)[0]\n\n\nBool = Literal[PandasDtype.Bool]  #: ``\"bool\"`` numpy dtype\nDateTime = Literal[PandasDtype.DateTime]  #: ``\"datetime64[ns]\"`` numpy dtype\nTimedelta = Literal[\n    PandasDtype.Timedelta\n]  #: ``\"timedelta64[ns]\"`` numpy dtype\nCategory = Literal[PandasDtype.Category]  #: pandas ``\"categorical\"`` datatype\nFloat = Literal[PandasDtype.Float]  #: ``\"float\"`` numpy dtype\nFloat16 = Literal[PandasDtype.Float16]  #: ``\"float16\"`` numpy dtype\nFloat32 = Literal[PandasDtype.Float32]  #: ``\"float32\"`` numpy dtype\nFloat64 = Literal[PandasDtype.Float64]  #: ``\"float64\"`` numpy dtype\nInt = Literal[PandasDtype.Int]  #: ``\"int\"`` numpy dtype\nInt8 = Literal[PandasDtype.Int8]  #: ``\"int8\"`` numpy dtype\nInt16 = Literal[PandasDtype.Int16]  #: ``\"int16\"`` numpy dtype\nInt32 = Literal[PandasDtype.Int32]  #: ``\"int32\"`` numpy dtype\nInt64 = Literal[PandasDtype.Int64]  #: ``\"int64\"`` numpy dtype\nUInt8 = Literal[PandasDtype.UInt8]  #: ``\"uint8\"`` numpy dtype\nUInt16 = Literal[PandasDtype.UInt16]  #: ``\"uint16\"`` numpy dtype\nUInt32 = Literal[PandasDtype.UInt32]  #: ``\"uint32\"`` numpy dtype\nUInt64 = Literal[PandasDtype.UInt64]  #: ``\"uint64\"`` numpy dtype\nINT8 = Literal[PandasDtype.INT8]  #: ``\"Int8\"`` pandas dtype:: pandas 0.24.0+\nINT16 = Literal[PandasDtype.INT16]  #: ``\"Int16\"`` pandas dtype: pandas 0.24.0+\nINT32 = Literal[PandasDtype.INT32]  #: ``\"Int32\"`` pandas dtype: pandas 0.24.0+\nINT64 = Literal[PandasDtype.INT64]  #: ``\"Int64\"`` pandas dtype: pandas 0.24.0+\nUINT8 = Literal[\n    PandasDtype.UINT8\n]  #: ``\"UInt8\"`` pandas dtype:: pandas 0.24.0+\nUINT16 = Literal[\n    PandasDtype.UINT16\n]  #: ``\"UInt16\"`` pandas dtype: pandas 0.24.0+\nUINT32 = Literal[\n    PandasDtype.UINT32\n]  #: ``\"UInt32\"`` pandas dtype: pandas 0.24.0+\nUINT64 = Literal[\n    PandasDtype.UINT64\n]  #: ``\"UInt64\"`` pandas dtype: pandas 0.24.0+\nObject = Literal[PandasDtype.Object]  #: ``\"object\"`` numpy dtype\n\nString = Literal[PandasDtype.String]  #: ``\"str\"`` numpy dtype\n\n#: ``\"string\"`` pandas dtypes: pandas 1.0.0+. For <1.0.0, this enum will\n#: fall back on the str-as-object-array representation.\nSTRING = Literal[PandasDtype.STRING]  #: ``\"str\"`` numpy dtype\n", "path": "pandera/typing.py"}], "after_files": [{"content": "\"\"\"Typing definitions and helpers.\"\"\"\n# pylint:disable=abstract-method,disable=too-many-ancestors\nimport sys\nfrom typing import TYPE_CHECKING, Generic, Type, TypeVar\n\nimport pandas as pd\nimport typing_inspect\n\nfrom .dtypes import PandasDtype, PandasExtensionType\n\nif sys.version_info < (3, 8):  # pragma: no cover\n    from typing_extensions import Literal\nelse:  # pragma: no cover\n    from typing import Literal  # pylint:disable=no-name-in-module\n\n\n_LEGACY_TYPING = sys.version_info[:3] < (3, 7, 0)\n\nGenericDtype = TypeVar(  # type: ignore\n    \"GenericDtype\",\n    PandasDtype,\n    PandasExtensionType,\n    bool,\n    int,\n    str,\n    float,\n    Literal[PandasDtype.Bool],\n    Literal[PandasDtype.DateTime],\n    Literal[PandasDtype.Category],\n    Literal[PandasDtype.Float],\n    Literal[PandasDtype.Float16],\n    Literal[PandasDtype.Float32],\n    Literal[PandasDtype.Float64],\n    Literal[PandasDtype.Int],\n    Literal[PandasDtype.Int8],\n    Literal[PandasDtype.Int16],\n    Literal[PandasDtype.Int32],\n    Literal[PandasDtype.Int64],\n    Literal[PandasDtype.UInt8],\n    Literal[PandasDtype.UInt16],\n    Literal[PandasDtype.UInt32],\n    Literal[PandasDtype.UInt64],\n    Literal[PandasDtype.INT8],\n    Literal[PandasDtype.INT16],\n    Literal[PandasDtype.INT32],\n    Literal[PandasDtype.INT64],\n    Literal[PandasDtype.UINT8],\n    Literal[PandasDtype.UINT16],\n    Literal[PandasDtype.UINT32],\n    Literal[PandasDtype.UINT64],\n    Literal[PandasDtype.Object],\n    Literal[PandasDtype.String],\n    Literal[PandasDtype.STRING],\n    Literal[PandasDtype.Timedelta],\n    covariant=True,\n)\nSchema = TypeVar(\"Schema\", bound=\"SchemaModel\")  # type: ignore\n\n\n# pylint:disable=too-few-public-methods\nclass Index(pd.Index, Generic[GenericDtype]):\n    \"\"\"Representation of pandas.Index, only used for type annotation.\n\n    *new in 0.5.0*\n    \"\"\"\n\n\n# pylint:disable=too-few-public-methods\nclass Series(pd.Series, Generic[GenericDtype]):  # type: ignore\n    \"\"\"Representation of pandas.Series, only used for type annotation.\n\n    *new in 0.5.0*\n    \"\"\"\n\n\nif TYPE_CHECKING:  # pragma: no cover\n    # pylint:disable=too-few-public-methods,invalid-name\n    T = TypeVar(\"T\")\n\n    class DataFrame(pd.DataFrame, Generic[T]):\n        \"\"\"\n        Representation of pandas.DataFrame, only used for type annotation.\n\n        *new in 0.5.0*\n        \"\"\"\n\n\nelse:\n    # pylint:disable=too-few-public-methods\n    class DataFrame(pd.DataFrame, Generic[Schema]):\n        \"\"\"\n        Representation of pandas.DataFrame, only used for type annotation.\n\n        *new in 0.5.0*\n        \"\"\"\n\n\nclass AnnotationInfo:  # pylint:disable=too-few-public-methods\n    \"\"\"Captures extra information about an annotation.\n\n    Attributes:\n        origin: The non-parameterized generic class.\n        arg: The first generic type (SchemaModel does not support more than 1 argument).\n        literal: Whether the annotation is a literal.\n        optional: Whether the annotation is optional.\n        raw_annotation: The raw annotation.\n    \"\"\"\n\n    def __init__(self, raw_annotation: Type) -> None:\n        self._parse_annotation(raw_annotation)\n\n    @property\n    def is_generic_df(self) -> bool:\n        \"\"\"True if the annotation is a pandera.typing.DataFrame.\"\"\"\n        return self.origin is not None and issubclass(self.origin, DataFrame)\n\n    def _parse_annotation(self, raw_annotation: Type) -> None:\n        \"\"\"Parse key information from annotation.\n\n        :param annotation: A subscripted type.\n        :returns: Annotation\n        \"\"\"\n        self.raw_annotation = raw_annotation\n\n        self.optional = typing_inspect.is_optional_type(raw_annotation)\n        if self.optional:\n            # e.g: Typing.Union[pandera.typing.Index[str], NoneType]\n            if _LEGACY_TYPING:  # pragma: no cover\n                # get_args -> ((pandera.typing.Index, <class 'str'>), <class 'NoneType'>)\n                self.origin, self.arg = typing_inspect.get_args(\n                    raw_annotation\n                )[0]\n            # get_args -> (pandera.typing.Index[str], <class 'NoneType'>)\n            raw_annotation = typing_inspect.get_args(raw_annotation)[0]\n\n        if not (self.optional and _LEGACY_TYPING):\n            self.origin = typing_inspect.get_origin(raw_annotation)\n            args = typing_inspect.get_args(raw_annotation)\n            self.arg = args[0] if args else args\n\n        self.literal = typing_inspect.is_literal_type(self.arg)\n        if self.literal:\n            self.arg = typing_inspect.get_args(self.arg)[0]\n\n\nBool = Literal[PandasDtype.Bool]  #: ``\"bool\"`` numpy dtype\nDateTime = Literal[PandasDtype.DateTime]  #: ``\"datetime64[ns]\"`` numpy dtype\nTimedelta = Literal[\n    PandasDtype.Timedelta\n]  #: ``\"timedelta64[ns]\"`` numpy dtype\nCategory = Literal[PandasDtype.Category]  #: pandas ``\"categorical\"`` datatype\nFloat = Literal[PandasDtype.Float]  #: ``\"float\"`` numpy dtype\nFloat16 = Literal[PandasDtype.Float16]  #: ``\"float16\"`` numpy dtype\nFloat32 = Literal[PandasDtype.Float32]  #: ``\"float32\"`` numpy dtype\nFloat64 = Literal[PandasDtype.Float64]  #: ``\"float64\"`` numpy dtype\nInt = Literal[PandasDtype.Int]  #: ``\"int\"`` numpy dtype\nInt8 = Literal[PandasDtype.Int8]  #: ``\"int8\"`` numpy dtype\nInt16 = Literal[PandasDtype.Int16]  #: ``\"int16\"`` numpy dtype\nInt32 = Literal[PandasDtype.Int32]  #: ``\"int32\"`` numpy dtype\nInt64 = Literal[PandasDtype.Int64]  #: ``\"int64\"`` numpy dtype\nUInt8 = Literal[PandasDtype.UInt8]  #: ``\"uint8\"`` numpy dtype\nUInt16 = Literal[PandasDtype.UInt16]  #: ``\"uint16\"`` numpy dtype\nUInt32 = Literal[PandasDtype.UInt32]  #: ``\"uint32\"`` numpy dtype\nUInt64 = Literal[PandasDtype.UInt64]  #: ``\"uint64\"`` numpy dtype\nINT8 = Literal[PandasDtype.INT8]  #: ``\"Int8\"`` pandas dtype:: pandas 0.24.0+\nINT16 = Literal[PandasDtype.INT16]  #: ``\"Int16\"`` pandas dtype: pandas 0.24.0+\nINT32 = Literal[PandasDtype.INT32]  #: ``\"Int32\"`` pandas dtype: pandas 0.24.0+\nINT64 = Literal[PandasDtype.INT64]  #: ``\"Int64\"`` pandas dtype: pandas 0.24.0+\nUINT8 = Literal[\n    PandasDtype.UINT8\n]  #: ``\"UInt8\"`` pandas dtype:: pandas 0.24.0+\nUINT16 = Literal[\n    PandasDtype.UINT16\n]  #: ``\"UInt16\"`` pandas dtype: pandas 0.24.0+\nUINT32 = Literal[\n    PandasDtype.UINT32\n]  #: ``\"UInt32\"`` pandas dtype: pandas 0.24.0+\nUINT64 = Literal[\n    PandasDtype.UINT64\n]  #: ``\"UInt64\"`` pandas dtype: pandas 0.24.0+\nObject = Literal[PandasDtype.Object]  #: ``\"object\"`` numpy dtype\n\nString = Literal[PandasDtype.String]  #: ``\"str\"`` numpy dtype\n\n#: ``\"string\"`` pandas dtypes: pandas 1.0.0+. For <1.0.0, this enum will\n#: fall back on the str-as-object-array representation.\nSTRING = Literal[PandasDtype.STRING]  #: ``\"str\"`` numpy dtype\n", "path": "pandera/typing.py"}]}