commit 7c65f758839ee8ea683f95a3bc160d2f864ca236 (HEAD -> main)
Author: Steve Holden <steve@holdenweb.com>
Date:   Fri Feb 20 18:12:31 2026 +0000

36 failing tests, all with the same exception:

    AttributeError: property 'name' of 'BoundField' object has no setter

This all traces back to line 84 of bound_fields.py, where the code reads

    self.name = name

Overcoming debugging issues, I eventually discovered that te3xtual.dom.DOMNode
has a read-only name property, and since the BoundField is a Widget subclass,
an attempt to set its name triggers the property.



commit 2a841b9c2a58e0853329d9f37dfce18e9c391c19 (HEAD -> main)
Author: Steve Holden <steve@holdenweb.com>
Date:   Sat Feb 21 11:57:02 2026 +0000

Realised this was an indication a bundled BoundField widget wasn't the best
alternative I backtracked and had Sonnet 4.6 re-implement BoundField with no
dependecies on Textual. It once more got the signature for the type.__new__
method wrong, inverting the order of the base classes and the namespace, but
otherwise there were only three test failures, and 148 passes!

1. Ambiguous name detection failure.

TestFormMetaclass.test_name_collision_in_composition_raises:
E       Failed: DID NOT RAISE <class 'textual_wtf.exceptions.FormError'>
tests/test_forms.py:55: Failed

In passing I found this comment on forms.py line 41 somewhat troubling:

        # Inherit fields from base Form classes (in MRO order, earlier wins).

Should the code really be scanning the base fields in reverse order? That's
for later!

I realised that the code, although it checked for name collisions when adding
an embedded form's fields it did not do so when adding a simple field.
Rectifying this omission passed the test.



2. Test not providing app context as required.

TestBoundFieldCall.test_render_resets_rendered_flag
E           LookupError: <ContextVar name='active_app' at 0x1037c58a0>
.venv/lib/python3.12/site-packages/textual/message_pump.py:248: LookupError

which then led to

>                   raise NoActiveAppError()
E                   textual._context.NoActiveAppError
.venv/lib/python3.12/site-packages/textual/message_pump.py:255: NoActiveAppError

Without stack trace information all I have is two locations in Textual's code
for which my code has created an issue. Using `pytyest --tb=long` wasn't
helpful in this case because the traceback is then for the second exception
rather than the first.

Closer examination showed that the test was completely bogus - it was
expecting the fields' _rendered attribute to be cleared after a compose()
call, but that's not what's supposed to happen.

Moving the original test managed to shadow another equally useless test, so
they've both gone


3. Missing declaration

>           error = app.query_one(".field-error", Static)
                                                  ^^^^^^
E           UnboundLocalError: cannot access local variable 'Static' where it is not associated with a value
tests/test_integration.py:242: UnboundLocalError

This was quite an interesting one. Just by examining the error message was
perplexed as to why the symbol was being treated as a local variable. After
some relatively unexceptional code, Sonnet randomly inserted an import!
Here's the body of the test in question.

        async with app.run_test() as pilot:
            await pilot.click("#submit")
            error = app.query_one(".field-error", Static)
            assert error.display
        from textual.widgets import Static  # noqa (used above)

After modifying the imports at the head of the module to include Static, the
removal of the import statement meant that Static was now no longer local,
allowing the interpreter to use the already-imported symbol.