Giter Club home page Giter Club logo

Comments (6)

gomarz avatar gomarz commented on June 19, 2024 1

Sorry about that! I'm still relatively new to using RF, so this was all very illuminating! Thanks so much for your help!

from robotframework.

pekkaklarck avatar pekkaklarck commented on June 19, 2024

Could you create a simple runnable example I could test locally?

from robotframework.

gomarz avatar gomarz commented on June 19, 2024

Hi, thanks for your response. Here is a simple example
Sample.zip
My error should be reproduceable by unzipping into a folder and running

robot Sample.robot

from within it

keywords.py

from robot.api.deco import keyword
from signals import WriteSignal

@keyword(name="Write")
def write(self, *signals: WriteSignal) -> None:
    print("test")
    # self.test_library.publish_can_message("write", signals)

Sample.robot

*** Settings ***
Metadata         Version                                                                                                  0.1
Documentation    Simple example showcasing NotRequired error:

Force Tags       PreCheck

Library                          ${EXECDIR}/keywords.py

*** Keywords ***

WriteValue
    [Documentation]                 Create dictionary and publishes CAN:Write message
    ...                             with signal values
    [Arguments]                     ${signal}                                                    ${value}                                  ${interval}=${None}
    &{DICT} =                       Create Dictionary                                            Network=CAN5                              Signal=${signal}                           Value=${value}
    Run Keyword If                  $interval is not None                                        Set To Dictionary                         ${CAN_DICT}                                Interval=${interval}
    keywords.Write                  ${DICT}

*** Test Cases ***

Change Language from Radio to a Language supported by IHU (French)
    WriteValue              1   1
    Sleep                      2

signals.py

from typing import Any, Literal, Protocol, Union
from typing_extensions import NotRequired, TypedDict

class Signal(TypedDict):
    """Base Signal"""

    Network: str
    Signal: str


class ReadSignal(Signal):
    """Read Signal"""

    Mode: Literal["Once", "OnChange"]
    Interval: NotRequired[Union[int, None]]


class WriteSignal(Signal):
    """Write Signal"""

    Value: str
    Interval: NotRequired[Union[int, None]]


class GeneralLogger(Protocol):  # pylint: disable=too-few-public-methods
    """Definition of logger, which might be used as async in MessageSubscriber"""

    def log(self, level: int, msg: object, *args: Any, **kwargs: Any) -> None:  # type: ignore[misc]
        """Log message with provided level"""

from robotframework.

pekkaklarck avatar pekkaklarck commented on June 19, 2024

Thanks for the example. It could still be simplified (for example, the library file could contain all need Python code), but I got the issue reproduced. Interestingly it doesn't happen with Python 3.11 or 3.12, though. Which Python version do you use?

from robotframework.

pekkaklarck avatar pekkaklarck commented on June 19, 2024

I investigated this further and the problem is that typing_extensions.NotRequired isn't handled properly by the standard typing module with Python 3.10 and earlier. The issue can be demonstrated with the following example:

from typing import get_type_hints, TypedDict
from typing_extensions import NotRequired

class X(TypedDict):
    x: int
    y: NotRequired[int]

print('hints:', get_type_hints(X))
print('required:', X.__required_keys__)

When the above is executed with Python 3.10 or older, the NotRequired annotation is not handled at all and you get this:

hints: {'x': <class 'int'>, 'y': typing_extensions.NotRequired[int]}
required: frozenset({'x', 'y'})

With Python 3.11 the result is, without changing the code, this:

hints: {'x': <class 'int'>, 'y': <class 'int'>}
required: frozenset({'x'})

The NotRequired annotation was added in Python 3.11, so it's not a surprise it's handled properly with that version automatically. With older versions we need to handle it ourselves.so that we replace NotRequired[type] in type hints with just type and also remove keys with such annotation from required keys.

Notice that if we change the imports in the above example so that we import everything from typing_extensions, NotRequired is handled properly. Because we cannot control how users import TypedDict and NotRequired, and because it feels a bit risky for us to use get_type_hints from typing_extensions instead of typing, I don't think that's a possible solution for the reported issue. Handling NotRequired ourselves is safer and also pretty simple.

from robotframework.

pekkaklarck avatar pekkaklarck commented on June 19, 2024

We probably should handle also Required and not only NotRequired. For more details about these special annotations see https://typing.readthedocs.io/en/latest/spec/typeddict.html#required-notrequired.

from robotframework.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.