[Python-Dev] PEP 484 wishes

2015-05-17 Thread Alex Grönholm
Looking at PEP 484, I came up with two use cases that I felt were not 
catered for:


1. Specifying that a parameter should be a subclass of another
   (example: Type[dict] would match dict or OrderedDict; plain "Type"
   would equal "type" from builtins)
2. Specifying that a callable should take at least the specified
   arguments but would not be limited to them: Callable[[str, int,
   ...], Any]

Case #2 works already (Callable[[str, int], Any] if the unspecified 
arguments are optional, but not if they're mandatory. Any thoughts?


___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 484 wishes

2015-05-18 Thread Alex Grönholm



18.05.2015, 02:50, Guido van Rossum kirjoitti:
On Sun, May 17, 2015 at 3:07 PM, Alex Grönholm 
mailto:alex.gronh...@nextday.fi>> wrote:


Looking at PEP 484, I came up with two use cases that I felt were
not catered for:

 1. Specifying that a parameter should be a subclass of another
(example: Type[dict] would match dict or OrderedDict; plain
"Type" would equal "type" from builtins)


I don't understand. What is "Type"? Can you work this out in a full 
example? This code is already okay:


def foo(a: dict):
...

foo(OrderedDict())
This code is passing an /instance/ of OrderedDict. But how can I specify 
that foo() accepts a /subclass/ of dict, and not an instance thereof?


A full example:

def foo(a: Type[dict]):
...

foo(dict)  # ok
foo(OrderedDict)  # ok
foo({'x': 1})  # error


 1. Specifying that a callable should take at least the specified
arguments but would not be limited to them: Callable[[str,
int, ...], Any]

Case #2 works already (Callable[[str, int], Any] if the
unspecified arguments are optional, but not if they're mandatory.
Any thoughts?

For #2 we explicitly debated this and found that there aren't use 
cases known that are strong enough to need additional flexibility in 
the args of a callable. (How is the code calling the callable going to 
know what arguments are safe to pass?) If there really is a need we 
can address in a future revision.
Consider a framework where a request handler always takes a Request 
object as its first argument, but the rest of the arguments could be 
anything. If you want to only allow registration of such callables, you 
could do this:


def calculate_sum(request: Request, *values):
   return sum(values)

def register_request_handler(handler: Callable[[Request, ...], Any]):
   ...

--
--Guido van Rossum (python.org/~guido <http://python.org/%7Eguido>)


___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 484 wishes

2015-05-18 Thread Alex Grönholm



18.05.2015, 18:05, Guido van Rossum kirjoitti:
On Mon, May 18, 2015 at 12:14 AM, Alex Grönholm 
mailto:alex.gronh...@nextday.fi>> wrote:




18.05.2015, 02:50, Guido van Rossum kirjoitti:

On Sun, May 17, 2015 at 3:07 PM, Alex Grönholm
mailto:alex.gronh...@nextday.fi>> wrote:

Looking at PEP 484, I came up with two use cases that I felt
were not catered for:

 1. Specifying that a parameter should be a subclass of
another (example: Type[dict] would match dict or
OrderedDict; plain "Type" would equal "type" from builtins)


I don't understand. What is "Type"? Can you work this out in a
full example? This code is already okay:

def foo(a: dict):
...

foo(OrderedDict())

This code is passing an /instance/ of OrderedDict. But how can I
specify that foo() accepts a /subclass/ of dict, and not an
instance thereof?

A full example:

def foo(a: Type[dict]):
...

foo(dict)  # ok
foo(OrderedDict)  # ok
foo({'x': 1})  # error


You want the argument to be a *class*. We currently don't support that 
beyond using 'type' as the annotation. We may get to this in a future 
version; it is relatively uncommon. As to what notation to use, 
perhaps it would make more sense to use Class and Class[dict], since 
in the world of PEP 484, a class is a concrete thing that you can 
instantiate, while a type is an abstraction used to describe the 
possible values of a variable/argument/etc.


Also, what you gave is still not a full example, since you don't show 
what you are going to do with that type. Not every class can be easily 
instantiated (without knowing the specific signature). So if you were 
planning to instantiate it, perhaps you should use Callable[..., dict] 
as the type instead. (The ellipsis is not yet supported by mypy -- 
https://github.com/JukkaL/mypy/issues/393 -- but it is allowed by the 
PEP.)

Here's one example, straight from the code of my new framework:

@typechecked
def register_extension_type(ext_type: str, extension_class: type, 
replace: bool=False):

"""
Adds a new extension type that can be used with a dictionary based 
configuration.


:param ext_type: the extension type identifier
:param extension_class: a class that implements IExtension
:param replace: ``True`` to replace an existing type
"""

assert_subclass('extension_class', extension_class, IExtension)
if ext_type in extension_types and not replace:
raise ValueError('Extension type "{}" already 
exists'.format(ext_type))


extension_types[ext_type] = extension_class

I would like to declare the second argument as "extension_class: 
Type[IExtension]" (or Class[IExtension], doesn't matter to me). 
Likewise, the type hint for "extension_types" should be "Dict[str, 
Type[IExtension]]".



 1. Specifying that a callable should take at least the
specified arguments but would not be limited to them:
Callable[[str, int, ...], Any]

Case #2 works already (Callable[[str, int], Any] if the
unspecified arguments are optional, but not if they're
mandatory. Any thoughts?

For #2 we explicitly debated this and found that there aren't use
cases known that are strong enough to need additional flexibility
in the args of a callable. (How is the code calling the callable
going to know what arguments are safe to pass?) If there really
is a need we can address in a future revision.

Consider a framework where a request handler always takes a
Request object as its first argument, but the rest of the
arguments could be anything. If you want to only allow
registration of such callables, you could do this:

def calculate_sum(request: Request, *values):
   return sum(values)

def register_request_handler(handler: Callable[[Request, ...], Any]):
   ...


Hm... Yeah, you'd be stuck with using Callable[..., Any] for now. 
Maybe in a future version of the PEP. (We can't boil the ocean of 
typing in one PEP. :-)


--
--Guido van Rossum (python.org/~guido <http://python.org/%7Eguido>)


___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 484 (Type Hints) announcement

2015-05-23 Thread Alex Grönholm
Would you mind updating the "typing" package on PyPI now to contain 
something useful? Thanks.


22.05.2015, 23:51, Mark Shannon kirjoitti:

Hello all,

I am pleased to announce that I am accepting PEP 484 (Type Hints).

Given the proximity of the beta release I thought I would get this 
announcement out now, even though there are some (very) minor details 
to iron out.
(If you want to know the details, it's all at 
https://github.com/ambv/typehinting)



I hope that PEP 484 will be a benefit to all users of Python.
I think the proposed annotation semantics and accompanying module are 
technically sound and I hope that they are socially acceptable to the 
Python community.


I have long been aware that as well as a powerful, sophisticated and 
"production quality" language, Python is also used by many casual 
programmers, and as a language to introduce children to programming.
I also realise that this PEP does not look like it will be any help to 
the part-time programmer or beginner. However, I am convinced that it 
will enable significant improvements to IDEs (hopefully including 
IDLE), static checkers and other tools.

These tools will then help us all, beginners included.

This PEP has been a huge amount of work, involving a lot of people.
So thank you to everyone involved. If I were to list names I would 
inevitably miss someone out. You know who you are.


Finally, if you are worried that this will make Python ugly and turn 
it into some sort of inferior Java, then I share you concerns, but I 
would like to remind you of another potential ugliness; operator 
overloading.


C++, Perl and Haskell have operator overloading and it gets abused 
something rotten to produce "concise" (a.k.a. line noise) code.
Python also has operator overloading and it is used sensibly, as it 
should be. Why?

It's a cultural issue; readability matters.

Python is your language, please use type-hints responsibly :)

Cheers,
Mark.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/alex.gronholm%40nextday.fi


___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com