foreign
taming the duck with type hints and it's
an introduction to static typing or type
hints in Python it's an introduction so
I'm going to go through things very
quickly what I'm really hoping is is
that if you've heard of it but you
haven't used it before that this might
give you some motivation to use it so
I'm going to do another one of these
very shallow but hopefully broad talks
first the context well python it uses a
typing system that I'm sure you're very
familiar with called duct typing which
I'll get into a bit later because I want
to contrast that with static typing and
the nice thing about it is it allows
programmers to be quick and to to very
quickly develop programs without
worrying about these pesky types and
again we we need to remember that python
was used in the the education system
early on in the U.S because it is a
simple elegant language
um but the issue is is that we don't
have to think about types but types are
still there and if we don't pass the
correct types to a function then we will
have a problem we will have an exception
so you know you've got the trade-off
you're extremely productive and fast but
errors can still be there
so what this talk is looking at is where
we get a Helper to help us with finding
those errors early on which is the type
hints
so in this talk what we're going to be
looking at is
um
the whole different kind of typing duck
or otherwise
and I'm hoping that it it
answers the question for you could it
actually help you because I'm not going
to say that everyone should be using
type hints that's silly people have
different ways they're they have
different areas that they're working in
but I'm I'm hoping that you know you can
make that decision a bit better we're
also going to look at some of the Python
syntax
to create these type pins because I want
to show you that it is quite a simple
process
and also there's the questions of if
you've already got to have a code base
how do you apply it do you have to apply
all or a bit at a time and and the last
point is what I started with which is
but most of all I'm hoping that you'll
want to try it just have a look see if
it suits your style
so it's a bit of a taste a taster of
type hints
okay just a bit of background about
myself
why am I interested in type hints well
it's mainly because I've been working
with statically typed languages for over
30 years and
um
as a kind of professional programmer I
want my tools so my whole environment my
compilers my editors all that I want
them to help me to create code to be
able to understand code so that's more
kind of the editor and tools but also to
make more correct code
debugging is much harder than if you
write it correctly in the first place
so uh and with uh C C plus plus I'm used
to a compiler that gives me these uh
these checks so that I can write more
correct code
but I've started using the type hints
um so I haven't used them a heck of a
lot but
um because I'm not focusing totally on
python but I do use it for uh tooling
and test
and I found that I am getting the same
sort of benefits that I get from my c
plus compiler when I'm using the type
pins
just an aside
about five years ago I actually went to
go language for a while and it was all
because I was frustrated that when I had
large code bases in Python I couldn't
find the mistakes without testing or
shipping even worse
so I liked go but I still really liked
the python uh better but I did find
things like interfaces and that that
we'll be looking at a bit later that
were very useful
so so that's why I'm interested in this
okay so let's start talking about types
and types of types is kind of neat it
sounds very meta but um as I said at the
very beginning python has types uh so
like you know integers spools floats all
of those types that we're used to and
also some of the types
of why I found python so interesting
when I first came to it which were the
collection types the tuples and
dictionaries and they also have some
special ones like callable and things
like that that are quite interesting so
python has lots of types in fact every
object or variable that you create in
Python has a type and a value and an ID
and some other things but every object
is an object of a certain type
and the type that the object is that
defines what operations are valid on
that the value of the type what will
what it can do
I've got some examples that will make
more sense in a second
so um and when we try to use an invalid
operation on an object we get an
exception so this is the case where you
have a function that's doing something
somebody's passed a object in which is
of the wrong type you try to use it you
get an exception now something I find
that's really good about python is this
fail fast idea
so it doesn't try to coerce types behind
the scenes for you and and like you know
just carry on instead it tries to do the
operation and if it can't do it an
exceptions raised and in fact there's
been a lot of work on error messages
recently that has made these error
messages that that you get in the
exception make a lot more sense
so I actually like that
by the way I'm I'm going to be using
names in this talk not particularly
precisely and that's because I just want
to get the idea across so you know I I
but one one type one name I'm using a
lot of is type hints and I'm sticking
with that because I really like the idea
that it's saying this is a hint it's not
part of the language it's not
constraining the language it's a hint to
other tools
so instead of things like type
annotations or statically typed that's
why we call it type hints
okay
right so I'm going to look well that's
where the high isn't it
um I'm going to just look at some of the
terms that we talk about when we say
python is a dynamically typed duct type
language
so
in the in the way that I'm looking at
Dynamic typing here is just the fact
that if you have a variable I'm going to
call a variable instead of an object if
you have a variable of a particular name
like Factor
it now has a type
so when it's first assigned python knows
this is a string and if I actually ran
this the type Factor would actually say
yeah it's a string
but we can actually change that type so
when we say Factor equal 2.7 as well as
changing the value it changes the type
for that so that's the dynamic typing
that I'm talking about here now again it
makes it easier to program in Python
especially for beginners because there's
less rules for them to learn it just
kind of works
so so there's definitely a benefit there
but it also as your program grows it
actually makes it harder to reason and
discuss the code because what is Factor
well Factor at the top is one thing and
Factor later is something different so
it has a bit of a code smell
that is valid in the language but isn't
necessarily the best coding
to use
okay the good one the interesting one
duct typing now I'm sure most of you are
aware of this you've been using python
but
um the idea behind it is
um is it comes from this this saying
that if it walks like a duck and quacks
like a duck then it must be a duck so
this is kind of like a good enough
principle if it's close enough to a duck
the stuff I want like in this case it
would be walking and quacking as long as
it can do those two things I'm going to
call it a duck for my purposes
so that's the idea behind duct typing
and python uses that
by assuming so it's it's an optimist
it's saying well hey I've got a function
you've passed me a parameter and you
know that it should be a duck so I'm
going to assume it's a duck and I'll ask
it to quack for me
and if we actually ask it to quack and
it doesn't know how to quack
taking this one a bit far unfortunately
but then
we will get an exception so if the type
isn't compatible isn't the right type we
will get an exception
so another thing I I just I'll be saying
a couple times during this talk is that
all python code uses and will and will
continue to use duck and dynamic typing
nobody's suggesting we actually change
that
so when you take a look at this code you
can see that there's a function scaled
down which takes a value and a factor so
it's an idea of scaling down a number
and returning that and at the very
beginning we pass it the float value and
the float or integer factor and the
scale value it runs fine
but if we then change the factor to
actually be of a different type where
it's now string then when we run it we
get this exception raised
so um and that's that is python just
giving it giving it a go and finding
that it didn't work and then informing
the user failing fast
okay type hints
10 minutes in we're starting to talk
about type hints so
what's happened here is on the uh the
top function
I have added hints to tell
to tell who I'll say in a second but uh
it's hints for what the type of the
um of the value when factor is and also
uh what it returns so the hint is just a
type
um after a colon for the arguments and
an arrow and a type for the return but
everything else looks exactly the same
you still have the colon at the end of
the float on the right to say that we
are defining a function and the body's
below nothing else has changed there
but the interesting bit is if we now run
this in Python nothing changes and
that's that's what's important because a
lot of people when type hits first were
talked about in 2015 they were totally
against them because they're saying this
is changing language I know and love
but it didn't change the language
why have we done it
well we've done it because we can now
use type checkers
and so this slide is talking about a
particular type chat Checker called My
Pie and there's quite a few out there
and on the um on the top line I'm saying
that there's Pi type PI right Pi Pi
charm
um so and and more I'm just using my Pi
because it's you know open source easy
to see it was one of the first ones
along with pie charm
and uh and so yeah through this talk
we're just talking about my pie
so running this type Checker is as
simple as invoking my pie with the name
of your top level file
and it will actually look at all files
that it Imports and and do an analysis
using the type hints to uh to figure out
what should be correct
so when that happens we actually get two
errors I'm going to look at the second
one first so the second error is exactly
where python complained where it was
saying that the second argument I can't
divide that because dividing a a float
by a string isn't supported
but the first error is kind of
interesting so this one is looking at
the dynamic types and as I said before
Dynamic types are okay in the language
but it does and can make your code a bit
harder to understand so instead of
dynamic types why not have two different
variables and then the names can
actually make more sense so it's
actually
it's actually picked up that the type of
that variable had changed
and we're going to look at how it does
that in a second
okay so static typing with Dynamic
typing
um
so
and Doc but we're going to get more to
that in a minute but the static typing
comes by way of type hints as we saw and
that we use different uh type checking
tools to check that the other nice thing
is is that the Ides or editors are using
that same information now pycharm
started it from my reading but now like
my editor emacs it understands it as
well so it's actually checking doing
those my pie checks as I as I type
and I just again this this was the last
time I'll say it but the goal of type
hints at least in the C python
implementation is not to not to use them
for the language
but it's to be used by the separate
tools
and that was said in in pet 526
okay
so now we're going to look at uh
we looked at using type hints for
function arguments now let's take a look
at using type hints for variables
and
the top example I'm having trouble
reading my screen here because of the
lights but the top example is is where
we have two variables color and files
and
um
my pie infers the types
when it sees them as I kind of mentioned
before and in this little piece of code
I've
changed the type on it
so so then when I run my Pi on it so
there's no functions here at all but
when I run my tie my Pi on it it's
telling me again that these types have
changed
so so it gives it to me for free
um
but that inferring of types it does have
some problems an example of that is when
we want to use none to carry error
information back from a function say so
we we start out and we say okay this
variable is none but normally if we if
we didn't have an error it's going to be
a list of strings so that's what my
files one was there
so on the the second code fragment
we're using a module that is in Python
called typing and we're using a a
something out of that called optional so
I've just thrown this in now I'll
explain this in more detail further on
but then we're we're making the type of
file list we're giving the hint that it
is a list of strings
or it could be none and that's exactly
what optional means so when I assign
none to it my pie at the bottom it was
fine with that
if I just said it was a list of strings
it would have given me an error on that
so now I can assign a a new list of
strings to it I can add to that bit of a
mistake in my code I meant to say file
two but hey we can live
okay now this is something that I really
like where with python as we all know we
have a convention for constants which is
just the uppercase snake case for
constants and that's worked reasonably
well but if somebody actually assigns to
the constant later there's no
implications of that so it's easy for us
to have an error in it so again from the
typing module we have this idea of a
final which means it can be assigned
once but it can't be changed
so with the with the type or with the
constants the default scale factor and
so on I've defined sorry I've hinted
that this can't be changed it's final
and it has a type of float
um and similarly with the string
I'm violating that in the next in uh
lines
um
eight and nine so I'm violating that and
when I run my pi over it it's telling me
that the problem here was not that the
that you had a change of type it was
that you assigned to it at all I really
like this I'm always assuming that you
know I'll set up something and I'll say
hey this is a constant and then somebody
will change it and it's hard to find so
uh so it's a small thing but I really
like it
ah okay
um so type Checkers understand a lot of
types so we're now up to a stage where a
lot of peps have come through the system
since uh python 3.5 and there's been a
lot of extra tight Machinery added so
that we can easily put in hints that
really reflect our code
so um so we've got all the simple types
like integers floats and so on but we
also have the collections and you can
see the syntax there where we use a
square bracket to say what the types are
for that collection so Tuple it can have
each of its
indices each of its things in the Tuple
can be different types so I've said that
as T1 T2 and so on where with a list we
we have a single type and a set and a
dictionary we have a type for the key
and a type for the value and they can be
different
and of course
any of those types can be inside a
collection so you can start to have
types inside types but it reflects the
code we write and that's the key thing
if the Machinery wasn't up to the code
that we write
nobody would use it
okay
um
yeah so so I just did a reason big
complex one with that list which has a
tuple and so on and the other one of
course is classes classes are types as
well so we can use a class from the
standard Library we can use our own and
we can
um
type hint that we expect an object of
this particular class
okay so some some really bad examples
they're just little code Snippets of
just showing how we can use the type
hints
um
with the count list where we pass in we
say that we will pass in a list of
integers and return an integer same idea
for find keys
but we're using a dictionary so that
that syntax is it's pretty small there's
not a lot of noise
originally There Was You Know type hints
in documentation all that stuff it was
so verbose for a uh a small
code fragment like this your type
information would be larger than the
fragment so this is quite
um quite succinct
with the line eight I'm actually using
something called the type Alias and the
idea here is to make things readable so
we we actually b day is uh is actually a
new type
which means the Tuple type that you see
there and I'll show that in in a slide
or two
so we have our ad birthdays that take a
list of that Tuple type and a single
Tuple type or sorry yeah a single
um
uh b-day one to add a birthday to that
list
okay
again I'm going through stuff really
quickly because I'm assuming that a lot
of people are are used to some of this
and I want to get to some interesting
ones but I've put this slide early
because I was afraid that I would go too
slow and I would run out of time so I
still have seven minutes so it's not too
bad
but um so here's the question that I
wanted to answer at the beginning and I
want you know have I convinced you that
these are easy to use but helpful so
again this is the third time I'm going
to mention that python remains a dynamic
duct type language and you lose nothing
when you go to type hints
though there are some cons which is
coming up so the pros what do you get
well it means that you can use a type
Checker to help you so in this case I
was using my pie but it's true of a
whole bunch of other ones
and one of the interesting things is is
that there is the definition of the full
standard Library when you download My
Pie you get this thing called the type
shed with the current instance of it and
it it has all of the stubs for the
standard Library so all of your use will
be checked
um all of your code will be checked when
you use the standard Library I mentioned
before that Ides and editors are using
these hints to provide better tooling
I'm really liking that
better documentation
as well where you're actually saying
what your intent is with the code that
you're expecting that a a variable of
this type will be passed to you the
downside is that you have to take the
time to one not reuse variables for
different purposes
think about the functions a bit more and
be explicit about the types add the type
hints in and the other one is is run a
type Checker against it because you
don't run a type Checker against it that
was a bit of a waste of time
and if you have a large code base that
can be a bit more difficult to add type
hints because when you start adding type
hints you will start getting errors and
um
it can be a bit more difficult
and
um
again everybody doesn't have to use type
hints because it just depends on if it
goes with your style but trying it I
think that's something that we can do
okay uh so some more interesting
Machinery is
um
I've shown optional from the typing
module we also have some other special
types like any
uh and any is the default type when my
Pi looks at your code to check it it
defaults to any for all of the arguments
all of the variables and what any means
is it basically just means anything can
happen so there's no use to check it
because anything can happen
so that's the default any string is kind
of interesting because we often
we often have interfaces that take
either a string or bytes any string says
it's just a type that can be either of
those but it make sure you don't mix
them so if you want bytes to be passed
for both parameters and this will do it
for you or string
the other interesting one I really like
is the union so the union is a way of
saying ah in this in this function I
will take Floats or I will take strings
now of course if you do that you then
have to
make sure that you check it correctly in
your code because you could get one or
the other you can't assume that it's
going to be afloat but that's where we
have things like is instance and it is
subclass
uh where we can do that check same thing
with the optional we'd have to check to
see if none was passed in but then we
have the if this is none so we've got a
way to do that
uh the code here uh you can just see
I've got Union showing there and that's
actually the old style of Union too
difficult don't want to have to do that
but you can see where we've just had a
union of a string interfloat and we're
using the is instance in the code to
make sure we we don't call a function on
something that it the type doesn't
support on the take take various the
second one now we actually have I think
this came in in 310 we can use the uh
the or bar in type hints to um
to
um
let us Define
Union type hints and that is used a lot
okay I'm running a bit long one other
thing I just want to say because it's so
interesting is I want to describe
something called a protocol and what
this is is this is duct taping it's
actually called structural typing in
this case but it allows us to say that
this function it takes not a particular
type but it takes an object that has
quack
um so what we do is we create on line
three a protocol called supports quack
in this case and see the syntax where we
just Define the signature of a function
but then we use Ellipsis dot dot and
that means we don't care about the body
we're only talking about the function
signature
and then if we try to run this we we get
an error because they're
um sorry this isn't running this is my
Pi this is the whole point when we try
to check it
we get an error immediately which is
saying that hey this one doesn't support
quack
if we try it with a duck object
that does support quack then my Pi is
totally fine so this is where we're
starting to go full circle where we can
still have duct typing but we can also
have checking as well
there is this idea of gradual type
hinting and it's because we've got
millions of lines of python code so
um so we we can just start putting
typing on just a couple functions and
just a couple files and we can still
check things and we've I've got some
hints at the bottom there where with my
Pi the first one is is that we can use
an option called ignore missing Imports
which allows us to say don't worry about
anything that I bring in
um sorry I've got a wrap up uh work on
type hints has been very fast and
furious 30 peps in eight years that's
ridiculous but that's because getting
tight Machinery is hard
uh I've got some references here
um the one I just want to point out is
go to the mypie org website and it has
is it my pug work uh anyways the my Pi
website it actually has a really good
tutorial on everything to do with these
types
thank you very much and don't forget to
run the type checker
thank you Brian
um unfortunately we won't have time to
take questions but um there's the mug
thanks very much this is why we do it
um we'll be now heading on for a break
and then we'll be having lightning talks
in Hall C at 350. thank you everyone
[Applause]