question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[bug] Lazy validation fails with TypeError: __call__() takes 2 positional arguments but 3 were given

See original GitHub issue

Describe the bug Tried to introduce Lazy Validators as described in https://www.dynaconf.com/validation/#computed-values i.e.

from dynaconf.utils.parse_conf import empty, Lazy

Validator("FOO", default=Lazy(empty, formatter=my_function))

First bug (documentation): The above fails with ImportError: cannot import name 'empty' from 'dynaconf.utils.parse_conf' –> “empty” seems to be now in dynaconf.utils.functional.empty

Second bug: Lazy Validator fails with TypeError: __call__() takes 2 positional arguments but 3 were given

To Reproduce Steps to reproduce the behavior:

from dynaconf.utils.parse_conf import Lazy
from dynaconf.utils.functional import empty

def lazy_foobar(s, v):
    return "foobar"

from dynaconf import Dynaconf
s = Dynaconf(
    validators=[Validator("FOOBAR", default=Lazy(empty, formatter=lazy_foobar)),],
)
print(s.FOOBAR)

stacktrace:

    print(s.FOOBAR)
  File "c:\ta\virtualenv\dconf\lib\site-packages\dynaconf\base.py", line 113, in __getattr__
    self._setup()
  File "c:\ta\virtualenv\dconf\lib\site-packages\dynaconf\base.py", line 164, in _setup
    settings_module=settings_module, **self._kwargs
  File "c:\ta\virtualenv\dconf\lib\site-packages\dynaconf\base.py", line 236, in __init__
    only=self._validate_only, exclude=self._validate_exclude
  File "c:\ta\virtualenv\dconf\lib\site-packages\dynaconf\validator.py", line 417, in validate
    validator.validate(self.settings, only=only, exclude=exclude)
  File "c:\ta\virtualenv\dconf\lib\site-packages\dynaconf\validator.py", line 198, in validate
    settings, settings.current_env, only=only, exclude=exclude
  File "c:\ta\virtualenv\dconf\lib\site-packages\dynaconf\validator.py", line 227, in _validate_items
    if callable(self.default)
TypeError: __call__() takes 2 positional arguments but 3 were given

Expected behavior Work as documented in https://www.dynaconf.com/validation/#computed-values

Environment (please complete the following information):

  • OS: Windows 10 Pro
  • Dynaconf Version: 3.1.7 (also 3.1.4)
  • Frameworks in use: N/A

Additional context Add any other context about the problem here.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
rochacbrunocommented, Oct 7, 2021

Hi @GibranHL0

My suggestions

on utils/parse_conf.py

# make the default value for Lazy to be an empty value
11  from dynaconf.utils.functional import empty
169  def __init__(self, value=empty, formatter=Formatters.python_formatter):

# accept a `validator_object` as named parameter and bind it to the context
178  def __call__(self, settings, validator_object=None):
         """LazyValue triggers format lazily."""
        self.settings = settings
        self.context["_validator_object"] = validator_object
        return self.formatter(self.value, **self.context)

Then, update the documentation on https://www.dynaconf.com/validation/#computed-values (docs/validation.md)

the correct way of using the computed lazy value must be

from dynaconf import Dynaconf, Validator
from dynaconf.utils.parse_conf import Lazy


def my_lazy_function(value, **context):
    """
    value: default value passed to the validator, defaults to `empty`
    context: a dictionary containing
             env: All the environment variables
             this: The settings instance
    """
    # Hypothetical example
    if env.get("HOSTNAME") == "localhost":
        result = f"{this.server.name}/local"
    else:
        result = f"{this.server.name}/{value}"
    return result


settings = Dynaconf(
    validators=[
        Validator("FOOBAR", default=Lazy("default_optional_value", formatter=my_lazy_function))
    ]
)

# When the value is first accessed, then the my_lazy_function will be called
print(settings.FOOBAR)
1reaction
GibranHL0commented, Oct 4, 2021

Hi 👋

I’d like to be assigned to this issue and give it a try.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Python TypeError takes 2 positional arguments but 3 are given
This code is supposed to calculate the shortest Manhattan distance between a node state (character position) and the nearest food location.
Read more >
[CT-672] _relations_cache_for_schemas() takes 2 positional ...
First time install of DBT (dbt-postgres) on Ubuntu. ... Log files don't seem to give hints on the cause of the error. How...
Read more >
pydantic validator __init__() takes exactly 1 positional ...
I see a type error, when I try to use it as is in the training code. pydantic.main.BaseModel.__init__ TypeError: __init__() takes exactly 1...
Read more >
Error in keras when trying to recreate example from website
Error in py_call_impl(callable, dots$args, dots$keywords) : TypeError: update() takes from 2 to 3 positional arguments but 4 were given.
Read more >
How to solve the error? ' __init__() takes 2 positional ...
' __init__() takes 2 positional arguments but 3 were given'. I have an assignment to create a regression model for a given datasets....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found