Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Cannot use keyword with parameterized special form like TypeForm[param] as type hint #5393

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

Closed
DetachHead opened this issue Apr 3, 2025 · 6 comments

Comments

@DetachHead
Copy link
Contributor

TypeForm is an experimental new type for typing type anotations, see https://peps.python.org/pep-0747/. it was added to typing_extensions in version 4.13.0.

attempting to use it in a keyword causes robot to crash:

# asdf.py

from robot.api.deco import keyword
from typing_extensions import TypeForm


@keyword
def foo(a: TypeForm[object]): ...
# foo.robot
*** Settings ***
Library     asdf


*** Test Cases ***
A
    Foo    int
> robot foo.robot
[ ERROR ] Error in library 'asdf': Adding keyword 'foo' failed: 'TypeForm' does not accept parameters, 'TypeForm[object]' has 1.
[ WARN ] Imported library 'asdf' contains no keywords.
==============================================================================
Foo
==============================================================================
A                                                                     | FAIL |
No keyword with name 'Foo' found.
------------------------------------------------------------------------------
Foo                                                                   | FAIL |
1 test, 0 passed, 1 failed
==============================================================================
Output:  C:\Users\user\project\output.xml
Log:     C:\Users\user\project\log.html
Report:  C:\Users\user\project\report.html

note that no conversions are required to convert an argument to a TypeForm, because it's valid for type annotations to be strings:

foo: "int" = 1
@LucianCrainic
Copy link
Contributor

Hi,

I tried it myself and it doesn't seems like an error due to RF. It looks like you're using TypeForm from typing_extensions incorrectly.

According to the error message, TypeForm[object] is not valid syntax. The TypeForm class is likely not designed to be used with type parameters like [object].

I fixed it with this approach:

from robot.api.deco import keyword
from typing import TypeVar

T = TypeVar('T', bound=object)

@keyword
def foo(a: T):
    print(a)

Robotframework file is the same. With this approach i get no errors.

@DetachHead
Copy link
Contributor Author

i think you're getting TypeForm mixed up with TypeVar, they're two completely different concepts. TypeVar is for declaring generics (aka type variables), whereas TypeForm is a way to type a type annotation itself. it's useful for functions that cast or do runtime type checking:

from typing_extensions import TypeForm

def validate_type(value: object, t: TypeForm[object]):
    ... # do some runtime type check

validate_type(1, int | str)

see https://peps.python.org/pep-0747/ for more info

@pekkaklarck
Copy link
Member

pekkaklarck commented Apr 5, 2025

I can reproduce the problem. It's due to our type hint inspecting code considering that nothing that's not an instance of type can have parameters. That's a false assumption and TypeForm isn't the only such special form. Another example is Annotated[int, 'xxx'], but it doesn't cause problems for us, because get_type_hints by default strips the wrapping Annotation and returns just the actual type.

Luckily this problem doesn't cause the whole execution to crash, but not being able to use a keyword with such a type hint is obviously annoying as well. This certainly needs to be fixed and luckily the fix seem to be rather simple. There will be no conversion for TypeForm, though, unless we explicitly add it. Do you think it would make sense? If yes, please submit a separate issue about that.

@pekkaklarck pekkaklarck added this to the v7.3 milestone Apr 5, 2025
@pekkaklarck pekkaklarck self-assigned this Apr 5, 2025
@pekkaklarck pekkaklarck changed the title crash when keyword uses typing_extensions.TypeForm annotation Cannot use keyword with parameterized special form like TypeForm[param] as type hint Apr 6, 2025
@DetachHead
Copy link
Contributor Author

sounds good, like i said a converter isn't really necessary because a string is already a valid TypeForm, which is mentioned here:

A string literal expression containing a valid type expression should likewise be assignable to TypeForm:

v5: TypeForm[set[str]] = "set[str]"  # OK

so that should make it trivial to support it in robotframework. though i guess it could be enhanced further to validate that the string is actually a valid type, but i'm happy to just have the fix for the crash, because i don't use .robot files much anymore since i made my pytest plugin so i don't really need converters since all of our new tests are written in python.

@pekkaklarck
Copy link
Member

Converting string "set[str]" to actual set[str] and validating that it matches TypeForm[set[str]] wouldn't be trivial, but it wouldn't be that complicated either. Anyway, that requires a separate issue.

@pekkaklarck
Copy link
Member

TypeForm is apparently supported natively by Python 3.14, so this issues is also related to the general Python 3.14 support (#5352).

pekkaklarck added a commit that referenced this issue Apr 7, 2025
This is related to #5393. Problems were discovered when unit tests
didn't succeed on Python 3.8. Investigation reveladed this:

1. Python 3.8 doesn't have Annotated that was used in a test that
   validated the fix for #5393.

2. Annotated can be imported from typing_extensions in tests, but
   it turned out that Python 3.8 get_origin and get_args don't handle
   it properly so test continued to fail.

3. A fix for the above was trying to import also get_origin and get_args
   from typing_extensions on Python 3.8. That fixed the provious problem,
   but string representation was still off.

4. It turned out that our type_name and type_repr didn't handle Annotated
   and TypeRef properly. Most likely the same issue occurred also with
   other parameterized special forms.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants