3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-12-24 03:33:10 +01:00

Condense (deep)copy definitions into structures.CopyWrapper

This commit is contained in:
James Lu 2017-08-25 17:05:53 -07:00
parent 8c0f19422f
commit 0907f05296
2 changed files with 42 additions and 21 deletions

View File

@ -12,7 +12,6 @@ import time
import socket
import ssl
import hashlib
from copy import copy, deepcopy
import inspect
import ipaddress
import queue
@ -480,6 +479,8 @@ class PyLinkNetworkCore(utils.DeprecatedAttributesObject, utils.CamelCaseToSnake
except AttributeError:
return False
structures._BLACKLISTED_COPY_TYPES.append(PyLinkNetworkCore)
class PyLinkNetworkCoreWithUtils(PyLinkNetworkCore):
def __init__(self, *args, **kwargs):
@ -1567,7 +1568,7 @@ class Server():
IrcServer = Server
class Channel(utils.DeprecatedAttributesObject, utils.CamelCaseToSnakeCase):
class Channel(utils.DeprecatedAttributesObject, utils.CamelCaseToSnakeCase, structures.CopyWrapper):
"""PyLink IRC channel class."""
def __init__(self, irc, name=None):
@ -1599,22 +1600,6 @@ class Channel(utils.DeprecatedAttributesObject, utils.CamelCaseToSnakeCase):
self.users.discard(target)
removeuser = remove_user
def __deepcopy__(self, memo):
"""Returns a deep copy of the channel object."""
# XXX: we can't pickle IRCNetwork, so just return a reference of it.
channel_copy = copy(self)
# For everything else, create a copy.
for attr, val in self.__dict__.items():
if not isinstance(val, PyLinkNetworkCore):
setattr(channel_copy, attr, deepcopy(val))
memo[id(self)] = channel_copy
return channel_copy
def deepcopy(self):
return deepcopy(self)
def is_voice(self, uid):
"""Returns whether the given user is voice in the channel."""
return uid in self.prefixmodes['voice']

View File

@ -10,10 +10,13 @@ import json
import pickle
import os
import threading
from copy import copy, deepcopy
from .log import log
from . import conf
_BLACKLISTED_COPY_TYPES = []
class KeyedDefaultdict(collections.defaultdict):
"""
Subclass of defaultdict allowing the key to be passed to the default factory.
@ -26,7 +29,34 @@ class KeyedDefaultdict(collections.defaultdict):
value = self[key] = self.default_factory(key)
return value
class CaseInsensitiveFixedSet(collections.abc.Set):
class CopyWrapper():
"""
Base container class implementing copy methods.
"""
def copy(self):
"""Returns a shallow copy of this object instance."""
return copy(self)
def __deepcopy__(self, memo):
"""Returns a deep copy of the channel object."""
newobj = copy(self)
log.debug('CopyWrapper: _BLACKLISTED_COPY_TYPES = %s', _BLACKLISTED_COPY_TYPES)
for attr, val in self.__dict__.items():
# We can't pickle IRCNetwork, so just return a reference of it.
if not isinstance(val, tuple(_BLACKLISTED_COPY_TYPES)):
log.debug('CopyWrapper: copying attr %r', attr)
setattr(newobj, attr, deepcopy(val))
memo[id(self)] = newobj
return newobj
def deepcopy(self):
"""Returns a deep copy of this object instance."""
return deepcopy(self)
class CaseInsensitiveFixedSet(collections.abc.Set, CopyWrapper):
"""
Implements a fixed set storing items case-insensitively.
"""
@ -55,8 +85,8 @@ class CaseInsensitiveFixedSet(collections.abc.Set):
def __contains__(self, key):
return self._data.__contains__(self._keymangle(key))
def copy(self, *args, **kwargs):
return self._data.copy(*args, **kwargs)
def __copy__(self):
return self.__class__(data=self._data.copy())
class CaseInsensitiveDict(collections.abc.MutableMapping, CaseInsensitiveFixedSet):
"""
@ -92,6 +122,9 @@ class IRCCaseInsensitiveDict(CaseInsensitiveDict):
"""Converts the given key to lowercase."""
return self._irc.to_lower(key)
def __copy__(self):
return self.__class__(self._irc, data=self._data.copy())
class CaseInsensitiveSet(collections.abc.MutableSet, CaseInsensitiveFixedSet):
"""
A mutable set storing items case insensitively.
@ -115,6 +148,9 @@ class IRCCaseInsensitiveSet(CaseInsensitiveSet):
"""Converts the given key to lowercase."""
return self._irc.to_lower(key)
def __copy__(self):
return self.__class__(self._irc, data=self._data.copy())
class DataStore:
"""
Generic database class. Plugins should use a subclass of this such as JSONDataStore or