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.

Serialization fails with no attribute __qualname__

See original GitHub issue

Description

Serialization fails when a task uses an instance of a callable class as a cache_validator.

AttributeError                            Traceback (most recent call last)
~/.virtualenvs/iguazu-venv/lib/python3.7/site-packages/prefect/utilities/serialization.py in _serialize(self, value, attr, obj, **kwargs)
    379         try:
--> 380             qual_name = to_qualified_name(value)
    381         except:

~/.virtualenvs/iguazu-venv/lib/python3.7/site-packages/prefect/utilities/serialization.py in to_qualified_name(obj)
     36     """
---> 37     return obj.__module__ + "." + obj.__qualname__
     38

AttributeError: 'Validator' object has no attribute '__qualname__'

During handling of the above exception, another exception occurred:

... 

~/.virtualenvs/iguazu-venv/lib/python3.7/site-packages/prefect/utilities/serialization.py in _serialize(self, value, attr, obj, **kwargs)
    383                 raise ValidationError("Invalid function reference: {}".format(value))
    384             else:
--> 385                 return qual_name
    386
    387         # sort matches such that the longest / most specific match comes first

UnboundLocalError: local variable 'qual_name' referenced before assignment

More details:

I found a small bug on the serialization code. In prefect.utilities.serialization.StatefulFunctionReference :

    def _serialize(self, value, attr, obj, **kwargs):  # type: ignore
        if value is None and self.allow_none:
            return None

        try:
            qual_name = to_qualified_name(value)
        except:
            if self.reject_invalid:
                raise ValidationError("Invalid function reference: {}".format(value))
            else:
                return qual_name
        ... more code ...

There is a return with an undefined variable (because when this fails, there is no qual_name variable.

I am not sure if this is a problem of that particular function, or is from to_qualified_name, which fails with an input instance instead of a class. The culprit from my side is that I have a task with cache_validator=SomeClass() … where SomeClass is a class with a __call__ member function, instead of using a cache_validator that is a function. I am attaching an example on the reproduction section.

Expected Behavior

Since cache_validator in a task is type-annotated to a Callable, I expected to be able to use an instance of a callable class without issues when serializing.

Reproduction

import datetime

from prefect import Flow, Task
from prefect.environments.storage import Docker


class Validator:
    def __init__(self):
        print('I am a validator, ready to say false al the time')
    def __call__(self, state, inputs, parameters):
        return False

my_task = Task(cache_validator=Validator(), cache_for=datetime.timedelta(days=1))
with Flow('example') as flow:
    my_task()

flow.storage = Docker()
flow.register()

Environment

$ prefect diagnostics
{
  "config_overrides": {},
  "env_vars": [],
  "system_information": {
    "platform": "Darwin-19.3.0-x86_64-i386-64bit",
    "prefect_version": "0.10.4",
    "python_version": "3.7.5"
  }
}

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5

github_iconTop GitHub Comments

2reactions
jcristcommented, May 5, 2020

Independently from our workaround / refactor, I think the undefined variable is still a bug, don’t you think?

Definitely. I’ve added a PR at #2491 to provide a better error message in this case. Your example now raises:

ValidationError: Invalid function reference, function required, got <__main__.Validator object at 0x10a892050>
0reactions
jcristcommented, May 5, 2020

With #2491 we raise a better error message. We plan in the future to relax this restriction, but it seemed prudent to give a more meaningful error in the meantime. See #2499 for future work.

Read more comments on GitHub >

github_iconTop Results From Across the Web

AttributeError: 'Overview' object has no attribute '__qualname__'
7 - made all the changes, but when I start server I have this error. AttributeError: 'Overview' object has no attribute '__qualname__'
Read more >
object has no attribute '__qualname__' after v3.1.0 · Issue #7856
Describe the bug After updating Sphinx to 3.1.0 and 3.1.1, getting this error: object has no attribute '__qualname__' To Reproduce Steps to ...
Read more >
Issue 13577: __qualname__ is not present on builtin ...
I was recently experimenting with the new PEP 3155 '__qualname__ implementation and noticed that '__qualname__' is not present on builtin ...
Read more >
qualname__ error when using advanced caching - Streamlit
Hi all! I'm trying to cache a function generating a pandas dataframe (, which includes an object of the module Bio.pairwise2 of the...
Read more >
AttributeError: 'tuple' object has no attribute 'serialize'
... object has no attribute 'serialize' Even if I replace the execute(loaded_plan ) with execute(plan) it still outputs the same error which ...
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