Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

Commit

Permalink
Replace the Memoize decorator with property cache to avoid memory leak.
Browse files Browse the repository at this point in the history
  • Loading branch information
Yan Tang committed Apr 6, 2016
1 parent 15c8d50 commit cc47139
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 32 deletions.
12 changes: 7 additions & 5 deletions python/src/keyczar/keyczar.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ def Write(self, writer, encrypter=None):
if isinstance(writer, basestring):
writer = writers.CreateWriter(writer)
warnings.warn(
'Using a string as the writer is deprecated. Use writers.CreateWriter',
'Using a string as the writer is deprecated. Use writers.CreateWriter',
DeprecationWarning)
self.metadata.encrypted = (encrypter is not None)
writer.WriteMetadata(self.metadata)
Expand Down Expand Up @@ -352,7 +352,7 @@ def CreateEncryptingStreamWriter(self, output_stream,
@type output_stream: 'file-like' object
@param encoder: the encoding stream to use on the ciphertext stream.
Defaults to base64 encoding with no padding or line breaks.
Defaults to base64 encoding with no padding or line breaks.
Use None for raw bytes.
@type encoder: 'file-like' object
Expand Down Expand Up @@ -547,7 +547,7 @@ def CreateDecryptingStreamReader(self, output_stream,
@type output_stream: 'file-like' object
@param decoder: the decoding stream to use on the incoming stream.
Defaults to base64 decoding with no padding or line breaks.
Defaults to base64 decoding with no padding or line breaks.
Use None for handling raw bytes.
@type decoder: 'file-like' object
Expand Down Expand Up @@ -729,12 +729,14 @@ def __Create(session_key, nonce):
return session

@property
@util.Memoize
def crypter(self):
"""
Returns a Crypter which can be used to encrypt and decrypt data using the session key.
"""
return Crypter(readers.StaticKeyReader(self.__session_key, keyinfo.DECRYPT_AND_ENCRYPT))
if not hasattr(self, '_crypter'):
self._crypter = Crypter(readers.StaticKeyReader(
self.__session_key, keyinfo.DECRYPT_AND_ENCRYPT))
return self._crypter

@property
def nonce(self):
Expand Down
32 changes: 5 additions & 27 deletions python/src/keyczar/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ class IncrementalBase64WSStreamWriter(codecs.StreamWriter, object):
"""
def __init__(self, stream, errors='strict'):
"""
"""
Creates an IncrementalBase64WSStreamWriter instance.
@param stream: a file-like object open for writing (binary) data.
Expand Down Expand Up @@ -706,7 +706,7 @@ class IncrementalBase64WSStreamReader(codecs.StreamReader, object):
"""

def __init__(self, stream, errors='strict'):
"""
"""
Creates an IncrementalBase64WSStreamReader instance.
@param stream: a file-like object open for reading (binary) data.
Expand All @@ -730,7 +730,7 @@ def __init__(self, stream, errors='strict'):
self.decoder = BufferedIncrementalBase64WSDecoder(errors=errors)

def read(self, size=-1, chars=-1, firstline=False):
"""
"""
Decodes data from the input stream and returns the resulting object.
@param chars: the number of characters to read from the stream. read() will
Expand All @@ -756,7 +756,7 @@ def read(self, size=-1, chars=-1, firstline=False):
end of the input data has been reached.
@rtype: string
"""

# NOTE: this is a copy of the code from Python v2.7 codecs.py tweaked to
# handle non-blocking streams i.e. those that return None to indicate no
# data is available but is not at EOF - see read() in the Python I/O module
Expand Down Expand Up @@ -845,27 +845,6 @@ def decode(self, input, errors='strict'):
"""
return self.decoder.decode(input)


def Memoize(func):
"""
General-purpose memoization decorator. Handles functions with any number of arguments,
including keyword arguments.
"""
memory = {}

@functools.wraps(func)
def memo(*args,**kwargs):
pickled_args = cPickle.dumps((args, sorted(kwargs.iteritems())))

if pickled_args not in memory:
memory[pickled_args] = func(*args,**kwargs)

return memory[pickled_args]

if memo.__doc__:
memo.__doc__ = "\n".join([memo.__doc__,"This function is memoized."])
return memo

def ImportAll(pluginpath):
"""
Simple plugin importer - imports from the specified subdirectory under the
Expand All @@ -883,7 +862,7 @@ def ImportAll(pluginpath):

def ImportBackends():
"""
Simple backend plugin importer - imports from the 'backends' subdirectory
Simple backend plugin importer - imports from the 'backends' subdirectory
under the util.py directory and any directories in the environment variable
'KEYCZAR_BACKEND_PATHS', which can contain >=1 paths joined using the o/s
"""
Expand All @@ -893,4 +872,3 @@ def ImportBackends():
if xtra_paths:
for path in xtra_paths.split(os.pathsep):
ImportAll(path)

0 comments on commit cc47139

Please sign in to comment.