summaryrefslogtreecommitdiff
path: root/pymemcache/client/base.py
Commit message (Collapse)AuthorAgeFilesLines
* Add more type annotationsJoe Gordon2022-10-031-66/+166
| | | | Continue to improve the type annotation coverage
* Start to add type hintsJoe Gordon2022-09-121-59/+119
| | | | | First pass at adding some type hints to pymemcache to make it easier to develop against etc.
* Expand Client with a method for sending arbitrary commands. (#395)Martin J2022-06-091-2/+72
|
* Small buffer pass optimization as discussed in #395. (#402)Martin J2022-06-071-4/+7
| | | | Basically ensure the client only does one pass over the buffer instead of two. Exact thread: https://github.com/pinterest/pymemcache/pull/395#discussion_r890288417
* Handle a blank stat value (#388)liquidpele2022-03-251-1/+1
| | | | | | | | | | | | | | | | | | | | | | A stat with a blank value makes the .stats() call fail with index error. ``` memcache_connection.stats() File "/lib/python3.6/site-packages/pymemcache/client/base.py", line 741, in stats result = self._fetch_cmd(b'stats', args, False) File "/lib/python3.6/site-packages/pymemcache/client/base.py", line 921, in _fetch_cmd result[key_value[1]] = key_value[2] IndexError: list index out of range ``` The line in question we saw that caused this: ``` b'STAT ep_initfile ' ``` This fixes things to no longer blow up. I chose to use a blank binary string instead of None because I suspect other code might make assumptions about the data being binary strings due to this bug. Co-authored-by: reecepeg <reecepeg@amazon.com>
* Formalize typing for server specifications (#376)Jon Parise2022-02-221-10/+11
| | | | | This also drops support for passing None as a server spec, which is something many tests were doing out of lazy convenience. I can't think of a reason why we'd want to support that for real world usage.
* Apply black formattingJoe Gordon2021-12-031-217/+237
| | | | https://black.readthedocs.io/en/stable/index.html
* fix typo (#356)Jürgen Gmach2021-11-181-1/+1
|
* Use default for get ignore_excJoe Gordon2021-09-221-1/+1
| | | | | | | ignore_exc should treat an error as a cache miss and default specifies what should be returned on a miss. Fixes issue #350
* docs: Fix a few typos (#348)Tim Gates2021-09-131-1/+1
|
* Fixes for rebase and further cleanupsJoe Gordon2021-07-201-4/+1
|
* Remove six dependency and run pyupgradeJoe Gordon2021-07-201-30/+29
| | | | | | | Now that we don't require Python 2 support no need for six. Code upgraded with pyupgrade and manual fixes to remove remaining six usage.
* [py27] Fixing a bug with bad conditions (#337)Hervé Beraud2021-07-061-1/+1
|
* Configure the socket keepalive from various clients (#338)Hervé Beraud2021-07-051-0/+3
|
* Fix doc rendering (#339)Hervé Beraud2021-07-051-14/+10
|
* Ensure us to close socket on MemcacheUnexpectedCloseErrorHervé Beraud2021-07-011-4/+24
| | | | | | | | | | | | | | | | | | | | During network maintenance operations or during server reboot users could face MemcacheUnexpectedCloseError. This kind of exception will be raised down the stack. It's a design choice [1]. Users should manage this kind of exception. However, at some points the opened sockets remains more or less opened after this kind of fail on the client side [2]. It will require n+1 calls to see them recreated when the connection will be possible. That's could be problem with services that implement several cache logics in parallel and where their clients are based on pymemcache. These changes simply ensure to close the socket properly. The socket will be recreated by the client if needed. [1] https://github.com/pinterest/pymemcache/issues/307 [2] https://bugzilla.redhat.com/show_bug.cgi?id=1977711
* Reduce method complexity to pass linter testsHervé Beraud2021-07-011-8/+8
| | | | | | | | The _store_cmd method became a bit to complexe and the linter complains when we add new conditions or try/except clause. These changes outsource some some processsing to reduce the complexity of the method.
* Implement socket keepalive configuration mechanisms (#332)Hervé Beraud2021-07-011-0/+81
|
* Client API for server shutdown protocol command (#328)LINKIWI2021-06-211-0/+30
|
* Remove idle connections from pool (#309)Jordan Carlson2021-06-011-0/+5
| | | | | | The Memcached server can be configured to drop idle connections (via the idle_timeout option). When this occurs, pymemcache may still try to use the connection, resulting in MemcacheUnexpectedCloseError. Hence the need for client-side idle timeout logic.
* Removing trailing space after a command if there are no arguments. (#311)Jerry Miu2021-04-141-1/+4
| | | According to the Memcached Protocol, the no argument form of the stats command should have no trailing spaces. Currently, b'stats \r\n' instead of b'stats\r\n' is being sent to the socket which leads to a malformed response.
* Move _check_cas() check into cas() methodJon Parise2021-02-041-1/+1
| | | | | | | | | | | | | _check_cas() does a good job of normalizing a CAS value and raising MemcacheIllegalInputError when fed an invalid value. We were only using this function in the `cas is not None` path within _store_cmd(). By moving this check into cas() itself, it allows us to also raise MemcacheIllegalInputError when `cas is None`, which can happen when this pattern is used for a new key: val, cas = c.gets('key') c.cas('key', 'value', cas)
* Added support for connections over IPv6.Nick Pope2020-09-031-16/+53
| | | | Fixes #257.
* Made isinstance() checks use six consistently.Nick Pope2020-09-021-7/+6
|
* Fix typos discovered by codespellChristian Clauss2020-08-211-2/+2
|
* Added missing HashClient.close() and HashClient.quit().Nick Pope2020-08-171-0/+4
| | | | Also added disconnect_all() as an alias for close().
* Minor cleanups to avoid unnecessary variables.Nick Pope2020-08-171-3/+2
|
* Updated docs for decrement (#289)Ben Yarmis2020-08-121-1/+1
| | | Co-authored-by: Ben Yarmis <byarmis@indeed.com>
* Make PooledClient and HashClient able to use a custom client class (#280)Simon Davy2020-04-281-14/+17
| | | | | The user can subclass Client (e.g to add telemetry or logging), and have their custom client class used by PooledClient and HashClient to create new clients.
* Add TLS support for TCP sockets (#276)Moisés Guimarães de Medeiros2020-04-071-3/+14
|
* Update MockMemcacheClient to reuse check_key (#273)Joe Gordon2020-03-191-5/+5
| | | | | | | | Our current MockMemcacheClient doesn't throw an error if a key has a space, and given MockMemcacheClient can be consumed by downstream things, we want it to act as close to the real client as possible. Rename _check_key to check_key_helper so we aren't importing a private function.
* Clarify noreply + self.default_noreply behavior (#255)Jon Parise2019-09-101-6/+10
| | | | | For add(), replace(), cas(), and delete(), if noreply is True (or if it is unset and self.default_noreply is True), the return value is always True.
* Validate cas inputs as strings of digits (#250)Stephen Rosen2019-08-261-0/+27
| | | | | | | | | | | | | | | | | | | | For consideration for v3.0.0 'cas' is documented as needing to be an int or bytestring of the digits 0-9. However, this is not actually enforced and it is possible to pass a value to pymemcache which doesn't conform to these rules. In fact, you can do weird things like `cas=b'noreply'` and potentially trigger "unexpected" behavior. To go along with validating int inputs, validate cas inputs. However, these are not necessarily integers. Instead, if an int or string is given, it will be encoded as a bytestring. But in order to validate the value given, it is checked against isdigit() . (NB: You could also use `int(cas)` for very similar checking.) Rationale for allowing non-integer inputs to cas is not obvious. Presumably it allows callers using `gets()` to pass the `cas` value they get back into a `cas` command without issue. But it may be debatable.
* Change serialization interface to be an object (#245)Stephen Rosen2019-08-261-33/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Change serialization interface to be an object Rather than passing separate serialization and deserialization methods to a pymemcache client, pass an object implementing a very simple two-method interface. This is a rather significant breaking change and should be part of an x.0.0 major release. Resolves #56 As suggested in that issue, this is a cleaner interface, as there's no sensible context in which you would provide only one of these two methods and it should therefore be thought of as a serialization/deserialization protocol. Also adds a note to the documentation's Best Practices list that you should use the built-in serializer object unless you have a reason to do otherwise. * Support "de/serializer" in addition to "serde" In order to support older client usage in addition to the new serialization object (protocol), restore the "serializer" and "deserializer" arguments to the Client classes. These are marked as deprecated and will be automatically wrapped into a small "serde" object. In order to make the various object names more distinguishable and more informative, the built-in default serializer is now called "python_memcache_pickle_serde" Additionally, default client.serde to a "no-op serializer". This object does no transforms on the data. By putting this in place, we can skip some conditionals in the code around presence or absence of a serializer and therefore simplify internally (at the cost of an extra, unnecessary, functional call in some cases). It also simplifies logic around the handling of flags because we are now *guaranteed* the presence of a serializer object which returns some flags. i.e. "default flags" are no longer the responsibility of the various serializer usage sites. This is done carefully to ensure that passing a `serializer` without a `deserializer` is respected.
* Check integer input values to Client methods (#243)Stephen Rosen2019-08-201-9/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If a caller tries to send - a fractional expiration time - a string for the "incr" command - delay=None (instead of delay=0) The pymemcache base client will now catch these usage mistakes a throw a MemcacheIllegalInputError. Although there are existing valid (but undocumented) usages of the current string conversion behavior, the docs state that these values are supposed to be ints. Now if a non-int value is used, it will immediately trigger an error. This behavior is superior to the prior behavior especially in the case where a command is used with `noreply=True`. It can fail to parse, but the client won't pick up on this until the next call to memcache which reads the reply. The especially bad case we're seeking to avoid is this: from pymemcache.client.base import Client client = Client(("localhost", 11211)) client.set("foo", "bar", expire=1.5, noreply=True) client.get("foo") # triggers MemcacheUnknownCommandError Applies to all commands using `expire`, `delay`, incr and decr inputs, and memlimit. Because this is can be a breaking change for some users, the changelog entry is written under 3.0.0 (unreleased). closes #240
* Fix flags when setting multiple values at once (#248)v2.2.1Jon Parise2019-08-051-9/+8
| | | | | | | | | | | | | | | | | | | | | We introduced the ability to override the serializer-returned flags values in 26f7c1b1. Unfortunately, there was a flaw in that logic which resulted in the first item's flags being used for all later items. This bug primarily affected set_many()'s behavior when the data dictionary contained multiple different value types which were assigned different per-value flags values by the serializer. For example: set_many({'a': 'string', 'b': 10}) If a serializer returned different flags for strings (e.g. 1) and integer values (e.g. 2), the previous logic would have set ``flags`` to 1 the first time through the loop and repeated that value for the second item, instead of using 2. This was the intended behavior when ``flags`` was explicitly passed to set_many(), but not for the default case where we still want to respect the flags values returned by the serializer.
* Add note about the overriding behavior of `flags` (#247)Jon Parise2019-08-011-4/+12
|
* Add Sphinx links to the exception classes (#246)Jon Parise2019-08-011-8/+8
|
* Be more consistent about using Client.encoding (#242)Stephen Rosen2019-07-241-4/+6
| | | | | | | | | | | | | | This is a stylistic issue with little chance for actual impact. Some methods use 'ascii' verbatim and some use `self.encoding` (which defaults to 'ascii'). Those which are using `ascii` are only supposed to be accepting integer inputs, so this is actually fine. However, the result is a potentially confusing discrepancy -- why does `Client.touch` use `ascii` while `Client.add` uses `self.encoding`? To alleviate this potential confusion, be consistent about applying `self.encoding` to all memcached commands in the base client. This does not impact the `_check_key` func, which re-encodes potential unicode inputs as ASCII.
* extracted _extract_value() from _fetch_cmd() (#237)JianGuoPinterest2019-06-121-19/+29
| | | extract _extract_value() from _fetch_cmd() to support customized value extraction logic.
* add flags in client functions (#235)JianGuoPinterest2019-06-111-31/+63
| | | added flags in client functions to provide support for extra memcached operations.
* add encoding in client functions (#232)JianGuoPinterest2019-06-071-6/+11
|
* Merge pull request #228 from jparise/repr-quotesJoe Gordon2019-05-071-4/+4
|\ | | | | Remove redundant '' from %r values
| * Remove redundant '' from %r valuesJon Parise2019-05-071-4/+4
| | | | | | | | repr()'d strings (via %r) are already quoted.
* | Improve ASCII encoding failure exceptionJon Parise2019-05-071-1/+2
|/ | | | | | Memcache can only store binary-safe values. We raise an exception when we're unable to encode a data value using the 'ascii' codec. Improve the exception message to make the error case clearer.
* Improve the cache_memlimit documentationJon Parise2019-01-081-1/+2
|
* added OK as acceptable responseBenjamin Berg2019-01-081-1/+15
| | | | | | | | -Should not throw exception when response was "OK" cache_memlimit added -Allows client to set cache memlimit
* Always send command keys in their original orderJon Parise2019-01-071-9/+6
| | | | | | | | | | | | | | Some commands are sensitive to the order of their key arguments so revise the previous code to explicitly build a list of prefixed keys and a dictionary of remapped keys. This generalization also lets us remove command-specific checks from this code path. The list of prefixed keys is used to build the command string (preserving order). The dictionary of remapped keys is used to map the prefixed keys from the response to the key names that were originally provided to the client.
* Always close the existing socket on _connect() (#208)Jon Parise2019-01-031-4/+8
| | | | | | | | I don't currently see a way in which we would enter _connect() with an existing socket, but let's explicitly close() first just to be safe. This also ensures we enter the rest of the _connect() code knowing that `self.sock is None`. While I'm here, add better test coverage for the close() method.
* Add UNIX domain socket support (#206)Jon Parise2019-01-021-4/+25
| | | | | | The client's `server` argument can now be a string containing the path to the memcached server's UNIX domain socket. Also document all of the connection-oriented client parameters.