Skip to content

Instantly share code, notes, and snippets.

@jhannah
Last active October 21, 2023 18:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhannah/c8113c86f083c6b6645c7d0997d786ee to your computer and use it in GitHub Desktop.
Save jhannah/c8113c86f083c6b6645c7d0997d786ee to your computer and use it in GitHub Desktop.
TypeError("'_cffi_backend.FFI' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')
Full stack dump for https://stackoverflow.com/questions/75503034/valueerror-typeerror-cffi-backend-ffi-object-is-not-iterable-typeerror
✗ pytest --pythonwarnings ignore::DeprecationWarning -k 'test_answer_answer_answer_result' -rPF
================================================= test session starts ==================================================
platform darwin -- Python 3.11.6, pytest-7.4.2, pluggy-1.3.0
plugins: anyio-3.7.1
collected 39 items / 38 deselected / 1 selected
routers/test_api.py F [100%]
======================================================= FAILURES =======================================================
___________________________________________ test_answer_answer_answer_result ___________________________________________
obj = <_cffi_backend.FFI object at 0x10688c200>, include = None, exclude = None, by_alias = True, exclude_unset = False
exclude_defaults = False, exclude_none = False, custom_encoder = {}, sqlalchemy_safe = True
def jsonable_encoder(
obj: Any,
include: Optional[IncEx] = None,
exclude: Optional[IncEx] = None,
by_alias: bool = True,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
custom_encoder: Optional[Dict[Any, Callable[[Any], Any]]] = None,
sqlalchemy_safe: bool = True,
) -> Any:
custom_encoder = custom_encoder or {}
if custom_encoder:
if type(obj) in custom_encoder:
return custom_encoder[type(obj)](obj)
else:
for encoder_type, encoder_instance in custom_encoder.items():
if isinstance(obj, encoder_type):
return encoder_instance(obj)
if include is not None and not isinstance(include, (set, dict)):
include = set(include)
if exclude is not None and not isinstance(exclude, (set, dict)):
exclude = set(exclude)
if isinstance(obj, BaseModel):
# TODO: remove when deprecating Pydantic v1
encoders: Dict[Any, Any] = {}
if not PYDANTIC_V2:
encoders = getattr(obj.__config__, "json_encoders", {}) # type: ignore[attr-defined]
if custom_encoder:
encoders.update(custom_encoder)
obj_dict = _model_dump(
obj,
mode="json",
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_none=exclude_none,
exclude_defaults=exclude_defaults,
)
if "__root__" in obj_dict:
obj_dict = obj_dict["__root__"]
return jsonable_encoder(
obj_dict,
exclude_none=exclude_none,
exclude_defaults=exclude_defaults,
# TODO: remove when deprecating Pydantic v1
custom_encoder=encoders,
sqlalchemy_safe=sqlalchemy_safe,
)
if dataclasses.is_dataclass(obj):
obj_dict = dataclasses.asdict(obj)
return jsonable_encoder(
obj_dict,
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)
if isinstance(obj, Enum):
return obj.value
if isinstance(obj, PurePath):
return str(obj)
if isinstance(obj, (str, int, float, type(None))):
return obj
if isinstance(obj, dict):
encoded_dict = {}
allowed_keys = set(obj.keys())
if include is not None:
allowed_keys &= set(include)
if exclude is not None:
allowed_keys -= set(exclude)
for key, value in obj.items():
if (
(
not sqlalchemy_safe
or (not isinstance(key, str))
or (not key.startswith("_sa"))
)
and (value is not None or not exclude_none)
and key in allowed_keys
):
encoded_key = jsonable_encoder(
key,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_none=exclude_none,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)
encoded_value = jsonable_encoder(
value,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_none=exclude_none,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)
encoded_dict[encoded_key] = encoded_value
return encoded_dict
if isinstance(obj, (list, set, frozenset, GeneratorType, tuple, deque)):
encoded_list = []
for item in obj:
encoded_list.append(
jsonable_encoder(
item,
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)
)
return encoded_list
if type(obj) in ENCODERS_BY_TYPE:
return ENCODERS_BY_TYPE[type(obj)](obj)
for encoder, classes_tuple in encoders_by_class_tuples.items():
if isinstance(obj, classes_tuple):
return encoder(obj)
try:
> data = dict(obj)
E TypeError: '_cffi_backend.FFI' object is not iterable
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:230: TypeError
During handling of the above exception, another exception occurred:
obj = <_cffi_backend.FFI object at 0x10688c200>, include = None, exclude = None, by_alias = True, exclude_unset = False
exclude_defaults = False, exclude_none = False, custom_encoder = {}, sqlalchemy_safe = True
def jsonable_encoder(
obj: Any,
include: Optional[IncEx] = None,
exclude: Optional[IncEx] = None,
by_alias: bool = True,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
custom_encoder: Optional[Dict[Any, Callable[[Any], Any]]] = None,
sqlalchemy_safe: bool = True,
) -> Any:
custom_encoder = custom_encoder or {}
if custom_encoder:
if type(obj) in custom_encoder:
return custom_encoder[type(obj)](obj)
else:
for encoder_type, encoder_instance in custom_encoder.items():
if isinstance(obj, encoder_type):
return encoder_instance(obj)
if include is not None and not isinstance(include, (set, dict)):
include = set(include)
if exclude is not None and not isinstance(exclude, (set, dict)):
exclude = set(exclude)
if isinstance(obj, BaseModel):
# TODO: remove when deprecating Pydantic v1
encoders: Dict[Any, Any] = {}
if not PYDANTIC_V2:
encoders = getattr(obj.__config__, "json_encoders", {}) # type: ignore[attr-defined]
if custom_encoder:
encoders.update(custom_encoder)
obj_dict = _model_dump(
obj,
mode="json",
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_none=exclude_none,
exclude_defaults=exclude_defaults,
)
if "__root__" in obj_dict:
obj_dict = obj_dict["__root__"]
return jsonable_encoder(
obj_dict,
exclude_none=exclude_none,
exclude_defaults=exclude_defaults,
# TODO: remove when deprecating Pydantic v1
custom_encoder=encoders,
sqlalchemy_safe=sqlalchemy_safe,
)
if dataclasses.is_dataclass(obj):
obj_dict = dataclasses.asdict(obj)
return jsonable_encoder(
obj_dict,
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)
if isinstance(obj, Enum):
return obj.value
if isinstance(obj, PurePath):
return str(obj)
if isinstance(obj, (str, int, float, type(None))):
return obj
if isinstance(obj, dict):
encoded_dict = {}
allowed_keys = set(obj.keys())
if include is not None:
allowed_keys &= set(include)
if exclude is not None:
allowed_keys -= set(exclude)
for key, value in obj.items():
if (
(
not sqlalchemy_safe
or (not isinstance(key, str))
or (not key.startswith("_sa"))
)
and (value is not None or not exclude_none)
and key in allowed_keys
):
encoded_key = jsonable_encoder(
key,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_none=exclude_none,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)
encoded_value = jsonable_encoder(
value,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_none=exclude_none,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)
encoded_dict[encoded_key] = encoded_value
return encoded_dict
if isinstance(obj, (list, set, frozenset, GeneratorType, tuple, deque)):
encoded_list = []
for item in obj:
encoded_list.append(
jsonable_encoder(
item,
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)
)
return encoded_list
if type(obj) in ENCODERS_BY_TYPE:
return ENCODERS_BY_TYPE[type(obj)](obj)
for encoder, classes_tuple in encoders_by_class_tuples.items():
if isinstance(obj, classes_tuple):
return encoder(obj)
try:
data = dict(obj)
except Exception as e:
errors: List[Exception] = []
errors.append(e)
try:
> data = vars(obj)
E TypeError: vars() argument must have __dict__ attribute
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:235: TypeError
The above exception was the direct cause of the following exception:
def test_answer_answer_answer_result():
for question_id in range(0, 3):
req = {
"user_id": user_id,
"question_id": question_id,
"answer": question_id * 2, # just some arbitrary but different number
"seconds": 3 * question_id + 1 # just some arbitrary but different number
}
print("JAY", req)
> res = client.post(url_prefix + "/" + quiz_id + "/answer", json=req)
routers/test_api.py:134:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python3.11/site-packages/starlette/testclient.py:590: in post
return super().post(
/usr/local/lib/python3.11/site-packages/httpx/_client.py:1132: in post
return self.request(
/usr/local/lib/python3.11/site-packages/starlette/testclient.py:465: in request
return super().request(
/usr/local/lib/python3.11/site-packages/httpx/_client.py:814: in request
return self.send(request, auth=auth, follow_redirects=follow_redirects)
/usr/local/lib/python3.11/site-packages/httpx/_client.py:901: in send
response = self._send_handling_auth(
/usr/local/lib/python3.11/site-packages/httpx/_client.py:929: in _send_handling_auth
response = self._send_handling_redirects(
/usr/local/lib/python3.11/site-packages/httpx/_client.py:966: in _send_handling_redirects
response = self._send_single_request(request)
/usr/local/lib/python3.11/site-packages/httpx/_client.py:1002: in _send_single_request
response = transport.handle_request(request)
/usr/local/lib/python3.11/site-packages/starlette/testclient.py:342: in handle_request
raise exc
/usr/local/lib/python3.11/site-packages/starlette/testclient.py:339: in handle_request
portal.call(self.app, scope, receive, send)
/usr/local/lib/python3.11/site-packages/anyio/from_thread.py:277: in call
return cast(T_Retval, self.start_task_soon(func, *args).result())
/usr/local/Cellar/python@3.11/3.11.6/Frameworks/Python.framework/Versions/3.11/lib/python3.11/concurrent/futures/_base.py:456: in result
return self.__get_result()
/usr/local/Cellar/python@3.11/3.11.6/Frameworks/Python.framework/Versions/3.11/lib/python3.11/concurrent/futures/_base.py:401: in __get_result
raise self._exception
/usr/local/lib/python3.11/site-packages/anyio/from_thread.py:217: in _call_func
retval = await retval
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/applications.py:292: in __call__
await super().__call__(scope, receive, send)
/usr/local/lib/python3.11/site-packages/starlette/applications.py:122: in __call__
await self.middleware_stack(scope, receive, send)
/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py:184: in __call__
raise exc
/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py:162: in __call__
await self.app(scope, receive, _send)
/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py:83: in __call__
await self.app(scope, receive, send)
/usr/local/lib/python3.11/site-packages/starlette/middleware/exceptions.py:79: in __call__
raise exc
/usr/local/lib/python3.11/site-packages/starlette/middleware/exceptions.py:68: in __call__
await self.app(scope, receive, sender)
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/middleware/asyncexitstack.py:20: in __call__
raise e
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/middleware/asyncexitstack.py:17: in __call__
await self.app(scope, receive, send)
/usr/local/lib/python3.11/site-packages/starlette/routing.py:718: in __call__
await route.handle(scope, receive, send)
/usr/local/lib/python3.11/site-packages/starlette/routing.py:276: in handle
await self.app(scope, receive, send)
/usr/local/lib/python3.11/site-packages/starlette/routing.py:66: in app
response = await func(request)
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/routing.py:291: in app
content = await serialize_response(
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/routing.py:179: in serialize_response
return jsonable_encoder(response_content)
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:239: in jsonable_encoder
return jsonable_encoder(
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:195: in jsonable_encoder
encoded_value = jsonable_encoder(
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:239: in jsonable_encoder
return jsonable_encoder(
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:195: in jsonable_encoder
encoded_value = jsonable_encoder(
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:239: in jsonable_encoder
return jsonable_encoder(
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:195: in jsonable_encoder
encoded_value = jsonable_encoder(
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:239: in jsonable_encoder
return jsonable_encoder(
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:195: in jsonable_encoder
encoded_value = jsonable_encoder(
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:239: in jsonable_encoder
return jsonable_encoder(
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:195: in jsonable_encoder
encoded_value = jsonable_encoder(
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:239: in jsonable_encoder
return jsonable_encoder(
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:195: in jsonable_encoder
encoded_value = jsonable_encoder(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
obj = <_cffi_backend.FFI object at 0x10688c200>, include = None, exclude = None, by_alias = True, exclude_unset = False
exclude_defaults = False, exclude_none = False, custom_encoder = {}, sqlalchemy_safe = True
def jsonable_encoder(
obj: Any,
include: Optional[IncEx] = None,
exclude: Optional[IncEx] = None,
by_alias: bool = True,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
custom_encoder: Optional[Dict[Any, Callable[[Any], Any]]] = None,
sqlalchemy_safe: bool = True,
) -> Any:
custom_encoder = custom_encoder or {}
if custom_encoder:
if type(obj) in custom_encoder:
return custom_encoder[type(obj)](obj)
else:
for encoder_type, encoder_instance in custom_encoder.items():
if isinstance(obj, encoder_type):
return encoder_instance(obj)
if include is not None and not isinstance(include, (set, dict)):
include = set(include)
if exclude is not None and not isinstance(exclude, (set, dict)):
exclude = set(exclude)
if isinstance(obj, BaseModel):
# TODO: remove when deprecating Pydantic v1
encoders: Dict[Any, Any] = {}
if not PYDANTIC_V2:
encoders = getattr(obj.__config__, "json_encoders", {}) # type: ignore[attr-defined]
if custom_encoder:
encoders.update(custom_encoder)
obj_dict = _model_dump(
obj,
mode="json",
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_none=exclude_none,
exclude_defaults=exclude_defaults,
)
if "__root__" in obj_dict:
obj_dict = obj_dict["__root__"]
return jsonable_encoder(
obj_dict,
exclude_none=exclude_none,
exclude_defaults=exclude_defaults,
# TODO: remove when deprecating Pydantic v1
custom_encoder=encoders,
sqlalchemy_safe=sqlalchemy_safe,
)
if dataclasses.is_dataclass(obj):
obj_dict = dataclasses.asdict(obj)
return jsonable_encoder(
obj_dict,
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)
if isinstance(obj, Enum):
return obj.value
if isinstance(obj, PurePath):
return str(obj)
if isinstance(obj, (str, int, float, type(None))):
return obj
if isinstance(obj, dict):
encoded_dict = {}
allowed_keys = set(obj.keys())
if include is not None:
allowed_keys &= set(include)
if exclude is not None:
allowed_keys -= set(exclude)
for key, value in obj.items():
if (
(
not sqlalchemy_safe
or (not isinstance(key, str))
or (not key.startswith("_sa"))
)
and (value is not None or not exclude_none)
and key in allowed_keys
):
encoded_key = jsonable_encoder(
key,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_none=exclude_none,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)
encoded_value = jsonable_encoder(
value,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_none=exclude_none,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)
encoded_dict[encoded_key] = encoded_value
return encoded_dict
if isinstance(obj, (list, set, frozenset, GeneratorType, tuple, deque)):
encoded_list = []
for item in obj:
encoded_list.append(
jsonable_encoder(
item,
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)
)
return encoded_list
if type(obj) in ENCODERS_BY_TYPE:
return ENCODERS_BY_TYPE[type(obj)](obj)
for encoder, classes_tuple in encoders_by_class_tuples.items():
if isinstance(obj, classes_tuple):
return encoder(obj)
try:
data = dict(obj)
except Exception as e:
errors: List[Exception] = []
errors.append(e)
try:
data = vars(obj)
except Exception as e:
errors.append(e)
> raise ValueError(errors) from e
E ValueError: [TypeError("'_cffi_backend.FFI' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]
../../../../Library/Python/3.11/lib/python/site-packages/fastapi/encoders.py:238: ValueError
------------------------------------------------- Captured stdout call -------------------------------------------------
JAY {'user_id': 'jhannah_33GnxYH', 'question_id': 0, 'answer': 0, 'seconds': 1}
=============================================== short test summary info ================================================
FAILED routers/test_api.py::test_answer_answer_answer_result - ValueError: [TypeError("'_cffi_backend.FFI' object is not iterable"), TypeError('vars() argument must have __dict__...
=========================================== 1 failed, 38 deselected in 2.99s ===========================================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment