alecthomas / alecthomas/voluptuous

Exclusive with default value?

Aperta
#245 1 commento 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
Python
Stelle
1.9k
Fork
237
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

*(disclamer: I hope this time I won't write another stupid issue like the two past ones)*

I wanted to get this behavior which is to have mutually exclusive keys in a dictionary with a default one in case none of them are provided:

Imagine the example below where two keys `foo` and `bar` are exclusive. If none of them are given, `foo` is used as default:
```
>>> schema({})
{'foo': 42}

>>> schema({'foo': 23})
{'foo': 23}

>>> schema({'bar': 23})
{'bar': 23}

>>> schema({'foo': 42, 'bar': 23})
Error: foo and bar are exclusive

>>> schema({'foo': 23, 'baz': 23})
{'foo': 23, 'baz': 23}
```

Unfortunately I realized that even if `Exclusive` inherit from `Optional` it does not offer a `default` value.

I initially wrote this below and I thought it was fine, but I eventually got a `KeyError`:

```
foobartype = int
s = Schema({
Optional(Exclusive('foo', 'foobar'), default=42): foobartype,
Exclusive('bar', 'foobar'): foobartype,
'baz': foobartype
})
```

It's logical because `Optional` uses the result of the first argument as the key value. Is that a bug?

```
>>> s({})
{'foo':42} # Oh great it works?

>>> s['foo']
KeyError: 'foo' # Damned did I really wrote `foo`?

>>> type(s({}).keys()[0])
Out[26]: voluptuous.schema_builder.Exclusive # Doomed....
```

At some point I just wanted to manually force a default value for `Exclusive`:

```
class Exclusive(Optional):
def __init__(self, schema, group_of_exclusion, msg=None, default=UNDEFINED):
super(Exclusive, self).__init__(schema, msg=msg, default=default)
self.group_of_exclusion = group_of_exclusion

foobartype = int
s = Schema({
Exclusive('foo', 'foobar', default=42): foobartype,
Exclusive('bar', 'foobar'): foobartype,
'baz': foobartype
}, required=True)
```

But, this time the `Exclusive` itself does not work anymore :(

```
>>> s({'bar': 32})
{'bar': 32, 'foo': 42}
```

Before digging further in voluptuous' code. I would like to know if I did something wrong (again?).

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.