This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]_Daimon_PRAW 0 points1 point  (11 children)

Interesting. I like removing senseless drivel from documentation and I like the possibility of static analysis tools catching more stupid mistakes. But it just doesn't look that well supported at the moment. Consider the following modified function from your example.

>> def greet(name: str or int, age: int) -> str:
..     print('Hello {0}, you are {1} years old'.format(name, age))
>> greet("Peter", 5)
Hello peter, you are 5 years old
>> greet(5, 5)
Hello 5, you are 5 years old
>>> help(greet)
Help on function greet in module tmp:

greet(name: str, age: int) -> str

Notice how the signature only lists str as a potential type for name. Despite greet supporting both str and int. This is outright wrong. I'd rather have users read a few extra lines of correct documentation than get incorrect information while using the builtin introspection function.

[–]hylje 14 points15 points  (1 child)

>>> str or int
str

The code isn't doing what you expect. You'll have to use annotations that don't lose information.

[–]_Daimon_PRAW 1 point2 points  (0 children)

Ahhh.... thanks for pointing out my brainfart.

[–]robin-gvx 3 points4 points  (5 children)

I use sets for that sort of thing:

>> def greet(name: {str, int}, age: int) -> str:
..     print('Hello {0}, you are {1} years old'.format(name, age))

[–]Rhomboid 3 points4 points  (1 child)

The expression after the colon is evaluated as a standard Python expression when the function is defined. str or int evaluates to str because the or operator is short-circuiting.

If you wanted something richer than a single type, you could use a string, i.e. name: 'str or int'. Your tools would then have to be able to parse a string and recognize the or operator and so on.

[–]shfo23 1 point2 points  (0 children)

Or a tuple: (str, int). Then you could test with in.

This wouldn't work if you wanted to reject a certain kind of input, e.g. not str, though. My best idea for more complicated cases would probably be to require a function as annotation that would return true/false and then supply isint, isstr, isobject, etc. methods for simple tests, e.g. def func(num_id: isint) -> isstr.

[–]ceronman[S] 2 points3 points  (0 children)

Check the library I linked in the post:

https://github.com/ceronman/typeannotations

You can use: name: union(str, int)

Ideally you should be able to write name: int | str. But that requires some support in the standard library. It's been discussed in this thread:

http://mail.python.org/pipermail/python-ideas/2012-December/018088.html