Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] AttributeError: 'Getattr' object has no attribute 'name' 1.10.0-a1 in _get_doc_blocks during parsing #11275

Open
2 tasks done
MisterWheatley opened this issue Feb 5, 2025 · 3 comments
Assignees
Labels
bug Something isn't working pre-regression Regression not yet in a stable release

Comments

@MisterWheatley
Copy link

MisterWheatley commented Feb 5, 2025

Is this a new bug in dbt-core?

  • I believe this is a new bug in dbt-core
  • I have searched the existing issues, and I could not find an existing issue for this bug

Current Behavior

I believe there is a simple bug in the following line when interacting with an edge case involving templated doc blocks.

and node.node.name == "doc"

This crashes the parsing of the manifest.

Expected Behavior

The project to be able to parse and use templated doc blocks as before.

Steps To Reproduce

  • Install v.1.10.0-a1 version
    Create templated doc block
{% docs test_doc %}
This is a test for {test_name}
{% enddocs %}

Use in model docs as follows:

version: 2
models:
  - name: my_model
    description: "{{ docs('test_doc').format(test_name = 'abc') }}"

Relevant log output

Directly from dbt Cloud IDE:

08:54:33 Traceback (most recent call last):
  File "/venv/dbt-sha-fea52c8b2d6f9cd66a57fc334c198c23887d533f/lib/python3.11/site-packages/dbt/cli/requires.py", line 223, in wrapper
    result, success = func(*args, **kwargs)
                      ^^^^^^^^^^^^^^^^^^^^^
  File "/venv/dbt-sha-fea52c8b2d6f9cd66a57fc334c198c23887d533f/lib/python3.11/site-packages/dbt/cli/requires.py", line 133, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/venv/dbt-sha-fea52c8b2d6f9cd66a57fc334c198c23887d533f/lib/python3.11/site-packages/dbt/cli/requires.py", line 335, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/venv/dbt-sha-fea52c8b2d6f9cd66a57fc334c198c23887d533f/lib/python3.11/site-packages/dbt/cli/requires.py", line 362, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/venv/dbt-sha-fea52c8b2d6f9cd66a57fc334c198c23887d533f/lib/python3.11/site-packages/dbt/cli/requires.py", line 414, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/venv/dbt-sha-fea52c8b2d6f9cd66a57fc334c198c23887d533f/lib/python3.11/site-packages/dbt/cli/requires.py", line 430, in wrapper
    setup_manifest(
  File "/venv/dbt-sha-fea52c8b2d6f9cd66a57fc334c198c23887d533f/lib/python3.11/site-packages/dbt/cli/requires.py", line 479, in setup_manifest
    ctx.obj["manifest"] = parse_manifest(
                          ^^^^^^^^^^^^^^^
  File "/venv/dbt-sha-fea52c8b2d6f9cd66a57fc334c198c23887d533f/lib/python3.11/site-packages/dbt/parser/manifest.py", line 2172, in parse_manifest
    manifest = ManifestLoader.get_full_manifest(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv/dbt-sha-fea52c8b2d6f9cd66a57fc334c198c23887d533f/lib/python3.11/site-packages/dbt/parser/manifest.py", line 330, in get_full_manifest
    manifest = loader.load()
               ^^^^^^^^^^^^^
  File "/venv/dbt-sha-fea52c8b2d6f9cd66a57fc334c198c23887d533f/lib/python3.11/site-packages/dbt/parser/manifest.py", line 490, in load
    self.process_docs(self.root_project)
  File "/venv/dbt-sha-fea52c8b2d6f9cd66a57fc334c198c23887d533f/lib/python3.11/site-packages/dbt/parser/manifest.py", line 1299, in process_docs
    _process_docs_for_node(ctx, node, self.manifest)
  File "/venv/dbt-sha-fea52c8b2d6f9cd66a57fc334c198c23887d533f/lib/python3.11/site-packages/dbt/parser/manifest.py", line 1765, in _process_docs_for_node
    column.doc_blocks = _get_doc_blocks(column.description, manifest, node.package_name)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv/dbt-sha-fea52c8b2d6f9cd66a57fc334c198c23887d533f/lib/python3.11/site-packages/dbt/parser/manifest.py", line 1731, in _get_doc_blocks
    and node.node.name == "doc"
        ^^^^^^^^^^^^^^
AttributeError: 'Getattr' object has no attribute 'name'

Environment

- OS: N/A
- Python: 3.11
- dbt: 1.10.0-a1

Which database adapter are you using with dbt?

bigquery

Additional Context

I believe this might be an un-expected edge-case/behaviour and if that is the case, then please just confirm that.

@MisterWheatley MisterWheatley added bug Something isn't working triage labels Feb 5, 2025
@jtcohen6
Copy link
Contributor

@MisterWheatley Thanks for opening!

I think this was an unintended consequence of this change:

It's not strictly documented / guaranteed that you can call .format() on docs blocks — though it is an implicit behavior of Jinja (strings are Python strings, and they can call Python string methods) — but the use of docs blocks actually isn't necessary to produce this bug. A simple string.format() will raise the same exception.

models:
  - name: my_model
    description: "{{ 'some string with {test_name}'.format(test_name = 'abc') }}"

The problem is that this is a callable (Call), and the node has a node, but the node's node doesn't have a name:

if (
isinstance(node, Call)
and hasattr(node, "node")
and hasattr(node, "args")
and node.node.name == "doc"
):

I think we avoid the exception by adding an extra line of defense:

            if (
                isinstance(node, Call)
                and hasattr(node, "node")
                and hasattr(node, "args")
               #
                and hasattr(node.node, "name")
                and node.node.name == "doc"
            ):

But we need to make sure that the original repro case passes — a call to a doc block and a call to .format()

cc @zqureshi

@jtcohen6 jtcohen6 added pre-regression Regression not yet in a stable release and removed triage labels Feb 13, 2025
@aranke
Copy link
Member

aranke commented Feb 13, 2025

@MisterWheatley Thanks for the prompt and detailed bug report!

I've rolled back the change in dbt Cloud, so if you restart your IDE this issue should not reoccur.

I'm going to work on a fix for this issue in the next few days, which will go out to dbt Cloud next week.

Thanks once again, and let me know if you have further issues.

@aranke aranke self-assigned this Feb 13, 2025
@MisterWheatley
Copy link
Author

@aranke and @jtcohen6 Thanks for the fast follow up and appreciate the further investigation.

If you need anything further from me, please don't hesitate to reach out.

In terms of not being guaranteed to use string formatting in doc blocks, it might be worth investigating an extension of the existing doc block that looks something like:

{{ doc('<doc_block_nam>, <doc_block_package_name>, fmt={key1="abc",...}) }}'

to provide the functionality in an official way, but I am not familiar enough with the deep internal workings to evaluate the effort needed to do this.

Incidentally, I don't think that the two argument form of doc block macro usage is documented anywhere (i.e. using a doc block from a package)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working pre-regression Regression not yet in a stable release
Projects
None yet
Development

No branches or pull requests

3 participants