Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make serde pickle version configurable #160

Closed
wants to merge 22 commits into from

Conversation

akatrevorjay
Copy link
Contributor

@akatrevorjay akatrevorjay commented Jun 3, 2017

See #156 for more info :)

* origin/master:
  Reverse backwards compatible change
  removed apidoc directory from repo
  add apidoc to .gitignore
@akatrevorjay
Copy link
Contributor Author

My quick hack was reverted. This provides similar functionality while maintaining backwards compatibility with ancient pythons or a mix of py2/py3 and python-memcached.

except Exception as exc:
# This includes exc as a string for troubleshooting as well as providing
# a trace.
log.exception('Could not depickle value: %s')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this because using the root logger is nearly impossible to troubleshoot, and this should really be exc level.

@akatrevorjay
Copy link
Contributor Author

akatrevorjay commented Jun 3, 2017

fin (edit: ish)

@akatrevorjay
Copy link
Contributor Author

How's this look everyone? Any thoughts?

Copy link
Collaborator

@nichochar nichochar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM, I'll leave a couple other people to review before merging though

if pickle_version is not None:
self.pickle_version = pickle_version

def from_python(self, key, value):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about call this function serialize() (here and in metaclass)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it because in my experience serialize and deserialize are not the best names. Using a common anchor it seems to stick with more juniors easier and avoids headache. Still, I can update if you want, but I'd recommend not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


return value, flags

def to_python(self, key, value, flags):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here with deserialize

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


def to_python(self, key, value, flags):
"""
Deserialize a value into a python object.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the doc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicochar, anytime for you bud.

Copy link
Contributor

@jogo jogo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I like the idea of not hard coding pickle protocol 0. But in general I am weary of even tiny backwards incompatible changes. As I have experienced the pain of updated dependencies causing things to break.

Backwards compatibility with the older serialization api previously
provided by this module.
"""
from . import codecs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to use absolute imports here.

https://www.python.org/dev/peps/pep-0008/#imports

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP8 allows relative imports. Is there a reason to not use them and opt for the less featureful alternative?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep it consistent with the rest of the project, which uses absolute imports. Both positions are defendable but I think there's a strong argument for consistency

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, consistency > opinions

@@ -0,0 +1,170 @@
# Copyright 2012 Pinterest.com
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why rename the file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To provide backwards compatibility

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Without polluting the primary namespace)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's also a better name.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine.

long_type = None


FLAG_BYTES = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I don't think removing these from this file will be a problem it is technically a backwards incompatible change and don't want to break backwards compatibility.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO These should have been private to begin with, plus can't you just bump the major? I'll import them into serde.py if you want though.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why this is backward incompatible? I think this is OK. Am I missing something @jogo?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already imported the API methods, and I don't think anyone should really be using constants in an arbitrary location in a library.

FLAG_PICKLE = 1 << 0
FLAG_INTEGER = 1 << 1
FLAG_LONG = 1 << 2
FLAG_COMPRESSED = 1 << 3 # unused, to main compatibility with python-memcached
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

./pymemcache/codecs.py:71:81: E501 line too long (83 > 80 characters)
    FLAG_COMPRESSED = 1 << 3  # unused, to main compatibility with python-memcached

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll conform to VT100 in an update

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

except Exception as exc:
# This includes exc as a string for troubleshooting as well as
# providing a trace.
log.exception('Could not depickle value (len=%d): %s',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unclear why this is better:

import logging
try:
    raise Exception("raised")
except Exception as exc:
    logging.exception("TEST: %s", exc)


try:
    raise Exception("raised")
except Exception:
    logging.exception("TEST")
ERROR:root:TEST: raised
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    raise Exception("raised")
Exception: raised
ERROR:root:TEST
Traceback (most recent call last):
  File "test.py", line 9, in <module>
    raise Exception("raised")
Exception: raised

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because from the initial line, you know what the exc was that caused it. This helps when an exception storm hits and you have N of them in your log interspersed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logging entries are usually configured with a better format than the default that you used, which contain things such as the process and thread ID.

import pytest
import six

try:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should import this the same way we do elsewhere in this code: from six.moves import cPickle as pickle

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I can do that, it breaks tab completion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

def test_pickle_version(self):
for pickle_version in range(-1, pickle.HIGHEST_PROTOCOL):
self.check(
dict(whoa='nelly', humans=u'horrid', answer=42),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to use a different key value pair for humans.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please assist me with what you would like.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you mean humans aren't horrid? But we are! Lol, I'll update it!

"""
Init

:param int pickle_version: Pickle version to use (from python).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not the pickle version but rather the pickle protocol version

https://docs.python.org/3/library/pickle.html#data-stream-format

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, will update.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Collaborator

@nichochar nichochar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple minor changes, but looking good. Thanks for baring with us @akatrevorjay, we really appreciate the work

Backwards compatibility with the older serialization api previously
provided by this module.
"""
from . import codecs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep it consistent with the rest of the project, which uses absolute imports. Both positions are defendable but I think there's a strong argument for consistency

long_type = None


FLAG_BYTES = 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why this is backward incompatible? I think this is OK. Am I missing something @jogo?

@nichochar
Copy link
Collaborator

Hi @akatrevorjay ,

After internal discussion:

  • we really appreciate the contribution, and believe that making the cpickle version configurable is a good (great even) change.
  • we want the change to make it to master, but we would like it to be as atomic and small as possible before we perform the merge.

Another way of saying this is that this is a rather low level library that many people depend on, and few people actually open up and modify. This means that the benefits of a refactor are rather low, whereas the risks of something breaking because of it would impact a large number of actors in a bad way.

Such a refactor would require us to probably bump a major version for the library, which doesn't make sense given the feature set change.

All of this being said, we all agree that your code is good and the new interface and naming make sense.

Course of action:

We would like to open a new PR with as little changes as possible allowing for the configurable CPickle version. We can then bump that as a minor patch.

Since you've already done a lot of the work here, we're happy to make the PR changes on our side, but if you would like to do them on yours, let us know.

Cheers!

…kleableness

* origin/master:
  Add that we're hiring on README
  Bump version
  Update changelog
  Add pypy3 to travis test matrix
  Run full benchmark test in travis
  Fix flake8 issues
  Test against py35 and py36
  Added Python 3.5 and 3.6 to the build.
  Have MockMemcacheClient support non-ascii strings (pinterest#169)
  Update getting_started.rst
  Fix typo in doc
  Close client socket if it fails to connect (pinterest#165)
  Don't Raise Generic Exception (pinterest#164)
  correct spelling mistake
@akatrevorjay
Copy link
Contributor Author

@nichochar How's that? Addressed all concerns, I believe?

@akatrevorjay
Copy link
Contributor Author

The failure is due to #178 , ie nothing to worry about

…kleableness

* origin/master:
  trevor sucks
  Remove deprecated Python version.
@akatrevorjay
Copy link
Contributor Author

Updated to latest master so it can pass tests (my other PR fixed that)

@akatrevorjay
Copy link
Contributor Author

@nichochar Hello again, I'm not sure if you saw my changes? Hope you're doing well!

@nichochar
Copy link
Collaborator

Hello again, thanks for bumping! We definitely appreciate the work.

Since there is a lot of changes, and I'm no longer making big decisions related to this project, I will defer the review decision to @jogo .

In of itself, the code looks fine, the arguments against it I believe are that the project is very mature and stable, this isn't fixing any bugs but refactoring quite a bit, and losing blame history with a file rewrite. The benefits need to be measured well, and I'll defer to @jogo

@jparise
Copy link
Collaborator

jparise commented Nov 23, 2018

Closing this in favor of the approach implemented in #190.

@jparise jparise closed this Nov 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants