diff --git a/generator/Data/XCB/Python/Parse.hs b/generator/Data/XCB/Python/Parse.hs
--- a/generator/Data/XCB/Python/Parse.hs
+++ b/generator/Data/XCB/Python/Parse.hs
@@ -27,8 +27,7 @@
 import Data.Attoparsec.ByteString.Char8
 import Data.Bits
 import qualified Data.ByteString.Char8 as BS
-import Data.Either
-import Data.Either.Combinators
+import Data.Either.Combinators as EC
 import Data.List
 import qualified Data.Map as M
 import Data.Tree
@@ -441,8 +440,9 @@
             -> ([String], Suite ())
 mkPackStmts ext name m accessor prefix membs =
   let packF = structElemToPyPack ext m accessor
-      (toPack, stmts) = partitionEithers $ map packF membs
-      (args, keys) = let (as, ks) = unzip toPack in (catMaybes as, ks)
+      (toPack, stmts) = span EC.isLeft $ map packF membs
+      stmts' = map (either mkBasePack id) stmts
+      (args, keys) = let (as, ks) = unzip (map EC.fromLeft' toPack) in (catMaybes as, ks)
 
       -- In some cases (e.g. xproto.ConfigureWindow) there is padding after
       -- value_mask. The way the xml specification deals with this is by
@@ -450,7 +450,7 @@
       -- implying it implicitly. Thus, we want to make sure that if we've already
       -- been told to pack something explcitly, that we don't also pack it
       -- implicitly.
-      (listNames, listOrSwitches) = unzip $ filter (flip notElem args . fst) (concat stmts)
+      (listNames, listOrSwitches) = unzip $ filter (flip notElem args . fst) (concat stmts')
       listWrites = concat $ map (uncurry mkWrites) $ zip listNames listOrSwitches
       listNames' = case (ext, name) of
                      -- XXX: QueryTextExtents has a field named "odd_length"
@@ -486,6 +486,11 @@
             -> Statement ()
       mkPop toPop n = mkAssign n $ mkCall (mkDot toPop "pop") [mkInt 0]
 
+      mkBasePack (Nothing, "") = []
+      mkBasePack (n, c) =
+        let n' = maybe "" id n
+        in [(n', Left (Just (mkCall "struct.pack" [mkStr ('=' : c), mkName n'])))]
+
 mkPackMethod :: String
              -> String
              -> TypeInfoMap
@@ -724,7 +729,7 @@
       isChecked = pyTruth $ isJust reply
       argChecked = ArgKeyword (ident "is_checked") (mkName "is_checked") ()
       checkedParam = Param (ident "is_checked") Nothing (Just isChecked) ()
-      allArgs = (mkParams $ "self" : args) ++ [checkedParam]
+      allArgs = (mkParams $ "self" : (filter (not . null) args)) ++ [checkedParam]
       mkArg' = flip ArgExpr ()
       ret = mkReturn $ mkCall "self.send_request" ((map mkArg' [ mkInt opcode
                                                                , mkName "buf"
@@ -737,10 +742,11 @@
 processXDecl ext (XUnion name _ membs) = do
   m <- get
   let unpackF = structElemToPyUnpack unpackerCopy ext m
-      (fields, listInfo) = partitionEithers $ map unpackF membs
-      toUnpack = concat $ map mkUnionUnpack fields
-      (names, listOrSwitches, _) = unzip3 listInfo
-      (exprs, _) = unzip $ map fromLeft' listOrSwitches
+      (fields, listInfo) = span EC.isLeft $ map unpackF membs
+      toUnpack = concat $ map (mkUnionUnpack . EC.fromLeft') fields
+      listInfo' = map (either mkBaseUnpack id) listInfo
+      (names, listOrSwitches, _) = unzip3 listInfo'
+      (exprs, _) = unzip $ map EC.fromLeft' listOrSwitches
       lists = map (uncurry mkAssign) $ zip (map mkAttr names) exprs
       initMethod = lists ++ toUnpack
       -- Here, we only want to pack the first member of the union, since every
@@ -755,6 +761,8 @@
                   -> Suite ()
     mkUnionUnpack (n, typ) =
       mkUnpackFrom unpackerCopy (maybeToList n) typ
+
+    mkBaseUnpack _ = error "xcffib: trailing base types unpack not implemented"
 
 processXDecl ext (XidUnion name _) =
   -- These are always unions of only XIDs.
diff --git a/xcffib.cabal b/xcffib.cabal
--- a/xcffib.cabal
+++ b/xcffib.cabal
@@ -1,5 +1,5 @@
 name:                xcffib
-version:             1.0.0
+version:             1.1.0
 synopsis:            A cffi-based python binding for X
 homepage:            http://github.com/tych0/xcffib
 license:             OtherLicense
