doloopwhile / pyjq

A Python binding for ./jq
MIT License
196 stars 30 forks source link

Implement support for dataclasses #83

Closed klimkin closed 1 year ago

klimkin commented 1 year ago

Enables use of jq on dataclass hierarchies without loosing the type information.

Treat dataclasses as dictionaries with __class__ field. This is different from using dataclasses.asdict() in how the results contain the dataclass objects.

Example:

from dataclasses import dataclass, asdict

@dataclass
class Parameter:
    name: str
    value: str

@dataclass
class Commit:
    parameters: list[Parameter]
    id: str

data = Commit(
    parameters=[
        Parameter(name="PKG_TAG_NAME", value="trunk"),
        Parameter(name="GIT_COMMIT", value="master"),
        Parameter(name="TRIGGERED_JOB", value="trunk-buildall"),
    ],
    id="2013-12-27_00-09-37",
)

import pyjq
script = pyjq.compile('.parameters[] | select(.name == "GIT_COMMIT")')
print("dataclass:", script.first(data))
print("asdict:   ", script.first(asdict(data)))

Output:

dataclass: Parameter(name='GIT_COMMIT', value='master')
asdict:    {'name': 'GIT_COMMIT', 'value': 'master'}

Note reserving __class__ key can be a breaking change (as any other metadata field), if a dictionary uses the field for a different purpose.

klimkin commented 1 year ago

Pulled off the PR due to the breaking changes for structures already using __class__ keys.