alecthomas / alecthomas/voluptuous

MultipleInvalid errors order is not always the same

Abierto
#484 2 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Python
Estrellas
1.9k
Forks
237
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

When validating this schema:

```python
Schema1 = Schema({
Required('value1'): Match2(r'^[\d\w_-]{1,64}$'),
Required('value2'): Any(IntField(), DecimalField(precision=3), TemplateString(), str)
})
```

With this test:

```python
def test_schema1_empty():
with pytest.raises(MultipleInvalid) as exception_info:
Schema1({})
assert len(exception_info.value.errors) == 2
assert str(exception_info.value.errors[0]) == "required key not provided @ data['value1']"
assert str(exception_info.value.errors[1]) == "required key not provided @ data['value2']"
```

The test fails 1 over 3-4 times.
I found it is related to the use of a set, that is unordered in python in schema_builder.py

Current code:
```python
def _compile_mapping(self, schema, invalid_msg=None):
"""Create validator for given mapping."""
invalid_msg = invalid_msg or 'mapping value'

# Keys that may be required
all_required_keys = set(key for key in schema
if key is not Extra
and ((self.required
and not isinstance(key, (Optional, Remove)))
or isinstance(key, Required)))

# Keys that may have defaults
all_default_keys = set(key for key in schema
if isinstance(key, Required)
or isinstance(key, Optional))
```

My proposal (that works for me) would be to use a dict instead of a set (to preserve validations errors order):
```python
def _compile_mapping(self, schema, invalid_msg=None):
"""Create validator for given mapping."""
invalid_msg = invalid_msg or 'mapping value'

# Keys that may be required

all_required_keys = {}
for key in schema:
if key is not Extra \
and ((self.required \
and not isinstance(key, (Optional, Remove))) \
or isinstance(key, Required)):
all_required_keys[key] = key

# Keys that may have defaults
all_default_keys = {}
for key in schema:
if isinstance(key, Required) or isinstance(key, Optional):
all_default_keys[key] = key
```

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.