AnswerDotAI / AnswerDotAI/ghapi
Same ghapi version returns different results depending on fastcore version (JSON `null` → empty `AttrDict`)
- Dominant language
- Python
- Stars
- 685
- Forks
- 70
- Avg merge
- 1m
- Merged PRs (30d)
- 2
Description
### Summary
When using the same ghapi version, the return value of API calls changes depending on the fastcore dependency version.
Specifically, JSON `null` values from the GitHub REST API (e.g. repository `description`) are returned as:
- `None` with `fastcore==1.8.16`
- empty `fastcore.basics.AttrDict` (`{}`) with `fastcore==1.11.2`
This breaks the semantic meaning of the API response and causes downstream issues (e.g. database storage, business logic).
### Why this is a problem
- GitHub API explicitly defines `description: null` as “no value”
- In Python, this should map to `None`
- `{}` (empty mapping) has a different semantic meaning than `None`
- The behavior changes without changing the ghapi version, only by upgrading a dependency
From a user’s perspective, this means:
> The same ghapi version produces different API results depending on dependency resolution
This breaks API contract stability and reproducibility.
### Environment
Component | Version
-- | --
ghapi | 1.0.8
fastcore (local) | 1.8.16
fastcore (sam) | 1.11.2
Python | 3.10.19
### Reproduction Code
```python
from ghapi.core import GhApi
api = GhApi(token="*******", owner="ORG_NAME")
batch = api.repos.list_for_org("ORG_NAME", per_page=1, page=1)
r0 = batch[0]
print("item:", r0.get("description"), type(r0.get("description")))
print("attr:", r0.description, type(r0.description))
print("has key:", "description" in r0)
```
### Actual Results
With `fastcore==1.11.2`
```shell
item: {}
attr: {}
has key: True
```
With `fastcore==1.8.16`
```shell
item: None
attr: None
has key: True
```
### Expected Behavior
JSON `null` values from the GitHub API should consistently map to Python `None`, regardless of fastcore version.
At minimum, ghapi should:
- Preserve the semantic meaning of `null`
- Or pin / constrain fastcore versions to avoid silent behavior changes
### Additional Notes
- The conversion appears to happen during `fastcore.dict2obj` processing
- ghapi currently forwards this behavior directly to users
- This is not a database or SQLAlchemy issue — the value is already `{}` immediately after the ghapi call
This behavior change is unexpected, breaking, and difficult to detect, especially in data ingestion pipelines.
I believe this is worth addressing either in ghapi itself or through tighter fastcore integration.
Thanks for your work on ghapi.
Contributor guide
Assessment
This issue has not been assessed yet.