diff --git a/modules/python.mlw b/modules/python.mlw
index 512007363661b39a7d0c79ac125162df4407c9f3..a171e300b0343058055e18d0e529e4c57ac14938 100644
--- a/modules/python.mlw
+++ b/modules/python.mlw
@@ -30,4 +30,9 @@ module Python
     ensures  { S.length !result = u - l }
     ensures  { forall i. l <= i < u -> result[i] = i }
 
+  (* TODO: specify division and modulus according to
+     https://docs.python.org/3/reference/expressions.html *)
+  function div int int : int
+  function mod int int : int
+
 end
diff --git a/plugins/python/py_ast.ml b/plugins/python/py_ast.ml
index 75b63efa5404cc7bae3099479613afd38423a823..7da0690120165cb10a09f1f1451334b145b0be30 100644
--- a/plugins/python/py_ast.ml
+++ b/plugins/python/py_ast.ml
@@ -50,10 +50,10 @@ and stmt_desc =
   | Sassign of ident * expr
   | Sprint of expr
   | Swhile of expr * Ptree.loop_annotation * block
-  | Sfor of ident * expr * block
+  | Sfor of ident * expr *  Ptree.loop_annotation * block
   | Seval of expr
   | Sset of expr * expr * expr (* e1[e2] = e3 *)
-  | Sassert of Ptree.term
+  | Sassert of Ptree.assertion_kind * Ptree.term
 
 and block = stmt list
 
diff --git a/plugins/python/py_lexer.mll b/plugins/python/py_lexer.mll
index 63d2afceaf4e5549b7f8c59d2f84ffbb4d43d4eb..da0fb6ede563f8c01eef0cbc6e7ff0ac04ed5234 100644
--- a/plugins/python/py_lexer.mll
+++ b/plugins/python/py_lexer.mll
@@ -16,6 +16,10 @@
 
   exception Lexing_error of string
 
+  let () = Why3.Exn_printer.register (fun fmt exn -> match exn with
+  | Lexing_error s -> Format.fprintf fmt "syntax error: %s" s
+  | _ -> raise exn)
+
   let id_or_kwd =
     let h = Hashtbl.create 32 in
     List.iter (fun (s, tok) -> Hashtbl.add h s tok)
@@ -67,12 +71,15 @@ rule next_tokens = parse
   | "##" space* "invariant" space+ { [INVARIANT] }
   | "##" space* "variant"   space+ { [VARIANT] }
   | "##" space* "assert"    space+ { [ASSERT] }
+  | "##" space* "assume"    space+ { [ASSUME] }
+  | "##" space* "check"     space+ { [CHECK] }
+  | "##"    { raise (Lexing_error "expecting an annotation") }
   | ident as id
             { [id_or_kwd id] }
   | '+'     { [PLUS] }
   | '-'     { [MINUS] }
   | '*'     { [TIMES] }
-  | '/'     { [DIV] }
+  | "//"    { [DIV] }
   | '%'     { [MOD] }
   | '='     { [EQUAL] }
   | "=="    { [CMP Beq] }
diff --git a/plugins/python/py_main.ml b/plugins/python/py_main.ml
index c4f49af8dd619a44a86ee3bb3c1c0718c9a12c0b..87b72c96008e3490ef8c4a704b3085f4517a1ff9 100644
--- a/plugins/python/py_main.ml
+++ b/plugins/python/py_main.ml
@@ -80,8 +80,8 @@ let rec expr env {Py_ast.expr_loc = loc; Py_ast.expr_desc = d } = match d with
       | Py_ast.Badd -> Eidapp (infix ~loc "+", [e1; e2])
       | Py_ast.Bsub -> Eidapp (infix ~loc "-", [e1; e2])
       | Py_ast.Bmul -> Eidapp (infix ~loc "*", [e1; e2])
-      | Py_ast.Bdiv -> assert false (*TODO*)
-      | Py_ast.Bmod -> assert false (*TODO*)
+      | Py_ast.Bdiv -> Eidapp (Qident (mk_id ~loc "div"), [e1; e2])
+      | Py_ast.Bmod -> Eidapp (Qident (mk_id ~loc "mod"), [e1; e2])
       | Py_ast.Beq  -> Eidapp (infix ~loc "=", [e1; e2])
       | Py_ast.Bneq -> Eidapp (infix ~loc "<>", [e1; e2])
       | Py_ast.Blt  -> Eidapp (infix ~loc "<", [e1; e2])
@@ -120,13 +120,13 @@ let rec stmt env ({Py_ast.stmt_loc = loc; Py_ast.stmt_desc = d } as s) =
       mk_expr ~loc (Einfix (x, mk_id ~loc "infix :=", e))
     else
       block env ~loc [s]
-  | Py_ast.Sfor (_id, _e, _s) ->
+  | Py_ast.Sfor (_id, _e, _a, _s) ->
     assert false (*TODO*)
   | Py_ast.Sset (e1, e2, e3) ->
     mk_expr ~loc (Eidapp (mixfix ~loc "[]<-",
                           [expr env e1; expr env e2; expr env e3]))
-  | Py_ast.Sassert t ->
-    mk_expr ~loc (Eassert (Aassert, deref env t))
+  | Py_ast.Sassert (k, t) ->
+    mk_expr ~loc (Eassert (k, deref env t))
 
 and block env ?(loc=Loc.dummy_position) = function
   | [] ->
diff --git a/plugins/python/py_parser.mly b/plugins/python/py_parser.mly
index 5ce06cd596cea0bca2aae9742d7352d5f4c84447..67ef15971f9d2cd9212e310c76d79d09d3889b87 100644
--- a/plugins/python/py_parser.mly
+++ b/plugins/python/py_parser.mly
@@ -14,6 +14,10 @@
   open Ptree
   open Py_ast
 
+  let () = Why3.Exn_printer.register (fun fmt exn -> match exn with
+    | Error -> Format.fprintf fmt "syntax error"
+    | _ -> raise exn)
+
   let floc s e = Loc.extract (s,e)
   let mk_id id s e = { id_str = id; id_lab = []; id_loc = floc s e }
   let mk_term d s e = { term_desc = d; term_loc = floc s e }
@@ -46,7 +50,7 @@
 %token LEFTPAR RIGHTPAR LEFTSQ RIGHTSQ COMMA EQUAL COLON BEGIN END NEWLINE
 %token PLUS MINUS TIMES DIV MOD
 (* annotations *)
-%token INVARIANT VARIANT ASSERT
+%token INVARIANT VARIANT ASSUME ASSERT CHECK
 %token ARROW LRARROW FORALL EXISTS DOT THEN LET
 
 (* precedences *)
@@ -145,14 +149,18 @@ stmt_desc:
     { Sif (c, s, []) }
 | IF c = expr COLON s1 = suite ELSE COLON s2 = suite
     { Sif (c, s1, s2) }
-| WHILE e = expr COLON s = simple_stmt NEWLINE
-    { Swhile (e, empty_annotation, [s]) }
-| WHILE e = expr COLON NEWLINE BEGIN a=loop_annotation l=nonempty_list(stmt) END
-    { Swhile (e, a, l) }
-| FOR x = ident IN e = expr COLON s = suite
-    { Sfor (x, e, s) }
+| WHILE e = expr COLON b=loop_body
+    { let a, l = b in Swhile (e, a, l) }
+| FOR x = ident IN e = expr COLON b=loop_body
+    { let a, l = b in Sfor (x, e, a, l) }
 ;
 
+loop_body:
+| s = simple_stmt NEWLINE
+  { empty_annotation, [s] }
+| NEWLINE BEGIN a=loop_annotation l=nonempty_list(stmt) END
+  { a, l }
+
 loop_annotation:
 | (* epsilon *)
     { empty_annotation }
@@ -178,12 +186,17 @@ simple_stmt_desc:
     { Sset (e1, e2, e3) }
 | PRINT e = expr
     { Sprint e }
-| ASSERT t = term
-    { Sassert t }
+| k=assertion_kind t = term
+    { Sassert (k, t) }
 | e = expr
     { Seval e }
 ;
 
+assertion_kind:
+| ASSERT  { Aassert }
+| ASSUME  { Aassume }
+| CHECK   { Acheck }
+
 ident:
   id = IDENT { mk_id id $startpos $endpos }
 ;
diff --git a/plugins/python/test.py b/plugins/python/test.py
index a01f29b6b2f94d5cabdf32acee24a0931fde2f90..3386b225bf9a96ada6badbc63b9a72f6a4da3eac 100644
--- a/plugins/python/test.py
+++ b/plugins/python/test.py
@@ -9,6 +9,8 @@ while b < 100:
   b = a+b
   ## assert b >= 1
   a = b-a
+
+# lists
 l = range(0, 10)
 ## assert forall i. 0 <= i < 10 -> l[i] >= 0
 l[2] = 42
@@ -21,6 +23,15 @@ while i < 10:
   l[i] = 0
   i = i+1
 
+# arithmetic
+# Python's division is *Euclidean* division
+q = -4 // 3
+## assert q == -2
+r = -4 % 3
+## assert r == 2
+## assert 4 // -3 == -2
+## assert 4 % -3 == -2
+
 # Local Variables:
 # compile-command: "make -C ../.. && why3 ide test.py"
 # End: