Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion codegen/parser/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def parse_openapi_spec(source: "Source", override: "Override") -> OpenAPIData:
for path, new_schema in override.schema_overrides.items():
ref = str(httpx.URL(fragment=path))
logger.info(f"Applying schema override for {ref!r}")
merge_inplace(source.resolve_ref(ref).data, new_schema)
merge_inplace(source.resolve_ref(ref), new_schema)

_ot = _override_config.set(override)
_st = _schemas.set({})
Expand Down
35 changes: 26 additions & 9 deletions codegen/parser/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"id",
}

COPY_KEY = "<copy>"
UNSET_KEY = "<unset>"
ADD_KEY = "<add>"
REMOVE_KEY = "<remove>"
Expand Down Expand Up @@ -102,7 +103,19 @@ def build_prop_name(name: str) -> str:
return fix_reserved_words(snake_case(name))


def merge_dict(old: dict, new: dict):
def _handle_copy(source: "Source", new: dict):
if COPY_KEY not in new:
return
copy_from = new.pop(COPY_KEY)
if not isinstance(copy_from, str):
raise TypeError(f"{COPY_KEY} value must be a reference string")
copy_source = source.resolve_ref(copy_from)
target_name = source.pointer.parts[-1]
source.parent.data[target_name] = copy_source.data


def merge_dict(source: "Source", new: dict):
old = source.data
# make change inplace to make json point correct
for key, value in new.items():
# remove a field
Expand All @@ -115,12 +128,13 @@ def merge_dict(old: dict, new: dict):
old[key] = value
else:
try:
merge_inplace(old[key], value)
merge_inplace(source / key, value)
except TypeError:
old[key] = value


def merge_list(old: list, new: list | dict):
def merge_list(source: "Source", new: list | dict):
old = source.data
if isinstance(new, list):
old.clear()
old.extend(new)
Expand All @@ -132,13 +146,16 @@ def merge_list(old: list, new: list | dict):
old.extend(new[ADD_KEY])


def merge_inplace(old: Any, new: Any):
if isinstance(old, dict) and isinstance(new, dict):
merge_dict(old, new)
elif isinstance(old, list) and isinstance(new, list | dict):
merge_list(old, new)
def merge_inplace(source: "Source", new: Any):
if isinstance(new, dict):
_handle_copy(source, new)

if isinstance(source.data, dict) and isinstance(new, dict):
merge_dict(source, new)
elif isinstance(source.data, list) and isinstance(new, list | dict):
merge_list(source, new)
else:
raise TypeError(f"Cannot merge type {type(old)} with {type(new)}")
raise TypeError(f"Cannot merge type {type(source.data)} with {type(new)}")


def schema_from_source(source: "Source") -> oas.Schema:
Expand Down
8 changes: 8 additions & 0 deletions codegen/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ def pointer(self) -> JsonPointer:
def data(self) -> Any:
return self.pointer.resolve(self.root)

@property
def parent(self) -> "Source":
parts = self.pointer.get_parts()
if not parts:
raise ValueError("Root source has no parent")
fragment = JsonPointer.from_parts(parts[:-1]).path
return self.resolve_ref(str(httpx.URL(fragment=fragment)))

def get_root(self: "Source") -> "Source":
return Source(uri=self.uri.copy_with(fragment=""), root=self.root)

Expand Down
2 changes: 1 addition & 1 deletion docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ If you encounter an schema error, you can patch the schema by modifying the `pyp

In the `[tool.codegen.overrides.schema_overrides]` section, you can modify the schema using json pointer. The value will override the original schema.

Specially, if the json pointer points to a dictionary, you can use special value `<unset>` to remove the key from the dictionary. If the json pointer points to a array, you can use a list value to replace the original array. Or you can use a dict with key `<add>` and `<remove>` to add or remove items from the array.
Specially, if the json pointer points to a dictionary, you can use special value `<unset>` to remove the key from the dictionary. If the json pointer points to a array, you can use a list value to replace the original array. Or you can use a dict with key `<add>` and `<remove>` to add or remove items from the array. For any json pointer, you can use a dict with key "<copy>" to replace the pointer data by the value pointer's data.

Please add a comment to explain the reason for the patch if you want to submit a PR.

Expand Down
27 changes: 25 additions & 2 deletions githubkit/versions/ghec_v2022_11_28/models/group_0644.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class WebhookCodeScanningAlertReopenedPropAlert(GitHubModel):
)
dismissed_by: Union[
WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy, None
] = Field()
] = Field(title="User")
dismissed_comment: Missing[Union[Annotated[str, Field(max_length=280)], None]] = (
Field(
default=UNSET,
Expand Down Expand Up @@ -67,7 +67,30 @@ class WebhookCodeScanningAlertReopenedPropAlert(GitHubModel):


class WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy(GitHubModel):
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
"""User"""

avatar_url: Missing[str] = Field(default=UNSET)
deleted: Missing[bool] = Field(default=UNSET)
email: Missing[Union[str, None]] = Field(default=UNSET)
events_url: Missing[str] = Field(default=UNSET)
followers_url: Missing[str] = Field(default=UNSET)
following_url: Missing[str] = Field(default=UNSET)
gists_url: Missing[str] = Field(default=UNSET)
gravatar_id: Missing[str] = Field(default=UNSET)
html_url: Missing[str] = Field(default=UNSET)
id: int = Field()
login: str = Field()
name: Missing[str] = Field(default=UNSET)
node_id: Missing[str] = Field(default=UNSET)
organizations_url: Missing[str] = Field(default=UNSET)
received_events_url: Missing[str] = Field(default=UNSET)
repos_url: Missing[str] = Field(default=UNSET)
site_admin: Missing[bool] = Field(default=UNSET)
starred_url: Missing[str] = Field(default=UNSET)
subscriptions_url: Missing[str] = Field(default=UNSET)
type: Missing[Literal["Bot", "User", "Organization"]] = Field(default=UNSET)
url: Missing[str] = Field(default=UNSET)
user_view_type: Missing[str] = Field(default=UNSET)


class WebhookCodeScanningAlertReopenedPropAlertPropMostRecentInstance(GitHubModel):
Expand Down
50 changes: 48 additions & 2 deletions githubkit/versions/ghec_v2022_11_28/types/group_0644.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,59 @@ class WebhookCodeScanningAlertReopenedPropAlertTypeForResponse(TypedDict):


class WebhookCodeScanningAlertReopenedPropAlertPropDismissedByType(TypedDict):
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
"""User"""

avatar_url: NotRequired[str]
deleted: NotRequired[bool]
email: NotRequired[Union[str, None]]
events_url: NotRequired[str]
followers_url: NotRequired[str]
following_url: NotRequired[str]
gists_url: NotRequired[str]
gravatar_id: NotRequired[str]
html_url: NotRequired[str]
id: int
login: str
name: NotRequired[str]
node_id: NotRequired[str]
organizations_url: NotRequired[str]
received_events_url: NotRequired[str]
repos_url: NotRequired[str]
site_admin: NotRequired[bool]
starred_url: NotRequired[str]
subscriptions_url: NotRequired[str]
type: NotRequired[Literal["Bot", "User", "Organization"]]
url: NotRequired[str]
user_view_type: NotRequired[str]


class WebhookCodeScanningAlertReopenedPropAlertPropDismissedByTypeForResponse(
TypedDict
):
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
"""User"""

avatar_url: NotRequired[str]
deleted: NotRequired[bool]
email: NotRequired[Union[str, None]]
events_url: NotRequired[str]
followers_url: NotRequired[str]
following_url: NotRequired[str]
gists_url: NotRequired[str]
gravatar_id: NotRequired[str]
html_url: NotRequired[str]
id: int
login: str
name: NotRequired[str]
node_id: NotRequired[str]
organizations_url: NotRequired[str]
received_events_url: NotRequired[str]
repos_url: NotRequired[str]
site_admin: NotRequired[bool]
starred_url: NotRequired[str]
subscriptions_url: NotRequired[str]
type: NotRequired[Literal["Bot", "User", "Organization"]]
url: NotRequired[str]
user_view_type: NotRequired[str]


class WebhookCodeScanningAlertReopenedPropAlertPropMostRecentInstanceType(TypedDict):
Expand Down
27 changes: 25 additions & 2 deletions githubkit/versions/ghec_v2026_03_10/models/group_0643.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class WebhookCodeScanningAlertReopenedPropAlert(GitHubModel):
)
dismissed_by: Union[
WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy, None
] = Field()
] = Field(title="User")
dismissed_comment: Missing[Union[Annotated[str, Field(max_length=280)], None]] = (
Field(
default=UNSET,
Expand Down Expand Up @@ -67,7 +67,30 @@ class WebhookCodeScanningAlertReopenedPropAlert(GitHubModel):


class WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy(GitHubModel):
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
"""User"""

avatar_url: Missing[str] = Field(default=UNSET)
deleted: Missing[bool] = Field(default=UNSET)
email: Missing[Union[str, None]] = Field(default=UNSET)
events_url: Missing[str] = Field(default=UNSET)
followers_url: Missing[str] = Field(default=UNSET)
following_url: Missing[str] = Field(default=UNSET)
gists_url: Missing[str] = Field(default=UNSET)
gravatar_id: Missing[str] = Field(default=UNSET)
html_url: Missing[str] = Field(default=UNSET)
id: int = Field()
login: str = Field()
name: Missing[str] = Field(default=UNSET)
node_id: Missing[str] = Field(default=UNSET)
organizations_url: Missing[str] = Field(default=UNSET)
received_events_url: Missing[str] = Field(default=UNSET)
repos_url: Missing[str] = Field(default=UNSET)
site_admin: Missing[bool] = Field(default=UNSET)
starred_url: Missing[str] = Field(default=UNSET)
subscriptions_url: Missing[str] = Field(default=UNSET)
type: Missing[Literal["Bot", "User", "Organization"]] = Field(default=UNSET)
url: Missing[str] = Field(default=UNSET)
user_view_type: Missing[str] = Field(default=UNSET)


class WebhookCodeScanningAlertReopenedPropAlertPropMostRecentInstance(GitHubModel):
Expand Down
50 changes: 48 additions & 2 deletions githubkit/versions/ghec_v2026_03_10/types/group_0643.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,59 @@ class WebhookCodeScanningAlertReopenedPropAlertTypeForResponse(TypedDict):


class WebhookCodeScanningAlertReopenedPropAlertPropDismissedByType(TypedDict):
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
"""User"""

avatar_url: NotRequired[str]
deleted: NotRequired[bool]
email: NotRequired[Union[str, None]]
events_url: NotRequired[str]
followers_url: NotRequired[str]
following_url: NotRequired[str]
gists_url: NotRequired[str]
gravatar_id: NotRequired[str]
html_url: NotRequired[str]
id: int
login: str
name: NotRequired[str]
node_id: NotRequired[str]
organizations_url: NotRequired[str]
received_events_url: NotRequired[str]
repos_url: NotRequired[str]
site_admin: NotRequired[bool]
starred_url: NotRequired[str]
subscriptions_url: NotRequired[str]
type: NotRequired[Literal["Bot", "User", "Organization"]]
url: NotRequired[str]
user_view_type: NotRequired[str]


class WebhookCodeScanningAlertReopenedPropAlertPropDismissedByTypeForResponse(
TypedDict
):
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
"""User"""

avatar_url: NotRequired[str]
deleted: NotRequired[bool]
email: NotRequired[Union[str, None]]
events_url: NotRequired[str]
followers_url: NotRequired[str]
following_url: NotRequired[str]
gists_url: NotRequired[str]
gravatar_id: NotRequired[str]
html_url: NotRequired[str]
id: int
login: str
name: NotRequired[str]
node_id: NotRequired[str]
organizations_url: NotRequired[str]
received_events_url: NotRequired[str]
repos_url: NotRequired[str]
site_admin: NotRequired[bool]
starred_url: NotRequired[str]
subscriptions_url: NotRequired[str]
type: NotRequired[Literal["Bot", "User", "Organization"]]
url: NotRequired[str]
user_view_type: NotRequired[str]


class WebhookCodeScanningAlertReopenedPropAlertPropMostRecentInstanceType(TypedDict):
Expand Down
27 changes: 25 additions & 2 deletions githubkit/versions/v2022_11_28/models/group_0553.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class WebhookCodeScanningAlertReopenedPropAlert(GitHubModel):
)
dismissed_by: Union[
WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy, None
] = Field()
] = Field(title="User")
dismissed_comment: Missing[Union[Annotated[str, Field(max_length=280)], None]] = (
Field(
default=UNSET,
Expand Down Expand Up @@ -67,7 +67,30 @@ class WebhookCodeScanningAlertReopenedPropAlert(GitHubModel):


class WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy(GitHubModel):
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
"""User"""

avatar_url: Missing[str] = Field(default=UNSET)
deleted: Missing[bool] = Field(default=UNSET)
email: Missing[Union[str, None]] = Field(default=UNSET)
events_url: Missing[str] = Field(default=UNSET)
followers_url: Missing[str] = Field(default=UNSET)
following_url: Missing[str] = Field(default=UNSET)
gists_url: Missing[str] = Field(default=UNSET)
gravatar_id: Missing[str] = Field(default=UNSET)
html_url: Missing[str] = Field(default=UNSET)
id: int = Field()
login: str = Field()
name: Missing[str] = Field(default=UNSET)
node_id: Missing[str] = Field(default=UNSET)
organizations_url: Missing[str] = Field(default=UNSET)
received_events_url: Missing[str] = Field(default=UNSET)
repos_url: Missing[str] = Field(default=UNSET)
site_admin: Missing[bool] = Field(default=UNSET)
starred_url: Missing[str] = Field(default=UNSET)
subscriptions_url: Missing[str] = Field(default=UNSET)
type: Missing[Literal["Bot", "User", "Organization"]] = Field(default=UNSET)
url: Missing[str] = Field(default=UNSET)
user_view_type: Missing[str] = Field(default=UNSET)


class WebhookCodeScanningAlertReopenedPropAlertPropMostRecentInstance(GitHubModel):
Expand Down
Loading
Loading