python-memcached
Advanced tools
| Metadata-Version: 1.1 | ||
| Name: python-memcached | ||
| Version: 1.56 | ||
| Summary: Pure python memcached client | ||
| Home-page: http://www.tummy.com/Community/software/python-memcached/ | ||
| Author: Sean Reifschneider | ||
| Author-email: jafo@tummy.com | ||
| License: UNKNOWN | ||
| Download-URL: ftp://ftp.tummy.com/pub/python-memcached/ | ||
| Description: [](https://travis-ci.org/linsomniac/python-memcached) | ||
| ## Overview | ||
| This software is a 100% Python interface to the memcached memory cache | ||
| daemon. It is the client side software which allows storing values | ||
| in one or more, possibly remote, memcached servers. Search google for | ||
| memcached for more information. | ||
| This package was originally written by Evan Martin of Danga. Please do | ||
| not contact Evan about maintenance. Sean Reifschneider of tummy.com, | ||
| ltd. has taken over maintenance of it. | ||
| Please report issues and submit code changes to the github repository at: | ||
| https://github.com/linsomniac/python-memcached | ||
| For changes prior to 2013-03-26, see the old Launchpad repository at: | ||
| Historic issues: https://launchpad.net/python-memcached | ||
| ## Testing | ||
| Test patches locally and easily by running tox: | ||
| pip install tox | ||
| tox -e py27 | ||
| Test for style by running tox: | ||
| tox -e pep8 | ||
| Platform: UNKNOWN | ||
| Classifier: Development Status :: 5 - Production/Stable | ||
| Classifier: Intended Audience :: Developers | ||
| Classifier: License :: OSI Approved :: Python Software Foundation License | ||
| Classifier: Operating System :: OS Independent | ||
| Classifier: Programming Language :: Python | ||
| Classifier: Topic :: Internet | ||
| Classifier: Topic :: Software Development :: Libraries :: Python Modules | ||
| Classifier: Programming Language :: Python | ||
| Classifier: Programming Language :: Python :: 2 | ||
| Classifier: Programming Language :: Python :: 2.6 | ||
| Classifier: Programming Language :: Python :: 2.7 | ||
| Classifier: Programming Language :: Python :: 3 | ||
| Classifier: Programming Language :: Python :: 3.2 | ||
| Classifier: Programming Language :: Python :: 3.3 | ||
| Classifier: Programming Language :: Python :: 3.4 |
| ChangeLog | ||
| MANIFEST.in | ||
| README.md | ||
| memcache.py | ||
| requirements.txt | ||
| setup.cfg | ||
| setup.py | ||
| test-requirements.txt | ||
| python_memcached.egg-info/PKG-INFO | ||
| python_memcached.egg-info/SOURCES.txt | ||
| python_memcached.egg-info/dependency_links.txt | ||
| python_memcached.egg-info/requires.txt | ||
| python_memcached.egg-info/top_level.txt |
| memcache |
+268
-139
@@ -65,3 +65,3 @@ #!/usr/bin/env python | ||
| return ( | ||
| (((binascii.crc32(key.encode('ascii')) & 0xffffffff) | ||
| (((binascii.crc32(key) & 0xffffffff) | ||
| >> 16) & 0x7fff) or 1) | ||
@@ -76,28 +76,16 @@ serverHashFunction = cmemcache_hash | ||
| try: | ||
| from zlib import compress, decompress | ||
| _supports_compress = True | ||
| except ImportError: | ||
| _supports_compress = False | ||
| # quickly define a decompress just in case we recv compressed data. | ||
| def decompress(val): | ||
| raise _Error( | ||
| "Received compressed data but I don't support " | ||
| "compression (import error)") | ||
| from io import BytesIO | ||
| try: | ||
| unicode | ||
| except NameError: | ||
| _has_unicode = False | ||
| if six.PY2: | ||
| try: | ||
| unicode | ||
| except NameError: | ||
| _has_unicode = False | ||
| else: | ||
| _has_unicode = True | ||
| else: | ||
| _has_unicode = True | ||
| try: | ||
| _str_cls = basestring | ||
| except NameError: | ||
| _str_cls = str | ||
| _str_cls = six.string_types | ||
| valid_key_chars_re = re.compile('[\x21-\x7e\x80-\xff]+$') | ||
| valid_key_chars_re = re.compile(b'[\x21-\x7e\x80-\xff]+$') | ||
@@ -107,3 +95,3 @@ | ||
| __author__ = "Sean Reifschneider <jafo-memcached@tummy.com>" | ||
| __version__ = "1.54" | ||
| __version__ = "1.56" | ||
| __copyright__ = "Copyright (C) 2003 Danga Interactive" | ||
@@ -114,5 +102,6 @@ # http://en.wikipedia.org/wiki/Python_Software_Foundation_License | ||
| SERVER_MAX_KEY_LENGTH = 250 | ||
| # Storing values larger than 1MB requires recompiling memcached. If | ||
| # you do, this value can be changed by doing | ||
| # "memcache.SERVER_MAX_VALUE_LENGTH = N" after importing this module. | ||
| # Storing values larger than 1MB requires starting memcached with -I <size> for | ||
| # memcached >= 1.4.2 or recompiling for < 1.4.2. If you do, this value can be | ||
| # changed by doing "memcache.SERVER_MAX_VALUE_LENGTH = N" after importing this | ||
| # module. | ||
| SERVER_MAX_VALUE_LENGTH = 1024 * 1024 | ||
@@ -185,2 +174,3 @@ | ||
| pickler=pickle.Pickler, unpickler=pickle.Unpickler, | ||
| compressor=zlib.compress, decompressor=zlib.decompress, | ||
| pload=None, pid=None, | ||
@@ -248,2 +238,4 @@ server_max_key_length=None, server_max_value_length=None, | ||
| self.unpickler = unpickler | ||
| self.compressor = compressor | ||
| self.decompressor = decompressor | ||
| self.persistent_load = pload | ||
@@ -266,2 +258,28 @@ self.persistent_id = pid | ||
| def _encode_key(self, key): | ||
| if isinstance(key, tuple): | ||
| if isinstance(key[1], six.text_type): | ||
| return (key[0], key[1].encode('utf8')) | ||
| elif isinstance(key, six.text_type): | ||
| return key.encode('utf8') | ||
| return key | ||
| def _encode_cmd(self, cmd, key, headers, noreply, *args): | ||
| cmd_bytes = cmd.encode() if six.PY3 else cmd | ||
| fullcmd = [cmd_bytes, b' ', key] | ||
| if headers: | ||
| if six.PY3: | ||
| headers = headers.encode() | ||
| fullcmd.append(b' ') | ||
| fullcmd.append(headers) | ||
| if noreply: | ||
| fullcmd.append(b' noreply') | ||
| if args: | ||
| fullcmd.append(b' ') | ||
| fullcmd.extend(args) | ||
| return b''.join(fullcmd) | ||
| def reset_cas(self): | ||
@@ -409,3 +427,3 @@ """Reset the cas cache. | ||
| def delete_multi(self, keys, time=0, key_prefix=''): | ||
| def delete_multi(self, keys, time=0, key_prefix='', noreply=False): | ||
| """Delete multiple keys in the memcache doing just one query. | ||
@@ -431,2 +449,4 @@ | ||
| L{set_multi}. | ||
| @param noreply: optional parameter instructs the server to not send the | ||
| reply. | ||
| @return: 1 if no failure in communication with any memcacheds. | ||
@@ -448,8 +468,9 @@ @rtype: int | ||
| write = bigcmd.append | ||
| extra = ' noreply' if noreply else '' | ||
| if time is not None: | ||
| for key in server_keys[server]: # These are mangled keys | ||
| write("delete %s %d\r\n" % (key, time)) | ||
| write("delete %s %d%s\r\n" % (key, time, extra)) | ||
| else: | ||
| for key in server_keys[server]: # These are mangled keys | ||
| write("delete %s\r\n" % key) | ||
| write("delete %s%s\r\n" % (key, extra)) | ||
| try: | ||
@@ -464,2 +485,6 @@ server.send_cmds(''.join(bigcmd)) | ||
| # if noreply, just return | ||
| if noreply: | ||
| return rc | ||
| # if any servers died on the way, don't expect them to respond. | ||
@@ -480,3 +505,3 @@ for server in dead_servers: | ||
| def delete(self, key, time=0): | ||
| def delete(self, key, time=0, noreply=False): | ||
| '''Deletes a key from the memcache. | ||
@@ -487,7 +512,10 @@ | ||
| should fail. Defaults to None for no delay. | ||
| @param noreply: optional parameter instructs the server to not send the | ||
| reply. | ||
| @rtype: int | ||
| ''' | ||
| return self._deletetouch(['DELETED', 'NOT_FOUND'], "delete", key, time) | ||
| return self._deletetouch([b'DELETED', b'NOT_FOUND'], "delete", key, | ||
| time, noreply) | ||
| def touch(self, key, time=0): | ||
| def touch(self, key, time=0, noreply=False): | ||
| '''Updates the expiration time of a key in memcache. | ||
@@ -501,7 +529,10 @@ | ||
| default to 0 == cache forever. | ||
| @param noreply: optional parameter instructs the server to not send the | ||
| reply. | ||
| @rtype: int | ||
| ''' | ||
| return self._deletetouch(['TOUCHED'], "touch", key, time) | ||
| return self._deletetouch([b'TOUCHED'], "touch", key, time, noreply) | ||
| def _deletetouch(self, expected, cmd, key, time=0): | ||
| def _deletetouch(self, expected, cmd, key, time=0, noreply=False): | ||
| key = self._encode_key(key) | ||
| if self.do_check_key: | ||
@@ -514,8 +545,10 @@ self.check_key(key) | ||
| if time is not None and time != 0: | ||
| cmd = "%s %s %d" % (cmd, key, time) | ||
| fullcmd = self._encode_cmd(cmd, key, str(time), noreply) | ||
| else: | ||
| cmd = "%s %s" % (cmd, key) | ||
| fullcmd = self._encode_cmd(cmd, key, None, noreply) | ||
| try: | ||
| server.send_cmd(cmd) | ||
| server.send_cmd(fullcmd) | ||
| if noreply: | ||
| return 1 | ||
| line = server.readline() | ||
@@ -532,3 +565,3 @@ if line and line.strip() in expected: | ||
| def incr(self, key, delta=1): | ||
| def incr(self, key, delta=1, noreply=False): | ||
| """Increment value for C{key} by C{delta} | ||
@@ -558,8 +591,11 @@ | ||
| @return: New value after incrementing. | ||
| @param noreply: optional parameter instructs the server to not send the | ||
| reply. | ||
| @return: New value after incrementing, no None for noreply or error. | ||
| @rtype: int | ||
| """ | ||
| return self._incrdecr("incr", key, delta) | ||
| return self._incrdecr("incr", key, delta, noreply) | ||
| def decr(self, key, delta=1): | ||
| def decr(self, key, delta=1, noreply=False): | ||
| """Decrement value for C{key} by C{delta} | ||
@@ -574,8 +610,12 @@ | ||
| @return: New value after decrementing or None on error. | ||
| @param noreply: optional parameter instructs the server to not send the | ||
| reply. | ||
| @return: New value after decrementing, or None for noreply or error. | ||
| @rtype: int | ||
| """ | ||
| return self._incrdecr("decr", key, delta) | ||
| return self._incrdecr("decr", key, delta, noreply) | ||
| def _incrdecr(self, cmd, key, delta): | ||
| def _incrdecr(self, cmd, key, delta, noreply=False): | ||
| key = self._encode_key(key) | ||
| if self.do_check_key: | ||
@@ -587,7 +627,9 @@ self.check_key(key) | ||
| self._statlog(cmd) | ||
| cmd = "%s %s %d" % (cmd, key, delta) | ||
| fullcmd = self._encode_cmd(cmd, key, str(delta), noreply) | ||
| try: | ||
| server.send_cmd(cmd) | ||
| server.send_cmd(fullcmd) | ||
| if noreply: | ||
| return | ||
| line = server.readline() | ||
| if line is None or line.strip() == 'NOT_FOUND': | ||
| if line is None or line.strip() == b'NOT_FOUND': | ||
| return None | ||
@@ -601,3 +643,3 @@ return int(line) | ||
| def add(self, key, val, time=0, min_compress_len=0): | ||
| def add(self, key, val, time=0, min_compress_len=0, noreply=False): | ||
| '''Add new key with value. | ||
@@ -611,5 +653,5 @@ | ||
| ''' | ||
| return self._set("add", key, val, time, min_compress_len) | ||
| return self._set("add", key, val, time, min_compress_len, noreply) | ||
| def append(self, key, val, time=0, min_compress_len=0): | ||
| def append(self, key, val, time=0, min_compress_len=0, noreply=False): | ||
| '''Append the value to the end of the existing key's value. | ||
@@ -623,5 +665,5 @@ | ||
| ''' | ||
| return self._set("append", key, val, time, min_compress_len) | ||
| return self._set("append", key, val, time, min_compress_len, noreply) | ||
| def prepend(self, key, val, time=0, min_compress_len=0): | ||
| def prepend(self, key, val, time=0, min_compress_len=0, noreply=False): | ||
| '''Prepend the value to the beginning of the existing key's value. | ||
@@ -635,5 +677,5 @@ | ||
| ''' | ||
| return self._set("prepend", key, val, time, min_compress_len) | ||
| return self._set("prepend", key, val, time, min_compress_len, noreply) | ||
| def replace(self, key, val, time=0, min_compress_len=0): | ||
| def replace(self, key, val, time=0, min_compress_len=0, noreply=False): | ||
| '''Replace existing key with value. | ||
@@ -647,5 +689,5 @@ | ||
| ''' | ||
| return self._set("replace", key, val, time, min_compress_len) | ||
| return self._set("replace", key, val, time, min_compress_len, noreply) | ||
| def set(self, key, val, time=0, min_compress_len=0): | ||
| def set(self, key, val, time=0, min_compress_len=0, noreply=False): | ||
| '''Unconditionally sets a key to a given value in the memcache. | ||
@@ -670,3 +712,3 @@ | ||
| @param min_compress_len: The threshold length to kick in | ||
| auto-compression of the value using the zlib.compress() | ||
| auto-compression of the value using the compressor | ||
| routine. If the value being cached is a string, then the | ||
@@ -680,6 +722,8 @@ length of the string is measured, else if the value is an | ||
| @param noreply: optional parameter instructs the server to not | ||
| send the reply. | ||
| ''' | ||
| return self._set("set", key, val, time, min_compress_len) | ||
| return self._set("set", key, val, time, min_compress_len, noreply) | ||
| def cas(self, key, val, time=0, min_compress_len=0): | ||
| def cas(self, key, val, time=0, min_compress_len=0, noreply=False): | ||
| '''Check and set (CAS) | ||
@@ -707,3 +751,3 @@ | ||
| @param min_compress_len: The threshold length to kick in | ||
| auto-compression of the value using the zlib.compress() | ||
| auto-compression of the value using the compressor | ||
| routine. If the value being cached is a string, then the | ||
@@ -716,4 +760,7 @@ length of the string is measured, else if the value is an | ||
| ever try to compress. | ||
| @param noreply: optional parameter instructs the server to not | ||
| send the reply. | ||
| ''' | ||
| return self._set("cas", key, val, time, min_compress_len) | ||
| return self._set("cas", key, val, time, min_compress_len, noreply) | ||
@@ -725,2 +772,3 @@ def _map_and_prefix_keys(self, key_iterable, key_prefix): | ||
| """ | ||
| key_prefix = self._encode_key(key_prefix) | ||
| # Check it just once ... | ||
@@ -741,16 +789,35 @@ key_extra_len = len(key_prefix) | ||
| # Ensure call to _get_server gets a Tuple as well. | ||
| str_orig_key = str(orig_key[1]) | ||
| serverhash, key = orig_key | ||
| key = self._encode_key(key) | ||
| if not isinstance(key, six.binary_type): | ||
| # set_multi supports int / long keys. | ||
| key = str(key) | ||
| if six.PY3: | ||
| key = key.encode('utf8') | ||
| bytes_orig_key = key | ||
| # Gotta pre-mangle key before hashing to a | ||
| # server. Returns the mangled key. | ||
| server, key = self._get_server( | ||
| (orig_key[0], key_prefix + str_orig_key)) | ||
| (serverhash, key_prefix + key)) | ||
| orig_key = orig_key[1] | ||
| else: | ||
| # set_multi supports int / long keys. | ||
| str_orig_key = str(orig_key) | ||
| server, key = self._get_server(key_prefix + str_orig_key) | ||
| key = self._encode_key(orig_key) | ||
| if not isinstance(key, six.binary_type): | ||
| # set_multi supports int / long keys. | ||
| key = str(key) | ||
| if six.PY3: | ||
| key = key.encode('utf8') | ||
| bytes_orig_key = key | ||
| server, key = self._get_server(key_prefix + key) | ||
| # alert when passed in key is None | ||
| if orig_key is None: | ||
| self.check_key(orig_key, key_extra_len=key_extra_len) | ||
| # Now check to make sure key length is proper ... | ||
| if self.do_check_key: | ||
| self.check_key(str_orig_key, key_extra_len=key_extra_len) | ||
| self.check_key(bytes_orig_key, key_extra_len=key_extra_len) | ||
@@ -767,3 +834,4 @@ if not server: | ||
| def set_multi(self, mapping, time=0, key_prefix='', min_compress_len=0): | ||
| def set_multi(self, mapping, time=0, key_prefix='', min_compress_len=0, | ||
| noreply=False): | ||
| '''Sets multiple keys in the memcache doing just one query. | ||
@@ -811,3 +879,3 @@ | ||
| @param min_compress_len: The threshold length to kick in | ||
| auto-compression of the value using the zlib.compress() | ||
| auto-compression of the value using the compressor | ||
| routine. If the value being cached is a string, then the | ||
@@ -821,2 +889,5 @@ length of the string is measured, else if the value is an | ||
| @param noreply: optional parameter instructs the server to not | ||
| send the reply. | ||
| @return: List of keys which failed to be stored [ memcache out | ||
@@ -845,11 +916,11 @@ of memory, etc. ]. | ||
| if store_info: | ||
| msg = "set %s %d %d %d\r\n%s\r\n" | ||
| write(msg % (key, | ||
| store_info[0], | ||
| time, | ||
| store_info[1], | ||
| store_info[2])) | ||
| flags, len_val, val = store_info | ||
| headers = "%d %d %d" % (flags, time, len_val) | ||
| fullcmd = self._encode_cmd('set', key, headers, | ||
| noreply, | ||
| b'\r\n', val, b'\r\n') | ||
| write(fullcmd) | ||
| else: | ||
| notstored.append(prefixed_to_orig_key[key]) | ||
| server.send_cmds(''.join(bigcmd)) | ||
| server.send_cmds(b''.join(bigcmd)) | ||
| except socket.error as msg: | ||
@@ -861,2 +932,6 @@ if isinstance(msg, tuple): | ||
| # if noreply, just return early | ||
| if noreply: | ||
| return notstored | ||
| # if any servers died on the way, don't expect them to respond. | ||
@@ -891,12 +966,18 @@ for server in dead_servers: | ||
| flags = 0 | ||
| if isinstance(val, str): | ||
| if isinstance(val, six.binary_type): | ||
| pass | ||
| elif isinstance(val, six.text_type): | ||
| val = val.encode('utf-8') | ||
| elif isinstance(val, int): | ||
| flags |= Client._FLAG_INTEGER | ||
| val = "%d" % val | ||
| val = str(val) | ||
| if six.PY3: | ||
| val = val.encode('ascii') | ||
| # force no attempt to compress this silly string. | ||
| min_compress_len = 0 | ||
| elif isinstance(val, long): | ||
| elif six.PY2 and isinstance(val, long): | ||
| flags |= Client._FLAG_LONG | ||
| val = "%d" % val | ||
| val = str(val) | ||
| if six.PY3: | ||
| val = val.encode('ascii') | ||
| # force no attempt to compress this silly string. | ||
@@ -917,7 +998,6 @@ min_compress_len = 0 | ||
| lv = len(val) | ||
| # We should try to compress if min_compress_len > 0 and we | ||
| # could import zlib and this string is longer than our min | ||
| # threshold. | ||
| # We should try to compress if min_compress_len > 0 | ||
| # and this string is longer than our min threshold. | ||
| if min_compress_len and lv > min_compress_len: | ||
| comp_val = zlib.compress(val) | ||
| comp_val = self.compressor(val) | ||
| # Only retain the result if the compression result is smaller | ||
@@ -936,3 +1016,4 @@ # than the original. | ||
| def _set(self, cmd, key, val, time, min_compress_len=0): | ||
| def _set(self, cmd, key, val, time, min_compress_len=0, noreply=False): | ||
| key = self._encode_key(key) | ||
| if self.do_check_key: | ||
@@ -947,22 +1028,25 @@ self.check_key(key) | ||
| if cmd == 'cas' and key not in self.cas_ids: | ||
| return self._set('set', key, val, time, min_compress_len, | ||
| noreply) | ||
| store_info = self._val_to_store_info(val, min_compress_len) | ||
| if not store_info: | ||
| return(0) | ||
| flags, len_val, encoded_val = store_info | ||
| if cmd == 'cas': | ||
| if key not in self.cas_ids: | ||
| return self._set('set', key, val, time, min_compress_len) | ||
| fullcmd = "%s %s %d %d %d %d\r\n%s" % ( | ||
| cmd, key, store_info[0], time, store_info[1], | ||
| self.cas_ids[key], store_info[2]) | ||
| headers = ("%d %d %d %d" | ||
| % (flags, time, len_val, self.cas_ids[key])) | ||
| else: | ||
| fullcmd = "%s %s %d %d %d\r\n%s" % ( | ||
| cmd, key, store_info[0], | ||
| time, store_info[1], store_info[2] | ||
| ) | ||
| headers = "%d %d %d" % (flags, time, len_val) | ||
| fullcmd = self._encode_cmd(cmd, key, headers, noreply, | ||
| b'\r\n', encoded_val) | ||
| try: | ||
| server.send_cmd(fullcmd) | ||
| return(server.expect("STORED", raise_exception=True) | ||
| == "STORED") | ||
| if noreply: | ||
| return True | ||
| return(server.expect(b"STORED", raise_exception=True) | ||
| == b"STORED") | ||
| except socket.error as msg: | ||
@@ -986,2 +1070,3 @@ if isinstance(msg, tuple): | ||
| def _get(self, cmd, key): | ||
| key = self._encode_key(key) | ||
| if self.do_check_key: | ||
@@ -997,3 +1082,5 @@ self.check_key(key) | ||
| try: | ||
| server.send_cmd("%s %s" % (cmd, key)) | ||
| cmd_bytes = cmd.encode() if six.PY3 else cmd | ||
| fullcmd = b''.join((cmd_bytes, b' ', key)) | ||
| server.send_cmd(fullcmd) | ||
| rkey = flags = rlen = cas_id = None | ||
@@ -1017,3 +1104,3 @@ | ||
| finally: | ||
| server.expect("END", raise_exception=True) | ||
| server.expect(b"END", raise_exception=True) | ||
| except (_Error, socket.error) as msg: | ||
@@ -1117,3 +1204,4 @@ if isinstance(msg, tuple): | ||
| try: | ||
| server.send_cmd("get %s" % " ".join(server_keys[server])) | ||
| fullcmd = b"get " + b" ".join(server_keys[server]) | ||
| server.send_cmd(fullcmd) | ||
| except socket.error as msg: | ||
@@ -1133,3 +1221,3 @@ if isinstance(msg, tuple): | ||
| line = server.readline() | ||
| while line and line != 'END': | ||
| while line and line != b'END': | ||
| rkey, flags, rlen = self._expectvalue(server, line) | ||
@@ -1152,3 +1240,3 @@ # Bo Yang reports that this can sometimes be None | ||
| if line and line[:5] == 'VALUE': | ||
| if line and line[:5] == b'VALUE': | ||
| resp, rkey, flags, len, cas_id = line.split() | ||
@@ -1163,3 +1251,3 @@ return (rkey, int(flags), int(len), int(cas_id)) | ||
| if line and line[:5] == 'VALUE': | ||
| if line and line[:5] == b'VALUE': | ||
| resp, rkey, flags, len = line.split() | ||
@@ -1183,11 +1271,18 @@ flags = int(flags) | ||
| if flags & Client._FLAG_COMPRESSED: | ||
| buf = zlib.decompress(buf) | ||
| buf = self.decompressor(buf) | ||
| flags &= ~Client._FLAG_COMPRESSED | ||
| if flags == 0 or flags == Client._FLAG_COMPRESSED: | ||
| # Either a bare string or a compressed string now decompressed... | ||
| val = buf | ||
| if flags == 0: | ||
| # Bare string | ||
| if six.PY3: | ||
| val = buf.decode('utf8') | ||
| else: | ||
| val = buf | ||
| elif flags & Client._FLAG_INTEGER: | ||
| val = int(buf) | ||
| elif flags & Client._FLAG_LONG: | ||
| val = long(buf) | ||
| if six.PY3: | ||
| val = int(buf) | ||
| else: | ||
| val = long(buf) | ||
| elif flags & Client._FLAG_PICKLE: | ||
@@ -1223,25 +1318,24 @@ try: | ||
| key = key[1] | ||
| if not key: | ||
| if key is None: | ||
| raise Client.MemcachedKeyNoneError("Key is None") | ||
| if key is '': | ||
| if key_extra_len is 0: | ||
| raise Client.MemcachedKeyNoneError("Key is empty") | ||
| # Make sure we're not a specific unicode type, if we're old enough that | ||
| # it's a separate type. | ||
| if _has_unicode is True and isinstance(key, unicode): | ||
| raise Client.MemcachedStringEncodingError( | ||
| "Keys must be str()'s, not unicode. Convert your unicode " | ||
| "strings using mystring.encode(charset)!") | ||
| if not isinstance(key, str): | ||
| raise Client.MemcachedKeyTypeError("Key must be str()'s") | ||
| # key is empty but there is some other component to key | ||
| return | ||
| if isinstance(key, _str_cls): | ||
| if (self.server_max_key_length != 0 and | ||
| len(key) + key_extra_len > self.server_max_key_length): | ||
| raise Client.MemcachedKeyLengthError( | ||
| "Key length is > %s" % self.server_max_key_length | ||
| ) | ||
| if not valid_key_chars_re.match(key): | ||
| raise Client.MemcachedKeyCharacterError( | ||
| "Control/space characters not allowed (key=%r)" % key) | ||
| if not isinstance(key, six.binary_type): | ||
| raise Client.MemcachedKeyTypeError("Key must be a binary string") | ||
| if (self.server_max_key_length != 0 and | ||
| len(key) + key_extra_len > self.server_max_key_length): | ||
| raise Client.MemcachedKeyLengthError( | ||
| "Key length is > %s" % self.server_max_key_length | ||
| ) | ||
| if not valid_key_chars_re.match(key): | ||
| raise Client.MemcachedKeyCharacterError( | ||
| "Control/space characters not allowed (key=%r)" % key) | ||
| class _Host(object): | ||
@@ -1292,3 +1386,3 @@ | ||
| self.buffer = '' | ||
| self.buffer = b'' | ||
@@ -1336,3 +1430,3 @@ def debuglog(self, str): | ||
| self.socket = s | ||
| self.buffer = '' | ||
| self.buffer = b'' | ||
| if self.flush_on_next_connect: | ||
@@ -1349,6 +1443,10 @@ self.flush() | ||
| def send_cmd(self, cmd): | ||
| self.socket.sendall(cmd + '\r\n') | ||
| if isinstance(cmd, six.text_type): | ||
| cmd = cmd.encode('utf8') | ||
| self.socket.sendall(cmd + b'\r\n') | ||
| def send_cmds(self, cmds): | ||
| """cmds already has trailing \r\n's applied.""" | ||
| if isinstance(cmds, six.text_type): | ||
| cmds = cmds.encode('utf8') | ||
| self.socket.sendall(cmds) | ||
@@ -1366,6 +1464,6 @@ | ||
| else: | ||
| recv = lambda bufsize: '' | ||
| recv = lambda bufsize: b'' | ||
| while True: | ||
| index = buf.find('\r\n') | ||
| index = buf.find(b'\r\n') | ||
| if index >= 0: | ||
@@ -1388,4 +1486,7 @@ break | ||
| line = self.readline(raise_exception) | ||
| if line != text: | ||
| self.debuglog("while expecting '%s', got unexpected response '%s'" | ||
| if self.debug and line != text: | ||
| if six.PY3: | ||
| text = text.decode('utf8') | ||
| line = line.decode('utf8', 'replace') | ||
| self.debuglog("while expecting %r, got unexpected response %r" | ||
| % (text, line)) | ||
@@ -1408,3 +1509,3 @@ return line | ||
| self.send_cmd('flush_all') | ||
| self.expect('OK') | ||
| self.expect(b'OK') | ||
@@ -1450,7 +1551,7 @@ def __str__(self): | ||
| def test_setget(key, val): | ||
| def test_setget(key, val, noreply=False): | ||
| global failures | ||
| print("Testing set/get {'%s': %s} ..." | ||
| % (to_s(key), to_s(val)), end=" ") | ||
| mc.set(key, val) | ||
| print("Testing set/get (noreply=%s) {'%s': %s} ..." | ||
| % (noreply, to_s(key), to_s(val)), end=" ") | ||
| mc.set(key, val, noreply=noreply) | ||
| newval = mc.get(key) | ||
@@ -1479,4 +1580,10 @@ if newval == val: | ||
| test_setget("a_string", "some random string") | ||
| test_setget("a_string_2", "some random string", noreply=True) | ||
| test_setget("an_integer", 42) | ||
| if test_setget("long", long(1 << 30)): | ||
| test_setget("an_integer_2", 42, noreply=True) | ||
| if six.PY3: | ||
| ok = test_setget("long", 1 << 30) | ||
| else: | ||
| ok = test_setget("long", long(1 << 30)) | ||
| if ok: | ||
| print("Testing delete ...", end=" ") | ||
@@ -1495,3 +1602,4 @@ if mc.delete("long"): | ||
| print("Testing get_multi ...",) | ||
| print(mc.get_multi(["a_string", "an_integer"])) | ||
| print(mc.get_multi(["a_string", "an_integer", "a_string_2", | ||
| "an_integer_2"])) | ||
@@ -1518,2 +1626,3 @@ # removed from the protocol | ||
| test_setget("foostruct", f) | ||
| test_setget("foostruct_2", f, noreply=True) | ||
@@ -1528,2 +1637,11 @@ print("Testing incr ...", end=" ") | ||
| print("Testing incr (noreply=True) ...", end=" ") | ||
| mc.incr("an_integer_2", 1, noreply=True) | ||
| x = mc.get("an_integer_2") | ||
| if x == 43: | ||
| print("OK") | ||
| else: | ||
| print("FAIL") | ||
| failures += 1 | ||
| print("Testing decr ...", end=" ") | ||
@@ -1538,2 +1656,12 @@ x = mc.decr("an_integer", 1) | ||
| print("Testing decr (noreply=True) ...", end=" ") | ||
| mc.decr("an_integer_2", 1, noreply=True) | ||
| x = mc.get("an_integer_2") | ||
| if x == 42: | ||
| print("OK") | ||
| else: | ||
| print("FAIL") | ||
| failures += 1 | ||
| sys.stdout.flush() | ||
| # sanity tests | ||
@@ -1562,2 +1690,3 @@ print("Testing sending spaces...", end=" ") | ||
| x = mc.set('a'*SERVER_MAX_KEY_LENGTH, 1) | ||
| x = mc.set('a'*SERVER_MAX_KEY_LENGTH, 1, noreply=True) | ||
| except Client.MemcachedKeyLengthError as msg: | ||
@@ -1564,0 +1693,0 @@ print("FAIL") |
+54
-6
@@ -1,10 +0,58 @@ | ||
| Metadata-Version: 1.0 | ||
| Metadata-Version: 1.1 | ||
| Name: python-memcached | ||
| Version: 1.54 | ||
| Summary: A Python memcached client library. | ||
| Version: 1.56 | ||
| Summary: Pure python memcached client | ||
| Home-page: http://www.tummy.com/Community/software/python-memcached/ | ||
| Author: Sean Reifschneider | ||
| Author-email: jafo-memcached@tummy.com | ||
| License: Python Software Foundation License | ||
| Description: A Python memcached client library. | ||
| Author-email: jafo@tummy.com | ||
| License: UNKNOWN | ||
| Download-URL: ftp://ftp.tummy.com/pub/python-memcached/ | ||
| Description: [](https://travis-ci.org/linsomniac/python-memcached) | ||
| ## Overview | ||
| This software is a 100% Python interface to the memcached memory cache | ||
| daemon. It is the client side software which allows storing values | ||
| in one or more, possibly remote, memcached servers. Search google for | ||
| memcached for more information. | ||
| This package was originally written by Evan Martin of Danga. Please do | ||
| not contact Evan about maintenance. Sean Reifschneider of tummy.com, | ||
| ltd. has taken over maintenance of it. | ||
| Please report issues and submit code changes to the github repository at: | ||
| https://github.com/linsomniac/python-memcached | ||
| For changes prior to 2013-03-26, see the old Launchpad repository at: | ||
| Historic issues: https://launchpad.net/python-memcached | ||
| ## Testing | ||
| Test patches locally and easily by running tox: | ||
| pip install tox | ||
| tox -e py27 | ||
| Test for style by running tox: | ||
| tox -e pep8 | ||
| Platform: UNKNOWN | ||
| Classifier: Development Status :: 5 - Production/Stable | ||
| Classifier: Intended Audience :: Developers | ||
| Classifier: License :: OSI Approved :: Python Software Foundation License | ||
| Classifier: Operating System :: OS Independent | ||
| Classifier: Programming Language :: Python | ||
| Classifier: Topic :: Internet | ||
| Classifier: Topic :: Software Development :: Libraries :: Python Modules | ||
| Classifier: Programming Language :: Python | ||
| Classifier: Programming Language :: Python :: 2 | ||
| Classifier: Programming Language :: Python :: 2.6 | ||
| Classifier: Programming Language :: Python :: 2.7 | ||
| Classifier: Programming Language :: Python :: 3 | ||
| Classifier: Programming Language :: Python :: 3.2 | ||
| Classifier: Programming Language :: Python :: 3.3 | ||
| Classifier: Programming Language :: Python :: 3.4 |
+6
-0
@@ -8,1 +8,7 @@ [bdist_rpm] | ||
| universal = 1 | ||
| [egg_info] | ||
| tag_build = | ||
| tag_date = 0 | ||
| tag_svn_revision = 0 | ||
+5
-5
@@ -7,3 +7,3 @@ #!/usr/bin/env python | ||
| setup(name="python-memcached", | ||
| version="1.54", | ||
| version="1.56", | ||
| description="Pure python memcached client", | ||
@@ -31,6 +31,6 @@ long_description=open("README.md").read(), | ||
| "Programming Language :: Python :: 2.7", | ||
| # "Programming Language :: Python :: 3", | ||
| # "Programming Language :: Python :: 3.2", | ||
| # "Programming Language :: Python :: 3.3", | ||
| # "Programming Language :: Python :: 3.4" | ||
| "Programming Language :: Python :: 3", | ||
| "Programming Language :: Python :: 3.2", | ||
| "Programming Language :: Python :: 3.3", | ||
| "Programming Language :: Python :: 3.4" | ||
| ]) |
| *.pyc | ||
| /dist | ||
| /python_memcached.egg-info | ||
| .tox | ||
| .coverage |
-12
| language: python | ||
| python: | ||
| - 2.6 | ||
| - 2.7 | ||
| - 3.2 | ||
| - 3.3 | ||
| - 3.4 | ||
| - pypy | ||
| - 3.3 | ||
| install: python setup.py install | ||
| before_script: pip install nose | ||
| script: nosetests |
-9
| test: | ||
| python memcache.py | ||
| ( cd tests; make ) | ||
| clean: | ||
| rm -f memcache.pyc memcache.py.orig | ||
| push: | ||
| bzr push lp:python-memcached |
-572
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> | ||
| <html><head><title>Python: module memcache</title> | ||
| <meta charset="utf-8"> | ||
| </head><body bgcolor="#f0f0f8"> | ||
| <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading"> | ||
| <tr bgcolor="#7799ee"> | ||
| <td valign=bottom> <br> | ||
| <font color="#ffffff" face="helvetica, arial"> <br><big><big><strong>memcache</strong></big></big> (version 1.54)</font></td | ||
| ><td align=right valign=bottom | ||
| ><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/tmp/python-memcached-1.54/memcache.py">/tmp/python-memcached-1.54/memcache.py</a></font></td></tr></table> | ||
| <p><tt>client module for memcached (memory cache daemon)<br> | ||
| <br> | ||
| Overview<br> | ||
| ========<br> | ||
| <br> | ||
| See U{the MemCached homepage<<a href="http://www.danga.com/memcached">http://www.danga.com/memcached</a>>} for more<br> | ||
| about memcached.<br> | ||
| <br> | ||
| Usage summary<br> | ||
| =============<br> | ||
| <br> | ||
| This should give you a feel for how this module operates::<br> | ||
| <br> | ||
| import memcache<br> | ||
| mc = memcache.<a href="#Client">Client</a>(['127.0.0.1:11211'], debug=0)<br> | ||
| <br> | ||
| mc.set("some_key", "Some value")<br> | ||
| value = mc.get("some_key")<br> | ||
| <br> | ||
| mc.set("another_key", 3)<br> | ||
| mc.delete("another_key")<br> | ||
| <br> | ||
| mc.set("key", "1") # note that the key used for incr/decr must be<br> | ||
| # a string.<br> | ||
| mc.incr("key")<br> | ||
| mc.decr("key")<br> | ||
| <br> | ||
| The standard way to use memcache with a database is like this:<br> | ||
| <br> | ||
| key = derive_key(obj)<br> | ||
| obj = mc.get(key)<br> | ||
| if not obj:<br> | ||
| obj = backend_api.get(...)<br> | ||
| mc.set(key, obj)<br> | ||
| <br> | ||
| # we now have obj, and future passes through this code<br> | ||
| # will use the object from the cache.<br> | ||
| <br> | ||
| Detailed Documentation<br> | ||
| ======================<br> | ||
| <br> | ||
| More detailed documentation is available in the L{<a href="#Client">Client</a>} class.</tt></p> | ||
| <p> | ||
| <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | ||
| <tr bgcolor="#aa55cc"> | ||
| <td colspan=3 valign=bottom> <br> | ||
| <font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr> | ||
| <tr><td bgcolor="#aa55cc"><tt> </tt></td><td> </td> | ||
| <td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="binascii.html">binascii</a><br> | ||
| <a href="os.html">os</a><br> | ||
| <a href="pickle.html">pickle</a><br> | ||
| </td><td width="25%" valign=top><a href="re.html">re</a><br> | ||
| <a href="six.html">six</a><br> | ||
| <a href="socket.html">socket</a><br> | ||
| </td><td width="25%" valign=top><a href="sys.html">sys</a><br> | ||
| <a href="threading.html">threading</a><br> | ||
| <a href="time.html">time</a><br> | ||
| </td><td width="25%" valign=top><a href="zlib.html">zlib</a><br> | ||
| </td></tr></table></td></tr></table><p> | ||
| <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | ||
| <tr bgcolor="#ee77aa"> | ||
| <td colspan=3 valign=bottom> <br> | ||
| <font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr> | ||
| <tr><td bgcolor="#ee77aa"><tt> </tt></td><td> </td> | ||
| <td width="100%"><dl> | ||
| <dt><font face="helvetica, arial"><a href="thread.html#_local">thread._local</a>(<a href="__builtin__.html#object">__builtin__.object</a>) | ||
| </font></dt><dd> | ||
| <dl> | ||
| <dt><font face="helvetica, arial"><a href="memcache.html#Client">Client</a> | ||
| </font></dt></dl> | ||
| </dd> | ||
| </dl> | ||
| <p> | ||
| <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | ||
| <tr bgcolor="#ffc8d8"> | ||
| <td colspan=3 valign=bottom> <br> | ||
| <font color="#000000" face="helvetica, arial"><a name="Client">class <strong>Client</strong></a>(<a href="thread.html#_local">thread._local</a>)</font></td></tr> | ||
| <tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td> | ||
| <td colspan=2><tt>Object representing a pool of memcache servers.<br> | ||
| <br> | ||
| See L{memcache} for an overview.<br> | ||
| <br> | ||
| In all cases where a key is used, the key can be either:<br> | ||
| 1. A simple hashable type (string, integer, etc.).<br> | ||
| 2. A tuple of C{(hashvalue, key)}. This is useful if you want<br> | ||
| to avoid making this module calculate a hash value. You may<br> | ||
| prefer, for example, to keep all of a given user's objects on<br> | ||
| the same memcache server, so you could use the user's unique<br> | ||
| id as the hash value.<br> | ||
| <br> | ||
| <br> | ||
| @group Setup: __init__, set_servers, forget_dead_hosts,<br> | ||
| disconnect_all, debuglog<br> | ||
| @group Insertion: set, add, replace, set_multi<br> | ||
| @group Retrieval: get, get_multi<br> | ||
| @group Integers: incr, decr<br> | ||
| @group Removal: delete, delete_multi<br> | ||
| @sort: __init__, set_servers, forget_dead_hosts, disconnect_all,<br> | ||
| debuglog,\ set, set_multi, add, replace, get, get_multi,<br> | ||
| incr, decr, delete, delete_multi<br> </tt></td></tr> | ||
| <tr><td> </td> | ||
| <td width="100%"><dl><dt>Method resolution order:</dt> | ||
| <dd><a href="memcache.html#Client">Client</a></dd> | ||
| <dd><a href="thread.html#_local">thread._local</a></dd> | ||
| <dd><a href="__builtin__.html#object">__builtin__.object</a></dd> | ||
| </dl> | ||
| <hr> | ||
| Methods defined here:<br> | ||
| <dl><dt><a name="Client-__init__"><strong>__init__</strong></a>(self, servers, debug<font color="#909090">=0</font>, pickleProtocol<font color="#909090">=0</font>, pickler<font color="#909090">=<class pickle.Pickler></font>, unpickler<font color="#909090">=<class pickle.Unpickler></font>, pload<font color="#909090">=None</font>, pid<font color="#909090">=None</font>, server_max_key_length<font color="#909090">=None</font>, server_max_value_length<font color="#909090">=None</font>, dead_retry<font color="#909090">=30</font>, socket_timeout<font color="#909090">=3</font>, cache_cas<font color="#909090">=False</font>, flush_on_reconnect<font color="#909090">=0</font>, check_keys<font color="#909090">=True</font>)</dt><dd><tt>Create a new <a href="#Client">Client</a> object with the given list of servers.<br> | ||
| <br> | ||
| @param servers: C{servers} is passed to L{set_servers}.<br> | ||
| @param debug: whether to display error messages when a server<br> | ||
| can't be contacted.<br> | ||
| @param pickleProtocol: number to mandate protocol used by<br> | ||
| (c)Pickle.<br> | ||
| @param pickler: optional override of default Pickler to allow<br> | ||
| subclassing.<br> | ||
| @param unpickler: optional override of default Unpickler to<br> | ||
| allow subclassing.<br> | ||
| @param pload: optional persistent_load function to call on<br> | ||
| pickle loading. Useful for cPickle since subclassing isn't<br> | ||
| allowed.<br> | ||
| @param pid: optional persistent_id function to call on pickle<br> | ||
| storing. Useful for cPickle since subclassing isn't allowed.<br> | ||
| @param dead_retry: number of seconds before retrying a<br> | ||
| blacklisted server. Default to 30 s.<br> | ||
| @param socket_timeout: timeout in seconds for all calls to a<br> | ||
| server. Defaults to 3 seconds.<br> | ||
| @param cache_cas: (default False) If true, cas operations will<br> | ||
| be cached. WARNING: This cache is not expired internally, if<br> | ||
| you have a long-running process you will need to expire it<br> | ||
| manually via client.<a href="#Client-reset_cas">reset_cas</a>(), or the cache can grow<br> | ||
| unlimited.<br> | ||
| @param server_max_key_length: (default SERVER_MAX_KEY_LENGTH)<br> | ||
| Data that is larger than this will not be sent to the server.<br> | ||
| @param server_max_value_length: (default<br> | ||
| SERVER_MAX_VALUE_LENGTH) Data that is larger than this will<br> | ||
| not be sent to the server.<br> | ||
| @param flush_on_reconnect: optional flag which prevents a<br> | ||
| scenario that can cause stale data to be read: If there's more<br> | ||
| than one memcached server and the connection to one is<br> | ||
| interrupted, keys that mapped to that server will get<br> | ||
| reassigned to another. If the first server comes back, those<br> | ||
| keys will map to it again. If it still has its data, <a href="#Client-get">get</a>()s<br> | ||
| can read stale data that was overwritten on another<br> | ||
| server. This flag is off by default for backwards<br> | ||
| compatibility.<br> | ||
| @param check_keys: (default True) If True, the key is checked<br> | ||
| to ensure it is the correct length and composed of the right<br> | ||
| characters.</tt></dd></dl> | ||
| <dl><dt><a name="Client-add"><strong>add</strong></a>(self, key, val, time<font color="#909090">=0</font>, min_compress_len<font color="#909090">=0</font>)</dt><dd><tt>Add new key with value.<br> | ||
| <br> | ||
| Like L{set}, but only stores in memcache if the key doesn't<br> | ||
| already exist.<br> | ||
| <br> | ||
| @return: Nonzero on success.<br> | ||
| @rtype: int</tt></dd></dl> | ||
| <dl><dt><a name="Client-append"><strong>append</strong></a>(self, key, val, time<font color="#909090">=0</font>, min_compress_len<font color="#909090">=0</font>)</dt><dd><tt>Append the value to the end of the existing key's value.<br> | ||
| <br> | ||
| Only stores in memcache if key already exists.<br> | ||
| Also see L{prepend}.<br> | ||
| <br> | ||
| @return: Nonzero on success.<br> | ||
| @rtype: int</tt></dd></dl> | ||
| <dl><dt><a name="Client-cas"><strong>cas</strong></a>(self, key, val, time<font color="#909090">=0</font>, min_compress_len<font color="#909090">=0</font>)</dt><dd><tt>Check and set (CAS)<br> | ||
| <br> | ||
| Sets a key to a given value in the memcache if it hasn't been<br> | ||
| altered since last fetched. (See L{gets}).<br> | ||
| <br> | ||
| The C{key} can optionally be an tuple, with the first element<br> | ||
| being the server hash value and the second being the key. If<br> | ||
| you want to avoid making this module calculate a hash value.<br> | ||
| You may prefer, for example, to keep all of a given user's<br> | ||
| objects on the same memcache server, so you could use the<br> | ||
| user's unique id as the hash value.<br> | ||
| <br> | ||
| @return: Nonzero on success.<br> | ||
| @rtype: int<br> | ||
| <br> | ||
| @param time: Tells memcached the time which this value should<br> | ||
| expire, either as a delta number of seconds, or an absolute<br> | ||
| unix time-since-the-epoch value. See the memcached protocol<br> | ||
| docs section "Storage Commands" for more info on <exptime>. We<br> | ||
| default to 0 == cache forever.<br> | ||
| <br> | ||
| @param min_compress_len: The threshold length to kick in<br> | ||
| auto-compression of the value using the zlib.<a href="#-compress">compress</a>()<br> | ||
| routine. If the value being cached is a string, then the<br> | ||
| length of the string is measured, else if the value is an<br> | ||
| object, then the length of the pickle result is measured. If<br> | ||
| the resulting attempt at compression yeilds a larger string<br> | ||
| than the input, then it is discarded. For backwards<br> | ||
| compatability, this parameter defaults to 0, indicating don't<br> | ||
| ever try to compress.</tt></dd></dl> | ||
| <dl><dt><a name="Client-check_key"><strong>check_key</strong></a>(self, key, key_extra_len<font color="#909090">=0</font>)</dt><dd><tt>Checks sanity of key.<br> | ||
| <br> | ||
| Fails if:<br> | ||
| <br> | ||
| Key length is > SERVER_MAX_KEY_LENGTH (Raises MemcachedKeyLength).<br> | ||
| Contains control characters (Raises MemcachedKeyCharacterError).<br> | ||
| Is not a string (Raises MemcachedStringEncodingError)<br> | ||
| Is an unicode string (Raises MemcachedStringEncodingError)<br> | ||
| Is not a string (Raises MemcachedKeyError)<br> | ||
| Is None (Raises MemcachedKeyError)</tt></dd></dl> | ||
| <dl><dt><a name="Client-debuglog"><strong>debuglog</strong></a>(self, str)</dt></dl> | ||
| <dl><dt><a name="Client-decr"><strong>decr</strong></a>(self, key, delta<font color="#909090">=1</font>)</dt><dd><tt>Decrement value for C{key} by C{delta}<br> | ||
| <br> | ||
| Like L{incr}, but decrements. Unlike L{incr}, underflow is<br> | ||
| checked and new values are capped at 0. If server value is 1,<br> | ||
| a decrement of 2 returns 0, not -1.<br> | ||
| <br> | ||
| @param delta: Integer amount to decrement by (should be zero<br> | ||
| or greater).<br> | ||
| <br> | ||
| @return: New value after decrementing or None on error.<br> | ||
| @rtype: int</tt></dd></dl> | ||
| <dl><dt><a name="Client-delete"><strong>delete</strong></a>(self, key, time<font color="#909090">=0</font>)</dt><dd><tt>Deletes a key from the memcache.<br> | ||
| <br> | ||
| @return: Nonzero on success.<br> | ||
| @param time: number of seconds any subsequent set / update commands<br> | ||
| should fail. Defaults to None for no delay.<br> | ||
| @rtype: int</tt></dd></dl> | ||
| <dl><dt><a name="Client-delete_multi"><strong>delete_multi</strong></a>(self, keys, time<font color="#909090">=0</font>, key_prefix<font color="#909090">=''</font>)</dt><dd><tt>Delete multiple keys in the memcache doing just one query.<br> | ||
| <br> | ||
| >>> notset_keys = mc.<a href="#Client-set_multi">set_multi</a>({'a1' : 'val1', 'a2' : 'val2'})<br> | ||
| >>> mc.<a href="#Client-get_multi">get_multi</a>(['a1', 'a2']) == {'a1' : 'val1','a2' : 'val2'}<br> | ||
| 1<br> | ||
| >>> mc.<a href="#Client-delete_multi">delete_multi</a>(['key1', 'key2'])<br> | ||
| 1<br> | ||
| >>> mc.<a href="#Client-get_multi">get_multi</a>(['key1', 'key2']) == {}<br> | ||
| 1<br> | ||
| <br> | ||
| This method is recommended over iterated regular L{delete}s as<br> | ||
| it reduces total latency, since your app doesn't have to wait<br> | ||
| for each round-trip of L{delete} before sending the next one.<br> | ||
| <br> | ||
| @param keys: An iterable of keys to clear<br> | ||
| @param time: number of seconds any subsequent set / update<br> | ||
| commands should fail. Defaults to 0 for no delay.<br> | ||
| @param key_prefix: Optional string to prepend to each key when<br> | ||
| sending to memcache. See docs for L{get_multi} and<br> | ||
| L{set_multi}.<br> | ||
| @return: 1 if no failure in communication with any memcacheds.<br> | ||
| @rtype: int</tt></dd></dl> | ||
| <dl><dt><a name="Client-disconnect_all"><strong>disconnect_all</strong></a>(self)</dt></dl> | ||
| <dl><dt><a name="Client-flush_all"><strong>flush_all</strong></a>(self)</dt><dd><tt>Expire all data in memcache servers that are reachable.</tt></dd></dl> | ||
| <dl><dt><a name="Client-forget_dead_hosts"><strong>forget_dead_hosts</strong></a>(self)</dt><dd><tt>Reset every host in the pool to an "alive" state.</tt></dd></dl> | ||
| <dl><dt><a name="Client-get"><strong>get</strong></a>(self, key)</dt><dd><tt>Retrieves a key from the memcache.<br> | ||
| <br> | ||
| @return: The value or None.</tt></dd></dl> | ||
| <dl><dt><a name="Client-get_multi"><strong>get_multi</strong></a>(self, keys, key_prefix<font color="#909090">=''</font>)</dt><dd><tt>Retrieves multiple keys from the memcache doing just one query.<br> | ||
| <br> | ||
| >>> success = mc.<a href="#Client-set">set</a>("foo", "bar")<br> | ||
| >>> success = mc.<a href="#Client-set">set</a>("baz", 42)<br> | ||
| >>> mc.<a href="#Client-get_multi">get_multi</a>(["foo", "baz", "foobar"]) == {<br> | ||
| ... "foo": "bar", "baz": 42<br> | ||
| ... }<br> | ||
| 1<br> | ||
| >>> mc.<a href="#Client-set_multi">set_multi</a>({'k1' : 1, 'k2' : 2}, key_prefix='pfx_') == []<br> | ||
| 1<br> | ||
| <br> | ||
| This looks up keys 'pfx_k1', 'pfx_k2', ... . Returned dict<br> | ||
| will just have unprefixed keys 'k1', 'k2'.<br> | ||
| <br> | ||
| >>> mc.<a href="#Client-get_multi">get_multi</a>(['k1', 'k2', 'nonexist'],<br> | ||
| ... key_prefix='pfx_') == {'k1' : 1, 'k2' : 2}<br> | ||
| 1<br> | ||
| <br> | ||
| get_mult [ and L{set_multi} ] can take str()-ables like ints /<br> | ||
| longs as keys too. Such as your db pri key fields. They're<br> | ||
| rotored through str() before being passed off to memcache,<br> | ||
| with or without the use of a key_prefix. In this mode, the<br> | ||
| key_prefix could be a table name, and the key itself a db<br> | ||
| primary key number.<br> | ||
| <br> | ||
| >>> mc.<a href="#Client-set_multi">set_multi</a>({42: 'douglass adams',<br> | ||
| ... 46: 'and 2 just ahead of me'},<br> | ||
| ... key_prefix='numkeys_') == []<br> | ||
| 1<br> | ||
| >>> mc.<a href="#Client-get_multi">get_multi</a>([46, 42], key_prefix='numkeys_') == {<br> | ||
| ... 42: 'douglass adams',<br> | ||
| ... 46: 'and 2 just ahead of me'<br> | ||
| ... }<br> | ||
| 1<br> | ||
| <br> | ||
| This method is recommended over regular L{get} as it lowers<br> | ||
| the number of total packets flying around your network,<br> | ||
| reducing total latency, since your app doesn't have to wait<br> | ||
| for each round-trip of L{get} before sending the next one.<br> | ||
| <br> | ||
| See also L{set_multi}.<br> | ||
| <br> | ||
| @param keys: An array of keys.<br> | ||
| <br> | ||
| @param key_prefix: A string to prefix each key when we<br> | ||
| communicate with memcache. Facilitates pseudo-namespaces<br> | ||
| within memcache. Returned dictionary keys will not have this<br> | ||
| prefix.<br> | ||
| <br> | ||
| @return: A dictionary of key/value pairs that were<br> | ||
| available. If key_prefix was provided, the keys in the retured<br> | ||
| dictionary will not have it present.</tt></dd></dl> | ||
| <dl><dt><a name="Client-get_slabs"><strong>get_slabs</strong></a>(self)</dt></dl> | ||
| <dl><dt><a name="Client-get_stats"><strong>get_stats</strong></a>(self, stat_args<font color="#909090">=None</font>)</dt><dd><tt>Get statistics from each of the servers.<br> | ||
| <br> | ||
| @param stat_args: Additional arguments to pass to the memcache<br> | ||
| "stats" command.<br> | ||
| <br> | ||
| @return: A list of tuples ( server_identifier,<br> | ||
| stats_dictionary ). The dictionary contains a number of<br> | ||
| name/value pairs specifying the name of the status field<br> | ||
| and the string value associated with it. The values are<br> | ||
| not converted from strings.</tt></dd></dl> | ||
| <dl><dt><a name="Client-gets"><strong>gets</strong></a>(self, key)</dt><dd><tt>Retrieves a key from the memcache. Used in conjunction with 'cas'.<br> | ||
| <br> | ||
| @return: The value or None.</tt></dd></dl> | ||
| <dl><dt><a name="Client-incr"><strong>incr</strong></a>(self, key, delta<font color="#909090">=1</font>)</dt><dd><tt>Increment value for C{key} by C{delta}<br> | ||
| <br> | ||
| Sends a command to the server to atomically increment the<br> | ||
| value for C{key} by C{delta}, or by 1 if C{delta} is<br> | ||
| unspecified. Returns None if C{key} doesn't exist on server,<br> | ||
| otherwise it returns the new value after incrementing.<br> | ||
| <br> | ||
| Note that the value for C{key} must already exist in the<br> | ||
| memcache, and it must be the string representation of an<br> | ||
| integer.<br> | ||
| <br> | ||
| >>> mc.<a href="#Client-set">set</a>("counter", "20") # returns 1, indicating success<br> | ||
| 1<br> | ||
| >>> mc.<a href="#Client-incr">incr</a>("counter")<br> | ||
| 21<br> | ||
| >>> mc.<a href="#Client-incr">incr</a>("counter")<br> | ||
| 22<br> | ||
| <br> | ||
| Overflow on server is not checked. Be aware of values<br> | ||
| approaching 2**32. See L{decr}.<br> | ||
| <br> | ||
| @param delta: Integer amount to increment by (should be zero<br> | ||
| or greater).<br> | ||
| <br> | ||
| @return: New value after incrementing.<br> | ||
| @rtype: int</tt></dd></dl> | ||
| <dl><dt><a name="Client-prepend"><strong>prepend</strong></a>(self, key, val, time<font color="#909090">=0</font>, min_compress_len<font color="#909090">=0</font>)</dt><dd><tt>Prepend the value to the beginning of the existing key's value.<br> | ||
| <br> | ||
| Only stores in memcache if key already exists.<br> | ||
| Also see L{append}.<br> | ||
| <br> | ||
| @return: Nonzero on success.<br> | ||
| @rtype: int</tt></dd></dl> | ||
| <dl><dt><a name="Client-replace"><strong>replace</strong></a>(self, key, val, time<font color="#909090">=0</font>, min_compress_len<font color="#909090">=0</font>)</dt><dd><tt>Replace existing key with value.<br> | ||
| <br> | ||
| Like L{set}, but only stores in memcache if the key already exists.<br> | ||
| The opposite of L{add}.<br> | ||
| <br> | ||
| @return: Nonzero on success.<br> | ||
| @rtype: int</tt></dd></dl> | ||
| <dl><dt><a name="Client-reset_cas"><strong>reset_cas</strong></a>(self)</dt><dd><tt>Reset the cas cache.<br> | ||
| <br> | ||
| This is only used if the <a href="#Client">Client</a>() object was created with<br> | ||
| "cache_cas=True". If used, this cache does not expire<br> | ||
| internally, so it can grow unbounded if you do not clear it<br> | ||
| yourself.</tt></dd></dl> | ||
| <dl><dt><a name="Client-set"><strong>set</strong></a>(self, key, val, time<font color="#909090">=0</font>, min_compress_len<font color="#909090">=0</font>)</dt><dd><tt>Unconditionally sets a key to a given value in the memcache.<br> | ||
| <br> | ||
| The C{key} can optionally be an tuple, with the first element<br> | ||
| being the server hash value and the second being the key. If<br> | ||
| you want to avoid making this module calculate a hash value.<br> | ||
| You may prefer, for example, to keep all of a given user's<br> | ||
| objects on the same memcache server, so you could use the<br> | ||
| user's unique id as the hash value.<br> | ||
| <br> | ||
| @return: Nonzero on success.<br> | ||
| @rtype: int<br> | ||
| <br> | ||
| @param time: Tells memcached the time which this value should<br> | ||
| expire, either as a delta number of seconds, or an absolute<br> | ||
| unix time-since-the-epoch value. See the memcached protocol<br> | ||
| docs section "Storage Commands" for more info on <exptime>. We<br> | ||
| default to 0 == cache forever.<br> | ||
| <br> | ||
| @param min_compress_len: The threshold length to kick in<br> | ||
| auto-compression of the value using the zlib.<a href="#-compress">compress</a>()<br> | ||
| routine. If the value being cached is a string, then the<br> | ||
| length of the string is measured, else if the value is an<br> | ||
| object, then the length of the pickle result is measured. If<br> | ||
| the resulting attempt at compression yeilds a larger string<br> | ||
| than the input, then it is discarded. For backwards<br> | ||
| compatability, this parameter defaults to 0, indicating don't<br> | ||
| ever try to compress.</tt></dd></dl> | ||
| <dl><dt><a name="Client-set_multi"><strong>set_multi</strong></a>(self, mapping, time<font color="#909090">=0</font>, key_prefix<font color="#909090">=''</font>, min_compress_len<font color="#909090">=0</font>)</dt><dd><tt>Sets multiple keys in the memcache doing just one query.<br> | ||
| <br> | ||
| >>> notset_keys = mc.<a href="#Client-set_multi">set_multi</a>({'key1' : 'val1', 'key2' : 'val2'})<br> | ||
| >>> mc.<a href="#Client-get_multi">get_multi</a>(['key1', 'key2']) == {'key1' : 'val1',<br> | ||
| ... 'key2' : 'val2'}<br> | ||
| 1<br> | ||
| <br> | ||
| <br> | ||
| This method is recommended over regular L{set} as it lowers<br> | ||
| the number of total packets flying around your network,<br> | ||
| reducing total latency, since your app doesn't have to wait<br> | ||
| for each round-trip of L{set} before sending the next one.<br> | ||
| <br> | ||
| @param mapping: A dict of key/value pairs to set.<br> | ||
| <br> | ||
| @param time: Tells memcached the time which this value should<br> | ||
| expire, either as a delta number of seconds, or an<br> | ||
| absolute unix time-since-the-epoch value. See the<br> | ||
| memcached protocol docs section "Storage Commands" for<br> | ||
| more info on <exptime>. We default to 0 == cache forever.<br> | ||
| <br> | ||
| @param key_prefix: Optional string to prepend to each key when<br> | ||
| sending to memcache. Allows you to efficiently stuff these<br> | ||
| keys into a pseudo-namespace in memcache:<br> | ||
| <br> | ||
| >>> notset_keys = mc.<a href="#Client-set_multi">set_multi</a>(<br> | ||
| ... {'key1' : 'val1', 'key2' : 'val2'},<br> | ||
| ... key_prefix='subspace_')<br> | ||
| >>> len(notset_keys) == 0<br> | ||
| True<br> | ||
| >>> mc.<a href="#Client-get_multi">get_multi</a>(['subspace_key1',<br> | ||
| ... 'subspace_key2']) == {'subspace_key1': 'val1',<br> | ||
| ... 'subspace_key2' : 'val2'}<br> | ||
| True<br> | ||
| <br> | ||
| Causes key 'subspace_key1' and 'subspace_key2' to be<br> | ||
| set. Useful in conjunction with a higher-level layer which<br> | ||
| applies namespaces to data in memcache. In this case, the<br> | ||
| return result would be the list of notset original keys,<br> | ||
| prefix not applied.<br> | ||
| <br> | ||
| @param min_compress_len: The threshold length to kick in<br> | ||
| auto-compression of the value using the zlib.<a href="#-compress">compress</a>()<br> | ||
| routine. If the value being cached is a string, then the<br> | ||
| length of the string is measured, else if the value is an<br> | ||
| object, then the length of the pickle result is<br> | ||
| measured. If the resulting attempt at compression yeilds a<br> | ||
| larger string than the input, then it is discarded. For<br> | ||
| backwards compatability, this parameter defaults to 0,<br> | ||
| indicating don't ever try to compress.<br> | ||
| <br> | ||
| @return: List of keys which failed to be stored [ memcache out<br> | ||
| of memory, etc. ].<br> | ||
| <br> | ||
| @rtype: list</tt></dd></dl> | ||
| <dl><dt><a name="Client-set_servers"><strong>set_servers</strong></a>(self, servers)</dt><dd><tt>Set the pool of servers used by this client.<br> | ||
| <br> | ||
| @param servers: an array of servers.<br> | ||
| Servers can be passed in two forms:<br> | ||
| 1. Strings of the form C{"host:port"}, which implies a<br> | ||
| default weight of 1.<br> | ||
| 2. Tuples of the form C{("host:port", weight)}, where<br> | ||
| C{weight} is an integer weight value.</tt></dd></dl> | ||
| <dl><dt><a name="Client-touch"><strong>touch</strong></a>(self, key, time<font color="#909090">=0</font>)</dt><dd><tt>Updates the expiration time of a key in memcache.<br> | ||
| <br> | ||
| @return: Nonzero on success.<br> | ||
| @param time: Tells memcached the time which this value should<br> | ||
| expire, either as a delta number of seconds, or an absolute<br> | ||
| unix time-since-the-epoch value. See the memcached protocol<br> | ||
| docs section "Storage Commands" for more info on <exptime>. We<br> | ||
| default to 0 == cache forever.<br> | ||
| @rtype: int</tt></dd></dl> | ||
| <hr> | ||
| Data descriptors defined here:<br> | ||
| <dl><dt><strong>__dict__</strong></dt> | ||
| <dd><tt>dictionary for instance variables (if defined)</tt></dd> | ||
| </dl> | ||
| <hr> | ||
| Data and other attributes defined here:<br> | ||
| <dl><dt><strong>MemcachedKeyCharacterError</strong> = <class 'memcache.MemcachedKeyCharacterError'></dl> | ||
| <dl><dt><strong>MemcachedKeyError</strong> = <class 'memcache.MemcachedKeyError'></dl> | ||
| <dl><dt><strong>MemcachedKeyLengthError</strong> = <class 'memcache.MemcachedKeyLengthError'></dl> | ||
| <dl><dt><strong>MemcachedKeyNoneError</strong> = <class 'memcache.MemcachedKeyNoneError'></dl> | ||
| <dl><dt><strong>MemcachedKeyTypeError</strong> = <class 'memcache.MemcachedKeyTypeError'></dl> | ||
| <dl><dt><strong>MemcachedStringEncodingError</strong> = <class 'memcache.MemcachedStringEncodingError'></dl> | ||
| <hr> | ||
| Methods inherited from <a href="thread.html#_local">thread._local</a>:<br> | ||
| <dl><dt><a name="Client-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Client-__delattr__">__delattr__</a>('name') <==> del x.name</tt></dd></dl> | ||
| <dl><dt><a name="Client-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#Client-__getattribute__">__getattribute__</a>('name') <==> x.name</tt></dd></dl> | ||
| <dl><dt><a name="Client-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Client-__setattr__">__setattr__</a>('name', value) <==> x.name = value</tt></dd></dl> | ||
| <hr> | ||
| Data and other attributes inherited from <a href="thread.html#_local">thread._local</a>:<br> | ||
| <dl><dt><strong>__new__</strong> = <built-in method __new__ of type object><dd><tt>T.<a href="#Client-__new__">__new__</a>(S, ...) -> a new object with type S, a subtype of T</tt></dl> | ||
| </td></tr></table></td></tr></table><p> | ||
| <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | ||
| <tr bgcolor="#eeaa77"> | ||
| <td colspan=3 valign=bottom> <br> | ||
| <font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr> | ||
| <tr><td bgcolor="#eeaa77"><tt> </tt></td><td> </td> | ||
| <td width="100%"><dl><dt><a name="-cmemcache_hash"><strong>cmemcache_hash</strong></a>(key)</dt></dl> | ||
| <dl><dt><a name="-compress"><strong>compress</strong></a>(...)</dt><dd><tt><a href="#-compress">compress</a>(string[, level]) -- Returned compressed string.<br> | ||
| <br> | ||
| Optional arg level is the compression level, in 0-9.</tt></dd></dl> | ||
| <dl><dt><a name="-decompress"><strong>decompress</strong></a>(...)</dt><dd><tt><a href="#-decompress">decompress</a>(string[, wbits[, bufsize]]) -- Return decompressed string.<br> | ||
| <br> | ||
| Optional arg wbits is the window buffer size. Optional arg bufsize is<br> | ||
| the initial output buffer size.</tt></dd></dl> | ||
| <dl><dt><a name="-serverHashFunction"><strong>serverHashFunction</strong></a> = cmemcache_hash(key)</dt></dl> | ||
| <dl><dt><a name="-useOldServerHashFunction"><strong>useOldServerHashFunction</strong></a>()</dt><dd><tt>Use the old python-memcache server hash function.</tt></dd></dl> | ||
| </td></tr></table><p> | ||
| <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | ||
| <tr bgcolor="#55aa55"> | ||
| <td colspan=3 valign=bottom> <br> | ||
| <font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr> | ||
| <tr><td bgcolor="#55aa55"><tt> </tt></td><td> </td> | ||
| <td width="100%"><strong>SERVER_MAX_KEY_LENGTH</strong> = 250<br> | ||
| <strong>SERVER_MAX_VALUE_LENGTH</strong> = 1048576<br> | ||
| <strong>__author__</strong> = 'Sean Reifschneider <jafo-memcached@tummy.com>'<br> | ||
| <strong>__copyright__</strong> = 'Copyright (C) 2003 Danga Interactive'<br> | ||
| <strong>__license__</strong> = 'Python Software Foundation License'<br> | ||
| <strong>__version__</strong> = '1.54'<br> | ||
| <strong>print_function</strong> = _Feature((2, 6, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 65536)<br> | ||
| <strong>valid_key_chars_re</strong> = <_sre.SRE_Pattern object></td></tr></table><p> | ||
| <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> | ||
| <tr bgcolor="#7799ee"> | ||
| <td colspan=3 valign=bottom> <br> | ||
| <font color="#ffffff" face="helvetica, arial"><big><strong>Author</strong></big></font></td></tr> | ||
| <tr><td bgcolor="#7799ee"><tt> </tt></td><td> </td> | ||
| <td width="100%">Sean Reifschneider <jafo-memcached@tummy.com></td></tr></table> | ||
| </body></html> |
-556
| PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 | ||
| -------------------------------------------- | ||
| 1. This LICENSE AGREEMENT is between the Python Software Foundation | ||
| ("PSF"), and the Individual or Organization ("Licensee") accessing and | ||
| otherwise using this software ("Python") in source or binary form and | ||
| its associated documentation. | ||
| 2. Subject to the terms and conditions of this License Agreement, PSF | ||
| hereby grants Licensee a nonexclusive, royalty-free, world-wide | ||
| license to reproduce, analyze, test, perform and/or display publicly, | ||
| prepare derivative works, distribute, and otherwise use Python | ||
| alone or in any derivative version, provided, however, that PSF's | ||
| License Agreement and PSF's notice of copyright, i.e., "Copyright (c) | ||
| 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Python Software Foundation; | ||
| All Rights Reserved" are retained in Python alone or in any derivative | ||
| version prepared by Licensee. | ||
| 3. In the event Licensee prepares a derivative work that is based on | ||
| or incorporates Python or any part thereof, and wants to make | ||
| the derivative work available to others as provided herein, then | ||
| Licensee hereby agrees to include in any such work a brief summary of | ||
| the changes made to Python. | ||
| 4. PSF is making Python available to Licensee on an "AS IS" | ||
| basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR | ||
| IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND | ||
| DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS | ||
| FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT | ||
| INFRINGE ANY THIRD PARTY RIGHTS. | ||
| 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON | ||
| FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS | ||
| A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, | ||
| OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. | ||
| 6. This License Agreement will automatically terminate upon a material | ||
| breach of its terms and conditions. | ||
| 7. Nothing in this License Agreement shall be deemed to create any | ||
| relationship of agency, partnership, or joint venture between PSF and | ||
| Licensee. This License Agreement does not grant permission to use PSF | ||
| trademarks or trade name in a trademark sense to endorse or promote | ||
| products or services of Licensee, or any third party. | ||
| 8. By copying, installing or otherwise using Python, Licensee | ||
| agrees to be bound by the terms and conditions of this License | ||
| Agreement. | ||
| BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 | ||
| ------------------------------------------- | ||
| BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 | ||
| 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an | ||
| office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the | ||
| Individual or Organization ("Licensee") accessing and otherwise using | ||
| this software in source or binary form and its associated | ||
| documentation ("the Software"). | ||
| 2. Subject to the terms and conditions of this BeOpen Python License | ||
| Agreement, BeOpen hereby grants Licensee a non-exclusive, | ||
| royalty-free, world-wide license to reproduce, analyze, test, perform | ||
| and/or display publicly, prepare derivative works, distribute, and | ||
| otherwise use the Software alone or in any derivative version, | ||
| provided, however, that the BeOpen Python License is retained in the | ||
| Software, alone or in any derivative version prepared by Licensee. | ||
| 3. BeOpen is making the Software available to Licensee on an "AS IS" | ||
| basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR | ||
| IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND | ||
| DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS | ||
| FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT | ||
| INFRINGE ANY THIRD PARTY RIGHTS. | ||
| 4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE | ||
| SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS | ||
| AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY | ||
| DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. | ||
| 5. This License Agreement will automatically terminate upon a material | ||
| breach of its terms and conditions. | ||
| 6. This License Agreement shall be governed by and interpreted in all | ||
| respects by the law of the State of California, excluding conflict of | ||
| law provisions. Nothing in this License Agreement shall be deemed to | ||
| create any relationship of agency, partnership, or joint venture | ||
| between BeOpen and Licensee. This License Agreement does not grant | ||
| permission to use BeOpen trademarks or trade names in a trademark | ||
| sense to endorse or promote products or services of Licensee, or any | ||
| third party. As an exception, the "BeOpen Python" logos available at | ||
| http://www.pythonlabs.com/logos.html may be used according to the | ||
| permissions granted on that web page. | ||
| 7. By copying, installing or otherwise using the software, Licensee | ||
| agrees to be bound by the terms and conditions of this License | ||
| Agreement. | ||
| CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 | ||
| --------------------------------------- | ||
| 1. This LICENSE AGREEMENT is between the Corporation for National | ||
| Research Initiatives, having an office at 1895 Preston White Drive, | ||
| Reston, VA 20191 ("CNRI"), and the Individual or Organization | ||
| ("Licensee") accessing and otherwise using Python 1.6.1 software in | ||
| source or binary form and its associated documentation. | ||
| 2. Subject to the terms and conditions of this License Agreement, CNRI | ||
| hereby grants Licensee a nonexclusive, royalty-free, world-wide | ||
| license to reproduce, analyze, test, perform and/or display publicly, | ||
| prepare derivative works, distribute, and otherwise use Python 1.6.1 | ||
| alone or in any derivative version, provided, however, that CNRI's | ||
| License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) | ||
| 1995-2001 Corporation for National Research Initiatives; All Rights | ||
| Reserved" are retained in Python 1.6.1 alone or in any derivative | ||
| version prepared by Licensee. Alternately, in lieu of CNRI's License | ||
| Agreement, Licensee may substitute the following text (omitting the | ||
| quotes): "Python 1.6.1 is made available subject to the terms and | ||
| conditions in CNRI's License Agreement. This Agreement together with | ||
| Python 1.6.1 may be located on the Internet using the following | ||
| unique, persistent identifier (known as a handle): 1895.22/1013. This | ||
| Agreement may also be obtained from a proxy server on the Internet | ||
| using the following URL: http://hdl.handle.net/1895.22/1013". | ||
| 3. In the event Licensee prepares a derivative work that is based on | ||
| or incorporates Python 1.6.1 or any part thereof, and wants to make | ||
| the derivative work available to others as provided herein, then | ||
| Licensee hereby agrees to include in any such work a brief summary of | ||
| the changes made to Python 1.6.1. | ||
| 4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" | ||
| basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR | ||
| IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND | ||
| DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS | ||
| FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT | ||
| INFRINGE ANY THIRD PARTY RIGHTS. | ||
| 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON | ||
| 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS | ||
| A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, | ||
| OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. | ||
| 6. This License Agreement will automatically terminate upon a material | ||
| breach of its terms and conditions. | ||
| 7. This License Agreement shall be governed by the federal | ||
| intellectual property law of the United States, including without | ||
| limitation the federal copyright law, and, to the extent such | ||
| U.S. federal law does not apply, by the law of the Commonwealth of | ||
| Virginia, excluding Virginia's conflict of law provisions. | ||
| Notwithstanding the foregoing, with regard to derivative works based | ||
| on Python 1.6.1 that incorporate non-separable material that was | ||
| previously distributed under the GNU General Public License (GPL), the | ||
| law of the Commonwealth of Virginia shall govern this License | ||
| Agreement only as to issues arising under or with respect to | ||
| Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this | ||
| License Agreement shall be deemed to create any relationship of | ||
| agency, partnership, or joint venture between CNRI and Licensee. This | ||
| License Agreement does not grant permission to use CNRI trademarks or | ||
| trade name in a trademark sense to endorse or promote products or | ||
| services of Licensee, or any third party. | ||
| 8. By clicking on the "ACCEPT" button where indicated, or by copying, | ||
| installing or otherwise using Python 1.6.1, Licensee agrees to be | ||
| bound by the terms and conditions of this License Agreement. | ||
| ACCEPT | ||
| CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 | ||
| -------------------------------------------------- | ||
| Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, | ||
| The Netherlands. All rights reserved. | ||
| Permission to use, copy, modify, and distribute this software and its | ||
| documentation for any purpose and without fee is hereby granted, | ||
| provided that the above copyright notice appear in all copies and that | ||
| both that copyright notice and this permission notice appear in | ||
| supporting documentation, and that the name of Stichting Mathematisch | ||
| Centrum or CWI not be used in advertising or publicity pertaining to | ||
| distribution of the software without specific, written prior | ||
| permission. | ||
| STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO | ||
| THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||
| FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE | ||
| FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | ||
| OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| This copy of Python includes a copy of bzip2, which is licensed under the following terms: | ||
| This program, "bzip2", the associated library "libbzip2", and all | ||
| documentation, are copyright (C) 1996-2005 Julian R Seward. All | ||
| rights reserved. | ||
| Redistribution and use in source and binary forms, with or without | ||
| modification, are permitted provided that the following conditions | ||
| are met: | ||
| 1. Redistributions of source code must retain the above copyright | ||
| notice, this list of conditions and the following disclaimer. | ||
| 2. The origin of this software must not be misrepresented; you must | ||
| not claim that you wrote the original software. If you use this | ||
| software in a product, an acknowledgment in the product | ||
| documentation would be appreciated but is not required. | ||
| 3. Altered source versions must be plainly marked as such, and must | ||
| not be misrepresented as being the original software. | ||
| 4. The name of the author may not be used to endorse or promote | ||
| products derived from this software without specific prior written | ||
| permission. | ||
| THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS | ||
| OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | ||
| GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| Julian Seward, Cambridge, UK. | ||
| jseward@acm.org | ||
| bzip2/libbzip2 version 1.0.3 of 15 February 2005 | ||
| This copy of Python includes a copy of db, which is licensed under the following terms: | ||
| /*- | ||
| * $Id: LICENSE,v 12.1 2005/06/16 20:20:10 bostic Exp $ | ||
| */ | ||
| The following is the license that applies to this copy of the Berkeley DB | ||
| software. For a license to use the Berkeley DB software under conditions | ||
| other than those described here, or to purchase support for this software, | ||
| please contact Sleepycat Software by email at info@sleepycat.com, or on | ||
| the Web at http://www.sleepycat.com. | ||
| =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | ||
| /* | ||
| * Copyright (c) 1990-2005 | ||
| * Sleepycat Software. All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * 3. Redistributions in any form must be accompanied by information on | ||
| * how to obtain complete source code for the DB software and any | ||
| * accompanying software that uses the DB software. The source code | ||
| * must either be included in the distribution or be available for no | ||
| * more than the cost of distribution plus a nominal fee, and must be | ||
| * freely redistributable under reasonable conditions. For an | ||
| * executable file, complete source code means the source code for all | ||
| * modules it contains. It does not include source code for modules or | ||
| * files that typically accompany the major components of the operating | ||
| * system on which the executable file runs. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY SLEEPYCAT SOFTWARE ``AS IS'' AND ANY EXPRESS | ||
| * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR | ||
| * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL SLEEPYCAT SOFTWARE | ||
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||
| * THE POSSIBILITY OF SUCH DAMAGE. | ||
| */ | ||
| /* | ||
| * Copyright (c) 1990, 1993, 1994, 1995 | ||
| * The Regents of the University of California. All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * 3. Neither the name of the University nor the names of its contributors | ||
| * may be used to endorse or promote products derived from this software | ||
| * without specific prior written permission. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| * SUCH DAMAGE. | ||
| */ | ||
| /* | ||
| * Copyright (c) 1995, 1996 | ||
| * The President and Fellows of Harvard University. All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * 3. Neither the name of the University nor the names of its contributors | ||
| * may be used to endorse or promote products derived from this software | ||
| * without specific prior written permission. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND | ||
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE | ||
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| * SUCH DAMAGE. | ||
| */ | ||
| This copy of Python includes a copy of openssl, which is licensed under the following terms: | ||
| LICENSE ISSUES | ||
| ============== | ||
| The OpenSSL toolkit stays under a dual license, i.e. both the conditions of | ||
| the OpenSSL License and the original SSLeay license apply to the toolkit. | ||
| See below for the actual license texts. Actually both licenses are BSD-style | ||
| Open Source licenses. In case of any license issues related to OpenSSL | ||
| please contact openssl-core@openssl.org. | ||
| OpenSSL License | ||
| --------------- | ||
| /* ==================================================================== | ||
| * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in | ||
| * the documentation and/or other materials provided with the | ||
| * distribution. | ||
| * | ||
| * 3. All advertising materials mentioning features or use of this | ||
| * software must display the following acknowledgment: | ||
| * "This product includes software developed by the OpenSSL Project | ||
| * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
| * | ||
| * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
| * endorse or promote products derived from this software without | ||
| * prior written permission. For written permission, please contact | ||
| * openssl-core@openssl.org. | ||
| * | ||
| * 5. Products derived from this software may not be called "OpenSSL" | ||
| * nor may "OpenSSL" appear in their names without prior written | ||
| * permission of the OpenSSL Project. | ||
| * | ||
| * 6. Redistributions of any form whatsoever must retain the following | ||
| * acknowledgment: | ||
| * "This product includes software developed by the OpenSSL Project | ||
| * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
| * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
| * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| * ==================================================================== | ||
| * | ||
| * This product includes cryptographic software written by Eric Young | ||
| * (eay@cryptsoft.com). This product includes software written by Tim | ||
| * Hudson (tjh@cryptsoft.com). | ||
| * | ||
| */ | ||
| Original SSLeay License | ||
| ----------------------- | ||
| /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
| * All rights reserved. | ||
| * | ||
| * This package is an SSL implementation written | ||
| * by Eric Young (eay@cryptsoft.com). | ||
| * The implementation was written so as to conform with Netscapes SSL. | ||
| * | ||
| * This library is free for commercial and non-commercial use as long as | ||
| * the following conditions are aheared to. The following conditions | ||
| * apply to all code found in this distribution, be it the RC4, RSA, | ||
| * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
| * included with this distribution is covered by the same copyright terms | ||
| * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
| * | ||
| * Copyright remains Eric Young's, and as such any Copyright notices in | ||
| * the code are not to be removed. | ||
| * If this package is used in a product, Eric Young should be given attribution | ||
| * as the author of the parts of the library used. | ||
| * This can be in the form of a textual message at program startup or | ||
| * in documentation (online or textual) provided with the package. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * 3. All advertising materials mentioning features or use of this software | ||
| * must display the following acknowledgement: | ||
| * "This product includes cryptographic software written by | ||
| * Eric Young (eay@cryptsoft.com)" | ||
| * The word 'cryptographic' can be left out if the rouines from the library | ||
| * being used are not cryptographic related :-). | ||
| * 4. If you include any Windows specific code (or a derivative thereof) from | ||
| * the apps directory (application code) you must include an acknowledgement: | ||
| * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| * SUCH DAMAGE. | ||
| * | ||
| * The licence and distribution terms for any publically available version or | ||
| * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
| * copied and put under another distribution licence | ||
| * [including the GNU Public Licence.] | ||
| */ | ||
| This copy of Python includes a copy of tcl, which is licensed under the following terms: | ||
| This software is copyrighted by the Regents of the University of | ||
| California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState | ||
| Corporation and other parties. The following terms apply to all files | ||
| associated with the software unless explicitly disclaimed in | ||
| individual files. | ||
| The authors hereby grant permission to use, copy, modify, distribute, | ||
| and license this software and its documentation for any purpose, provided | ||
| that existing copyright notices are retained in all copies and that this | ||
| notice is included verbatim in any distributions. No written agreement, | ||
| license, or royalty fee is required for any of the authorized uses. | ||
| Modifications to this software may be copyrighted by their authors | ||
| and need not follow the licensing terms described here, provided that | ||
| the new terms are clearly indicated on the first page of each file where | ||
| they apply. | ||
| IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY | ||
| FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES | ||
| ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY | ||
| DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE | ||
| POSSIBILITY OF SUCH DAMAGE. | ||
| THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, | ||
| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE | ||
| IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE | ||
| NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR | ||
| MODIFICATIONS. | ||
| GOVERNMENT USE: If you are acquiring this software on behalf of the | ||
| U.S. government, the Government shall have only "Restricted Rights" | ||
| in the software and related documentation as defined in the Federal | ||
| Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you | ||
| are acquiring the software on behalf of the Department of Defense, the | ||
| software shall be classified as "Commercial Computer Software" and the | ||
| Government shall have only "Restricted Rights" as defined in Clause | ||
| 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the | ||
| authors grant the U.S. Government and others acting in its behalf | ||
| permission to use and distribute the software in accordance with the | ||
| terms specified in this license. | ||
| This copy of Python includes a copy of tk, which is licensed under the following terms: | ||
| This software is copyrighted by the Regents of the University of | ||
| California, Sun Microsystems, Inc., and other parties. The following | ||
| terms apply to all files associated with the software unless explicitly | ||
| disclaimed in individual files. | ||
| The authors hereby grant permission to use, copy, modify, distribute, | ||
| and license this software and its documentation for any purpose, provided | ||
| that existing copyright notices are retained in all copies and that this | ||
| notice is included verbatim in any distributions. No written agreement, | ||
| license, or royalty fee is required for any of the authorized uses. | ||
| Modifications to this software may be copyrighted by their authors | ||
| and need not follow the licensing terms described here, provided that | ||
| the new terms are clearly indicated on the first page of each file where | ||
| they apply. | ||
| IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY | ||
| FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES | ||
| ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY | ||
| DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE | ||
| POSSIBILITY OF SUCH DAMAGE. | ||
| THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, | ||
| INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE | ||
| IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE | ||
| NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR | ||
| MODIFICATIONS. | ||
| GOVERNMENT USE: If you are acquiring this software on behalf of the | ||
| U.S. government, the Government shall have only "Restricted Rights" | ||
| in the software and related documentation as defined in the Federal | ||
| Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you | ||
| are acquiring the software on behalf of the Department of Defense, the | ||
| software shall be classified as "Commercial Computer Software" and the | ||
| Government shall have only "Restricted Rights" as defined in Clause | ||
| 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the | ||
| authors grant the U.S. Government and others acting in its behalf | ||
| permission to use and distribute the software in accordance with the | ||
| terms specified in this license. |
| #!/usr/bin/env python | ||
| # | ||
| # Tests for set_multi. | ||
| # | ||
| # ============== | ||
| # This is based on a skeleton test file, more information at: | ||
| # | ||
| # https://github.com/linsomniac/python-unittest-skeleton | ||
| from __future__ import print_function | ||
| import socket | ||
| import sys | ||
| import unittest | ||
| sys.path.append('..') | ||
| import memcache | ||
| DEBUG = False | ||
| class test_Memcached_Set_Multi(unittest.TestCase): | ||
| def setUp(self): | ||
| RECV_CHUNKS = ['chunk1'] | ||
| class FakeSocket(object): | ||
| def __init__(self, *args): | ||
| if DEBUG: | ||
| print('FakeSocket{0!r}'.format(args)) | ||
| self._recv_chunks = list(RECV_CHUNKS) | ||
| def connect(self, *args): | ||
| if DEBUG: | ||
| print('FakeSocket.connect{0!r}'.format(args)) | ||
| def sendall(self, *args): | ||
| if DEBUG: | ||
| print('FakeSocket.sendall{0!r}'.format(args)) | ||
| def recv(self, *args): | ||
| if self._recv_chunks: | ||
| data = self._recv_chunks.pop(0) | ||
| else: | ||
| data = '' | ||
| if DEBUG: | ||
| print('FakeSocket.recv{0!r} -> {1!r}'.format(args, data)) | ||
| return data | ||
| def close(self): | ||
| if DEBUG: | ||
| print('FakeSocket.close()') | ||
| self.old_socket = socket.socket | ||
| socket.socket = FakeSocket | ||
| def tearDown(self): | ||
| socket.socket = self.old_socket | ||
| def test_Socket_Disconnect(self): | ||
| client = memcache.Client(['memcached'], debug=True) | ||
| mapping = {'foo': 'FOO', 'bar': 'BAR'} | ||
| bad_keys = client.set_multi(mapping) | ||
| self.assertEqual(sorted(bad_keys), ['bar', 'foo']) | ||
| if DEBUG: | ||
| print('set_multi({0!r}) -> {1!r}'.format(mapping, bad_keys)) | ||
| if __name__ == '__main__': | ||
| unittest.main() |
-24
| [tox] | ||
| minversion = 1.6 | ||
| envlist = py26,py27,py32,py33,py34,pypy,pep8 | ||
| skipsdist = True | ||
| [testenv] | ||
| usedevelop = True | ||
| # Customize pip command, add -U to force updates. | ||
| install_command = pip install -U {opts} {packages} | ||
| deps = -r{toxinidir}/requirements.txt | ||
| -r{toxinidir}/test-requirements.txt | ||
| commands = nosetests {posargs} | ||
| [tox:jenkins] | ||
| downloadcache = ~/cache/pip | ||
| [testenv:pep8] | ||
| commands = flake8 | ||
| [testenv:cover] | ||
| commands = nosetests --with-coverage {posargs} | ||
| [flake8] | ||
| exclude = .venv*,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*.egg,.update-venv |
Sorry, the diff of this file is not supported yet
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
1470
4.26%86109
-42.54%14
-12.5%