Skip to content

Commit

Permalink
Check if object is SQLAlchemy before dataclass
Browse files Browse the repository at this point in the history
  • Loading branch information
Kludex committed May 1, 2024
1 parent 5c6ee64 commit c9cac79
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 9 deletions.
4 changes: 2 additions & 2 deletions logfire/_internal/json_encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,12 @@ def to_json_value(o: Any, seen: set[int]) -> JsonValue:
return {
key if isinstance(key, str) else safe_repr(key): to_json_value(value, seen) for key, value in o.items()
} # type: ignore
elif is_sqlalchemy(o):
return _get_sqlalchemy_data(o, seen)
elif dataclasses.is_dataclass(o):
return {f.name: to_json_value(getattr(o, f.name), seen) for f in dataclasses.fields(o)}
elif is_attrs(o):
return _get_attrs_data(o, seen)
elif is_sqlalchemy(o):
return _get_sqlalchemy_data(o, seen)

# Check the class type and its superclasses for a matching encoder
for base in o.__class__.__mro__[:-1]:
Expand Down
4 changes: 2 additions & 2 deletions logfire/_internal/json_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,12 @@ def create_json_schema(obj: Any, seen: set[int]) -> JsonDict:
return _array_schema(obj, seen)
elif isinstance(obj, Mapping):
return _mapping_schema(obj, seen)
elif is_sqlalchemy(obj):
return _sqlalchemy_schema(obj, seen)
elif dataclasses.is_dataclass(obj):
return _dataclass_schema(obj, seen)
elif is_attrs(obj):
return _attrs_schema(obj, seen)
elif is_sqlalchemy(obj):
return _sqlalchemy_schema(obj, seen)

global _type_to_schema
_type_to_schema = _type_to_schema or type_to_schema()
Expand Down
9 changes: 4 additions & 5 deletions tests/test_json_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
import pandas
import pytest
from attrs import define
from dirty_equals import IsJson, IsStr
from dirty_equals import IsJson
from inline_snapshot import snapshot
from pydantic import AnyUrl, BaseModel, ConfigDict, FilePath, NameEmail, SecretBytes, SecretStr
from pydantic.dataclasses import dataclass as pydantic_dataclass
from sqlalchemy import String, create_engine
from sqlalchemy.orm import DeclarativeBase, Mapped, Session, mapped_column
from sqlalchemy.orm.decl_api import MappedAsDataclass

import logfire
from logfire.testing import TestExporter
Expand Down Expand Up @@ -829,7 +830,7 @@ def test_log_non_scalar_args(


def test_log_sqlalchemy_class(exporter: TestExporter) -> None:
class Base(DeclarativeBase):
class Base(MappedAsDataclass, DeclarativeBase):
pass

class Model(Base):
Expand Down Expand Up @@ -903,9 +904,7 @@ def __init__(self, id: int, name: str):
'logfire.span_type': 'log',
'logfire.level_num': 9,
'logfire.msg_template': 'test message {var=}',
'logfire.msg': IsStr(
regex='test message var=<tests.test_json_args.test_log_sqlalchemy_class.<locals>.Model object at .*'
),
'logfire.msg': "test message var=test_log_sqlalchemy_class.<locals>.Model(id=1, name='test name')",
'code.filepath': 'test_json_args.py',
'code.function': 'test_log_sqlalchemy_class',
'code.lineno': 123,
Expand Down

0 comments on commit c9cac79

Please sign in to comment.