Repository: pydantic/pydantic

Issue:
Duplicated errors when using a Literal choice
# Bug

Please complete:
* OS: macOS Mojave 10.14.6 (18G87)
* Python version `import sys; print(sys.version)`: 3.7.4 (default, Jul  9 2019, 18:13:23) [Clang 10.0.1 (clang-1001.0.46.4)]
* Pydantic version `import pydantic; print(pydantic.VERSION)`: 0.32.2

I tried looking for an existing issue, [found this](https://www.amazon.com/Low-Culture-Everything-Around-Computer/dp/B07381HM47), but didn't seem appropriate.

In #651, examples on how to use the `Literal` option were introduced, including [this example](https://github.com/samuelcolvin/pydantic/blob/bc600145184979d774e40c5d98f7a76d90ca616a/docs/examples/literal1.py) showing a single validation error, and the acceptable choices.

Running this file today produces two errors, instead of one, and doesn't populate the `permitted` value correctly.

```shellsession
$ python docs/examples/literal1.py
2 validation errors for Pie
flavor
  unexpected value; permitted: 'apple' (type=value_error.const; given=cherry; permitted=('apple',))
flavor
  unexpected value; permitted: 'pumpkin' (type=value_error.const; given=cherry; permitted=('pumpkin',))
```



Comments:
Thanks for making an issue, I’ll take a look.

Patch:
diff --git a/pydantic/fields.py b/pydantic/fields.py
--- a/pydantic/fields.py
+++ b/pydantic/fields.py
@@ -31,7 +31,6 @@
     display_as_type,
     is_literal_type,
     lenient_issubclass,
-    literal_values,
     sequence_like,
 )
 from .validators import NoneType, constant_validator, dict_validator, find_validators
@@ -197,11 +196,7 @@ def _populate_sub_fields(self) -> None:  # noqa: C901 (ignore complexity)
             # python 3.7 only, Pattern is a typing object but without sub fields
             return
         if is_literal_type(self.type_):
-            values = literal_values(self.type_)
-            if len(values) > 1:
-                self.type_ = Union[tuple(Literal[value] for value in values)]
-            else:
-                return
+            return
         origin = getattr(self.type_, '__origin__', None)
         if origin is None:
             # field is not "typing" object eg. Union, Dict, List etc.
diff --git a/pydantic/schema.py b/pydantic/schema.py
--- a/pydantic/schema.py
+++ b/pydantic/schema.py
@@ -49,6 +49,7 @@
     constr,
 )
 from .utils import (
+    Literal,
     is_callable_type,
     is_literal_type,
     is_new_type,
@@ -758,8 +759,16 @@ def field_singleton_schema(  # noqa: C901 (ignore complexity)
     if is_new_type(field_type):
         field_type = new_type_supertype(field_type)
     if is_literal_type(field_type):
-        # If there were multiple literal values, field.sub_fields would not be falsy
-        literal_value = literal_values(field_type)[0]
+        values = literal_values(field_type)
+        if len(values) > 1:
+            return field_schema(
+                multivalue_literal_field_for_schema(values, field),
+                by_alias=by_alias,
+                model_name_map=model_name_map,
+                ref_prefix=ref_prefix,
+                known_models=known_models,
+            )
+        literal_value = values[0]
         field_type = type(literal_value)
         f_schema['const'] = literal_value
     if issubclass(field_type, Enum):
@@ -807,6 +816,19 @@ def field_singleton_schema(  # noqa: C901 (ignore complexity)
     raise ValueError(f'Value not declarable with JSON Schema, field: {field}')
 
 
+def multivalue_literal_field_for_schema(values: Tuple[Any, ...], field: Field) -> Field:
+    return Field(
+        name=field.name,
+        type_=Union[tuple(Literal[value] for value in values)],
+        class_validators=field.class_validators,
+        model_config=field.model_config,
+        default=field.default,
+        required=field.required,
+        alias=field.alias,
+        schema=field.schema,
+    )
+
+
 def encode_default(dft: Any) -> Any:
     if isinstance(dft, (int, float, str)):
         return dft


Test patch:
diff --git a/tests/test_types.py b/tests/test_types.py
--- a/tests/test_types.py
+++ b/tests/test_types.py
@@ -1730,14 +1730,8 @@ class Model(BaseModel):
     assert exc_info.value.errors() == [
         {
             'loc': ('a_or_b',),
-            'msg': "unexpected value; permitted: 'a'",
+            'msg': "unexpected value; permitted: 'a', 'b'",
             'type': 'value_error.const',
-            'ctx': {'given': 'c', 'permitted': ('a',)},
-        },
-        {
-            'loc': ('a_or_b',),
-            'msg': "unexpected value; permitted: 'b'",
-            'type': 'value_error.const',
-            'ctx': {'given': 'c', 'permitted': ('b',)},
-        },
+            'ctx': {'given': 'c', 'permitted': ('a', 'b')},
+        }
     ]