PyCon Day 3: Morning Sessions
Python Typology
Matthias Kramm
This is an example that could benefit from type checking
def make_announcement(emails):
for addr in emails:
send_email(addr)
make_announcement("users@goo.gl")
This sucks, because all of a sudden it sends a bunch of e-mails to ‘u’, ‘s’, ‘e’, etc.
The type annotation:
def make_announcement(emails: Iterable[Union[str, bytes]]) -> None:
for addr in emails:
send_email(addr)
make_announcement("users@goo.gl")
- Sometimes you can’t put the annotations directly into the source code.
- .pyi files
- “header files”
- .pyi is to .py what .h is to .c
- We’ve been using this to annotate the entire Python standard library
def abort() -> None: ...
ellipsis is real. Use that instead of the body of the function.
- Annotations don’t change how Python works!
>>> make_announcement("foo") # Does *not* throw an error
- You do need external tools
- mypy is the defacto standard
pytype
(speaker’s tool)
def f(x: int):
return x
f("foo")
$ mypy file.py
# Type error
- pycharm will give you a yellow bar over the line that has an error
def avg(x: Iterable[float]):
return sum(x)
def f(x: str):
x = 42
file.py: note: In function "f":
file.py:2: error: Incompatible types in assignment (expression has type "int", variable has type "str")
- pytype tries very hard to work for Python code that was written without type annotations
def foo(i: int):
m = []
x = m[i]
- Error cannot retrieve item out of list (empty?)
The Transition to Type Annotations: Part 1: Checking unannotated code
- pytype allows you to run type-checking on Python code that’s completely unannotated. (So does mypy with caveats)
import sys
sys.foobar()
file.py:3: error: "module" has no attribute "foobar
def f():
return "foo" + 42
- “file unsupported operand
import warnings
warnings.format working("out of foobar", filename="foobar_factory.py", lineno=42)
Catches unused mandatory params.
import math
math.sqrt(3j)
-
Can’t do that. These are all examples of benefits of using type checking even if you don’t have annotations in your own code
- You can automate the process of annotating.
- Two step process
$ pytype file.py -o file.pyi
No file.pyi
contains the (inferred) types of file.py
def get_label(self):
return self.name.capitalize()
- Assume that we don’t know the type of name. We just know that it’s something returned by the capitalize function.
- Same is true when you infer the type for the argument
def dict_subset(d):
return {key: d[key] for key in d.keys() if key.startswith(PREFIX)}
- It knows that the result if from the keys method so it can infer that it’s a string
- Sometimes the results depend on what modules you import
def f(i):
array = [1, 2, 3]
return array[i]
def miles_to_kilometers(m):
return m * 1.6
- Obviously it works with ints and floats, but we forgot about the complex type.
Future features
- duck typing
def compute_height(pressure: SupportsFloats):
return 10711.9 - float (pressure) * 10.57
class PressureSensor(object):
def __float__(self):
...
- Suppose we have two files a.py and b.py and a.py imports b.py
$ pytype a.py
File "a.py", line 1: Can't find module 'b'.
- More complicated tree/DAG
- We’re working on automated dependency analysis (“Think gcc -M”)
import lab...
- Shows graphs of dependency analysis
- Entire Google codebase
Questions
- Q: Motivating example unions Iterable and String etc. A: A string is actually an Iterable and pytype doesn’t actually catch this.
- Q: These tools only do static analysis. Is there anything that does runtime? A: Yes, but everything I’ve seen requires a decorator, that says check the types of this function. Which is OK, because you need to touch the function anyways, and then people know that this is type checked.
- Q: Have you done work on numpy/scipy, and being able to infer the shapes? Often these things run for a long time before finding error. A: At this point your not talking about types, you’re talking about values. Maybe… need to consider it.
- Q: What are your thoughts on parametric polymorphism? Any type variable extraction?
HTTP Can Do That?!
A collection of bad ideas
Sumana Harihareswara @brainwane Changeset Consulting
HTTP
- HypeText Transfer Protocol (you know this, but I have a deep deep need to enumerate acronyms)
- IETF RCF 7230
- Crash course
- Client (strange green head)
- Server (ominous, cubical, PRISM server)
- Request and Response
- Message: start-line (version, method, status code), headers (content-length, content-type), body (picture of a chandelier)
- Methods
- GET (gimme)
- POST (here you go)
- Above are the Dave Matthews Band of verbs
- They’re great and all, but maybe you can explore your horizons a bit farther
- Bad idea: write an API that only does POST but not GET
- CRUD (Create, Read, Update, Delete)
- There are methods for all of this
- DELETE is an under appreciated method to delete a resource
- HTTP 204 is “yup file is deleted”
- Is this a good idea? Kind of maybe
- Use proper auth, and keep it in a walled garden
- PUT
- Wait, I though POST was that?
- Usually we use POST for create a new set of data for this thing.
- PUT /cards/5 means “Put this picture at /cards/5”
- POST /cards/5 means, “Hey webapp, this picture kind of relates to /cards/5, but you figure out how
- PATCH
- Update the content on the server somehow
- OPTIONS
- Ask what verbs the client can use
- HEAD
- Like GET, but just gets the metadata
- Don’t get the body
- Often you only need…
- Does this resource exist?
- Do I have permission to GET it?
- How long is it, what’s the content type?
- Headers
- Content-types
- text/*
- application/*
- chemical/* Really?
- ETag
- If-Match
- If-None-Match
- If-Modified-Since
- Last-Modified
- You could do conditional GET; you can be a data vegan by living lightly on the earth and only getting data that is so big.
- An unpopular header: From (the e-mail address of the person making the request)
- Uses: Really bad auth
- “Yes, I saw your site launch”
- Coded messages meant for network surveillor
- Popular/required header
- Host
- Content-types
$ netcat myhostname.tld 80
GET / adsadfadf
blog comments powered by Disqus