Page 1 of 1
Unexpected behavior from pickle.dump
Posted: Wed May 23, 2018 6:03 am
by arawra
Code: Select all
sp plugin reload rpgo
[SP] Unloading plugin 'rpgo'...
D:\csgo\csgo/addons/source-python/plugins/rpgo/player_database.db
<_io.BufferedWriter name=Path('D:\\csgo\\csgo/addons/source-python/plugins/rpgo/player_database.db')>
<built-in function dump>
WARNING: __getstate__ ADDED AS A DATABASE ATTRIBUTE
[SP] Caught an Exception:
Traceback (most recent call last):
File "..\addons\source-python\packages\source-python\plugins\manager.py", line 217, in unload
plugin._unload()
File "..\addons\source-python\packages\source-python\plugins\instance.py", line 81, in _unload
self.module.unload()
File "..\addons\source-python\plugins\rpgo\rpgo.py", line 376, in unload
pickle.dump(playerList, databaseFile)
TypeError: 'int' object is not callable
[SP] Successfully unloaded plugin 'rpgo'.
[SP] Loading plugin 'rpgo'...
[SP] Successfully loaded plugin 'rpgo'.
Syntax: Select all
def unload():
with open(database, 'wb') as databaseFile:
print(database)
print(databaseFile)
print(pickle.dump)
pickle.dump(playerList, databaseFile)
with open(jsonDatabase, 'w') as f:
json.dump(json.dumps(playerList), f)
message(messages['mod unloaded'])
This is only happening when playerList is populated with some data.
Re: Unexpected behavior from pickle.dump
Posted: Thu May 24, 2018 3:22 am
by quartata
What's in playerList?
Re: Unexpected behavior from pickle.dump
Posted: Thu May 24, 2018 3:48 am
by arawra
Syntax: Select all
class PlayerData(dict):
def __init__(self):
self.kills = 0
self.spree = 0
self.gold = 0
self.rpgClass = messages['default class']
self.cooldown = False
self.stunTimer = None
self.speedTimer = None
self.baseSpeed = 1.0
self.pounces = 0
for eachClass in CLASSES:
self['%s'%eachClass] = {
'Level' :1,
'XP' :0
}
playerList = _PlayerList()
str_path = GAME_PATH + '/addons/source-python/plugins/rpgo/'
database = os.path.normpath(str_path + 'player_database.db')
jsonDatabase = os.path.normpath(str_path + 'player_database.json')
if os.path.isfile(database):
if not os.stat(database).st_size == 0:
with open(database, 'rb') as databaseFile:
playerList = pickle.load(databaseFile)
class _PlayerList(dict):
def __missing__(self, steamid):
index = index_from_steamid(steamid)
player = Player(index)
if steamid == 'BOT':
steamid += "_" + player.name
value = self[steamid] = PlayerData()
playerList[steamid].rpgClass = messages['default class']
if not player.is_bot():
message(messages['default class message'], player.index)
message(player.name + messages['new player'])
return value
Re: Unexpected behavior from pickle.dump
Posted: Thu May 24, 2018 4:14 am
by quartata
Inheriting from dict is tricky, I suspect that's what's causing the error (perhaps one of your fields in PlayerData is shadowing something). I would replace inheriting dict for PlayerData with a data field containing the dict.
Re: Unexpected behavior from pickle.dump
Posted: Thu May 24, 2018 5:06 am
by Ayuto
It could also be a missing super().__init__() call.
Re: Unexpected behavior from pickle.dump
Posted: Tue May 29, 2018 1:42 am
by arawra
Yeah I still have no idea whats causing this.
Code: Select all
[SP] Unloading plugin 'rpgo'...
[('__class__', <class 'rpgo.rpgo._PlayerList'>),
('__contains__',
<built-in method __contains__ of _PlayerList object at 0x02D164C8>),
('__delattr__',
<method-wrapper '__delattr__' of _PlayerList object at 0x02D164C8>),
('__delitem__',
<method-wrapper '__delitem__' of _PlayerList object at 0x02D164C8>),
('__dict__', {}),
('__dir__', <built-in method __dir__ of _PlayerList object at 0x02D164C8>),
('__doc__', None),
('__eq__', <method-wrapper '__eq__' of _PlayerList object at 0x02D164C8>),
('__format__',
<built-in method __format__ of _PlayerList object at 0x02D164C8>),
('__ge__', <method-wrapper '__ge__' of _PlayerList object at 0x02D164C8>),
('__getattribute__',
<method-wrapper '__getattribute__' of _PlayerList object at 0x02D164C8>),
('__getitem__',
<built-in method __getitem__ of _PlayerList object at 0x02D164C8>),
('__gt__', <method-wrapper '__gt__' of _PlayerList object at 0x02D164C8>),
('__hash__', None),
('__init__', <method-wrapper '__init__' of _PlayerList object at 0x02D164C8>),
('__init_subclass__',
<built-in method __init_subclass__ of type object at 0x02CAC790>),
('__iter__', <method-wrapper '__iter__' of _PlayerList object at 0x02D164C8>),
('__le__', <method-wrapper '__le__' of _PlayerList object at 0x02D164C8>),
('__len__', <method-wrapper '__len__' of _PlayerList object at 0x02D164C8>),
('__lt__', <method-wrapper '__lt__' of _PlayerList object at 0x02D164C8>),
('__missing__',
<bound method _PlayerList.__missing__ of {'STEAM_1:1:45055382': {'kills': 0, 'spree': 0, 'gold': 0, 'rpgClass': 'Warrior', 'cooldown': False, 'stunTimer': None, 'speedTimer': None, 'baseSpeed': 1.0, 'pounces': 0, 'Warrior': {'Level': 1, 'XP': 560}, 'Rogue': {'Level': 1, 'XP': 0}, 'Priest': {'Level': 1, 'XP': 0}, 'Warlock': {'Level': 1, 'XP': 0}, 'Mage': {'Level': 1, 'XP': 0}, 'Ranger': {'Level': 1, 'XP': 0}, 'Druid': {'Level': 1, 'XP': 0}, 'attr': 0}, 'BOT_Scott': {'kills': 0, 'spree': 0, 'gold': 0, 'rpgClass': 'Warrior', 'cooldown': False, 'stunTimer': None, 'speedTimer': None, 'baseSpeed': 1.0, 'pounces': 0, 'Warrior': {'Level': 1, 'XP': 0}, 'Rogue': {'Level': 1, 'XP': 0}, 'Priest': {'Level': 1, 'XP': 0}, 'Warlock': {'Level': 1, 'XP': 0}, 'Mage': {'Level': 1, 'XP': 0}, 'Ranger': {'Level': 1, 'XP': 0}, 'Druid': {'Level': 1, 'XP': 0}}, 'STEAM_1:1:22252686': {'kills': 0, 'spree': 0, 'gold': 0, 'rpgClass': 'Warrior', 'cooldown': False, 'stunTimer': None, 'speedTimer': None, 'baseSpeed': 1.0, 'pounces': 0, 'Warrior': {'Level': 1, 'XP': 280}, 'Rogue': {'Level': 1, 'XP': 0}, 'Priest': {'Level': 1, 'XP': 0}, 'Warlock': {'Level': 1, 'XP': 0}, 'Mage': {'Level': 1, 'XP': 0}, 'Ranger': {'Level': 1, 'XP': 0}, 'Druid': {'Level': 1, 'XP': 0}}, 'BOT_Tim': {'kills': 0, 'spree': 0, 'gold': 0, 'rpgClass': 'Warrior', 'cooldown': False, 'stunTimer': None, 'speedTimer': None, 'baseSpeed': 1.0, 'pounces': 0, 'Warrior': {'Level': 1, 'XP': 0}, 'Rogue': {'Level': 1, 'XP': 0}, 'Priest': {'Level': 1, 'XP': 0}, 'Warlock': {'Level': 1, 'XP': 0}, 'Mage': {'Level': 1, 'XP': 0}, 'Ranger': {'Level': 1, 'XP': 0}, 'Druid': {'Level': 1, 'XP': 0}}}>),
('__module__', 'rpgo.rpgo'),
('__ne__', <method-wrapper '__ne__' of _PlayerList object at 0x02D164C8>),
('__new__', <built-in method __new__ of type object at 0x1E2CF728>),
('__reduce__',
<built-in method __reduce__ of _PlayerList object at 0x02D164C8>),
('__reduce_ex__',
<built-in method __reduce_ex__ of _PlayerList object at 0x02D164C8>),
('__repr__', <method-wrapper '__repr__' of _PlayerList object at 0x02D164C8>),
('__setattr__',
<method-wrapper '__setattr__' of _PlayerList object at 0x02D164C8>),
('__setitem__',
<method-wrapper '__setitem__' of _PlayerList object at 0x02D164C8>),
('__sizeof__',
<built-in method __sizeof__ of _PlayerList object at 0x02D164C8>),
('__slotnames__', []),
('__str__', <method-wrapper '__str__' of _PlayerList object at 0x02D164C8>),
('__subclasshook__',
<built-in method __subclasshook__ of type object at 0x02CAC790>),
('__weakref__', None),
('clear', <built-in method clear of _PlayerList object at 0x02D164C8>),
('copy', <built-in method copy of _PlayerList object at 0x02D164C8>),
('fromkeys', <built-in method fromkeys of type object at 0x02CAC790>),
('get', <built-in method get of _PlayerList object at 0x02D164C8>),
('items', <built-in method items of _PlayerList object at 0x02D164C8>),
('keys', <built-in method keys of _PlayerList object at 0x02D164C8>),
('pop', <built-in method pop of _PlayerList object at 0x02D164C8>),
('popitem', <built-in method popitem of _PlayerList object at 0x02D164C8>),
('setdefault',
<built-in method setdefault of _PlayerList object at 0x02D164C8>),
('update', <built-in method update of _PlayerList object at 0x02D164C8>),
('values', <built-in method values of _PlayerList object at 0x02D164C8>)]
WARNING: __getstate__ ADDED AS A DATABASE ATTRIBUTE
[SP] Caught an Exception:
Traceback (most recent call last):
File "..\addons\source-python\packages\source-python\plugins\manager.py", line 217, in unload
plugin._unload()
File "..\addons\source-python\packages\source-python\plugins\instance.py", line 81, in _unload
self.module.unload()
File "..\addons\source-python\plugins\rpgo\rpgo.py", line 379, in unload
pickle.dump(playerList, file)
TypeError: 'int' object is not callable
[SP] Successfully unloaded plugin 'rpgo'.
Syntax: Select all
def unload():
pprint(getmembers(playerList))
file = open(database, 'wb')
pickle.dump(playerList, file)
file.close()
with open(jsonDatabase, 'w') as f:
json.dump(json.dumps(playerList), f)
message(messages['mod unloaded'])
Re: Unexpected behavior from pickle.dump
Posted: Tue May 29, 2018 1:45 am
by satoon101
Did you do this?
Ayuto wrote:It could also be a missing super().__init__() call.
If you override dict's __init__ method, you need to call super().__init__() to fully initialize the dictionary. If you don't, it can and will lead to errors like the one you are experiencing.
Re: Unexpected behavior from pickle.dump
Posted: Tue May 29, 2018 2:08 am
by arawra
I did find the issue.
super().__init__() had little effect. The issue was trying to override missing properties of the object.
This works fine.
Syntax: Select all
def __getattr__(self, attr):
# Redirect to __getitem__
# Can also use:
# return self[attr]
try:
return self[attr]
except KeyError:
raise AttributeError('Attribute "{0}" not found'.format(attr))
This does not.
Syntax: Select all
def __getattr__(self, attr):
# Redirect to __getitem__
# Can also use:
# return self[attr]
try:
return self[attr]
except KeyError:
if attr in CLASSES:
self['%s'%attr] = {
'Level' :1,
'XP' :0
}
else:
#print("WARNING: %s ADDED AS A DATABASE ATTRIBUTE"%attr)
self.attr = 0
return self.attr
This would set
__getstate__ as an integer, which isn't what I want XD. Currently doing a solution.
Re: Unexpected behavior from pickle.dump
Posted: Tue May 29, 2018 3:19 am
by satoon101
That's code that was not posted previously in this thread. It's a little difficult for us to answer questions if you don't supply all relevant code.
Also, in your except/if you aren't returning anything.
Edit: I am also unsure what you are trying to do in the 'else'. You are NOT setting the given attribute to 0. You are literally setting the attribute 'attr' to 0. If you want to create the given attribute and set it (completely arbitrarily) to 0, you will want to either call self.__setattr__ or use the setattr built-in.