diff --git a/Project.toml b/Project.toml
index b4de1e27..63110dec 100644
--- a/Project.toml
+++ b/Project.toml
@@ -16,8 +16,15 @@ Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
 Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
 UnsafePointers = "e17b2a0c-0bdf-430a-bd0c-3a23cae4ff39"
 
+[weakdeps]
+JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
+
+[extensions]
+JLD2Ext = "JLD2"
+
 [compat]
 CondaPkg = "0.2.21"
+JLD2 = "0.4.38"
 MacroTools = "0.5"
 Requires = "1"
 Tables = "1"
@@ -26,6 +33,7 @@ julia = "1.6.1"
 
 [extras]
 Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
+JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
 Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
 TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a"
 
diff --git a/ext/JLD2Ext.jl b/ext/JLD2Ext.jl
new file mode 100644
index 00000000..27d001b1
--- /dev/null
+++ b/ext/JLD2Ext.jl
@@ -0,0 +1,40 @@
+module JLD2Ext
+
+using JLD2
+using PythonCall
+
+### Py
+
+struct Py_Serialized
+    x::Union{Nothing,Vector{UInt8}}
+end
+
+JLD2.writeas(::Type{Py}) = Py_Serialized
+
+function JLD2.wconvert(::Type{Py_Serialized}, x::Py)
+    if PythonCall.pyisnull(x)
+        v = nothing
+    else
+        v = copy(PythonCall._Py.pybytes_asvector(pyimport("pickle").dumps(x)))
+    end
+    Py_Serialized(v)
+end
+
+function JLD2.rconvert(::Type{Py}, x::Py_Serialized)
+    v = x.x
+    if v === nothing
+        PythonCall.pynew()
+    else
+        pyimport("pickle").loads(pybytes(v))
+    end
+end
+
+### PyException - handled similarly as with Serialization.jl
+
+JLD2.writeas(::Type{PyException}) = Py_Serialized
+
+JLD2.wconvert(::Type{Py_Serialized}, x::PyException) = JLD2.wconvert(Py_Serialized, x.v)
+
+JLD2.rconvert(::Type{PyException}, x::Py_Serialized) = PyException(JLD2.rconvert(Py, x))
+
+end
diff --git a/test/Aqua.jl b/test/Aqua.jl
index 957c8682..9c6eadfa 100644
--- a/test/Aqua.jl
+++ b/test/Aqua.jl
@@ -2,5 +2,5 @@
     # The unbound_args test fails on methods with signature like foo(::Type{Tuple{Vararg{V}}}) where V
     # Seems like a bug.
     import Aqua
-    Aqua.test_all(PythonCall, unbound_args=false)
+    Aqua.test_all(PythonCall, unbound_args=false, project_toml_formatting=false)
 end