diff --git a/generator/Data/XCB/Python/AST.hs b/generator/Data/XCB/Python/AST.hs
--- a/generator/Data/XCB/Python/AST.hs
+++ b/generator/Data/XCB/Python/AST.hs
@@ -195,8 +195,8 @@
     pretty (Fun name args bod) = text "def" <+> pretty name <> (parens (addCommas args)) <> colon
                                  $+$ indent (pretty bod)
     pretty (Decorated decorator name args bod) = text "@" <> text decorator $+$ pretty (Fun name args bod)
-    pretty (Class name [] body) = text "@dataclass(init=False)" $+$ text "class" <+> pretty name <> colon $+$ indent (pretty body)
-    pretty (Class name superclasses body) = text "@dataclass(init=False)" $+$ text "class" <+> pretty name <> parens (addCommas superclasses) <> colon $+$ indent (pretty body)
+    pretty (Class name [] body) = text "class" <+> pretty name <> colon $+$ indent (pretty body)
+    pretty (Class name superclasses body) = text "class" <+> pretty name <> parens (addCommas superclasses) <> colon $+$ indent (pretty body)
     pretty (Conditional cond if_ else_) = text "if" <+> pretty cond <> colon $+$ indent (pretty if_) $+$ pretty else_
     pretty (Assign to expr) = pretty to <+> text "=" <+> pretty expr
     pretty (AugmentedAssign to op expr) = pretty to <+> pretty op <> text "=" <+> pretty expr
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
@@ -90,7 +90,7 @@
     processXHeader :: XHeader
                    -> State TypeInfoMap (String, Suite)
     processXHeader header = do
-      let imports = [Import "xcffib", Import "struct", Import "io", FromImport "dataclasses" "dataclass"]
+      let imports = [Import "xcffib", Import "struct", Import "io"]
           version = mkVersion header
           key = maybeToList $ mkKey header
           globals = [mkDict "_events", mkDict "_errors"]
@@ -760,15 +760,17 @@
 processXDecl ext (XUnion name _ membs) = do
   m <- get
   let unpackF = structElemToPyUnpack unpackerCopy ext m
-      (fields, listInfo) = span EC.isLeft $ map unpackF membs
-      toUnpack = concat $ map (mkUnionUnpack . EC.fromLeft') fields
-      initMethod = if any EC.isLeft listInfo
-                   then [notImplemented]
-                   else (mkListUnpack listInfo) ++ toUnpack
+      (_, stmts) = span EC.isLeft $ map unpackF membs
+      -- not exactly correct, same problem as in commit
+      -- 64168007c20e80dd58e2456d8dac74e71d7f6b96 or
+      -- d2d521fd117f2d2698f8d4ef1fd4792a4ef1c088, i.e. we shouldn't partition
+      -- these, we should render them in order. (hilariously, those commits
+      -- mention partitionEithers, which is equivalent to (span EC.isLeft)...
+      initMethodStmts = concat $ map (either mkUnionUnpack mkUnionListUnpack) stmts
       -- Here, we only want to pack the first member of the union, since every
       -- member is the same data and we don't want to repeatedly pack it.
       pack = mkPackMethod ext name m Nothing [head membs] Nothing
-      decl = [mkXClass name "xcffib.Union" False initMethod [pack]]
+      decl = [mkXClass name "xcffib.Union" False initMethodStmts [pack]]
   modify $ mkModify ext name (CompositeType ext name)
   return $ Declaration decl
   where
@@ -778,12 +780,10 @@
     mkUnionUnpack (n, typ) =
       mkUnpackFrom unpackerCopy (maybeToList n) typ
 
-    mkListUnpack listInfo =
-      let listInfo' = map EC.fromRight' listInfo
-          (names, listOrSwitches, _) = unzip3 listInfo'
-          (exprs, _) = unzip $ map EC.fromLeft' listOrSwitches
-          lists = map (uncurry mkAssign) $ zip (map mkAttr names) exprs
-      in lists
+    mkUnionListUnpack :: (String, Either (Expr, Expr) ([(Expr, [GenStructElem Type])]), Maybe Int) -> Suite
+    mkUnionListUnpack (n, listOrSwitches, _) =
+      let (expr, _) = EC.fromLeft' listOrSwitches
+      in [mkAssign (mkAttr n) expr]
 
 processXDecl ext (XidUnion name _) =
   -- These are always unions of only XIDs.
diff --git a/generator/Data/XCB/Python/PyHelpers.hs b/generator/Data/XCB/Python/PyHelpers.hs
--- a/generator/Data/XCB/Python/PyHelpers.hs
+++ b/generator/Data/XCB/Python/PyHelpers.hs
@@ -32,8 +32,7 @@
   mkDictUpdate,
   mkMethod,
   mkReturn,
-  mkIf,
-  notImplemented
+  mkIf
   ) where
 
 import Data.List.Split
@@ -126,6 +125,3 @@
 
 mkIf :: Expr -> Suite -> Statement
 mkIf e s = Conditional e s []
-
-notImplemented :: Statement
-notImplemented = Raise "xcffib.XcffibNotImplemented"
diff --git a/test/GeneratorTests.hs b/test/GeneratorTests.hs
--- a/test/GeneratorTests.hs
+++ b/test/GeneratorTests.hs
@@ -42,6 +42,7 @@
           , "render"
           , "randr"
           , "eventstruct"
+          , "action"
           ]
 
 mkFname :: String -> FilePath
diff --git a/test/generator/action.py b/test/generator/action.py
new file mode 100644
--- /dev/null
+++ b/test/generator/action.py
@@ -0,0 +1,160 @@
+import xcffib
+import struct
+import io
+_events = {}
+_errors = {}
+class SANoAction(xcffib.Struct):
+    xge = False
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Struct.__init__(self, unpacker)
+        base = unpacker.offset
+        self.type, = unpacker.unpack("B7x")
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = io.BytesIO()
+        buf.write(struct.pack("=B7x", self.type))
+        return buf.getvalue()
+    fixed_size = 8
+    @classmethod
+    def synthetic(cls, type):
+        self = cls.__new__(cls)
+        self.type = type
+        return self
+class SASetMods(xcffib.Struct):
+    xge = False
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Struct.__init__(self, unpacker)
+        base = unpacker.offset
+        self.type, self.flags, self.mask, self.realMods, self.vmodsHigh, self.vmodsLow = unpacker.unpack("BBBBBB2x")
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = io.BytesIO()
+        buf.write(struct.pack("=BBBBBB2x", self.type, self.flags, self.mask, self.realMods, self.vmodsHigh, self.vmodsLow))
+        return buf.getvalue()
+    fixed_size = 8
+    @classmethod
+    def synthetic(cls, type, flags, mask, realMods, vmodsHigh, vmodsLow):
+        self = cls.__new__(cls)
+        self.type = type
+        self.flags = flags
+        self.mask = mask
+        self.realMods = realMods
+        self.vmodsHigh = vmodsHigh
+        self.vmodsLow = vmodsLow
+        return self
+class SASetGroup(xcffib.Struct):
+    xge = False
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Struct.__init__(self, unpacker)
+        base = unpacker.offset
+        self.type, self.flags, self.group = unpacker.unpack("BBb5x")
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = io.BytesIO()
+        buf.write(struct.pack("=BBb5x", self.type, self.flags, self.group))
+        return buf.getvalue()
+    fixed_size = 8
+    @classmethod
+    def synthetic(cls, type, flags, group):
+        self = cls.__new__(cls)
+        self.type = type
+        self.flags = flags
+        self.group = group
+        return self
+class SAMovePtrFlag:
+    NoAcceleration = 1 << 0
+    MoveAbsoluteX = 1 << 1
+    MoveAbsoluteY = 1 << 2
+class SAMovePtr(xcffib.Struct):
+    xge = False
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Struct.__init__(self, unpacker)
+        base = unpacker.offset
+        self.type, self.flags, self.xHigh, self.xLow, self.yHigh, self.yLow = unpacker.unpack("BBbBbB2x")
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = io.BytesIO()
+        buf.write(struct.pack("=BBbBbB2x", self.type, self.flags, self.xHigh, self.xLow, self.yHigh, self.yLow))
+        return buf.getvalue()
+    fixed_size = 8
+    @classmethod
+    def synthetic(cls, type, flags, xHigh, xLow, yHigh, yLow):
+        self = cls.__new__(cls)
+        self.type = type
+        self.flags = flags
+        self.xHigh = xHigh
+        self.xLow = xLow
+        self.yHigh = yHigh
+        self.yLow = yLow
+        return self
+class SAPtrBtn(xcffib.Struct):
+    xge = False
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Struct.__init__(self, unpacker)
+        base = unpacker.offset
+        self.type, self.flags, self.count, self.button = unpacker.unpack("BBBB4x")
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = io.BytesIO()
+        buf.write(struct.pack("=BBBB4x", self.type, self.flags, self.count, self.button))
+        return buf.getvalue()
+    fixed_size = 8
+    @classmethod
+    def synthetic(cls, type, flags, count, button):
+        self = cls.__new__(cls)
+        self.type = type
+        self.flags = flags
+        self.count = count
+        self.button = button
+        return self
+class SALockPtrBtn(xcffib.Struct):
+    xge = False
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Struct.__init__(self, unpacker)
+        base = unpacker.offset
+        self.type, self.flags, self.button = unpacker.unpack("BBxB4x")
+        self.bufsize = unpacker.offset - base
+    def pack(self):
+        buf = io.BytesIO()
+        buf.write(struct.pack("=BBxB4x", self.type, self.flags, self.button))
+        return buf.getvalue()
+    fixed_size = 8
+    @classmethod
+    def synthetic(cls, type, flags, button):
+        self = cls.__new__(cls)
+        self.type = type
+        self.flags = flags
+        self.button = button
+        return self
+class Action(xcffib.Union):
+    xge = False
+    def __init__(self, unpacker):
+        if isinstance(unpacker, xcffib.Protobj):
+            unpacker = xcffib.MemoryUnpacker(unpacker.pack())
+        xcffib.Union.__init__(self, unpacker)
+        self.noaction = SANoAction(unpacker.copy())
+        self.setmods = SASetMods(unpacker.copy())
+        self.lockmods = SASetMods(unpacker.copy())
+        self.setgroup = SASetGroup(unpacker.copy())
+        self.lockgroup = SASetGroup(unpacker.copy())
+        self.moveptr = SAMovePtr(unpacker.copy())
+        self.ptrbtn = SAPtrBtn(unpacker.copy())
+        self.lockptrbtn = SALockPtrBtn(unpacker.copy())
+        self.type, = unpacker.copy().unpack("B")
+    def pack(self):
+        buf = io.BytesIO()
+        buf.write(self.noaction.pack() if hasattr(self.noaction, "pack") else SANoAction.synthetic(*self.noaction).pack())
+        return buf.getvalue()
+xcffib._add_ext(key, actionExtension, _events, _errors)
diff --git a/test/generator/action.xml b/test/generator/action.xml
new file mode 100644
--- /dev/null
+++ b/test/generator/action.xml
@@ -0,0 +1,76 @@
+<!-- based on xkb -->
+<xcb header="action">
+	<struct name="SANoAction">
+		<field name="type" type="CARD8" enum="SAType" />
+		<pad bytes="7" />
+	</struct>
+
+	<struct name="SASetMods">
+		<field name="type" type="CARD8" enum="SAType" />
+		<field name="flags" type="CARD8" mask="SA" />
+		<field name="mask" type="CARD8" mask="ModMask" />
+		<field name="realMods" type="CARD8" mask="ModMask" />
+		<field name="vmodsHigh" type="CARD8" mask="VModsHigh" />
+		<field name="vmodsLow" type="CARD8" mask="VModsLow" />
+		<pad bytes="2" />
+	</struct>
+
+	<typedef oldname="SASetMods" newname="SALatchMods" />
+
+	<typedef oldname="SASetMods" newname="SALockMods" />
+
+	<struct name="SASetGroup">
+		<field name="type" type="CARD8" enum="SAType" />
+		<field name="flags" type="CARD8" mask="SA" />
+		<field name="group" type="INT8" />
+		<pad bytes="5" />
+	</struct>
+
+	<typedef oldname="SASetGroup" newname="SALatchGroup" />
+
+	<typedef oldname="SASetGroup" newname="SALockGroup" />
+
+	<enum name="SAMovePtrFlag">
+		<item name="NoAcceleration"> <bit>0</bit> </item>
+		<item name="MoveAbsoluteX">  <bit>1</bit> </item>
+		<item name="MoveAbsoluteY">  <bit>2</bit> </item>
+	</enum>
+
+	<struct name="SAMovePtr">
+		<field name="type" type="CARD8" enum="SAType" />
+		<field name="flags" type="CARD8" mask="SAMovePtrFlag" />
+		<field name="xHigh" type="INT8" />
+		<field name="xLow" type="CARD8" />
+		<field name="yHigh" type="INT8" />
+		<field name="yLow" type="CARD8" />
+		<pad bytes="2" />
+	</struct>
+
+	<struct name="SAPtrBtn">
+		<field name="type" type="CARD8" enum="SAType" />
+		<field name="flags" type="CARD8" />
+		<field name="count" type="CARD8" />
+		<field name="button" type="CARD8" />
+		<pad bytes="4" />
+	</struct>
+
+	<struct name="SALockPtrBtn">
+		<field name="type" type="CARD8" enum="SAType" />
+		<field name="flags" type="CARD8" />
+		<pad bytes="1" />
+		<field name="button" type="CARD8" />
+		<pad bytes="4" />
+	</struct>
+
+	<union name="Action">
+		<field name="noaction" type="SANoAction" />
+		<field name="setmods" type="SASetMods" />
+		<field name="lockmods" type="SALockMods" />
+		<field name="setgroup" type="SASetGroup" />
+		<field name="lockgroup" type="SALockGroup" />
+		<field name="moveptr" type="SAMovePtr" />
+		<field name="ptrbtn" type="SAPtrBtn" />
+		<field name="lockptrbtn" type="SALockPtrBtn" />
+		<field name="type" type="CARD8" enum="SAType" />
+	</union>
+</xcb>
diff --git a/test/generator/enum.py b/test/generator/enum.py
--- a/test/generator/enum.py
+++ b/test/generator/enum.py
@@ -1,17 +1,14 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class DeviceUse:
     IsXPointer = 0
     IsXKeyboard = 1
     IsXExtensionDevice = 2
     IsXExtensionKeyboard = 3
     IsXExtensionPointer = 4
-@dataclass(init=False)
 class EventMask:
     NoEvent = 0
     KeyPress = 1 << 0
diff --git a/test/generator/error.py b/test/generator/error.py
--- a/test/generator/error.py
+++ b/test/generator/error.py
@@ -1,13 +1,11 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 MAJOR_VERSION = 2
 MINOR_VERSION = 2
 key = xcffib.ExtensionKey("ERROR")
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class RequestError(xcffib.Error):
     xge = False
     def __init__(self, unpacker):
diff --git a/test/generator/event.py b/test/generator/event.py
--- a/test/generator/event.py
+++ b/test/generator/event.py
@@ -1,13 +1,11 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 MAJOR_VERSION = 1
 MINOR_VERSION = 4
 key = xcffib.ExtensionKey("EVENT")
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class ScreenChangeNotifyEvent(xcffib.Event):
     xge = False
     def __init__(self, unpacker):
diff --git a/test/generator/eventstruct.py b/test/generator/eventstruct.py
--- a/test/generator/eventstruct.py
+++ b/test/generator/eventstruct.py
@@ -1,13 +1,10 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class EventForSend(xcffib.Buffer):
     pass
-@dataclass(init=False)
 class eventstructExtension(xcffib.Extension):
     def SendExtensionEvent(self, device_id, propagate, num_classes, num_events, events, classes, is_checked=False):
         buf = io.BytesIO()
diff --git a/test/generator/no_sequence.py b/test/generator/no_sequence.py
--- a/test/generator/no_sequence.py
+++ b/test/generator/no_sequence.py
@@ -1,10 +1,8 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class KeymapNotifyEvent(xcffib.Event):
     xge = False
     def __init__(self, unpacker):
diff --git a/test/generator/randr.py b/test/generator/randr.py
--- a/test/generator/randr.py
+++ b/test/generator/randr.py
@@ -1,13 +1,11 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 MAJOR_VERSION = 1
 MINOR_VERSION = 6
 key = xcffib.ExtensionKey("RANDR")
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class TRANSFORM(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -35,7 +33,6 @@
         self.matrix32 = matrix32
         self.matrix33 = matrix33
         return self
-@dataclass(init=False)
 class GetCrtcTransformReply(xcffib.Reply):
     xge = False
     def __init__(self, unpacker):
@@ -58,10 +55,8 @@
         unpacker.pad("i")
         self.current_params = xcffib.List(unpacker, "i", self.current_nparams)
         self.bufsize = unpacker.offset - base
-@dataclass(init=False)
 class GetCrtcTransformCookie(xcffib.Cookie):
     reply_type = GetCrtcTransformReply
-@dataclass(init=False)
 class randrExtension(xcffib.Extension):
     def GetCrtcTransform(self, crtc, is_checked=True):
         buf = io.BytesIO()
diff --git a/test/generator/record.py b/test/generator/record.py
--- a/test/generator/record.py
+++ b/test/generator/record.py
@@ -1,13 +1,11 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 MAJOR_VERSION = 1
 MINOR_VERSION = 13
 key = xcffib.ExtensionKey("RECORD")
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class Range8(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -28,7 +26,6 @@
         self.first = first
         self.last = last
         return self
-@dataclass(init=False)
 class Range16(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -49,7 +46,6 @@
         self.first = first
         self.last = last
         return self
-@dataclass(init=False)
 class ExtRange(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -72,7 +68,6 @@
         self.major = major
         self.minor = minor
         return self
-@dataclass(init=False)
 class Range(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
diff --git a/test/generator/render.py b/test/generator/render.py
--- a/test/generator/render.py
+++ b/test/generator/render.py
@@ -1,13 +1,11 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 MAJOR_VERSION = 0
 MINOR_VERSION = 11
 key = xcffib.ExtensionKey("RENDER")
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class COLOR(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -30,7 +28,6 @@
         self.blue = blue
         self.alpha = alpha
         return self
-@dataclass(init=False)
 class RECTANGLE(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -53,7 +50,6 @@
         self.width = width
         self.height = height
         return self
-@dataclass(init=False)
 class renderExtension(xcffib.Extension):
     def FillRectangles(self, op, dst, color, rects_len, rects, is_checked=False):
         buf = io.BytesIO()
diff --git a/test/generator/render_1.7.py b/test/generator/render_1.7.py
--- a/test/generator/render_1.7.py
+++ b/test/generator/render_1.7.py
@@ -1,13 +1,11 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 MAJOR_VERSION = 0
 MINOR_VERSION = 11
 key = xcffib.ExtensionKey("RENDER")
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class PictOp:
     Clear = 0
     Src = 1
diff --git a/test/generator/request.py b/test/generator/request.py
--- a/test/generator/request.py
+++ b/test/generator/request.py
@@ -1,10 +1,8 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class requestExtension(xcffib.Extension):
     def CreateWindow(self, depth, wid, parent, x, y, width, height, border_width, _class, visual, value_mask, value_list, is_checked=False):
         buf = io.BytesIO()
diff --git a/test/generator/request_reply.py b/test/generator/request_reply.py
--- a/test/generator/request_reply.py
+++ b/test/generator/request_reply.py
@@ -1,10 +1,8 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class STR(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -26,7 +24,6 @@
         self.name_len = name_len
         self.name = name
         return self
-@dataclass(init=False)
 class ListExtensionsReply(xcffib.Reply):
     xge = False
     def __init__(self, unpacker):
@@ -37,10 +34,8 @@
         self.names_len, = unpacker.unpack("xB2x4x24x")
         self.names = xcffib.List(unpacker, STR, self.names_len)
         self.bufsize = unpacker.offset - base
-@dataclass(init=False)
 class ListExtensionsCookie(xcffib.Cookie):
     reply_type = ListExtensionsReply
-@dataclass(init=False)
 class request_replyExtension(xcffib.Extension):
     def ListExtensions(self, is_checked=True):
         buf = io.BytesIO()
diff --git a/test/generator/struct.py b/test/generator/struct.py
--- a/test/generator/struct.py
+++ b/test/generator/struct.py
@@ -1,10 +1,8 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class AxisInfo(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -26,7 +24,6 @@
         self.minimum = minimum
         self.maximum = maximum
         return self
-@dataclass(init=False)
 class ValuatorInfo(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
diff --git a/test/generator/switch.py b/test/generator/switch.py
--- a/test/generator/switch.py
+++ b/test/generator/switch.py
@@ -1,10 +1,8 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class INT64(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -25,7 +23,6 @@
         self.hi = hi
         self.lo = lo
         return self
-@dataclass(init=False)
 class GetPropertyReply(xcffib.Reply):
     xge = False
     def __init__(self, unpacker):
@@ -41,10 +38,8 @@
         if self.format & PropertyFormat._32Bits:
             self.data32 = xcffib.List(unpacker, "I", self.num_items)
         self.bufsize = unpacker.offset - base
-@dataclass(init=False)
 class GetPropertyCookie(xcffib.Cookie):
     reply_type = GetPropertyReply
-@dataclass(init=False)
 class GetPropertyWithPadReply(xcffib.Reply):
     xge = False
     def __init__(self, unpacker):
@@ -64,10 +59,8 @@
             unpacker.pad("I")
             self.data32 = xcffib.List(unpacker, "I", self.num_items)
         self.bufsize = unpacker.offset - base
-@dataclass(init=False)
 class GetPropertyWithPadCookie(xcffib.Cookie):
     reply_type = GetPropertyWithPadReply
-@dataclass(init=False)
 class switchExtension(xcffib.Extension):
     def GetProperty(self, value_mask, items, is_checked=True):
         buf = io.BytesIO()
diff --git a/test/generator/type_pad.py b/test/generator/type_pad.py
--- a/test/generator/type_pad.py
+++ b/test/generator/type_pad.py
@@ -1,10 +1,8 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class CHARINFO(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -29,7 +27,6 @@
         self.descent = descent
         self.attributes = attributes
         return self
-@dataclass(init=False)
 class FONTPROP(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -50,7 +47,6 @@
         self.name = name
         self.value = value
         return self
-@dataclass(init=False)
 class ListFontsWithInfoReply(xcffib.Reply):
     xge = False
     def __init__(self, unpacker):
@@ -69,10 +65,8 @@
         unpacker.pad("c")
         self.name = xcffib.List(unpacker, "c", self.name_len)
         self.bufsize = unpacker.offset - base
-@dataclass(init=False)
 class ListFontsWithInfoCookie(xcffib.Cookie):
     reply_type = ListFontsWithInfoReply
-@dataclass(init=False)
 class type_padExtension(xcffib.Extension):
     def ListFontsWithInfo(self, max_names, pattern_len, pattern, is_checked=True):
         buf = io.BytesIO()
diff --git a/test/generator/union.py b/test/generator/union.py
--- a/test/generator/union.py
+++ b/test/generator/union.py
@@ -1,10 +1,8 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class ClientMessageData(xcffib.Union):
     xge = False
     def __init__(self, unpacker):
diff --git a/test/generator/xproto_1.7.py b/test/generator/xproto_1.7.py
--- a/test/generator/xproto_1.7.py
+++ b/test/generator/xproto_1.7.py
@@ -1,13 +1,11 @@
 import xcffib
 import struct
 import io
-from dataclasses import dataclass
 MAJOR_VERSION = 0
 MINOR_VERSION = 11
 key = xcffib.ExtensionKey("XPROTO")
 _events = {}
 _errors = {}
-@dataclass(init=False)
 class Atom:
     _None = 0
     Any = 0
diff --git a/xcffib.cabal b/xcffib.cabal
--- a/xcffib.cabal
+++ b/xcffib.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.4
 name:                xcffib
-version:             1.8.0
+version:             1.9.0
 synopsis:            A cffi-based python binding for X
 homepage:            http://github.com/tych0/xcffib
 license:             Apache-2.0
