Skip to content

Commit f981011

Browse files
authored
🐛 Fix: code-scanning-alert event dismissed_by type error (#286)
1 parent 1b6919f commit f981011

14 files changed

Lines changed: 333 additions & 27 deletions

File tree

codegen/parser/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def parse_openapi_spec(source: "Source", override: "Override") -> OpenAPIData:
5656
for path, new_schema in override.schema_overrides.items():
5757
ref = str(httpx.URL(fragment=path))
5858
logger.info(f"Applying schema override for {ref!r}")
59-
merge_inplace(source.resolve_ref(ref).data, new_schema)
59+
merge_inplace(source.resolve_ref(ref), new_schema)
6060

6161
_ot = _override_config.set(override)
6262
_st = _schemas.set({})

codegen/parser/utils.py

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"id",
2424
}
2525

26+
COPY_KEY = "<copy>"
2627
UNSET_KEY = "<unset>"
2728
ADD_KEY = "<add>"
2829
REMOVE_KEY = "<remove>"
@@ -102,7 +103,19 @@ def build_prop_name(name: str) -> str:
102103
return fix_reserved_words(snake_case(name))
103104

104105

105-
def merge_dict(old: dict, new: dict):
106+
def _handle_copy(source: "Source", new: dict):
107+
if COPY_KEY not in new:
108+
return
109+
copy_from = new.pop(COPY_KEY)
110+
if not isinstance(copy_from, str):
111+
raise TypeError(f"{COPY_KEY} value must be a reference string")
112+
copy_source = source.resolve_ref(copy_from)
113+
target_name = source.pointer.parts[-1]
114+
source.parent.data[target_name] = copy_source.data
115+
116+
117+
def merge_dict(source: "Source", new: dict):
118+
old = source.data
106119
# make change inplace to make json point correct
107120
for key, value in new.items():
108121
# remove a field
@@ -115,12 +128,13 @@ def merge_dict(old: dict, new: dict):
115128
old[key] = value
116129
else:
117130
try:
118-
merge_inplace(old[key], value)
131+
merge_inplace(source / key, value)
119132
except TypeError:
120133
old[key] = value
121134

122135

123-
def merge_list(old: list, new: list | dict):
136+
def merge_list(source: "Source", new: list | dict):
137+
old = source.data
124138
if isinstance(new, list):
125139
old.clear()
126140
old.extend(new)
@@ -132,13 +146,16 @@ def merge_list(old: list, new: list | dict):
132146
old.extend(new[ADD_KEY])
133147

134148

135-
def merge_inplace(old: Any, new: Any):
136-
if isinstance(old, dict) and isinstance(new, dict):
137-
merge_dict(old, new)
138-
elif isinstance(old, list) and isinstance(new, list | dict):
139-
merge_list(old, new)
149+
def merge_inplace(source: "Source", new: Any):
150+
if isinstance(new, dict):
151+
_handle_copy(source, new)
152+
153+
if isinstance(source.data, dict) and isinstance(new, dict):
154+
merge_dict(source, new)
155+
elif isinstance(source.data, list) and isinstance(new, list | dict):
156+
merge_list(source, new)
140157
else:
141-
raise TypeError(f"Cannot merge type {type(old)} with {type(new)}")
158+
raise TypeError(f"Cannot merge type {type(source.data)} with {type(new)}")
142159

143160

144161
def schema_from_source(source: "Source") -> oas.Schema:

codegen/source.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ def pointer(self) -> JsonPointer:
2929
def data(self) -> Any:
3030
return self.pointer.resolve(self.root)
3131

32+
@property
33+
def parent(self) -> "Source":
34+
parts = self.pointer.get_parts()
35+
if not parts:
36+
raise ValueError("Root source has no parent")
37+
fragment = JsonPointer.from_parts(parts[:-1]).path
38+
return self.resolve_ref(str(httpx.URL(fragment=fragment)))
39+
3240
def get_root(self: "Source") -> "Source":
3341
return Source(uri=self.uri.copy_with(fragment=""), root=self.root)
3442

docs/contributing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ If you encounter an schema error, you can patch the schema by modifying the `pyp
3636

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

39-
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.
39+
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.
4040

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

githubkit/versions/ghec_v2022_11_28/models/group_0644.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class WebhookCodeScanningAlertReopenedPropAlert(GitHubModel):
3636
)
3737
dismissed_by: Union[
3838
WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy, None
39-
] = Field()
39+
] = Field(title="User")
4040
dismissed_comment: Missing[Union[Annotated[str, Field(max_length=280)], None]] = (
4141
Field(
4242
default=UNSET,
@@ -67,7 +67,30 @@ class WebhookCodeScanningAlertReopenedPropAlert(GitHubModel):
6767

6868

6969
class WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy(GitHubModel):
70-
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
70+
"""User"""
71+
72+
avatar_url: Missing[str] = Field(default=UNSET)
73+
deleted: Missing[bool] = Field(default=UNSET)
74+
email: Missing[Union[str, None]] = Field(default=UNSET)
75+
events_url: Missing[str] = Field(default=UNSET)
76+
followers_url: Missing[str] = Field(default=UNSET)
77+
following_url: Missing[str] = Field(default=UNSET)
78+
gists_url: Missing[str] = Field(default=UNSET)
79+
gravatar_id: Missing[str] = Field(default=UNSET)
80+
html_url: Missing[str] = Field(default=UNSET)
81+
id: int = Field()
82+
login: str = Field()
83+
name: Missing[str] = Field(default=UNSET)
84+
node_id: Missing[str] = Field(default=UNSET)
85+
organizations_url: Missing[str] = Field(default=UNSET)
86+
received_events_url: Missing[str] = Field(default=UNSET)
87+
repos_url: Missing[str] = Field(default=UNSET)
88+
site_admin: Missing[bool] = Field(default=UNSET)
89+
starred_url: Missing[str] = Field(default=UNSET)
90+
subscriptions_url: Missing[str] = Field(default=UNSET)
91+
type: Missing[Literal["Bot", "User", "Organization"]] = Field(default=UNSET)
92+
url: Missing[str] = Field(default=UNSET)
93+
user_view_type: Missing[str] = Field(default=UNSET)
7194

7295

7396
class WebhookCodeScanningAlertReopenedPropAlertPropMostRecentInstance(GitHubModel):

githubkit/versions/ghec_v2022_11_28/types/group_0644.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,59 @@ class WebhookCodeScanningAlertReopenedPropAlertTypeForResponse(TypedDict):
7878

7979

8080
class WebhookCodeScanningAlertReopenedPropAlertPropDismissedByType(TypedDict):
81-
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
81+
"""User"""
82+
83+
avatar_url: NotRequired[str]
84+
deleted: NotRequired[bool]
85+
email: NotRequired[Union[str, None]]
86+
events_url: NotRequired[str]
87+
followers_url: NotRequired[str]
88+
following_url: NotRequired[str]
89+
gists_url: NotRequired[str]
90+
gravatar_id: NotRequired[str]
91+
html_url: NotRequired[str]
92+
id: int
93+
login: str
94+
name: NotRequired[str]
95+
node_id: NotRequired[str]
96+
organizations_url: NotRequired[str]
97+
received_events_url: NotRequired[str]
98+
repos_url: NotRequired[str]
99+
site_admin: NotRequired[bool]
100+
starred_url: NotRequired[str]
101+
subscriptions_url: NotRequired[str]
102+
type: NotRequired[Literal["Bot", "User", "Organization"]]
103+
url: NotRequired[str]
104+
user_view_type: NotRequired[str]
82105

83106

84107
class WebhookCodeScanningAlertReopenedPropAlertPropDismissedByTypeForResponse(
85108
TypedDict
86109
):
87-
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
110+
"""User"""
111+
112+
avatar_url: NotRequired[str]
113+
deleted: NotRequired[bool]
114+
email: NotRequired[Union[str, None]]
115+
events_url: NotRequired[str]
116+
followers_url: NotRequired[str]
117+
following_url: NotRequired[str]
118+
gists_url: NotRequired[str]
119+
gravatar_id: NotRequired[str]
120+
html_url: NotRequired[str]
121+
id: int
122+
login: str
123+
name: NotRequired[str]
124+
node_id: NotRequired[str]
125+
organizations_url: NotRequired[str]
126+
received_events_url: NotRequired[str]
127+
repos_url: NotRequired[str]
128+
site_admin: NotRequired[bool]
129+
starred_url: NotRequired[str]
130+
subscriptions_url: NotRequired[str]
131+
type: NotRequired[Literal["Bot", "User", "Organization"]]
132+
url: NotRequired[str]
133+
user_view_type: NotRequired[str]
88134

89135

90136
class WebhookCodeScanningAlertReopenedPropAlertPropMostRecentInstanceType(TypedDict):

githubkit/versions/ghec_v2026_03_10/models/group_0643.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class WebhookCodeScanningAlertReopenedPropAlert(GitHubModel):
3636
)
3737
dismissed_by: Union[
3838
WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy, None
39-
] = Field()
39+
] = Field(title="User")
4040
dismissed_comment: Missing[Union[Annotated[str, Field(max_length=280)], None]] = (
4141
Field(
4242
default=UNSET,
@@ -67,7 +67,30 @@ class WebhookCodeScanningAlertReopenedPropAlert(GitHubModel):
6767

6868

6969
class WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy(GitHubModel):
70-
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
70+
"""User"""
71+
72+
avatar_url: Missing[str] = Field(default=UNSET)
73+
deleted: Missing[bool] = Field(default=UNSET)
74+
email: Missing[Union[str, None]] = Field(default=UNSET)
75+
events_url: Missing[str] = Field(default=UNSET)
76+
followers_url: Missing[str] = Field(default=UNSET)
77+
following_url: Missing[str] = Field(default=UNSET)
78+
gists_url: Missing[str] = Field(default=UNSET)
79+
gravatar_id: Missing[str] = Field(default=UNSET)
80+
html_url: Missing[str] = Field(default=UNSET)
81+
id: int = Field()
82+
login: str = Field()
83+
name: Missing[str] = Field(default=UNSET)
84+
node_id: Missing[str] = Field(default=UNSET)
85+
organizations_url: Missing[str] = Field(default=UNSET)
86+
received_events_url: Missing[str] = Field(default=UNSET)
87+
repos_url: Missing[str] = Field(default=UNSET)
88+
site_admin: Missing[bool] = Field(default=UNSET)
89+
starred_url: Missing[str] = Field(default=UNSET)
90+
subscriptions_url: Missing[str] = Field(default=UNSET)
91+
type: Missing[Literal["Bot", "User", "Organization"]] = Field(default=UNSET)
92+
url: Missing[str] = Field(default=UNSET)
93+
user_view_type: Missing[str] = Field(default=UNSET)
7194

7295

7396
class WebhookCodeScanningAlertReopenedPropAlertPropMostRecentInstance(GitHubModel):

githubkit/versions/ghec_v2026_03_10/types/group_0643.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,59 @@ class WebhookCodeScanningAlertReopenedPropAlertTypeForResponse(TypedDict):
7878

7979

8080
class WebhookCodeScanningAlertReopenedPropAlertPropDismissedByType(TypedDict):
81-
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
81+
"""User"""
82+
83+
avatar_url: NotRequired[str]
84+
deleted: NotRequired[bool]
85+
email: NotRequired[Union[str, None]]
86+
events_url: NotRequired[str]
87+
followers_url: NotRequired[str]
88+
following_url: NotRequired[str]
89+
gists_url: NotRequired[str]
90+
gravatar_id: NotRequired[str]
91+
html_url: NotRequired[str]
92+
id: int
93+
login: str
94+
name: NotRequired[str]
95+
node_id: NotRequired[str]
96+
organizations_url: NotRequired[str]
97+
received_events_url: NotRequired[str]
98+
repos_url: NotRequired[str]
99+
site_admin: NotRequired[bool]
100+
starred_url: NotRequired[str]
101+
subscriptions_url: NotRequired[str]
102+
type: NotRequired[Literal["Bot", "User", "Organization"]]
103+
url: NotRequired[str]
104+
user_view_type: NotRequired[str]
82105

83106

84107
class WebhookCodeScanningAlertReopenedPropAlertPropDismissedByTypeForResponse(
85108
TypedDict
86109
):
87-
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
110+
"""User"""
111+
112+
avatar_url: NotRequired[str]
113+
deleted: NotRequired[bool]
114+
email: NotRequired[Union[str, None]]
115+
events_url: NotRequired[str]
116+
followers_url: NotRequired[str]
117+
following_url: NotRequired[str]
118+
gists_url: NotRequired[str]
119+
gravatar_id: NotRequired[str]
120+
html_url: NotRequired[str]
121+
id: int
122+
login: str
123+
name: NotRequired[str]
124+
node_id: NotRequired[str]
125+
organizations_url: NotRequired[str]
126+
received_events_url: NotRequired[str]
127+
repos_url: NotRequired[str]
128+
site_admin: NotRequired[bool]
129+
starred_url: NotRequired[str]
130+
subscriptions_url: NotRequired[str]
131+
type: NotRequired[Literal["Bot", "User", "Organization"]]
132+
url: NotRequired[str]
133+
user_view_type: NotRequired[str]
88134

89135

90136
class WebhookCodeScanningAlertReopenedPropAlertPropMostRecentInstanceType(TypedDict):

githubkit/versions/v2022_11_28/models/group_0553.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class WebhookCodeScanningAlertReopenedPropAlert(GitHubModel):
3636
)
3737
dismissed_by: Union[
3838
WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy, None
39-
] = Field()
39+
] = Field(title="User")
4040
dismissed_comment: Missing[Union[Annotated[str, Field(max_length=280)], None]] = (
4141
Field(
4242
default=UNSET,
@@ -67,7 +67,30 @@ class WebhookCodeScanningAlertReopenedPropAlert(GitHubModel):
6767

6868

6969
class WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy(GitHubModel):
70-
"""WebhookCodeScanningAlertReopenedPropAlertPropDismissedBy"""
70+
"""User"""
71+
72+
avatar_url: Missing[str] = Field(default=UNSET)
73+
deleted: Missing[bool] = Field(default=UNSET)
74+
email: Missing[Union[str, None]] = Field(default=UNSET)
75+
events_url: Missing[str] = Field(default=UNSET)
76+
followers_url: Missing[str] = Field(default=UNSET)
77+
following_url: Missing[str] = Field(default=UNSET)
78+
gists_url: Missing[str] = Field(default=UNSET)
79+
gravatar_id: Missing[str] = Field(default=UNSET)
80+
html_url: Missing[str] = Field(default=UNSET)
81+
id: int = Field()
82+
login: str = Field()
83+
name: Missing[str] = Field(default=UNSET)
84+
node_id: Missing[str] = Field(default=UNSET)
85+
organizations_url: Missing[str] = Field(default=UNSET)
86+
received_events_url: Missing[str] = Field(default=UNSET)
87+
repos_url: Missing[str] = Field(default=UNSET)
88+
site_admin: Missing[bool] = Field(default=UNSET)
89+
starred_url: Missing[str] = Field(default=UNSET)
90+
subscriptions_url: Missing[str] = Field(default=UNSET)
91+
type: Missing[Literal["Bot", "User", "Organization"]] = Field(default=UNSET)
92+
url: Missing[str] = Field(default=UNSET)
93+
user_view_type: Missing[str] = Field(default=UNSET)
7194

7295

7396
class WebhookCodeScanningAlertReopenedPropAlertPropMostRecentInstance(GitHubModel):

0 commit comments

Comments
 (0)