Skip to content

[py] Addressing mypy type annotation errors #15928

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: trunk
Choose a base branch
from

Conversation

bandophahita
Copy link
Contributor

@bandophahita bandophahita commented Jun 20, 2025

User description

🔗 Related Issues

addresses part of #15697

💥 What does this PR do?

Updates annotations and sets proper default objects.

🔧 Implementation Notes

💡 Additional Considerations

🔄 Types of changes

  • Cleanup (formatting, renaming)
  • Bug fix (backwards compatible)

PR Type

Other


Description

  • Fix mypy type annotation errors across webdriver services

  • Change Sequence[str] to list[str] for service arguments

  • Add explicit type annotations for class attributes

  • Update ChromiumDriver constructor parameter types


Changes walkthrough 📝

Relevant files
Bug fix
3 files
service.py
Update service_args type annotations to list[str]               
+4/-4     
service.py
Fix type annotations and add attribute declarations           
+6/-4     
service.py
Change service_args type from Sequence to list                     
+3/-3     
Enhancement
4 files
webdriver.py
Add explicit type annotations for options and service       
+3/-0     
webdriver.py
Update constructor parameter types and imports                     
+6/-7     
service.py
Add log_output type annotation declaration                             
+2/-0     
webdriver.py
Add explicit type annotations for attributes                         
+3/-0     

Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.
  • @selenium-ci selenium-ci added the C-py Python Bindings label Jun 20, 2025
    Copy link
    Contributor

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    🎫 Ticket compliance analysis ✅

    15697 - PR Code Verified

    Compliant requirements:

    • Fix mypy type annotation errors across webdriver services
    • Change Sequence[str] to list[str] for service arguments
    • Add explicit type annotations for class attributes
    • Update ChromiumDriver constructor parameter types

    Requires further human verification:

    • Verify that all mypy errors are resolved after these changes
    • Confirm backward compatibility is maintained
    ⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Complex Type

    The log_output attribute has an overly complex Union type annotation that could be simplified and may indicate unclear type requirements.

    log_output: Union[Optional[IOBase], Optional[Union[int, IOBase]], Optional[SubprocessStdAlias]]
    Breaking Change

    Constructor parameters changed from Optional to required, which could break existing code that relies on None defaults.

    browser_name: str,
    vendor_prefix: str,
    options: ChromiumOptions = ChromiumOptions(),
    service: ChromiumService = ChromiumService(),

    Copy link
    Contributor

    qodo-merge-pro bot commented Jun 20, 2025

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    General
    Simplify complex type annotation
    Suggestion Impact:The suggestion impacted the commit by simplifying the complex type annotation, though the implementation differs slightly from the suggested approach

    code diff:

    -    log_output: Union[Optional[IOBase], Optional[Union[int, IOBase]], Optional[SubprocessStdAlias]]
    +    log_output: Union[None, IOBase, int, SubprocessStdAlias]

    The type annotation is overly complex with nested Optional types. Simplify to
    Optional[Union[int, IOBase, SubprocessStdAlias]] for better readability and
    correctness.

    py/selenium/webdriver/chromium/service.py [38]

    -log_output: Union[Optional[IOBase], Optional[Union[int, IOBase]], Optional[SubprocessStdAlias]]
    +log_output: Optional[Union[int, IOBase, SubprocessStdAlias]]

    [Suggestion processed]

    Suggestion importance[1-10]: 5

    __

    Why: The suggestion correctly identifies that the nested Optional and Union types in the type hint for log_output can be simplified. Applying the suggestion improves code readability and adheres to type hinting best practices.

    Low
    • Update

    @navin772
    Copy link
    Member

    @bandophahita Thank you for the contribution! This looks good.
    Could you also add mypy fixes for wpewebkit/service.py and webkitgtk/service.py in this PR, those are quite similar to the ones you updated above and will fix type errors for all service.py files.

    Also, run the formatter - ./scripts/format.sh to get the CI passing.

    @cgoldberg
    Copy link
    Contributor

    Change Sequence[str] to list[str] for service arguments

    Why do we need this? What's wrong with accepting a sequence?

    @bandophahita
    Copy link
    Contributor Author

    bandophahita commented Jun 23, 2025

    Change Sequence[str] to list[str] for service arguments

    Why do we need this? What's wrong with accepting a sequence?

    Need is probably too strong of a term. It made sense to me to keep it a list since that's what _service_args is and that's how all of the code internally passes arguments. Nothing would prevent accepting a Sequence since it is converted to a list in the __init__.

    Short answer; keeping the types simple prevents confusion. But in case that's an issue, I reverted the argument annotations.

    @MarcelWilson MarcelWilson force-pushed the mypy_annotation_cleanup branch from 78d767c to 926aafb Compare June 23, 2025 15:08
    @cgoldberg
    Copy link
    Contributor

    I reverted the argument annotations.

    I still see a change from Sequence to list. Just leave them as a sequence unless there is a need to enforce a list.

    @bandophahita
    Copy link
    Contributor Author

    bandophahita commented Jun 23, 2025

    I still see a change from Sequence to list. Just leave them as a sequence unless there is a need to enforce a list.

    There are changes from Sequence to list but those are attributes. I reverted the argument annotations.

    @bandophahita
    Copy link
    Contributor Author

    bandophahita commented Jun 23, 2025

    I still see a change from Sequence to list. Just leave them as a sequence unless there is a need to enforce a list.

    I think I should explain the change. The problem was when referencing service.service_args (which is a property returning _service_args) it was annotated as a Sequence; and yet internally there were actions that can only be performed as a list object. Mypy was catching and reporting this inconsistancy. Sequence is fine for the argument being passed in, but it was then being converted to a list. The annotation was in incorrect for the attribute.

    @cgoldberg
    Copy link
    Contributor

    @bandophahita can you explain why we need the new class attributes?

    @bandophahita
    Copy link
    Contributor Author

    bandophahita commented Jun 24, 2025

    @bandophahita can you explain why we need the new class attributes?

    For sure. These are technically not NEW attributes but simply annotations for the class attributes. They dont do anything at runtime. Mypy reads them as the annotations instead of autodetecting/using what is set in the __init__. Mypy sometimes can't deterimne what a dynamic attribute is very well, these help it. I can go through them and breakdown how, if you want.

    @@ -27,6 +27,8 @@
    class WebDriver(ChromiumDriver):
    """Controls the MSEdgeDriver and allows you to drive the browser."""

    service: Service
    Copy link
    Contributor Author

    @bandophahita bandophahita Jun 24, 2025

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    This class annotation lets mypy understand that the webdriver has an attribute service that is an instance of Service. The Optional[Service] argument annotation caused mypy to believe the attribute webdriver.servce could be None, when in fact it never is. Mypy isn't smart enough to read the code that way.

    @@ -35,6 +35,9 @@ class ChromiumService(service.Service):
    :param driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable.
    """

    _service_args: list[str]
    log_output: Union[None, IOBase, int, SubprocessStdAlias]
    Copy link
    Contributor Author

    @bandophahita bandophahita Jun 24, 2025

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Annotation to let mypy know what log_output attribute can be. Autodetermination wasn't smart enough to see past the argument annotation which was fine for the argument but incomplete for the attribute.

    Copy link
    Contributor Author

    @bandophahita bandophahita Jun 24, 2025

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    There is a real possibility that the argument annotation is incomplete here too. I didn't address this. Someone more familiar with the log_output argument should confirm it's annotation.

    @cgoldberg cgoldberg changed the title addressing mypy errors [py] Addressing mypy type annotation errors Jun 24, 2025
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    4 participants