Skip to content

Python 3.14 multiprocessing cannot pickle weakref ReferenceType #189

@ds-cbo

Description

@ds-cbo

Describe the bug

Traceback (most recent call last):
  File "/root/pg_chameleon/venv/bin/chameleon", line 5, in <module>
    exec(compile(open(__file__).read(), __file__, 'exec'))
    ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/pg_chameleon/venv/bin/chameleon.py", line 58, in <module>
    getattr(replica, args.command)()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/root/pg_chameleon/pg_chameleon/lib/global_lib.py", line 670, in start_replica
    self.__run_replica()
    ~~~~~~~~~~~~~~~~~~^^
  File "/root/pg_chameleon/pg_chameleon/lib/global_lib.py", line 598, in __run_replica
    self.replay_daemon.start()
    ~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/lib64/python3.14/multiprocessing/process.py", line 121, in start
    self._popen = self._Popen(self)
                  ~~~~~~~~~~~^^^^^^
  File "/usr/lib64/python3.14/multiprocessing/context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/usr/lib64/python3.14/multiprocessing/context.py", line 300, in _Popen
    return Popen(process_obj)
  File "/usr/lib64/python3.14/multiprocessing/popen_forkserver.py", line 35, in __init__
    super().__init__(process_obj)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/usr/lib64/python3.14/multiprocessing/popen_fork.py", line 20, in __init__
    self._launch(process_obj)
    ~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/usr/lib64/python3.14/multiprocessing/popen_forkserver.py", line 47, in _launch
    reduction.dump(process_obj, buf)
    ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.14/multiprocessing/reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^
TypeError: cannot pickle 'weakref.ReferenceType' object

To Reproduce
Steps to reproduce the behavior:

git clone https://github.com/the4thdoctor/pg_chameleon.git
cd pg_chameleon
python3.14 -m venv venv
. ./venv/bin/activate
pip install -e .
chameleon --debug start_replica --source mysql

Expected behavior
A clear and concise description of what you expected to happen.

Environment:

  • OS: Fedora Server 43 and macOS 26.2
  • MySQL Version: 8.4
  • PostgreSQL Version: 17
  • Python Version: 3.14

Additional context

Does work fine on python 3.9 on Fedora, does not work on python 3.9 on macos. A small investigation seems to suggest it's the read_daemon and replay_daemon objects on the replica_engine object that cannot be pickled. With the following patch, it seems to continue without this error:

diff --git i/pg_chameleon/lib/global_lib.py w/pg_chameleon/lib/global_lib.py
index b4c9a72..b71b722 100644
--- i/pg_chameleon/lib/global_lib.py
+++ w/pg_chameleon/lib/global_lib.py
@@ -176,6 +176,16 @@ class replica_engine(object):
                 self.pg_engine.disconnect_db()
                 sys.exit()

+    def __getstate__(self):
+        res = self.__dict__
+        res = res.copy()
+
+        # don't need those in the forked processes, and we cannot pickle them
+        for k in ('read_daemon', 'replay_daemon'):
+            if k in res:
+                del res[k]
+        return res
+

But that does yield another error (on macOS 3.9 and 3.14, not tested on Fedora):

  File "/opt/homebrew/Cellar/python@3.9/3.9.25/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/spawn.py", line 134, in _check_not_importing_main
    raise RuntimeError('''
RuntimeError:
        An attempt has been made to start a new process before the
        current process has finished its bootstrapping phase.

        This probably means that you are not using fork to start your
        child processes and you have forgotten to use the proper idiom
        in the main module:

            if __name__ == '__main__':
                freeze_support()
                ...

        The "freeze_support()" line can be omitted if the program
        is not going to be frozen to produce an executable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions