Compatible stubs for Pythonista 3.4+ - #5
Conversation
* some stubs updated * project tree changed to typeshed-like * switching to the pyproject.toml * updated CI (can publish to properly configured trusted publisher * version number changed to 3.4.0 (3.4.x is a minimal supported Pythonista version, the patch-number is a stubs version for a current pythonista version)
Reviewer's GuideThis PR refactors the project to a typeshed‐style layout, migrates build and package metadata to pyproject.toml, overhauls CI to use uv + ruff/mypy with a publish workflow, and replaces the old setup.py stub roster with comprehensive .pyi stubs for Pythonista 3.4+ APIs. Entity relationship diagram for new Pythonista stub moduleserDiagram
"pythonista_stubs" ||--o{ "appex" : contains
"pythonista_stubs" ||--o{ "clipboard" : contains
"pythonista_stubs" ||--o{ "console" : contains
"pythonista_stubs" ||--o{ "editor" : contains
"pythonista_stubs" ||--o{ "reminders" : contains
"pythonista_stubs" ||--o{ "sound" : contains
"pythonista_stubs" ||--o{ "speech" : contains
"pythonista_stubs" ||--o{ "ui" : contains
"pythonista_stubs" ||--o{ "canvas" : contains
"pythonista_stubs" ||--o{ "contacts" : contains
"pythonista_stubs" ||--o{ "dialogs" : contains
"pythonista_stubs" ||--o{ "keychain" : contains
"pythonista_stubs" ||--o{ "linguistictagger" : contains
"pythonista_stubs" ||--o{ "location" : contains
"pythonista_stubs" ||--o{ "motion" : contains
"pythonista_stubs" ||--o{ "notification" : contains
"pythonista_stubs" ||--o{ "objc_util" : contains
"pythonista_stubs" ||--o{ "photos" : contains
"pythonista_stubs" ||--o{ "shortcuts" : contains
"pythonista_stubs" ||--o{ "cb" : contains
"pythonista_stubs" ||--o{ "keyboard" : contains
"pythonista_stubs" ||--o{ "__init__" : contains
"pythonista_stubs" ||--o{ "_cb" : contains
"cb" }o--|| "_cb" : imports
"dialogs" }o--|| "console" : imports
"dialogs" }o--|| "ui" : imports
"appex" }o--|| "ui" : imports
"appex" }o--|| "PIL.Image" : imports
"clipboard" }o--|| "PIL.Image" : imports
"photos" }o--|| "PIL.Image" : imports
"photos" }o--|| "ui" : imports
Class diagram for new and refactored Pythonista stub typesclassDiagram
class Asset {
+get_image(original: bool)
+get_image_data(original: bool)
+get_ui_image(size, crop)
+edit_content(jpeg_path)
+delete()
+revert()
local_id: str
pixel_width: int
pixel_height: int
media_type: "image"|"video"
media_subtypes: List[str]
creation_date: datetime
modification_date: datetime
hidden: bool
favorite: bool
duration: float
location: dict
can_edit_content: bool
can_edit_properties: bool
can_delete: bool
}
class AssetCollection {
+delete()
+add_assets(assets)
+remove_assets(assets)
assets: List[Asset]
local_id: str
title: str
type: "album"|"smart_album"|"moment"
subtype: str
start_date: datetime
end_date: datetime
can_delete: bool
can_add_assets: bool
can_remove_assets: bool
can_rename: bool
}
AssetCollection "1" o-- "*" Asset
class Reminder {
+save()
alarms: List[Alarm]
completed: bool
completion_date: datetime
due_date: datetime
notes: str
priority: int
title: str
url: str
}
class Alarm {
date: datetime
location: tuple
proximity: "enter"|"leave"|"none"
}
Reminder "*" o-- "*" Alarm
class Calendar {
+save()
title: str
identifier: str
}
Calendar "1" o-- "*" Reminder
class Person {
address: List[Tuple[str, Dict[str, str]]]
birthday: datetime
creation_date: datetime
department: str
email: List[Tuple[str, str]]
first_name: str
full_name: str
id: int
image_data: bytes
job_title: str
last_name: str
middle_name: str
modification_date: datetime
nickname: str
note: str
organization: str
phone: List[Tuple[str, str]]
related_names: List[Tuple[str, str]]
social_profile: List[Tuple[str, Dict[str, str]]]
url: List[Tuple[str, str]]
vcard: str
}
class Group {
name: str
id: int
}
Group "1" o-- "*" Person
class Effect {
+stop()
looping: bool
pan: float
pitch: float
position: tuple
volume: float
}
class Player {
+play()
+stop()
+pause()
current_time: float
duration: float
finished_handler: Callable
number_of_loops: int
playing: bool
pan: float
}
class Recorder {
+record(duration)
+stop()
+pause()
current_time: float
recording: bool
meters: dict
}
class MIDIPlayer {
+play()
+stop()
current_time: float
duration: float
rate: float
}
class ObjCClass {
+__init__(name: str)
}
class ObjCInstance {
+__init__(ptr)
}
class ObjCBlock {
+__init__(func, restype, argtypes)
}
class CentralManager {
+scan_for_peripherals()
+stop_scan()
+connect_peripheral(p)
+cancel_peripheral_connection(p)
state: int
}
class Peripheral {
manufacturer_data: bytes
name: str
uuid: str
state: int
services: List[Service]
+discover_services()
+discover_characteristics(service)
+set_notify_value(characteristic, flag)
+write_characteristic_value(characteristic, data, with_response)
+read_characteristic_value(characteristic)
}
class Service {
characteristics: List[Characteristic]
primary: bool
uuid: str
}
class Characteristic {
properties: int
value: bytes
uuid: str
notifying: bool
}
CentralManager "1" o-- "*" Peripheral
Peripheral "1" o-- "*" Service
Service "1" o-- "*" Characteristic
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Warning Rate limit exceeded@o-murphy has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 23 minutes and 26 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (39)
WalkthroughThis update restructures the Pythonista stubs package, replacing legacy stub files with a new, unified set under Changes
Sequence Diagram(s)sequenceDiagram
participant Developer
participant GitHub Actions
participant PyPI
Developer->>GitHub Actions: Push, PR, Release, or Manual Trigger
GitHub Actions->>GitHub Actions: Run 'testing' job (setup, lint, type-check)
GitHub Actions->>GitHub Actions: On release, run 'publish' job (build, publish)
GitHub Actions->>PyPI: Publish package (on release event)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~35 minutes Poem
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Summary of Changes
Hello @o-murphy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
I've refactored the Pythonista stubs project to enhance compatibility with Pythonista 3.4+ and modernize its build and dependency management. This involved restructuring the stub files into a more organized, typeshed-like layout and migrating the project configuration to pyproject.toml. These changes aim to improve the development experience by providing clearer type hints and a more standardized project setup, while also updating the version and CI processes for better release management.
Highlights
- Stub File Restructuring and Updates: The project's stub files have been updated and reorganized into a
typeshed-like structure under a newpythonista_stubsdirectory. This improves consistency and maintainability for type hints. - Modernized Project Configuration with pyproject.toml: The project has transitioned from
setup.pyandmypy.inito a modernpyproject.tomlfor all project configuration, including build system, dependencies, and tool settings. This streamlines development and dependency management. - Version Compatibility Update: The version number has been updated to 3.4.0, indicating compatibility with Pythonista 3.4 and newer versions.
- CI/CD Enhancements: The Continuous Integration (CI) setup has been updated to support publishing to a properly configured trusted publisher, enhancing the release process.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
There was a problem hiding this comment.
Hey @o-murphy - I've reviewed your changes - here's some feedback:
- The
requires-python >=3.10in pyproject.toml conflicts with the stated support for Pythonista 3.4+; please adjust the Python requirement or clarify the supported versions. - Some stubs use relative imports (e.g.
from . import console as _console)—verify those import paths resolve correctly under thepythonista_stubspackage for both mypy and IDE tooling. - Since you switched to a dynamic version in pyproject.toml, ensure the
VERSIONfile is updated to3.4.0so the published package reflects the intended stub version.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `requires-python >=3.10` in pyproject.toml conflicts with the stated support for Pythonista 3.4+; please adjust the Python requirement or clarify the supported versions.
- Some stubs use relative imports (e.g. `from . import console as _console`)—verify those import paths resolve correctly under the `pythonista_stubs` package for both mypy and IDE tooling.
- Since you switched to a dynamic version in pyproject.toml, ensure the `VERSION` file is updated to `3.4.0` so the published package reflects the intended stub version.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
PR Code Suggestions ✨Explore these optional code suggestions:
|
||||||||||||
There was a problem hiding this comment.
Caution
Changes requested ❌
Reviewed everything up to 5fb7267 in 1 minute and 44 seconds. Click for details.
- Reviewed
3468lines of code in41files - Skipped
0files when reviewing. - Skipped posting
4draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. pyproject.toml:13
- Draft comment:
The 'requires-python = ">=3.10"' setting may need review. The PR description notes minimal support for Pythonista 3.4+, so please confirm that requiring Python 3.10 for static analysis doesn’t inadvertently exclude users running older versions when using the stubs. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%The comment is asking the PR author to confirm their intention regarding the Python version requirement. It suggests a potential issue with excluding users running older versions, but it doesn't provide a specific code suggestion or ask for a test. It violates the rule against asking the author to confirm their intention.
2. pyproject.toml:48
- Draft comment:
Typographical suggestion: In the comment '# to include root-places .pyi stubs', 'root-places' might be a typo. Consider changing it to 'root-level' or a similar phrase if that is what was intended. - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% While "root-places" is an unusual term, this is just about wording in a comment. Comments are meant to help developers understand the code, but this suggestion is very minor and doesn't affect functionality. The existing comment, while using unusual wording, still conveys its basic meaning about including .pyi stubs. The unusual term might genuinely confuse future developers. The comment is part of a configuration file where clarity is important. However, this is still just a stylistic suggestion about comment wording. Per the rules, we should not make purely informative comments or ones that don't require clear code changes. The comment should be deleted as it's a minor stylistic suggestion about documentation that doesn't affect functionality or require actual code changes.
3. stubs/_cb.pyi:1
- Draft comment:
Typo suggestion: The header on line 1 reads "Created on July, 07 2025...". The comma after "July" looks out of place. Consider revising it (e.g., "Created on July 07, 2025..."). - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% While this is technically about changed code since it's a new file, the comment is about an extremely minor formatting issue in a header comment that doesn't affect functionality or code quality. The rules state not to make comments that are obvious or unimportant. Date formatting in a header comment is very low importance. The date format with the comma is technically incorrect, and having consistent date formatting could be considered a code quality issue. While correct, this is an extremely minor stylistic issue in a comment that doesn't impact code functionality or maintainability. The rules specifically say not to make unimportant comments. This comment should be deleted as it addresses an extremely minor formatting issue that doesn't meaningfully impact code quality.
4. stubs/pythonista_stubs/editor.pyi:102
- Draft comment:
Typo: In theapply_ui_themedocstring, consider replacing "descendents" with "descendants". - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% While this is a spelling error, it's in a docstring and is a very minor issue. The meaning is still completely clear. The rules state we should not make purely informative comments or unimportant changes. This feels like a very low-priority issue that doesn't materially affect the code quality or functionality. The spelling error could propagate if other developers copy this docstring as a template. Documentation quality is important for maintainability. While documentation quality matters, this particular spelling variation is so minor and still completely understandable that fixing it provides negligible value. Delete the comment as it points out an extremely minor spelling issue that doesn't materially affect code quality or understanding.
Workflow ID: wflow_HMXMl4uL7eETLgNf
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
There was a problem hiding this comment.
Code Review
This pull request is a significant improvement, modernizing the project's packaging by migrating to pyproject.toml and adopting a typeshed-like structure for stubs. My review focuses on refining the packaging configuration to ensure all stubs are correctly included, correcting some syntax in the stub files, and enhancing type hint completeness for better static analysis.
|
@hbmartin If you approve it I will megre. Also please setup trusted publisher to pypi to able publish to pypi on github release action |
There was a problem hiding this comment.
Actionable comments posted: 20
🧹 Nitpick comments (22)
.idea/inspectionProfiles/profiles_settings.xml (1)
1-6: Avoid committing IDE-specific files (.idea).Recommend excluding JetBrains project files from VCS to reduce noise and accidental config drift. Add to .gitignore:
.idea/If you intentionally track IDE settings, consider documenting that in CONTRIBUTING.md.
stubs/pythonista_stubs/__init__.pyi (1)
1-1: Consider marking version as Final for clarity.Marking as Final helps type checkers treat it as a constant. Use typing_extensions for broader compatibility.
+from typing_extensions import Final -__version__: str +__version__: Final[str]setup.py (1)
3-3: Remove or justify the no-opsetup()callWith a PEP 517 build (
pyproject.toml+setuptools.build_meta) this file is no longer used for builds or editable installs (PEP 660).
Keeping a dummysetup.pycan confuse tooling and duplicate metadata maintenance. Either delete the file or add a short comment explaining that it is retained only for legacy pip (< 21.3) compatibility.stubs/pythonista_stubs/clipboard.pyi (1)
11-15: Simplify the PIL import in stubs
.pyifiles are not executed at runtime, so thetry/exceptfallback is unnecessary.
Prefer the canonical pattern:from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from PIL.Image import Image else: Image = Any # type: ignore[assignment]This avoids redef-warnings and expresses intent cleanly.
stubs/pythonista_stubs/linguistictagger.pyi (1)
12-31: Reuse declared constants in_Schemeto avoid driftThe Literal list hard-codes the scheme strings, which risks diverging from the constants above. Build it from the constants instead:
_Scheme = Literal[ SCHEME_TOKEN_TYPE, SCHEME_LEXICAL_CLASS, SCHEME_NAME_TYPE, SCHEME_NAME_TYPE_OR_LEXICAL_CLASS, SCHEME_LEMMA, SCHEME_LANGUAGE, SCHEME_SCRIPT, ]One source of truth improves maintainability.
stubs/pythonista_stubs/motion.pyi (1)
6-34: Consider introducing aVector3/Vector4alias.All value-returning helpers repeatedly declare
Tuple[float, float, float](and once four floats). Definingfrom typing import Tuple, TypeAlias Vector3: TypeAlias = Tuple[float, float, float] Vector4: TypeAlias = Tuple[float, float, float, float]once at the top and re-using the aliases cuts duplication and improves readability without affecting callers.
stubs/pythonista_stubs/speech.pyi (2)
23-30: Tighten therateparameter typing.If the underlying API clamps values between 0.0 – 1.0, consider
from typing import Annotated Rate = Annotated[float, "0.0 ≤ rate ≤ 1.0"] def say(text: str, language: Optional[str] = None, rate: Rate = 0.5) -> None: ...(or a
Literal[0.25, 0.5, 1.0]set if only discrete steps are accepted).
40-54: Provide a shaped type for the recognition result.
List[Tuple[str, List[Dict]]]hides the structure of the dicts. A smallTypedDict, e.g.class Alt(TypedDict): confidence: float words: List[str]makes static analysis far more useful and self-documenting.
stubs/pythonista_stubs/appex.pyi (2)
14-16: Use aTYPE_CHECKINGgate for the optional Pillow importThe fallback assignment
PilImage: Anyis only needed at runtime, not during type-checking.
A cleaner pattern:from typing import TYPE_CHECKING if TYPE_CHECKING: from PIL.Image import Image as PilImage else: PilImage = Any # type: ignore[assignment]Reduces unnecessary import attempts at runtime and keeps the type checker happy.
55-63: Synchronise annotations with the doc-stringThe return annotation is
List[Union[Image, PilImage]], but the doc-string mentionsui.Image.
Once the realui.Imagealias is imported (see previous note), update either the annotations or the doc-string so both mention the same concrete types to avoid confusion.stubs/pythonista_stubs/contacts.pyi (1)
12-39: Mark constants asFinalfor stronger type safety-from typing import Dict, List, Optional, Tuple +from typing import Dict, List, Optional, Tuple, Final ... -HOME: str = ... +HOME: Final[str] = ...Applying
Finalprevents accidental reassignment and gives static analysers better guarantees.stubs/pythonista_stubs/editor.pyi (1)
98-106: Doc-string refers toui.Viewbut the annotation is plainViewOnce the real
ui.Viewis imported, make the annotation explicit:-def apply_ui_theme(ui_view: View, ... +def apply_ui_theme(ui_view: ui.View, ...Keeps annotation and documentation in lock-step.
stubs/pythonista_stubs/notification.pyi (1)
11-13: Model_Actionand_TriggerwithTypedDictfor richer checkingfrom typing import TypedDict, Literal class _Action(TypedDict, total=False): title: str identifier: str foreground: bool class _Trigger(TypedDict, total=False): date: float repeats: boolTypedDicts let users discover valid keys and value types during code completion.
stubs/pythonista_stubs/reminders.pyi (1)
17-24: Consider a named structure for location-based alarmsAnonymous
Tuple[str, float, float, float]provides little clarity.
A smallNamedTupleorTypedDict(title,lat,lon,radius) would make the API self-documenting and safer.stubs/pythonista_stubs/location.pyi (2)
65-67: Align return type name in docstring with signatureAfter importing Image from ui, update the docstring to avoid the misleading ui.Image reference.
- ui.Image: The rendered map snapshot. + Image: The rendered map snapshot.
16-23: Widen container types (or consider TypedDicts) to avoid over-constraining return payloadsPythonista location APIs often return additional keys. Current typing may be too strict (e.g., geocode results may include non-float fields). Either:
- minimally widen to Mapping[...] for inputs/outputs, or
- introduce TypedDicts with optional keys.
Minimal widening:
-from typing import Dict, List, Optional, Literal +from typing import Dict, List, Optional, Literal, Mapping @@ -def get_location() -> Optional[Dict[str, float]]: +def get_location() -> Optional[Mapping[str, float]]: @@ -def geocode(address: Dict[str, str]) -> List[Dict[str, float]]: +def geocode(address: Mapping[str, str]) -> List[Mapping[str, float]]: @@ -def reverse_geocode(location: Dict[str, float]) -> List[Dict[str, str]]: +def reverse_geocode(location: Mapping[str, float]) -> List[Mapping[str, str]]:If you prefer precision, I can draft TypedDicts for Location/Geocode/Address with optional fields.
Also applies to: 32-41, 70-78
stubs/pythonista_stubs/console.pyi (1)
34-47: Update docstring to reference input (not raw_input)In Python 3, input superseded raw_input.
- This function is similar to the built-in raw_input function, but the user’s + This function is similar to the built-in input function, but the user’sstubs/_cb.pyi (1)
57-58: Fix typo in comment for notifyingMinor nit: “of bool” looks accidental.
- notifying: bool # of bool + notifying: boolstubs/pythonista_stubs/photos.pyi (1)
181-186: RedundantUnion[Optional[…]]
Union[Optional[Asset], Optional[List[Asset]]]expands toUnion[Asset, List[Asset], None].
Simplify to improve readability:-) -> Union[Optional[Asset], Optional[List[Asset]]]: +) -> Optional[Union[Asset, List[Asset]]]:stubs/pythonista_stubs/dialogs.pyi (1)
244-250: Avoid mutable default in stub signatureEven in stubs, using a list literal as a default (
types: List[str] = ["public.data"]) is frowned upon because it leaks a shared mutable object to type-checkers.-def pick_document(types: List[str] = ["public.data"]) -> Optional[str]: +def pick_document(types: List[str] | None = None) -> Optional[str]:Inside the runtime implementation you’d substitute the default.
stubs/pythonista_stubs/objc_util.pyi (1)
91-97: Default forsuperclassshould beNoneUsing
...as a default value for a parameter annotatedObjCClassis misleading and forces callers to pass anObjCClassanyway. A clearer contract is:-superclass: ObjCClass = ..., +superclass: ObjCClass | None = None,stubs/pythonista_stubs/canvas.pyi (1)
194-196: Minor docstring typo
draw_clipboard()docstring is missing a verb:-"""Draw the image in the clipboard in a given rectangle.""" +"""Draws the image in the clipboard in a given rectangle."""
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (37)
.github/workflows/ci.yml(1 hunks).idea/inspectionProfiles/profiles_settings.xml(1 hunks)MANIFEST.in(1 hunks)VERSION(1 hunks)mypy.ini(0 hunks)pyproject.toml(1 hunks)setup.py(1 hunks)stubs/_cb.pyi(1 hunks)stubs/appex/__init__.pyi(0 hunks)stubs/clipboard/__init__.pyi(0 hunks)stubs/console/__init__.pyi(0 hunks)stubs/editor/__init__.py(0 hunks)stubs/pythonista_stubs/__init__.pyi(1 hunks)stubs/pythonista_stubs/appex.pyi(1 hunks)stubs/pythonista_stubs/canvas.pyi(1 hunks)stubs/pythonista_stubs/cb.pyi(1 hunks)stubs/pythonista_stubs/clipboard.pyi(1 hunks)stubs/pythonista_stubs/console.pyi(1 hunks)stubs/pythonista_stubs/contacts.pyi(1 hunks)stubs/pythonista_stubs/dialogs.pyi(1 hunks)stubs/pythonista_stubs/editor.pyi(1 hunks)stubs/pythonista_stubs/keyboard.pyi(1 hunks)stubs/pythonista_stubs/keychain.pyi(1 hunks)stubs/pythonista_stubs/linguistictagger.pyi(1 hunks)stubs/pythonista_stubs/location.pyi(1 hunks)stubs/pythonista_stubs/motion.pyi(1 hunks)stubs/pythonista_stubs/notification.pyi(1 hunks)stubs/pythonista_stubs/objc_util.pyi(1 hunks)stubs/pythonista_stubs/photos.pyi(1 hunks)stubs/pythonista_stubs/reminders.pyi(1 hunks)stubs/pythonista_stubs/shortcuts.pyi(1 hunks)stubs/pythonista_stubs/sound.pyi(1 hunks)stubs/pythonista_stubs/speech.pyi(1 hunks)stubs/pythonista_stubs/ui.py(1 hunks)stubs/reminders/__init__.pyi(0 hunks)stubs/sound/__init__.pyi(0 hunks)stubs/speech/__init__.pyi(0 hunks)
💤 Files with no reviewable changes (8)
- mypy.ini
- stubs/speech/init.pyi
- stubs/reminders/init.pyi
- stubs/clipboard/init.pyi
- stubs/console/init.pyi
- stubs/appex/init.pyi
- stubs/sound/init.pyi
- stubs/editor/init.py
🧰 Additional context used
🧬 Code Graph Analysis (10)
stubs/pythonista_stubs/motion.pyi (1)
stubs/pythonista_stubs/location.pyi (2)
start_updates(24-26)stop_updates(28-30)
stubs/pythonista_stubs/clipboard.pyi (2)
stubs/pythonista_stubs/appex.pyi (2)
Image(10-10)get_image(65-73)stubs/pythonista_stubs/photos.pyi (2)
Image(11-11)get_image(20-22)
stubs/pythonista_stubs/cb.pyi (1)
stubs/_cb.pyi (17)
Characteristic(53-57)Service(59-62)Peripheral(64-77)CentralManager(79-101)did_discover_peripheral(87-87)did_connect_peripheral(88-88)did_fail_to_connect_peripheral(89-91)did_disconnect_peripheral(92-94)did_discover_services(95-95)did_discover_characteristics(96-98)did_write_value(99-99)did_update_value(100-100)did_update_state(101-101)scan_for_peripherals(83-83)stop_scan(84-84)connect_peripheral(85-85)cancel_peripheral_connection(86-86)
stubs/pythonista_stubs/appex.pyi (6)
stubs/pythonista_stubs/editor.pyi (2)
View(9-9)get_text(19-25)stubs/pythonista_stubs/ui.py (1)
View(4-13)stubs/pythonista_stubs/dialogs.pyi (1)
Image(15-15)stubs/pythonista_stubs/location.pyi (1)
Image(9-9)stubs/pythonista_stubs/photos.pyi (3)
Image(11-11)get_image(20-22)get_image_data(24-26)stubs/pythonista_stubs/clipboard.pyi (1)
get_image(32-46)
stubs/pythonista_stubs/dialogs.pyi (4)
stubs/pythonista_stubs/appex.pyi (1)
Image(10-10)stubs/pythonista_stubs/location.pyi (1)
Image(9-9)stubs/pythonista_stubs/photos.pyi (1)
Image(11-11)stubs/pythonista_stubs/console.pyi (5)
alert(57-83)input_alert(85-111)login_alert(141-167)password_alert(113-139)hud_alert(179-191)
stubs/pythonista_stubs/reminders.pyi (1)
stubs/pythonista_stubs/contacts.pyi (1)
save(158-160)
stubs/pythonista_stubs/editor.pyi (1)
stubs/pythonista_stubs/ui.py (1)
View(4-13)
stubs/pythonista_stubs/location.pyi (5)
stubs/pythonista_stubs/appex.pyi (1)
Image(10-10)stubs/pythonista_stubs/dialogs.pyi (1)
Image(15-15)stubs/pythonista_stubs/photos.pyi (1)
Image(11-11)stubs/pythonista_stubs/motion.pyi (2)
start_updates(11-13)stop_updates(15-17)stubs/pythonista_stubs/contacts.pyi (1)
is_authorized(170-172)
stubs/pythonista_stubs/keyboard.pyi (1)
stubs/pythonista_stubs/ui.py (1)
View(4-13)
stubs/pythonista_stubs/canvas.pyi (1)
stubs/pythonista_stubs/console.pyi (1)
clear(9-11)
🔇 Additional comments (4)
stubs/pythonista_stubs/ui.py (1)
13-13: LGTM: stub formatting change is fine.Single-line ellipsis for the constructor is clear and consistent with stubs style. No functional/signature change.
stubs/pythonista_stubs/shortcuts.pyi (1)
11-44: Stub looks goodTypes and doc-strings are clear, and parameter defaults match real-world usage. Nice work.
.github/workflows/ci.yml (1)
54-55: Guard publishing with a tag instead of event name alone.
github.event_name == 'release'fires for any release action (including edits). Using
if: github.event.action == 'published'(you already filter the workflow trigger) or checkinggithub.reffor arefs/tags/*pattern avoids accidental re-publishes.stubs/_cb.pyi (1)
65-66: Confirm manufacturer_data nullabilitySome peripherals may not include manufacturer data. Consider Optional[bytes] if the runtime can emit None or omit the field.
Please verify via the Pythonista _cb help or quick runtime probe:
import _cb # After discovering a peripheral without manufacturer data: # Check attribute value on Peripheral instance: # print(repr(p.manufacturer_data)) # Is it b'' or None?If None is possible, update:
- manufacturer_data: bytes + manufacturer_data: Optional[bytes]
| # These are imported from the `ui` module, which is part of Pythonista. | ||
| class Image: ... | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Use the canonical ui.Image type instead of redefining Image locally
Redefining Image here creates inconsistencies across stubs. Import it from the ui stub to keep types unified.
Apply:
-from typing import Dict, List, Optional, Literal
+from typing import Dict, List, Optional, Literal
+from .ui import Image
-
-# These are imported from the `ui` module, which is part of Pythonista.
-class Image: ...
+# Image is provided by the `ui` module.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # These are imported from the `ui` module, which is part of Pythonista. | |
| class Image: ... | |
| from typing import Dict, List, Optional, Literal | |
| from .ui import Image | |
| # Image is provided by the `ui` module. |
🤖 Prompt for AI Agents
In stubs/pythonista_stubs/location.pyi around lines 8 to 10, the Image class is
redefined locally which causes inconsistencies. Remove the local Image class
definition and instead import the canonical Image type from the ui module stub
to unify the type usage across stubs.
hbmartin
left a comment
There was a problem hiding this comment.
Awesome stuff 🚀
Take a look at the comments and let me know what you think
I will fix few things I'm agreed with |
|
Awesome shitt, somehow I deleted changes |
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
||||||||||||
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
||||||||||||
There was a problem hiding this comment.
Caution
Changes requested ❌
Reviewed everything up to 9e6abdc in 1 minute and 42 seconds. Click for details.
- Reviewed
3548lines of code in43files - Skipped
0files when reviewing. - Skipped posting
5draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. .idea/misc.xml:6
- Draft comment:
The ProjectRootManager configuration still uses 'Python 3.7', which conflicts with the project’s requirement of Python >=3.10 (as specified in pyproject.toml). Consider updating the project JDK version in the IDE settings for consistency. - Reason this comment was not posted:
Comment was on unchanged code.
2. MANIFEST.in:2
- Draft comment:
Typographical note: The second line just has "include" and appears incomplete. Please verify if this was intended or if a file pattern is missing. - Reason this comment was not posted:
Marked as duplicate.
3. stubs/_cb.pyi:1
- Draft comment:
Minor typographical suggestion: In the header, consider revising the date format to remove the comma after "July" (e.g., "Created on July 07, 2025 by ..."). - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% This is an extremely minor stylistic suggestion about punctuation in a comment. While technically correct that dates are usually written without that comma, this kind of nitpicking about comment formatting doesn't improve code quality or functionality. The current format is perfectly readable and understandable. The comma removal would make the date format more standard. Header comments are the first thing users see, so maintaining professional formatting could be important. While proper formatting is good, this level of nitpicking about punctuation in comments doesn't meet the bar for a necessary code change and violates the rule about not making purely informative comments. Delete this comment as it's an extremely minor stylistic suggestion about comment formatting that doesn't warrant a code change.
4. stubs/pythonista_stubs/dialogs.pyi:55
- Draft comment:
Typographical note: In the docstring forlogin_alert, the reference toconsole.password_alert()appears to be swapped. Should this reference beconsole.login_alert()instead? - Reason this comment was not posted:
Marked as duplicate.
5. stubs/pythonista_stubs/dialogs.pyi:78
- Draft comment:
Minor inconsistency: The docstring uses both 'cancelled' and 'canceled' in different parts. Consider making the spelling consistent. - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% This is a type stub file whose primary purpose is to provide type hints for static analysis and autocompletion. The spelling inconsistency doesn't affect functionality or type checking. While consistency is good, this is a very minor cosmetic issue that doesn't impact the file's main purpose. The rules say not to make purely informative comments or obvious/unimportant ones. The inconsistency could be confusing to users reading the documentation. Both spellings are technically correct (British vs American English). While both spellings are valid, this cosmetic documentation issue is too minor to warrant a comment in a type stub file review. The focus should be on type correctness and functionality. Delete this comment as it's a minor documentation consistency issue that doesn't affect the primary purpose of type stub files.
Workflow ID: wflow_076PdGcHYM76KBsQ
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
There was a problem hiding this comment.
Caution
Changes requested ❌
Reviewed everything up to 52858ce in 1 minute and 30 seconds. Click for details.
- Reviewed
3548lines of code in43files - Skipped
0files when reviewing. - Skipped posting
6draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. stubs/_cb.pyi:1
- Draft comment:
The header states 'Created on July, 07 2025' – please verify if this future date is intentional or a typo. - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% According to the rules, we should not ask authors to verify or confirm things. The date, while unusual, is just metadata in a comment and doesn't affect the actual code functionality. This is not a critical issue requiring code changes. The rules specifically say not to make comments that start with "verify that..." which this does. The future date could indicate confusion or a mistake that might affect documentation accuracy. Documentation correctness could be important for maintainability. While documentation accuracy is good, this is just a metadata comment that doesn't affect code functionality. The rules explicitly state not to ask for verifications or make purely informative comments. Delete the comment as it violates the rule against asking for verification and doesn't require any actual code changes.
2. pyproject.toml:46
- Draft comment:
The package configuration maps 'pythonista_stubs' to the 'stubs' directory. Please ensure that all stub files are correctly located so that they are discovered by the package finder. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%This comment is asking the PR author to ensure that stub files are correctly located, which falls under the rule of not asking the author to ensure or verify things. It doesn't provide a specific suggestion or point out a specific issue with the code.
3. setup.py:1
- Draft comment:
The minimal setup.py (just 'setup()') is acceptable given the move to pyproject.toml, but consider adding a brief comment noting its purpose for backwards compatibility. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =30%<= threshold50%The comment is suggesting adding a comment for clarity, which is not strictly necessary for functionality or correctness. It doesn't ask for a specific code change or test, and it doesn't point out a potential issue with the code. Therefore, it seems to be more of an informative suggestion rather than a necessary action.
4. stubs/pythonista_stubs/__init__.pyi:1
- Draft comment:
Currently, this file only annotates version; adding a module docstring could improve readability and clarify the module’s purpose. - Reason this comment was not posted:
Comment was on unchanged code.
5. stubs/pythonista_stubs/console.pyi:186
- Draft comment:
Typographical error: In the hud_alert docstring, consider changing "It Can be 'success'" to "It can be 'success'" (with a lowercase 'c'). - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% While this is technically correct and the file is new, docstring capitalization issues are very minor and don't affect functionality. The comment is about a purely cosmetic issue. According to the rules, we should not make purely informative comments or comments about obvious/unimportant issues. The file is new so all content is technically "changed". And consistent capitalization could be considered part of code quality. While consistency is good, this is too minor of an issue to warrant a PR comment. It doesn't affect functionality or readability significantly. Delete this comment as it addresses a trivial capitalization issue that doesn't meaningfully impact code quality or functionality.
6. stubs/pythonista_stubs/console.pyi:188
- Draft comment:
Typographical error: In the hud_alert docstring, change "It Can be between 0.25 and 5.0 seconds" to "It can be between 0.25 and 5.0 seconds" (use lowercase 'c'). - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% While this is technically correct and the file is new, this is an extremely minor stylistic issue in a docstring. It doesn't affect functionality, code quality, or even documentation clarity. The rules state not to make comments that are obvious or unimportant. This seems to fall into that category. The capitalization inconsistency could be seen as unprofessional in documentation. Multiple instances of the same error might indicate a pattern worth fixing. While consistency is good, this is too minor of an issue to warrant a PR comment. Documentation polish can be handled through other means. Delete this comment as it's too minor and doesn't materially improve the code or documentation quality enough to warrant a PR comment.
Workflow ID: wflow_j05XrjItozZPKsTF
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
PR Code Suggestions ✨Explore these optional code suggestions:
|
|||||||||||||||||
|
My VCS was broken. Now looks ok. I think it's done |

User description
PR Type
Enhancement
Description
Modernized project structure to typeshed-like organization
Migrated from setup.py to pyproject.toml configuration
Updated CI/CD with uv package manager and ruff linting
Added comprehensive type stubs for Pythonista modules
Diagram Walkthrough
File Walkthrough
9 files
Simplified to minimal setup() callUpdated CI to use uv and ruffAdded automated publishing workflowAdded IDE inspection settingsUpdated IDE configurationAdded package manifest for stub filesAdded version file with 3.4.0Removed old mypy configurationAdded modern Python project configuration7 files
Removed Python implementation fileRemoved old appex stub implementationRemoved old clipboard stub implementationRemoved old console stub implementationRemoved old reminders stub implementationRemoved old sound stub implementationRemoved old speech stub implementation1 files
Minor formatting cleanup22 files
Added Bluetooth Core module stubsAdded package version stubAdded comprehensive appex module stubsAdded canvas drawing module stubsAdded Bluetooth module wrapper stubsAdded comprehensive clipboard module stubsAdded comprehensive console module stubsAdded contacts module stubsAdded dialogs module stubsAdded comprehensive editor module stubsAdded keyboard module stubsAdded keychain module stubsAdded linguistic tagger module stubsAdded location services module stubsAdded motion sensors module stubsAdded notification module stubsAdded Objective-C bridge module stubsAdded photos library module stubsAdded comprehensive reminders module stubsAdded shortcuts integration module stubsAdded comprehensive sound module stubsAdded speech synthesis module stubs3 files