PyO3 modules may only be initialized once per interpreter process

Python and python framework

Moderator: leecollings

Post Reply
pipiche
Posts: 2016
Joined: Monday 02 April 2018 20:33
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: France
Contact:

PyO3 modules may only be initialized once per interpreter process

Post by pipiche »

We have a plugin which use the cryptophraphy 41.0.1 module, when you stop and then start the plugin (without restarting Domoticz), you get this error

I found a pointer to that GitHub issue, https://github.com/PyO3/pyo3/issues/2644 but not an expert in the embedded python library
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.632 Error: Zigpy-Elelabs: Call to function 'onStart' failed, exception details:
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.646 Error: Zigpy-Elelabs: Traceback (most recent call last):
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.646 Error: Zigpy-Elelabs: File "/var/lib/domoticz/plugins/Domoticz-Zigbee/plugin.py", line 1537, in onStart
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.646 Error: Zigpy-Elelabs: _plugin.onStart()
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.646 Error: Zigpy-Elelabs: File "/var/lib/domoticz/plugins/Domoticz-Zigbee/plugin.py", line 602, in onStart
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.646 Error: Zigpy-Elelabs: from zigpy.config import (CONF_DEVICE, CONF_DEVICE_PATH,
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.646 Error: Zigpy-Elelabs: File "/usr/local/lib/python3.10/site-packages/zigpy/config/__init__.py", line 32, in <module>
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.646 Error: Zigpy-Elelabs: from zigpy.config.validators import (
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.646 Error: Zigpy-Elelabs: File "/usr/local/lib/python3.10/site-packages/zigpy/config/validators.py", line 9, in <module>
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.646 Error: Zigpy-Elelabs: import zigpy.zdo.types as zdo_t
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.647 Error: Zigpy-Elelabs: File "/usr/local/lib/python3.10/site-packages/zigpy/zdo/__init__.py", line 10, in <module>
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.647 Error: Zigpy-Elelabs: import zigpy.util
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.647 Error: Zigpy-Elelabs: File "/usr/local/lib/python3.10/site-packages/zigpy/util.py", line 14, in <module>
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.647 Error: Zigpy-Elelabs: from cryptography.hazmat.primitives.ciphers import Cipher
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.647 Error: Zigpy-Elelabs: File "/usr/local/lib/python3.10/site-packages/cryptography/hazmat/primitives/ciphers/__init__.py", line 11, in <module>
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.647 Error: Zigpy-Elelabs: from cryptography.hazmat.primitives.ciphers.base import (
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.647 Error: Zigpy-Elelabs: File "/usr/local/lib/python3.10/site-packages/cryptography/hazmat/primitives/ciphers/base.py", line 10, in <module>
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.647 Error: Zigpy-Elelabs: from cryptography.exceptions import (
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.647 Error: Zigpy-Elelabs: File "/usr/local/lib/python3.10/site-packages/cryptography/exceptions.py", line 9, in <module>
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.647 Error: Zigpy-Elelabs: from cryptography.hazmat.bindings._rust import exceptions as rust_exceptions
Jun 02 16:35:43 rasp domoticz[21346]: 2023-06-02 16:35:43.647 Error: Zigpy-Elelabs: ImportError: PyO3 modules may only be initialized once per interpreter process
Last edited by pipiche on Tuesday 13 June 2023 12:51, edited 1 time in total.
Zigbee for Domoticz plugin / RPI3B+ / Electrolama ZZH-P / 45 devices

If the plugin provides you value, you can support me with a donation Paypal.

Wiki is available here.

Zigbee for Domoticz FAQ
pipiche
Posts: 2016
Joined: Monday 02 April 2018 20:33
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: France
Contact:

Re: PyO3 modules may only be initialized once per interpreter process[/quote]

Post by pipiche »

@dnpwwo, what do you think ? Should I create an Issue on the domoticz GitHub ?

Here is a quick way to test it

(1) install the latest cryptopgrahy python3 module

Code: Select all

sudo python3 -m pip install cryptography==41.0.01 --upgrade
(2) Install the python3 plugin to duplicate the problem (see after)
(3) restart domoticz
(4) add "Multiple Reload" plugin
(5) Use update to generate a stop/start and look after the domoticz log

You'll get this error message
Jun 05 16:54:27 rasp domoticz[15544]: 2023-06-05 16:54:27.956 Error: Test MultipleReload: (MultipleReload) failed to load 'plugin.py', Python Path used was '/var/lib/domoticz/plugins/MulitpleReload/:/usr/lib/python310.zip:/usr/lib/python3.10:/usr/lib/python3.10/lib-dynload:/usr/local/lib/python3.10/site-packages:/usr/lib/python3.10/site-packages'.
Jun 05 16:54:27 rasp domoticz[15544]: 2023-06-05 16:54:27.970 Error: Test MultipleReload: Traceback (most recent call last):
Jun 05 16:54:27 rasp domoticz[15544]: 2023-06-05 16:54:27.970 Error: Test MultipleReload: File "/var/lib/domoticz/plugins/MulitpleReload/plugin.py", line 17, in <module>
Jun 05 16:54:27 rasp domoticz[15544]: 2023-06-05 16:54:27.970 Error: Test MultipleReload: from cryptography.hazmat.primitives.ciphers import Cipher
Jun 05 16:54:27 rasp domoticz[15544]: 2023-06-05 16:54:27.970 Error: Test MultipleReload: File "/usr/local/lib/python3.10/site-packages/cryptography/hazmat/primitives/ciphers/__init__.py", line 11, in <module>
Jun 05 16:54:27 rasp domoticz[15544]: 2023-06-05 16:54:27.970 Error: Test MultipleReload: from cryptography.hazmat.primitives.ciphers.base import (
Jun 05 16:54:27 rasp domoticz[15544]: 2023-06-05 16:54:27.970 Error: Test MultipleReload: File "/usr/local/lib/python3.10/site-packages/cryptography/hazmat/primitives/ciphers/base.py", line 10, in <module>
Jun 05 16:54:27 rasp domoticz[15544]: 2023-06-05 16:54:27.970 Error: Test MultipleReload: from cryptography.exceptions import (
Jun 05 16:54:27 rasp domoticz[15544]: 2023-06-05 16:54:27.970 Error: Test MultipleReload: File "/usr/local/lib/python3.10/site-packages/cryptography/exceptions.py", line 9, in <module>
Jun 05 16:54:27 rasp domoticz[15544]: 2023-06-05 16:54:27.970 Error: Test MultipleReload: from cryptography.hazmat.bindings._rust import exceptions as rust_exceptions
Jun 05 16:54:27 rasp domoticz[15544]: 2023-06-05 16:54:27.970 Error: Test MultipleReload: ImportError: PyO3 modules may only be initialized once per interpreter process
Here after is the plugin.py code.

Code: Select all

"""
<plugin key="MultipleReload" name="Multiple Reload" author="pipcihe" version="0.1" externallink="">
    <params>
        <param field="Mode5" label="Debug mode" width="250px">
            <options>
                <option label="Off" value="False" default="true"/>
                <option label="On" value="True"/>
            </options>
        </param>

    </params>
</plugin>
"""

import Domoticz

from cryptography.hazmat.primitives.ciphers import Cipher

class BasePlugin:

    def __init__(self):
        self.plugin_ready = False
        return

    def onStart(self):
        Domoticz.Debug('onStart called')
        if Parameters["Mode5"]=="True":
            Domoticz.Debugging(2)
            self.debug=True
        else:
            self.debug=False

    def onHeartbeat(self):
        Domoticz.Debug('onHeartbeat called')

    def onCommand(self, Unit, Command, Level, Hue):
        Domoticz.Debug('onCommand called')

    def onStop(self):
        Domoticz.Debug('onStop called')

global _plugin
_plugin = BasePlugin()

def onStart():
    global _plugin
    _plugin.onStart()

def onStop():
    global _plugin
    _plugin.onStop()

def onHeartbeat():
    global _plugin
    _plugin.onHeartbeat()

def onCommand(Unit, Command, Level, Hue):
    global _plugin
    _plugin.onCommand(Unit, Command, Level, Hue)
Zigbee for Domoticz plugin / RPI3B+ / Electrolama ZZH-P / 45 devices

If the plugin provides you value, you can support me with a donation Paypal.

Wiki is available here.

Zigbee for Domoticz FAQ
pipiche
Posts: 2016
Joined: Monday 02 April 2018 20:33
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: France
Contact:

Re: PyO3 modules may only be initialized once per interpreter process[/quote]

Post by pipiche »

In fact I wonder why we do an Py_Initialize() everytime we restart a plugin.
Shall we not do the Py_Initialize() only the first time and then rely on it

So it is not needed to Py_FinalizeEx()

And probably save some memory leaks
Zigbee for Domoticz plugin / RPI3B+ / Electrolama ZZH-P / 45 devices

If the plugin provides you value, you can support me with a donation Paypal.

Wiki is available here.

Zigbee for Domoticz FAQ
zak45
Posts: 953
Joined: Sunday 22 January 2017 11:37
Target OS: Windows
Domoticz version: V2024.4
Contact:

Re: PyO3 modules may only be initialized once per interpreter process[/quote]

Post by zak45 »

got the same problem with the Broadlink plugin !
pipiche
Posts: 2016
Joined: Monday 02 April 2018 20:33
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: France
Contact:

Re: PyO3 modules may only be initialized once per interpreter process[/quote]

Post by pipiche »

should we report it as an issue in Domoticz github ?
Zigbee for Domoticz plugin / RPI3B+ / Electrolama ZZH-P / 45 devices

If the plugin provides you value, you can support me with a donation Paypal.

Wiki is available here.

Zigbee for Domoticz FAQ
pipiche
Posts: 2016
Joined: Monday 02 April 2018 20:33
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: France
Contact:

Re: PyO3 modules may only be initialized once per interpreter process[/quote]

Post by pipiche »

zak45 wrote: Thursday 08 June 2023 14:00 got the same problem with the Broadlink plugin !
https://github.com/domoticz/domoticz/issues/5717
Zigbee for Domoticz plugin / RPI3B+ / Electrolama ZZH-P / 45 devices

If the plugin provides you value, you can support me with a donation Paypal.

Wiki is available here.

Zigbee for Domoticz FAQ
User avatar
gizmocuz
Posts: 2580
Joined: Thursday 11 July 2013 18:59
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Top of the world
Contact:

Re: PyO3 modules may only be initialized once per interpreter process

Post by gizmocuz »

I think the idea is to totally remove the plugin from memory and start it again (will also flush memory/close connections, graceful sign-out etc)
This happens also with normal hardware.
So, by the looks of it, this is not happening. I wonder if it is still in memory when the hardware is being disabled/deleted.
Best to fire up visual studio, compile, set breakpoints and debug
Quality outlives Quantity!
User avatar
Dnpwwo
Posts: 820
Joined: Sunday 23 March 2014 9:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Melbourne, Australia
Contact:

Re: PyO3 modules may only be initialized once per interpreter process

Post by Dnpwwo »

I suspect this is not solvable because it is an issue with the library and not Python (or the framework).

There is no 'un-import' function in Python to force a complete cleanup, I believe Python holds libraries in an internal cache even if nothing is referencing them anymore.

Importing them a second time should be fine but some libraries don't handle this properly because they hold values globally inside themselves (which seems to be the case here). A defect should be raised against the library itself.
The reasonable man adapts himself to the world; the unreasonable one persists to adapt the world to himself. Therefore all progress depends on the unreasonable man. George Bernard Shaw
JBN
Posts: 40
Joined: Saturday 13 July 2013 8:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Sweden
Contact:

Re: PyO3 modules may only be initialized once per interpreter process

Post by JBN »

This post is mainly for others that might run into the same problems that I experienced.

I made a plugin for Reolink cameras using reolink_aio and it requires asyncio. I managed to get that working using the pattern from @pipiche as described here viewtopic.php?p=288731 and solution https://github.com/zigbeefordomoticz/Do ... d639d1f84d.

However, I tried to figure out why I got "'NoneType' object is not callable" from reolink_aio when restarting the module (perhaps not the normal behavior but something I do when debugging the plugin). After some searching the NoneType error happens when reolink_aio calls datetime.strptime (as an example when getting the camera host and issue a new subscribe webhook). Thus, it seems that strptime also suffers from problematic caching and is reported here - https://github.com/python/cpython/issues/71587. No fix has been published as of yet.

I have a work-around in place, that seems to solve it, for datetime in the meanwhile:

Code: Select all

import sys
sys.modules["_datetime"] = None
import datetime
pipiche
Posts: 2016
Joined: Monday 02 April 2018 20:33
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: France
Contact:

Re: PyO3 modules may only be initialized once per interpreter process

Post by pipiche »

By doing that, you are not using the c compiled version but the pure python version


Envoyé de mon iPhone en utilisant Tapatalk
Zigbee for Domoticz plugin / RPI3B+ / Electrolama ZZH-P / 45 devices

If the plugin provides you value, you can support me with a donation Paypal.

Wiki is available here.

Zigbee for Domoticz FAQ
JBN
Posts: 40
Joined: Saturday 13 July 2013 8:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Sweden
Contact:

Re: PyO3 modules may only be initialized once per interpreter process

Post by JBN »

Thanks for the comment and your work. I assume that primarly makes the plugin slower when using datetime functions. I might be able to change the upstream reolink_aio module so it works but at least now it seems work.
pipiche
Posts: 2016
Joined: Monday 02 April 2018 20:33
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: France
Contact:

Re: PyO3 modules may only be initialized once per interpreter process

Post by pipiche »

Dnpwwo wrote: Saturday 08 July 2023 0:12 I suspect this is not solvable because it is an issue with the library and not Python (or the framework).

There is no 'un-import' function in Python to force a complete cleanup, I believe Python holds libraries in an internal cache even if nothing is referencing them anymore.

Importing them a second time should be fine but some libraries don't handle this properly because they hold values globally inside themselves (which seems to be the case here). A defect should be raised against the library itself.
https://github.com/pyca/cryptography/issues/9016
Zigbee for Domoticz plugin / RPI3B+ / Electrolama ZZH-P / 45 devices

If the plugin provides you value, you can support me with a donation Paypal.

Wiki is available here.

Zigbee for Domoticz FAQ
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 1 guest