HBNetwork / python-decouple

Strict separation of config from code.
MIT License
2.83k stars 196 forks source link

Confusing interplay between cast = str and default value = None #110

Closed felciano closed 3 years ago

felciano commented 3 years ago

It looks like the cast operator takes precedence over default values, including casting None as a default value, with inconsistent results depending on what type is referenced by cast:

print (config("THIS_VAR_IS_MISSING", default=None) == None)     # True
print (config("THIS_VAR_IS_MISSING", cast=str, default=None) == None)   # False
print (config("THIS_VAR_IS_MISSING", cast=int, default=None) == None)   # throws TypeError

This means, for example, a if not my_var test for a missing environment variable whose default is None may or may not be true depending on whether a cast=str option was specified. While this may strictly adhere to python semantics , where str(None) returns the string "None", it seems counter-intuitive and possibly dangerous for a configuration library.

Would it make sense to add a constraint that if both cast and default options are used, then the default value must be of a valid cast type?

felciano commented 3 years ago

Just in case anyone else runs across this, this is an ugly workaround that likely gets the behavior you want:

MY_VAR = config("MY_VAR", cast=str, default=None)
if MY_VAR == "None": MY_VAR = None
henriquebastos commented 3 years ago

The default value should aways be a string so cast would work the same way with env values or default values.