Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nest assignment is ignored smd['some-key']['x'] #58

Open
marcelomanzo opened this issue Jun 9, 2022 · 12 comments
Open

Nest assignment is ignored smd['some-key']['x'] #58

marcelomanzo opened this issue Jun 9, 2022 · 12 comments

Comments

@marcelomanzo
Copy link

from shared_memory_dict import SharedMemoryDict
smd = SharedMemoryDict(name='tokens', size=1024)
smd['some-key'] = {}
smd['some-key']['x'] = 1 #this statement is ignored
print(smd) #output {'some-key': {}}

@druidance
Copy link

druidance commented Apr 2, 2024

Was baffled by this limitation as well.

As a work around, how about juggling the nested object?

from shared_memory_dict import SharedMemoryDict

smd = SharedMemoryDict(name='tokens', size=1024)

temp = smd['some-key'] = {}
temp['x'] = 1
smd['some-key'] = temp
print(smd) #output {'some-key': {'x': 1}}

edit: added more comments

@githubdontbanmeagain
Copy link

Is there a better fix for this? The "juggling" above throws an error.

@druidance
Copy link

Is there a better fix for this? The "juggling" above throws an error.

Hey,

Could you show the error you're getting there?

@githubdontbanmeagain
Copy link

client is a initialized class, key is a str

smd = SharedMemoryDict(name="123", size=1024)
smd["data"]

def add_to_data():
    temp = smd["data"]
    temp[key] = {
            "key": key,
            "client": client,
    }
    smd["data"] = temp

def add_to_data()
Traceback (most recent call last):
  File "C:\Users\x\x.py", line 34, in x
    smd"data"] = temp
  File "C:\Users\x\AppData\Local\Programs\Python\Python39\lib\site-packages\shared_memory_dict\dict.py", line 96, in __setitem__
    db[key] = value
  File "C:\Users\x\AppData\Local\Programs\Python\Python39\lib\contextlib.py", line 124, in __exit__
    next(self.gen)
  File "C:\Users\x\AppData\Local\Programs\Python\Python39\lib\site-packages\shared_memory_dict\dict.py", line 89, in _modify_db
    self._save_memory(db)
  File "C:\Users\x\AppData\Local\Programs\Python\Python39\lib\site-packages\shared_memory_dict\dict.py", line 177, in _save_memory
    data = self._serializer.dumps(db)
  File "C:\Users\x\AppData\Local\Programs\Python\Python39\lib\site-packages\shared_memory_dict\serializers.py", line 44, in dumps
    return pickle.dumps(obj, pickle.HIGHEST_PROTOCOL)
AttributeError: Can't pickle local object 'WeakValueDictionary.__init__.<locals>.remove'

@githubdontbanmeagain
Copy link

I tested it without client, that seems to be the issue. I'm not quite sure how to go about this

@githubdontbanmeagain
Copy link

Got this error when using the built in JSONSerializer instead, as I read pickle has problems with local objects:

  File "C:\Users\x\AppData\Local\Programs\Python\Python39\lib\site-packages\shared_memory_dict\serializers.py", line 31, in dumps
    raise SerializationError(obj)
shared_memory_dict.serializers.SerializationError: Failed to serialize data: {...

@druidance
Copy link

druidance commented Aug 7, 2024

client is a initialized class, key is a str

I think this is the problem you've got there as it relates to the fact that you cannot assign custom objects (that cannot be pickled) as values. Change your client type to something more common - such as str or int - and you'll get the result.

from shared_memory_dict import SharedMemoryDict

smd = SharedMemoryDict(name="123", size=1024)
smd["data"] = {}


def add_to_data(key, client):
    temp = smd["data"]
    temp[key] = {
            "key": key,
            "client": client,
    }
    smd["data"] = temp

key = 1
client = 'Client'
add_to_data(key, client)

What is the reason for passing such client object between the processes? Does it hold some kind of important information you want to update?

@githubdontbanmeagain
Copy link

Yes, the client class has functions and data that I need to access in other files. So simply using a string would not really work..

I tried using dill (a drop in replacement for pickle with more support for custom types), but I face different issues there.

I could store the clients in a local dict in that file, and then send read/write commands through shared memory, but that would really be pain, I'm trying to find a clean solution.

@druidance
Copy link

How about refactoring class data out to DTOs that can be passed around through the SharedMemoryDict functionality?

I think that was the core concept behind shared_memory objects.

@githubdontbanmeagain
Copy link

That would kinda be a little complex, the functions need the context of the client class to work properly, as there are multiple clients initialized

@druidance
Copy link

Sorry, but I'm afraid I cannot help any further since I do not possess enough information about the logic you're trying to implement. It seems to be out of SharedMemoryDict scope.

@githubdontbanmeagain
Copy link

All good, it's an issue with pickle/dill.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants