Skip to content

Commit

Permalink
fix: disuse __slots__ in most places (#330)
Browse files Browse the repository at this point in the history
In Python 2.7, classes which use `__slots__` can't be pickled. Users
have reported problems trying to pickle NDB entities, indicating there
is some perceived use case for pickling entities.

Fixes #311
  • Loading branch information
Chris Rossi authored Feb 11, 2020
1 parent f550510 commit a8b723b
Show file tree
Hide file tree
Showing 13 changed files with 3 additions and 143 deletions.
2 changes: 0 additions & 2 deletions google/cloud/ndb/_datastore_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ class BlobKey(object):
:class:`bytes` instance.
"""

__slots__ = ("_blob_key",)

def __init__(self, blob_key):
if isinstance(blob_key, bytes):
if len(blob_key) > _MAX_STRING_LENGTH:
Expand Down
9 changes: 0 additions & 9 deletions google/cloud/ndb/_eventloop.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,6 @@ class EventLoop(object):
get added to this queue and then processed by the event loop.
"""

__slots__ = (
"current",
"idlers",
"inactive",
"queue",
"rpcs",
"rpc_results",
)

def __init__(self):
self.current = collections.deque()
self.idlers = collections.deque()
Expand Down
4 changes: 0 additions & 4 deletions google/cloud/ndb/blobstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ def __init__(self, *args, **kwargs):


class BlobInfo(object):
__slots__ = ()

def __init__(self, *args, **kwargs):
raise exceptions.NoLongerImplementedError()

Expand Down Expand Up @@ -111,8 +109,6 @@ def __init__(self, *args, **kwargs):


class BlobReader(object):
__slots__ = ()

def __init__(self, *args, **kwargs):
raise exceptions.NoLongerImplementedError()

Expand Down
6 changes: 0 additions & 6 deletions google/cloud/ndb/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,21 +546,15 @@ def urlfetch(self, *args, **kwargs):


class ContextOptions(object):
__slots__ = ()

def __init__(self, *args, **kwargs):
raise exceptions.NoLongerImplementedError()


class TransactionOptions(object):
__slots__ = ()

def __init__(self, *args, **kwargs):
raise exceptions.NoLongerImplementedError()


class AutoBatcher(object):
__slots__ = ()

def __init__(self, *args, **kwargs):
raise exceptions.NoLongerImplementedError()
2 changes: 0 additions & 2 deletions google/cloud/ndb/django_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,5 @@


class NdbDjangoMiddleware(object):
__slots__ = ()

def __init__(self, *args, **kwargs):
raise NotImplementedError
2 changes: 0 additions & 2 deletions google/cloud/ndb/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,6 @@ class Key(object):
arguments were given with the path.
"""

__slots__ = ("_key", "_reference")

def __new__(cls, *path_args, **kwargs):
# Avoid circular import in Python 2.7
from google.cloud.ndb import context as context_module
Expand Down
8 changes: 0 additions & 8 deletions google/cloud/ndb/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@
class _BaseMetadata(model.Model):
"""Base class for all metadata models."""

__slots__ = ()

_use_cache = False
_use_global_cache = False

Expand All @@ -81,8 +79,6 @@ def _get_kind(cls):
class Namespace(_BaseMetadata):
"""Model for __namespace__ metadata query results."""

__slots__ = ()

KIND_NAME = "__namespace__"
EMPTY_NAMESPACE_ID = 1

Expand Down Expand Up @@ -127,8 +123,6 @@ def key_to_namespace(cls, key):
class Kind(_BaseMetadata):
"""Model for __kind__ metadata query results."""

__slots__ = ()

KIND_NAME = "__kind__"

@property
Expand Down Expand Up @@ -168,8 +162,6 @@ def key_to_kind(cls, key):
class Property(_BaseMetadata):
"""Model for __property__ metadata query results."""

__slots__ = ()

KIND_NAME = "__property__"

@property
Expand Down
34 changes: 0 additions & 34 deletions google/cloud/ndb/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,6 @@ def __ne__(self, other):
class IndexProperty(_NotEqualMixin):
"""Immutable object representing a single property in an index."""

__slots__ = ("_name", "_direction")

@utils.positional(1)
def __new__(cls, name, direction):
instance = super(IndexProperty, cls).__new__(cls)
Expand Down Expand Up @@ -426,8 +424,6 @@ def __hash__(self):
class Index(_NotEqualMixin):
"""Immutable object representing an index."""

__slots__ = ("_kind", "_properties", "_ancestor")

@utils.positional(1)
def __new__(cls, kind, properties, ancestor):
instance = super(Index, cls).__new__(cls)
Expand Down Expand Up @@ -475,8 +471,6 @@ def __hash__(self):
class IndexState(_NotEqualMixin):
"""Immutable object representing an index and its state."""

__slots__ = ("_definition", "_state", "_id")

@utils.positional(1)
def __new__(cls, definition, state, id):
instance = super(IndexState, cls).__new__(cls)
Expand Down Expand Up @@ -526,8 +520,6 @@ def __hash__(self):


class ModelAdapter(object):
__slots__ = ()

def __new__(self, *args, **kwargs):
raise exceptions.NoLongerImplementedError()

Expand Down Expand Up @@ -796,8 +788,6 @@ def make_connection(*args, **kwargs):
class ModelAttribute(object):
"""Base for classes that implement a ``_fix_up()`` method."""

__slots__ = ()

def _fix_up(self, cls, code_name):
"""Fix-up property name. To be implemented by subclasses.
Expand All @@ -824,8 +814,6 @@ class _BaseValue(_NotEqualMixin):
TypeError: If ``b_val`` is a list.
"""

__slots__ = ("b_val",)

def __init__(self, b_val):
if b_val is None:
raise TypeError("Cannot wrap None")
Expand Down Expand Up @@ -2169,8 +2157,6 @@ class ModelKey(Property):
.. automethod:: _validate
"""

__slots__ = ()

def __init__(self):
super(ModelKey, self).__init__()
self._name = "__key__"
Expand Down Expand Up @@ -2253,8 +2239,6 @@ class BooleanProperty(Property):
.. automethod:: _validate
"""

__slots__ = ()

def _validate(self, value):
"""Validate a ``value`` before setting it.
Expand Down Expand Up @@ -2285,8 +2269,6 @@ class IntegerProperty(Property):
.. automethod:: _validate
"""

__slots__ = ()

def _validate(self, value):
"""Validate a ``value`` before setting it.
Expand Down Expand Up @@ -2318,8 +2300,6 @@ class FloatProperty(Property):
.. automethod:: _validate
"""

__slots__ = ()

def _validate(self, value):
"""Validate a ``value`` before setting it.
Expand Down Expand Up @@ -2602,8 +2582,6 @@ class Item(ndb.Model):
NotImplementedError: If ``indexed=True`` is provided.
"""

__slots__ = ()

def __init__(self, *args, **kwargs):
indexed = kwargs.pop("indexed", False)
if indexed:
Expand Down Expand Up @@ -2732,8 +2710,6 @@ class StringProperty(TextProperty):
NotImplementedError: If ``indexed=False`` is provided.
"""

__slots__ = ()

def __init__(self, *args, **kwargs):
indexed = kwargs.pop("indexed", True)
if not indexed:
Expand All @@ -2757,8 +2733,6 @@ class GeoPtProperty(Property):
.. automethod:: _validate
"""

__slots__ = ()

def _validate(self, value):
"""Validate a ``value`` before setting it.
Expand Down Expand Up @@ -2967,8 +2941,6 @@ class User(object):
UserNotFoundError: If ``email`` is empty.
"""

__slots__ = ("_auth_domain", "_email", "_user_id")

def __init__(self, email=None, _auth_domain=None, _user_id=None):
if _auth_domain is None:
raise ValueError("_auth_domain is required")
Expand Down Expand Up @@ -3465,8 +3437,6 @@ class BlobKeyProperty(Property):
.. automethod:: _validate
"""

__slots__ = ()

def _validate(self, value):
"""Validate a ``value`` before setting it.
Expand Down Expand Up @@ -3685,8 +3655,6 @@ class DateProperty(DateTimeProperty):
.. automethod:: _validate
"""

__slots__ = ()

def _validate(self, value):
"""Validate a ``value`` before setting it.
Expand Down Expand Up @@ -3747,8 +3715,6 @@ class TimeProperty(DateTimeProperty):
.. automethod:: _validate
"""

__slots__ = ()

def _validate(self, value):
"""Validate a ``value`` before setting it.
Expand Down
4 changes: 0 additions & 4 deletions google/cloud/ndb/msgprop.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,10 @@


class EnumProperty(object):
__slots__ = ()

def __init__(self, *args, **kwargs):
raise NotImplementedError


class MessageProperty(object):
__slots__ = ()

def __init__(self, *args, **kwargs):
raise NotImplementedError
23 changes: 3 additions & 20 deletions google/cloud/ndb/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,6 @@ class PropertyOrder(object):
or not (ascending). Default is False.
"""

__slots__ = ["name", "reverse"]

def __init__(self, name, reverse=False):
self.name = name
self.reverse = reverse
Expand Down Expand Up @@ -227,8 +225,6 @@ class RepeatedStructuredPropertyPredicate(object):
contain a value for each key in ``match_keys``.
"""

__slots__ = ["name", "match_keys", "match_values"]

def __init__(self, name, match_keys, entity_pb):
self.name = name
self.match_keys = match_keys
Expand Down Expand Up @@ -305,8 +301,6 @@ class Parameter(ParameterizedThing):
TypeError: If the ``key`` is not a string or integer.
"""

__slots__ = ("_key",)

def __init__(self, key):
if not isinstance(key, six.integer_types + six.string_types):
raise TypeError(
Expand Down Expand Up @@ -411,8 +405,6 @@ class Node(object):

_multiquery = False

__slots__ = ()

def __new__(cls):
if cls is Node:
raise TypeError("Cannot instantiate Node, only a subclass.")
Expand Down Expand Up @@ -479,8 +471,6 @@ def resolve(self, bindings, used):
class FalseNode(Node):
"""Tree node for an always-failing filter."""

__slots__ = ()

def __eq__(self, other):
"""Equality check.
Expand Down Expand Up @@ -524,8 +514,6 @@ class ParameterNode(Node):
:class:`.ParameterizedFunction`.
"""

__slots__ = ("_prop", "_op", "_param")

def __new__(cls, prop, op, param):
# Avoid circular import in Python 2.7
from google.cloud.ndb import model
Expand Down Expand Up @@ -643,7 +631,9 @@ class FilterNode(Node):
:class:`frozenset`)
"""

__slots__ = ("_name", "_opsymbol", "_value")
_name = None
_opsymbol = None
_value = None

def __new__(cls, name, opsymbol, value):
# Avoid circular import in Python 2.7
Expand Down Expand Up @@ -754,8 +744,6 @@ class PostFilterNode(Node):
the given filter.
"""

__slots__ = ("predicate",)

def __new__(cls, predicate):
instance = super(PostFilterNode, cls).__new__(cls)
instance.predicate = predicate
Expand Down Expand Up @@ -826,8 +814,6 @@ class _BooleanClauses(object):
with the current boolean expression via ``AND`` or ``OR``.
"""

__slots__ = ("name", "combine_or", "or_parts")

def __init__(self, name, combine_or):
self.name = name
self.combine_or = combine_or
Expand Down Expand Up @@ -919,8 +905,6 @@ class ConjunctionNode(Node):
expression.
"""

__slots__ = ("_nodes",)

def __new__(cls, *nodes):
if not nodes:
raise TypeError("ConjunctionNode() requires at least one node.")
Expand Down Expand Up @@ -1075,7 +1059,6 @@ class DisjunctionNode(Node):
"""

_multiquery = True
__slots__ = ("_nodes",)

def __new__(cls, *nodes):
if not nodes:
Expand Down
Loading

0 comments on commit a8b723b

Please sign in to comment.