diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Version 0.0.4.2 2019-11-11 by luispedro
+	* Fix non-ASCII keys
+
+Version 0.0.4.1 2019-11-05 by luispedro
+	* Fix Python extension compilation
+
 Version 0.0.4.0 2017-11-27 by luispedro
 	* Load hash table into memory
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -14,11 +14,10 @@
 wrappers follow similar APIs with variations to accommodate the language
 specificity. They all use the same underlying code, so you can open a hashtable
 created in C from Haskell, modify it within your Haskell code, and later open
-the result in Python (although Python's version currently only deals with
-integers, stored as longs).
+the result in Python.
 
-Cross-language functionality will work best for very simple types so that you
-can control their binary representation (64-bit integers, for example).
+Cross-language functionality will only work for simple types where you can
+control their binary representation (64-bit integers, for example).
 
 Reading does not touch the disk representation at all and, thus, can be done on
 top of read-only files or using multiple threads (and different processes will
@@ -61,10 +60,15 @@
 }
 ```
 
+The C API relies on error codes and error strings (the `&err` argument above).
+The header file has [decent
+documentation](https://github.com/luispedro/diskhash/blob/master/src/diskhash.h).
+
 ### Haskell
 
 In Haskell, you have different types/functions for read-write and read-only
-hashtables.
+hashtables. Read-write operations are `IO` operations, read-only hashtables are
+pure.
 
 Read write example:
 
diff --git a/diskhash.cabal b/diskhash.cabal
--- a/diskhash.cabal
+++ b/diskhash.cabal
@@ -1,5 +1,5 @@
 name:               diskhash
-version:            0.0.4.0
+version:            0.0.4.2
 synopsis:           Disk-based hash table
 description:        Disk-based hash table
 category:           Data
diff --git a/haskell/Data/DiskHash/Tests.hs b/haskell/Data/DiskHash/Tests.hs
--- a/haskell/Data/DiskHash/Tests.hs
+++ b/haskell/Data/DiskHash/Tests.hs
@@ -3,8 +3,9 @@
 module Main where
 
 import           Test.Framework.TH
-import           Test.HUnit
-import           Test.QuickCheck.Property
+import           Test.HUnit (assertEqual, assertBool)
+import           Test.QuickCheck (ASCIIString(..))
+import           Test.QuickCheck.Property (Property, ioProperty)
 import           Test.Framework.Providers.HUnit
 import           Test.Framework.Providers.QuickCheck2
 
@@ -14,7 +15,7 @@
 import           Control.Monad (forM, forM_)
 import           Control.Exception (throwIO)
 import           System.IO.Error (isDoesNotExistError, catchIOError)
-import           System.Directory (doesFileExist, removeFile)
+import           System.Directory (removeFile)
 import           Data.Int
 
 import Data.DiskHash
@@ -70,22 +71,22 @@
     assertEqual "Lookup" (Just (9 :: Int64)) (htLookupRO "key" ht)
     removeFileIfExists outname
 
--- prop_insert_find :: [(String, Int64)] -> IO Bool
+prop_insert_find :: [(ASCIIString, Int64)] -> Property
 prop_insert_find args = ioProperty $ do
     let args' = normArgs args
     found <- withDiskHashRW outname 15 $ \ht -> do
         forM_ args' $ \(k,val) -> htInsert k val ht
         forM args' $ \(k, val) -> do
             v <- htLookupRW k ht
-            return $ v == Just val
+            return $! v == Just val
     removeFileIfExists outname
     return $! and found
 
 
-normArgs :: [(String, Int64)] -> [(B.ByteString, Int64)]
+normArgs :: [(ASCIIString, Int64)] -> [(B.ByteString, Int64)]
 normArgs = normArgs' [] . map (first normKey)
     where
-        normKey = B8.pack . (filter (/= '\0'))
+        normKey = B8.pack . (filter (/= '\0')) . getASCIIString
         normArgs' r [] = r
         normArgs' r (x@(k,_):xs)
             | k `elem` (map fst r) = normArgs' r xs
diff --git a/src/diskhash.c b/src/diskhash.c
--- a/src/diskhash.c
+++ b/src/diskhash.c
@@ -37,11 +37,12 @@
 static
 uint64_t hash_key(const char* k, int use_hash_2) {
     /* Taken from http://www.cse.yorku.ca/~oz/hash.html */
+    const unsigned char* ku = (const unsigned char*)k;
     uint64_t hash = 5381;
     uint64_t next;
-    for ( ; *k; ++k) {
+    for ( ; *ku; ++ku) {
         hash *= 33;
-        next = *k;
+        next = *ku;
         if (use_hash_2) {
             next = rtable[next];
         }
