3

PEP-484 provides semantics for type annotations. These are geared very much towards a) documentation and b) help for IDEs. They are less geared towards code optimization.

For example, it is unfortunately not possible to use PEP 484 annotations either with Cython https://groups.google.com/d/msg/cython-users/DHcbk78rDec/6-b5XtCRGBEJ

or with Numba, the latter using its own annotation format in the form of strings like "float64(int32, int32)" http://numba.pydata.org/numba-doc/0.24.0/reference/types.html

How do I work within the framework of PEP 484 with my own types? I explicitly do not want to break PEP-484 semantics, but augment the existing types with additional information visible to my own type checker, but invisible to any PEP-484 conforming type checker or IDE.

Will the following be interpreted within the PEP-484 semantics as List[int]?

class Int32(int): pass
x = [1]   # type: List[Int32]

How about a more fancy type like this?

def combine(typeA, typeB):
    class X(typeA, typeB): pass
    return X

class Metre(): pass

# is y an 'int' to PEP-484 typecheckers?
y = 1 # type: combine(Int32, Metre)

Any recommendations for libraries to work with type-hinting, both for type parsing and type checking?

Dan
  • 161
  • 1
  • 4
  • Similar question on `numpy` and 484 - http://stackoverflow.com/q/35673895/901925 – hpaulj Jun 24 '16 at 07:12
  • I am interested in studying different type systems. I would like to have a system with the flexibility of Shen (http://www.shenlanguage.org/learn-shen/types/types_sequent_calculus.html) and the ability to define own types and typing rules. The first step is to build a static checker for units of measurement. The 484 typing semantics are very tempting, b/c they are very flexible, for example I (hope) to express that a variable is of type Int32 and at the same time has the dimension metre. The optimizer is happy with int32, physical units are checked, and the gui recognizes y as an int. – Dan Jun 24 '16 at 07:17
  • good link to the numpy question, that goes in the right long term direction, I also like the datashape project. To get started, I am more interested in the typing side how to handle my own types in the 484 context and how to parse the type information from the program. Of course, I hope that in the future external libraries will be able to share type annotations to the maximum possible extent. – Dan Jun 24 '16 at 07:28

1 Answers1

3

Since Python 3.5, we not only have the PEP 483, PEP 484, but also typing module that implements it.

For complete understanding, you might want to read through those 3 documents. But for your specific case, the short answer is that in PEP484 realm you can work with own types in 4 ways:

  1. just annotate using own types,
  2. create type aliases,
  3. use NewType, or
  4. use own generic types

If what you seek is above all else:

additional information visible to my own type checker, but invisible to any PEP-484 conforming type checker

then the 2nd approach gives you just that. If you do:

Int32 = int
Int64 = int

x = 0 # type: Int32
y = 0 # type: Int64

Then Int32 and Int64 would be the same in PEP484 realm, but you could add some additional checks by looking into the AST (Abstract Syntax Tree) of your code using community-maintained typed-ast module. That module parses type comments in addition to code, so you can read the exact annotation used, and thus get some additional type information for x and y.


And, if being invisible is not the number one priority, then:

  • instead of class Int32(int): pass I would rather do typing.NewType('Int32', int), and

  • instead of combine(Int32, Metre) I would use typing.Union[Int32, Metre].

i.e.

Int32 = typing.NewType('Int32', int)

class Metre:
    pass

x = [Int32(1)]  # type: List[Int32]
y = Int32(1) # type: typing.Union[Int32, Metre]

print(x[0] + 1) # ok, since Int32 is still int
y = Metre() # ok, since y can be Int32 or Metre

On the above code, you can run community-maintained static type-checker mypy.


Both typed-ast and mypy are now (year 2016) under very active development. Not everything works as expected, but as far as I can see they are good enough for many use cases already, and also there seem to be no alternatives.

mbdevpl
  • 4,605
  • 4
  • 30
  • 42