Re: [Python-Dev] What's missing in PEP-484 (Type hints)

2015-05-12 Thread Dima Tisnek
re: comprehension

Perhaps PEP can, at least, have a short list/summary of limitations?
I recall something was mentioned, but I can't find a section like that in PEP.


re: example

following https://github.com/JukkaL/mypy/blob/master/stubs/3.2/socket.py

# socket.pyi python2
class _socketobject:
family = 0  # inferred from initializer (?)
type = 0  # type: int  # explicit

# socket.pyi python3
class socket:
family = AddressFamily.AF_UNSPEC  # inferred I presume?

def settimeout(timeout: Union[int, float, None]) - None: pass  #
negative arguments illegal
timeout = -1.0  # yet, that's what you get by default (set None)


Perhaps, after all, socket module is a bad example.
I suppose you have a point that well-written modules are
self-documenting anyway...
Here's another try:

# _sqlite3.pyi python2 version
# warning, readonly: module allows reassignment, but you really shouldn't!
# instead use sqlite3.register_xxx functions
converters = {}  # type: Dict[str, Callable[[str], Any]]
adapters = {}  # type: Dict[Tuple[Type, SomethingInternal],
Callable[[Any], str]]




On 7 May 2015 at 17:39, Guido van Rossum gu...@python.org wrote:
 On Thu, May 7, 2015 at 7:25 AM, Dima Tisnek dim...@gmail.com wrote:

 On 30 April 2015 at 14:33, Steven D'Aprano st...@pearwood.info wrote:
  On Thu, Apr 30, 2015 at 01:41:53PM +0200, Dima Tisnek wrote:
  # internal vs external
  @intify
  def foo() - int:
  b = 42
  return b  # check 1
  x = foo() // 2  # check 2
 
  Does the return type apply to implementation (str) or decorated
  callable (int)?
 
  I would expect that a static type checker would look at foo, and flag
  this as an error. The annotation says that foo returns an int, but it
  clearly returns a string. That's an obvious error.

 Is this per PEP, or just a guess?

 I think PEP needs to be explicit about this.


 The PEP shouldn't have to explain all the rules for type inferencing.
 There's a section What is checked? that says (amongst other things):

   The body of a checked function is checked for consistency with the
   given annotations.  The annotations are also used to check correctness
   of calls appearing in other checked functions.

  Normally local variables will have their type inferred from the
  operations done to them:
 
  s = arg[1:]  # s has the same type as arg

 Good point, should be mentioned in PEP.


 Again, what do you want the PEP to say? I am trying to keep the PEP shorter
 than the actual code that implements the type checker. :-)


 Technically, type can be empty list, mixed list or custom return type
 for overloaded __getitem__ that accepts slices.

 I'm sorry if I was not clear. My question was how should type of
 ephemeral `x` be specified.
 In other words, can types be specified on anything inside a comprehension?


 That's actually a good question; the PEP shows some examples of #type:
 comments in peculiar places, but there's no example using list
 comprehensions. Your best bet is to leave it to the type inferencer; if your
 comprehension is so complex that need to put type annotations on parts of
 it, you may be better off rewriting it as a regular for-loop, which offers
 more options for annotations.


 Stub is better (required?) because it allows to specify types of
 attributes that are not assigned in class scope, but that are expected
 to be there as result of __init__ or because it's a C extension.


 Note that the PEP does not explicitly say whether the information of a stub
 might be *merged* with the information gleaned from the source code. The
 basic model is that if a stub is present the implementation source code is
 not read at all by the type checker (and, conversely, information from stubs
 is not available at all at runtime). But it is possible for some type
 checker to improve upon this model.


 An example in PEP would be good.


 Can you give an example that I can edit and put in the PEP?

 --
 --Guido van Rossum (python.org/~guido)
___
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] What's missing in PEP-484 (Type hints)

2015-05-07 Thread Dima Tisnek
On 30 April 2015 at 14:33, Steven D'Aprano st...@pearwood.info wrote:
 On Thu, Apr 30, 2015 at 01:41:53PM +0200, Dima Tisnek wrote:

 # Syntactic sugar
 Beautiful is better than ugly,  thus nice syntax is needed.
 Current syntax is very mechanical.
 Syntactic sugar is needed on top of current PEP.

 I think the annotation syntax is beautiful. It reminds me of Pascal.

Haha, good one!



 # internal vs external
 @intify
 def foo() - int:
 b = 42
 return b  # check 1
 x = foo() // 2  # check 2

 Does the return type apply to implementation (str) or decorated callable 
 (int)?

 I would expect that a static type checker would look at foo, and flag
 this as an error. The annotation says that foo returns an int, but it
 clearly returns a string. That's an obvious error.

Is this per PEP, or just a guess?

I think PEP needs to be explicit about this.

[snipped]

 lambda arg: arg + 1

 Obviously arg must be a Number, since it has to support addition with
 ints.

Well, no, it can be any custom type that implements __add__
Anyhow, the question was about non-trivial lambdas.

 # local variables
 Not mentioned in the PEP
 Non-trivial code could really use these.

 Normally local variables will have their type inferred from the
 operations done to them:

 s = arg[1:]  # s has the same type as arg

Good point, should be mentioned in PEP.

Technically, type can be empty list, mixed list or custom return type
for overloaded __getitem__ that accepts slices.

 # comprehensions
 [3 * x.data for x in foo if bar in x.type]
 Arguable, perhaps annotation is only needed on `foo` here, but then
 how complex comprehensions, e.g. below, the intermediate comprehension
 could use an annotation
 [xx for y in [...] if ...]

 A list comprehension is obviously of type List. If you need to give a
 more specific hint:

 result = [expr for x in things if cond(x)]  #type: List[Whatever]

 See also the discussion of cast in the PEP.

 https://www.python.org/dev/peps/pep-0484/#id25

Good point for overall comprehension type.
re: cast, personally I have some reservations against placing `cast()`
into runtime path.

I'm sorry if I was not clear. My question was how should type of
ephemeral `x` be specified.
In other words, can types be specified on anything inside a comprehension?

 # class attributes
 s = socket.socket(...)
 s.type, s.family, s.proto  # int
 s.fileno  # callable
 If annotations are only available for methods, it will lead to
 Java-style explicit getters and setters.
 Python language and data model prefers properties instead, thus
 annotations are needed on attributes.

 class Thing:
 a = 42  # can be inferred
 b = []  # inferred as List[Any]
 c = []  #type: List[float]

Good point, I suppose comments + stub file may be sufficient.

Stub is better (required?) because it allows to specify types of
attributes that are not assigned in class scope, but that are expected
to be there as result of __init__ or because it's a C extension.

An example in PEP would be good.
___
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] What's missing in PEP-484 (Type hints)

2015-05-07 Thread Dima Tisnek
 # plain data
 user1 = dict(id=123,  # always int
 name=uuu,  # always str
 ...)  # other fields possible
 smth = [42, xx, ...]
 (why not namedtuple? b/c extensible, mutable)
 At least one PHP IDE allows to annotate PDO.
 Perhaps it's just bad taste in Python? Or is there a valid use-case?

 Most (all?) of this is actually mentioned in the PEP:
 https://www.python.org/dev/peps/pep-0484/#type-comments

The question was about mixed containers, e.g.:
x = [12, Jane]
y = [13, John, 99.9]

There first element is always int, second always str, and rest is variable.
___
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] What's missing in PEP-484 (Type hints)

2015-05-07 Thread Guido van Rossum
On Thu, May 7, 2015 at 7:25 AM, Dima Tisnek dim...@gmail.com wrote:

 On 30 April 2015 at 14:33, Steven D'Aprano st...@pearwood.info wrote:
  On Thu, Apr 30, 2015 at 01:41:53PM +0200, Dima Tisnek wrote:
  # internal vs external
  @intify
  def foo() - int:
  b = 42
  return b  # check 1
  x = foo() // 2  # check 2
 
  Does the return type apply to implementation (str) or decorated
 callable (int)?
 
  I would expect that a static type checker would look at foo, and flag
  this as an error. The annotation says that foo returns an int, but it
  clearly returns a string. That's an obvious error.

 Is this per PEP, or just a guess?

 I think PEP needs to be explicit about this.


The PEP shouldn't have to explain all the rules for type inferencing.
There's a section What is checked? that says (amongst other things):

  The body of a checked function is checked for consistency with the
  given annotations.  The annotations are also used to check correctness
  of calls appearing in other checked functions.

 Normally local variables will have their type inferred from the
  operations done to them:
 
  s = arg[1:]  # s has the same type as arg

 Good point, should be mentioned in PEP.


Again, what do you want the PEP to say? I am trying to keep the PEP shorter
than the actual code that implements the type checker. :-)


 Technically, type can be empty list, mixed list or custom return type
 for overloaded __getitem__ that accepts slices.

 I'm sorry if I was not clear. My question was how should type of
 ephemeral `x` be specified.
 In other words, can types be specified on anything inside a comprehension?


That's actually a good question; the PEP shows some examples of #type:
comments in peculiar places, but there's no example using list
comprehensions. Your best bet is to leave it to the type inferencer; if
your comprehension is so complex that need to put type annotations on parts
of it, you may be better off rewriting it as a regular for-loop, which
offers more options for annotations.


 Stub is better (required?) because it allows to specify types of
 attributes that are not assigned in class scope, but that are expected
 to be there as result of __init__ or because it's a C extension.


Note that the PEP does not explicitly say whether the information of a stub
might be *merged* with the information gleaned from the source code. The
basic model is that if a stub is present the implementation source code is
not read at all by the type checker (and, conversely, information from
stubs is not available at all at runtime). But it is possible for some type
checker to improve upon this model.


 An example in PEP would be good.


Can you give an example that I can edit and put in the PEP?

-- 
--Guido van Rossum (python.org/~guido)
___
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] What's missing in PEP-484 (Type hints)

2015-05-02 Thread Florian Bruhin
* Dima Tisnek dim...@gmail.com [2015-04-30 13:41:53 +0200]:
 # lambda
 Not mentioned in the PEP, omitted for convenience or is there a rationale?
 f = lambda x: None if x is None else str(x ** 2)
 Current syntax seems to preclude annotation of `x` due to colon.
 Current syntax sort of allows lamba return type annotation, but it's
 easy to confuse with `f`.

Not sure if you'd really want to stuff type annotations into a
lambda... at that point you'd IMHO be better off by using a real
function.

 # local variables
 Not mentioned in the PEP
 Non-trivial code could really use these.
 
 
 # global variables
 Not mentioned in the PEP
 Module-level globals are part of API, annotation is welcome.
 What is the syntax?
 
 
 # comprehensions
 [3 * x.data for x in foo if bar in x.type]
 Arguable, perhaps annotation is only needed on `foo` here, but then
 how complex comprehensions, e.g. below, the intermediate comprehension
 could use an annotation
 [xx foj y in [...] if ...]
 
 
 # class attributes
 s = socket.socket(...)
 s.type, s.family, s.proto  # int
 s.fileno  # callable
 If annotations are only available for methods, it will lead to
 Java-style explicit getters and setters.
 Python language and data model prefers properties instead, thus
 annotations are needed on attributes.
 
 
 # plain data
 user1 = dict(id=123,  # always int
 name=uuu,  # always str
 ...)  # other fields possible
 smth = [42, xx, ...]
 (why not namedtuple? b/c extensible, mutable)
 At least one PHP IDE allows to annotate PDO.
 Perhaps it's just bad taste in Python? Or is there a valid use-case?

Most (all?) of this is actually mentioned in the PEP:
https://www.python.org/dev/peps/pep-0484/#type-comments

Florian

-- 
http://www.the-compiler.org | m...@the-compiler.org (Mail/XMPP)
   GPG: 916E B0C8 FD55 A072 | http://the-compiler.org/pubkey.asc
 I love long mails! | http://email.is-not-s.ms/


pgpZkNAI4_hcR.pgp
Description: PGP signature
___
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


[Python-Dev] What's missing in PEP-484 (Type hints)

2015-04-30 Thread Dima Tisnek
# Syntactic sugar
Beautiful is better than ugly,  thus nice syntax is needed.
Current syntax is very mechanical.
Syntactic sugar is needed on top of current PEP.


# internal vs external
@intify
def foo() - int:
b = 42
return b  # check 1
x = foo() // 2  # check 2

Does the return type apply to implementation (str) or decorated callable (int)?
How can same annotation or a pair of annotations be used to:
* validate return statement type
* validate subsequent use
* look reasonable in the source code


# lambda
Not mentioned in the PEP, omitted for convenience or is there a rationale?
f = lambda x: None if x is None else str(x ** 2)
Current syntax seems to preclude annotation of `x` due to colon.
Current syntax sort of allows lamba return type annotation, but it's
easy to confuse with `f`.


# local variables
Not mentioned in the PEP
Non-trivial code could really use these.


# global variables
Not mentioned in the PEP
Module-level globals are part of API, annotation is welcome.
What is the syntax?


# comprehensions
[3 * x.data for x in foo if bar in x.type]
Arguable, perhaps annotation is only needed on `foo` here, but then
how complex comprehensions, e.g. below, the intermediate comprehension
could use an annotation
[xx for y in [...] if ...]


# class attributes
s = socket.socket(...)
s.type, s.family, s.proto  # int
s.fileno  # callable
If annotations are only available for methods, it will lead to
Java-style explicit getters and setters.
Python language and data model prefers properties instead, thus
annotations are needed on attributes.


# plain data
user1 = dict(id=123,  # always int
name=uuu,  # always str
...)  # other fields possible
smth = [42, xx, ...]
(why not namedtuple? b/c extensible, mutable)
At least one PHP IDE allows to annotate PDO.
Perhaps it's just bad taste in Python? Or is there a valid use-case?


# personal note
I think it's amazing how much thought has already been put into this
proposal. The foundation is pretty solid (per Guido talk). I am not at
all opposed to software that infers types (like jedi), or reads
user-specified types (like phpstorm and pep 484) and does something
good with that. In fact I'm ambivalent to current proposal, standard
and promise of better tools on one hand; narrow scope, debatable looks
on the other.


-- dima
___
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] What's missing in PEP-484 (Type hints)

2015-04-30 Thread Steven D'Aprano
On Thu, Apr 30, 2015 at 01:41:53PM +0200, Dima Tisnek wrote:

 # Syntactic sugar
 Beautiful is better than ugly,  thus nice syntax is needed.
 Current syntax is very mechanical.
 Syntactic sugar is needed on top of current PEP.

I think the annotation syntax is beautiful. It reminds me of Pascal.


 # internal vs external
 @intify
 def foo() - int:
 b = 42
 return b  # check 1
 x = foo() // 2  # check 2
 
 Does the return type apply to implementation (str) or decorated callable 
 (int)?

I would expect that a static type checker would look at foo, and flag 
this as an error. The annotation says that foo returns an int, but it 
clearly returns a string. That's an obvious error.

Here is how I would write that:


# Perhaps typing should have a Function type?
def intify(func: Callable[[], str]) - Callable[[], int]:
@functools.wraps(func)
def inner() - int:
return int(func())
return inner


@intify
def foo() - str:
b = 42
return b


That should, I hope, pass the type check, and without lying about the 
signature of *undecorated* foo.

The one problem with this is that naive readers will assume that 
*decorated* foo also has a return type of str, and be confused. That's a 
problem. One solution might be, don't write decorators that change the 
return type, but that seems horribly restrictive. Another solution 
might be to write a comment:

@intify  # changes return type to int
def foo() - str:
...

but that's duplicating information already in the intify decorator, and 
it relies on the programmer writing a comment, which people don't do 
unless they really need to.

I think that the only solution is education: given a decorator, you 
cannot assume that the annotations still apply unless you know what the 
decorator does.


 How can same annotation or a pair of annotations be used to:
 * validate return statement type
 * validate subsequent use
 * look reasonable in the source code
 
 
 # lambda
 Not mentioned in the PEP, omitted for convenience or is there a rationale?
 f = lambda x: None if x is None else str(x ** 2)
 Current syntax seems to preclude annotation of `x` due to colon.
 Current syntax sort of allows lamba return type annotation, but it's
 easy to confuse with `f`.

I don't believe that you can annotate lambda functions with current 
syntax. For many purposes, I do not think that is important: a good type 
checker will often be able to infer the return type of the lambda, and 
from that infer what argument types are permitted:

lambda arg: arg + 1

Obviously arg must be a Number, since it has to support addition with 
ints.


 # local variables
 Not mentioned in the PEP
 Non-trivial code could really use these.

Normally local variables will have their type inferred from the 
operations done to them:

s = arg[1:]  # s has the same type as arg

When that is not satisfactory, you can annotate variables with a comment:

s = arg[1:]  #type: List[int]

https://www.python.org/dev/peps/pep-0484/#id24


 # global variables
 Not mentioned in the PEP
 Module-level globals are part of API, annotation is welcome.
 What is the syntax?

As above.


 # comprehensions
 [3 * x.data for x in foo if bar in x.type]
 Arguable, perhaps annotation is only needed on `foo` here, but then
 how complex comprehensions, e.g. below, the intermediate comprehension
 could use an annotation
 [xx for y in [...] if ...]

A list comprehension is obviously of type List. If you need to give a 
more specific hint:

result = [expr for x in things if cond(x)]  #type: List[Whatever]

See also the discussion of cast in the PEP.

https://www.python.org/dev/peps/pep-0484/#id25


 # class attributes
 s = socket.socket(...)
 s.type, s.family, s.proto  # int
 s.fileno  # callable
 If annotations are only available for methods, it will lead to
 Java-style explicit getters and setters.
 Python language and data model prefers properties instead, thus
 annotations are needed on attributes.

class Thing:
a = 42  # can be inferred
b = []  # inferred as List[Any]
c = []  #type: List[float]



-- 
Steve
___
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