Skip to content

Default values and subcast #270

@ghost

Description

As far as I can tell the default value can either be of the cast type or a string. So env.bool('FOO', True), env.bool('FOO', 'true'), env.bool('FOO', '1') and env.bool('FOO', 'YES') all are basically the same.

>>> os.environ.get('FOO')
>>> env.bool('FOO', True)
True
>>> env.bool('FOO', 'true')
True
>>> env.bool('FOO', '1')
True
>>> env.bool('FOO', 'YES')
True

The same goes for lists with a subcast to a basic type. env.list('FOO', '1, 2, 42', subcast=float) and env.list('FOO', [1.0, 2.0, 42.0], subcast=float) both do work.

>>> env.list('FOO', '1, 2, 42', subcast=float)
[1.0, 2.0, 42.0]
>>> env.list('FOO', [1.0, 2.0, 42.0], subcast=float)
[1.0, 2.0, 42.0]

But, using the target type as default only works as long as the subcast type/callable can be called with the cast type itself. It breaks when the callable expects a string and returns something else. For example:

>>> env.list('FOO', 'a:b, b:c', subcast=lambda s: tuple(s.split(':')))
[('a', 'b'), (' b', 'c')]
>>> env.list('FOO', ['a:b', 'b:c'], subcast=lambda s: tuple(s.split(':')))
[('a', 'b'), ('b', 'c')]
>>> env.list('FOO', [('a', 'b'), ('b', 'c')], subcast=lambda s: tuple(s.split(':')))
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "[…]\lib\site-packages\environs\__init__.py", line 123, in method
    value = field.deserialize(value)
  File "[…]\lib\site-packages\marshmallow\fields.py", line 368, in deserialize
    output = self._deserialize(value, attr, data, **kwargs)
  File "[…]\lib\site-packages\marshmallow\fields.py", line 784, in _deserialize
    result.append(self.inner.deserialize(each, **kwargs))
  File "[…]\lib\site-packages\marshmallow\fields.py", line 368, in deserialize
    output = self._deserialize(value, attr, data, **kwargs)
  File "[…]\lib\site-packages\environs\__init__.py", line 188, in _deserialize
    return func(value)
  File "<console>", line 1, in <lambda>
AttributeError: 'tuple' object has no attribute 'split'

If this is expected behaviour, I’d be happy to provide a pull request with a supplement to the documentation (well, README.md).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions