Skip to content

added to_json method to DAEmpty class for JSON serialization#877

Merged
jhpyle merged 1 commit intojhpyle:masterfrom
jpagh:daempty-to-json
Jan 1, 2026
Merged

added to_json method to DAEmpty class for JSON serialization#877
jhpyle merged 1 commit intojhpyle:masterfrom
jpagh:daempty-to-json

Conversation

@jpagh
Copy link
Contributor

@jpagh jpagh commented Nov 16, 2025

I accidentally added a DAEmpty object to my interview dictionary, and now I can't "Show variables and values". I figured that since we added to_json() support that we might as well use it to avoid an error.

Error
TypeError: Object of type DAEmpty is not JSON serializable
Log
Traceback (most recent call last):
  File "/usr/share/docassemble/local3.12/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/docassemble/local3.12/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/docassemble/local3.12/lib/python3.12/site-packages/docassemble/webapp/server.py", line 6712, in get_variables
    return jsonify(success=True, variables=variables, steps=steps, encrypted=is_encrypted, uid=session_id, i=yaml_filename)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/docassemble/local3.12/lib/python3.12/site-packages/flask/json/__init__.py", line 170, in jsonify
    return current_app.json.response(*args, **kwargs)  # type: ignore[return-value]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/docassemble/local3.12/lib/python3.12/site-packages/flask/json/provider.py", line 214, in response
    f"{self.dumps(obj, **dump_args)}\n", mimetype=self.mimetype
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/docassemble/local3.12/lib/python3.12/site-packages/flask/json/provider.py", line 179, in dumps
    return json.dumps(obj, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
          ^^^^^^^^^^^
  File "/usr/lib/python3.12/json/encoder.py", line 200, in encode
    chunks = self.iterencode(o, _one_shot=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/json/encoder.py", line 258, in iterencode
    return _iterencode(o, 0)
           ^^^^^^^^^^^^^^^^^
  File "/usr/share/docassemble/local3.12/lib/python3.12/site-packages/flask/json/provider.py", line 121, in _default
    raise TypeError(f"Object of type {type(o).__name__} is not JSON serializable")
TypeError: Object of type DAEmpty is not JSON serializable

@jhpyle jhpyle merged commit fc52577 into jhpyle:master Jan 1, 2026
3 checks passed
BryceStevenWilley added a commit to SuffolkLITLab/docassemble-EFSPIntegration that referenced this pull request Jan 14, 2026
Should have already happened in jhpyle/docassemble#877,
but that patch isn't working for some reason. Interviews will still error when
trying to view the variables and values, but it shouldn't error when trying to
send the info with `requests` now.
BryceStevenWilley added a commit to SuffolkLITLab/docassemble-EFSPIntegration that referenced this pull request Jan 14, 2026
Should have already happened in jhpyle/docassemble#877,
but that patch isn't working for some reason. Interviews will still error when
trying to view the variables and values, but it shouldn't error when trying to
send the info with `requests` now.
BryceStevenWilley added a commit to SuffolkLITLab/docassemble-EFSPIntegration that referenced this pull request Jan 14, 2026
Should have already happened in jhpyle/docassemble#877,
but that patch isn't working for some reason. Interviews will still error when
trying to view the variables and values, but it shouldn't error when trying to
send the info with `requests` now.
BryceStevenWilley added a commit to SuffolkLITLab/docassemble that referenced this pull request Jan 14, 2026
Due to a slight change in jhpyle@0f5b49a
(not mentioned in the description, so I don't know what the intention was for changing it),
`as_dict()` is checked for and called before `to_json()` when `safe_json` is
converting objects to JSON serializeable types.

However, when calling `getattr()` on a `DAEmpty`, it will return another `DAEmpty` object.
Since `DAEmpty`s are also callable objects that return another `DAEmpty`, calling `as_dict()`
first will still leave a `DAEmpty` in the output, which is not safely JSON serializeable,
leaving the issues raised in jhpyle#877 unfixed.

Adding a special case for DAEmpty to call `to_json()` avoids this issue.
Other approaches that could fix the issue include:

* Just moving the `hasattr(the_object, "to_json")...` check before the `as_dict` one.
  While this is the simplest solution, it adds an implicit assumption in the code that
  will be easily missed on future refactorings of this function.
* Making sure that the results of calling `as_dict` are still JSON safe.
  This would cause an infinite recursion on DAEmptys, and either wouldn't fix error
  or would result in max level nested entries for DAEmptys.
* Add a `as_dict` function to DAEmpty. This would work, but `as_dict` isn't used
  elsewhere in docassemble code much.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants