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 "class" <+> pretty name <> colon $+$ indent (pretty body)
-    pretty (Class name superclasses body) = text "class" <+> pretty name <> parens (addCommas superclasses) <> colon $+$ indent (pretty body)
+    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 (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"]
+      let imports = [Import "xcffib", Import "struct", Import "io", FromImport "dataclasses" "dataclass"]
           version = mkVersion header
           key = maybeToList $ mkKey header
           globals = [mkDict "_events", mkDict "_errors"]
diff --git a/test/generator/enum.py b/test/generator/enum.py
--- a/test/generator/enum.py
+++ b/test/generator/enum.py
@@ -1,14 +1,17 @@
 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,11 +1,13 @@
 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,11 +1,13 @@
 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,10 +1,13 @@
 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,8 +1,10 @@
 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,11 +1,13 @@
 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):
@@ -33,6 +35,7 @@
         self.matrix32 = matrix32
         self.matrix33 = matrix33
         return self
+@dataclass(init=False)
 class GetCrtcTransformReply(xcffib.Reply):
     xge = False
     def __init__(self, unpacker):
@@ -55,8 +58,10 @@
         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,11 +1,13 @@
 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):
@@ -26,6 +28,7 @@
         self.first = first
         self.last = last
         return self
+@dataclass(init=False)
 class Range16(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -46,6 +49,7 @@
         self.first = first
         self.last = last
         return self
+@dataclass(init=False)
 class ExtRange(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -68,6 +72,7 @@
         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,11 +1,13 @@
 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):
@@ -28,6 +30,7 @@
         self.blue = blue
         self.alpha = alpha
         return self
+@dataclass(init=False)
 class RECTANGLE(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -50,6 +53,7 @@
         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,11 +1,13 @@
 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,8 +1,10 @@
 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,8 +1,10 @@
 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):
@@ -24,6 +26,7 @@
         self.name_len = name_len
         self.name = name
         return self
+@dataclass(init=False)
 class ListExtensionsReply(xcffib.Reply):
     xge = False
     def __init__(self, unpacker):
@@ -34,8 +37,10 @@
         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,8 +1,10 @@
 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):
@@ -24,6 +26,7 @@
         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,8 +1,10 @@
 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):
@@ -23,6 +25,7 @@
         self.hi = hi
         self.lo = lo
         return self
+@dataclass(init=False)
 class GetPropertyReply(xcffib.Reply):
     xge = False
     def __init__(self, unpacker):
@@ -38,8 +41,10 @@
         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):
@@ -59,8 +64,10 @@
             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,8 +1,10 @@
 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):
@@ -27,6 +29,7 @@
         self.descent = descent
         self.attributes = attributes
         return self
+@dataclass(init=False)
 class FONTPROP(xcffib.Struct):
     xge = False
     def __init__(self, unpacker):
@@ -47,6 +50,7 @@
         self.name = name
         self.value = value
         return self
+@dataclass(init=False)
 class ListFontsWithInfoReply(xcffib.Reply):
     xge = False
     def __init__(self, unpacker):
@@ -65,8 +69,10 @@
         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,8 +1,10 @@
 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,11 +1,13 @@
 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.7.1
+version:             1.8.0
 synopsis:            A cffi-based python binding for X
 homepage:            http://github.com/tych0/xcffib
 license:             Apache-2.0
