refactor(ia): use Any as argument instead of PyObject#33
Conversation
Reviewer's GuideRefactors various Ignition/Jython scripting APIs and their stubs to use the more general Any type for variadic *args parameters instead of PyObject, keeping **kwargs types unchanged, and keeps runtime code behavior the same by only updating type comments and .pyi signatures. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 3 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="stubs/stubs/com/inductiveautomation/ignition/common/script/abc/__init__.pyi" line_range="38" />
<code_context>
self, pyKey: PyObject, def_: Optional[PyObject] = ...
) -> PyObject: ...
- def update(self, *args: PyObject, **kwargs: Union[str, unicode]) -> None: ...
+ def update(self, *args: Any, **kwargs: Union[str, unicode]) -> None: ...
def __setitem__(self, pyKey: PyObject, pyValue: PyObject) -> None: ...
def __delitem__(self, pyKey: PyObject) -> None: ...
</code_context>
<issue_to_address>
**suggestion:** The `kwargs` type on `update` is narrower than Python `dict.update` semantics.
Since `*args` is now `Any`, consider widening `**kwargs` from `Union[str, unicode]` to `Any` as well to better match `dict.update` semantics. Callers may reasonably pass non-string keyword values (numbers, booleans, nested structures), and the current text-only type could cause unnecessary type-checking issues for valid usages.
```suggestion
def update(self, *args: Any, **kwargs: Any) -> None: ...
```
</issue_to_address>
### Comment 2
<location path="stubs/stubs/com/inductiveautomation/ignition/common/script/abc/__init__.pyi" line_range="48" />
<code_context>
def pop(self, index: Optional[int] = ...) -> PyObject: ...
def remove(self, element: PyObject) -> None: ...
- def sort(self, *args: PyObject, **kwargs: Union[str, unicode]) -> None: ...
+ def sort(self, *args: Any, **kwargs: Union[str, unicode]) -> None: ...
def __add__(self, other: PyObject) -> PyObject: ...
def __imul__(self, other: PyObject) -> PyObject: ...
</code_context>
<issue_to_address>
**suggestion:** Consider loosening `kwargs` for `sort` to better reflect typical Python `list.sort` usage.
For `MutableJythonSequence.sort`, `**kwargs: Union[str, unicode]` doesn’t match typical `list.sort` usage (e.g. `sort(key=..., reverse=True)`), where values aren’t limited to strings. Consider `**kwargs: Any`, or explicitly typing parameters (`key: Optional[Callable[..., Any]] = ..., reverse: bool = ...`) to better reflect Python semantics and improve typing usability.
Suggested implementation:
```
def insert(self, index: int, element: PyObject) -> None: ...
def pop(self, index: Optional[int] = ...) -> PyObject: ...
def remove(self, element: PyObject) -> None: ...
def sort(
self,
key: Optional[Callable[..., Any]] = ...,
reverse: bool = ...,
) -> None: ...
def __add__(self, other: PyObject) -> PyObject: ...
def __imul__(self, other: PyObject) -> PyObject: ...
```
If `Callable` is not already imported in this stub file, add it to the existing `from typing import ...` line, e.g.:
- `from typing import Any, Optional, Union`
+ `from typing import Any, Optional, Union, Callable`
This will ensure the new `Callable` annotation for `sort` is properly recognized.
</issue_to_address>
### Comment 3
<location path="stubs/stubs/com/inductiveautomation/ignition/common/script/builtin/http/__init__.pyi" line_range="15-18" />
<code_context>
- ) -> Promise: ...
- def get(self, *args: PyObject, **kwargs: Union[str, unicode]) -> Response: ...
- def getAsync(self, *args: PyObject, **kwargs: Union[str, unicode]) -> Promise: ...
+ def delete(self, *args: Any, **kwargs: Union[str, unicode]) -> Response: ...
+ def deleteAsync(self, *args: Any, **kwargs: Union[str, unicode]) -> Promise: ...
+ def get(self, *args: Any, **kwargs: Union[str, unicode]) -> Response: ...
+ def getAsync(self, *args: Any, **kwargs: Union[str, unicode]) -> Promise: ...
def getConnectTimeout(self) -> long: ...
def getCookieManager(self) -> CookieManager: ...
</code_context>
<issue_to_address>
**suggestion:** `kwargs` for HTTP methods may be too strictly typed as `Union[str, unicode]`.
Given common kwargs like `timeout`, `headers`, `data`, or `json` are often non-strings (e.g., numbers, dicts), constraining `**kwargs` to `Union[str, unicode]` is likely too narrow for an HTTP client. Consider widening to `Any` or a more appropriate mapping type to better match real usage and avoid unnecessary type-checker complaints.
Suggested implementation:
```
class JythonHttpClient(Object):
def delete(self, *args: Any, **kwargs: Any) -> Response: ...
def deleteAsync(self, *args: Any, **kwargs: Any) -> Promise: ...
def get(self, *args: Any, **kwargs: Any) -> Response: ...
def getAsync(self, *args: Any, **kwargs: Any) -> Promise: ...
```
```
class Promise(Object):
def cancel(self) -> bool: ...
def get(self, *args: Any, **kwargs: Any) -> Any: ...
def getFuture(self) -> CompletableFuture: ...
def handleException(self, callback: PyObject) -> Promise: ...
def isDone(self) -> bool: ...
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| self, pyKey: PyObject, def_: Optional[PyObject] = ... | ||
| ) -> PyObject: ... | ||
| def update(self, *args: PyObject, **kwargs: Union[str, unicode]) -> None: ... | ||
| def update(self, *args: Any, **kwargs: Union[str, unicode]) -> None: ... |
There was a problem hiding this comment.
suggestion: The kwargs type on update is narrower than Python dict.update semantics.
Since *args is now Any, consider widening **kwargs from Union[str, unicode] to Any as well to better match dict.update semantics. Callers may reasonably pass non-string keyword values (numbers, booleans, nested structures), and the current text-only type could cause unnecessary type-checking issues for valid usages.
| def update(self, *args: Any, **kwargs: Union[str, unicode]) -> None: ... | |
| def update(self, *args: Any, **kwargs: Any) -> None: ... |
| def pop(self, index: Optional[int] = ...) -> PyObject: ... | ||
| def remove(self, element: PyObject) -> None: ... | ||
| def sort(self, *args: PyObject, **kwargs: Union[str, unicode]) -> None: ... | ||
| def sort(self, *args: Any, **kwargs: Union[str, unicode]) -> None: ... |
There was a problem hiding this comment.
suggestion: Consider loosening kwargs for sort to better reflect typical Python list.sort usage.
For MutableJythonSequence.sort, **kwargs: Union[str, unicode] doesn’t match typical list.sort usage (e.g. sort(key=..., reverse=True)), where values aren’t limited to strings. Consider **kwargs: Any, or explicitly typing parameters (key: Optional[Callable[..., Any]] = ..., reverse: bool = ...) to better reflect Python semantics and improve typing usability.
Suggested implementation:
def insert(self, index: int, element: PyObject) -> None: ...
def pop(self, index: Optional[int] = ...) -> PyObject: ...
def remove(self, element: PyObject) -> None: ...
def sort(
self,
key: Optional[Callable[..., Any]] = ...,
reverse: bool = ...,
) -> None: ...
def __add__(self, other: PyObject) -> PyObject: ...
def __imul__(self, other: PyObject) -> PyObject: ...
If Callable is not already imported in this stub file, add it to the existing from typing import ... line, e.g.:
from typing import Any, Optional, Union
from typing import Any, Optional, Union, Callable
This will ensure the new Callable annotation for sort is properly recognized.
| def delete(self, *args: Any, **kwargs: Union[str, unicode]) -> Response: ... | ||
| def deleteAsync(self, *args: Any, **kwargs: Union[str, unicode]) -> Promise: ... | ||
| def get(self, *args: Any, **kwargs: Union[str, unicode]) -> Response: ... | ||
| def getAsync(self, *args: Any, **kwargs: Union[str, unicode]) -> Promise: ... |
There was a problem hiding this comment.
suggestion: kwargs for HTTP methods may be too strictly typed as Union[str, unicode].
Given common kwargs like timeout, headers, data, or json are often non-strings (e.g., numbers, dicts), constraining **kwargs to Union[str, unicode] is likely too narrow for an HTTP client. Consider widening to Any or a more appropriate mapping type to better match real usage and avoid unnecessary type-checker complaints.
Suggested implementation:
class JythonHttpClient(Object):
def delete(self, *args: Any, **kwargs: Any) -> Response: ...
def deleteAsync(self, *args: Any, **kwargs: Any) -> Promise: ...
def get(self, *args: Any, **kwargs: Any) -> Response: ...
def getAsync(self, *args: Any, **kwargs: Any) -> Promise: ...
class Promise(Object):
def cancel(self) -> bool: ...
def get(self, *args: Any, **kwargs: Any) -> Any: ...
def getFuture(self) -> CompletableFuture: ...
def handleException(self, callback: PyObject) -> Promise: ...
def isDone(self) -> bool: ...
Summary by Sourcery
Enhancements: