Skip to content

Commit a316b6f

Browse files
committed
fix(ndb): replace asserts in production code with explicit checks
1 parent ec2312c commit a316b6f

File tree

3 files changed

+56
-28
lines changed

3 files changed

+56
-28
lines changed

packages/google-cloud-ndb/google/cloud/ndb/_datastore_query.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,10 @@ def has_next_async(self):
342342
if self._batch is None:
343343
yield self._next_batch() # First time
344344

345-
assert self._batch is not None
346-
assert self._index is not None
345+
if self._batch is None:
346+
raise TypeError("self._batch cannot be None")
347+
if self._index is None:
348+
raise TypeError("self._index cannot be None")
347349
if self._index < len(self._batch):
348350
raise tasklets.Return(True)
349351

@@ -425,8 +427,10 @@ def next(self):
425427
self._cursor_before = None
426428
raise StopIteration
427429

428-
assert self._batch is not None
429-
assert self._index is not None
430+
if self._batch is None:
431+
raise TypeError("self._batch cannot be None")
432+
if self._index is None:
433+
raise TypeError("self._index cannot be None")
430434
# Won't block
431435
next_result = self._batch[self._index]
432436
self._index += 1
@@ -560,7 +564,8 @@ def next(self):
560564
if not self.has_next():
561565
raise StopIteration()
562566

563-
assert self._next_result is not None
567+
if self._next_result is None:
568+
raise TypeError("self._next_result cannot be None")
564569
# Won't block
565570
next_result = self._next_result
566571
self._next_result = None
@@ -725,7 +730,8 @@ def next(self):
725730
if not self.has_next():
726731
raise StopIteration()
727732

728-
assert self._next_result is not None
733+
if self._next_result is None:
734+
raise TypeError("self._next_result cannot be None")
729735
# Won't block
730736
next_result = self._next_result
731737
self._next_result = None

packages/google-cloud-ndb/google/cloud/ndb/_gql.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,8 @@ def _AddProcessedParameterFilter(self, identifier, condition, operator, paramete
409409
if identifier.lower() == "ancestor":
410410
self._has_ancestor = True
411411
filter_rule = (self._ANCESTOR, "is")
412-
assert condition.lower() == "is"
412+
if condition.lower() != "is":
413+
raise ValueError("condition must be 'is'")
413414

414415
if operator == "list" and condition.lower() not in ["in", "not_in"]:
415416
self._Error("Only IN can process a list of values, given '%s'" % condition)

packages/google-cloud-ndb/google/cloud/ndb/model.py

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,8 @@ def new_entity(key):
611611
subvalue = value
612612
value = structprop._get_base_value(entity)
613613
if value in (None, []): # empty list for repeated props
614-
assert structprop._model_class is not None
614+
if structprop._model_class is None:
615+
raise TypeError("structprop._model_class cannot be None")
615616
kind = structprop._model_class._get_kind()
616617
key = key_module.Key(kind, None)
617618
if structprop._repeated:
@@ -642,7 +643,8 @@ def new_entity(key):
642643
# the other entries in the value list
643644
while len(subvalue) > len(value):
644645
# Need to make some more subentities
645-
assert structprop._model_class is not None
646+
if structprop._model_class is None:
647+
raise TypeError("structprop._model_class cannot be None")
646648
expando_kind = structprop._model_class._get_kind()
647649
expando_key = key_module.Key(expando_kind, None)
648650
value.append(new_entity(expando_key._key))
@@ -2055,7 +2057,8 @@ def _legacy_deserialize(self, entity, p, unused_depth=1):
20552057
if self._repeated:
20562058
if self._has_value(entity):
20572059
value = self._retrieve_value(entity)
2058-
assert isinstance(value, list), repr(value)
2060+
if not isinstance(value, list):
2061+
raise TypeError(f"Expected list, got {type(value)}")
20592062
value.append(val)
20602063
else:
20612064
# We promote single values to lists if we are a list property
@@ -4161,7 +4164,8 @@ def _get_for_dict(self, entity):
41614164

41624165
def __getattr__(self, attrname):
41634166
"""Dynamically get a subproperty."""
4164-
assert self._model_class is not None
4167+
if self._model_class is None:
4168+
raise TypeError("self._model_class cannot be None")
41654169
# Optimistically try to use the dict key.
41664170
prop = self._model_class._properties.get(attrname)
41674171

@@ -4180,7 +4184,8 @@ def __getattr__(self, attrname):
41804184
)
41814185

41824186
prop_copy = copy.copy(prop)
4183-
assert self._name is not None
4187+
if self._name is None:
4188+
raise TypeError("self._name cannot be None")
41844189
prop_copy._name = self._name + "." + prop_copy._name
41854190

41864191
# Cache the outcome, so subsequent requests for the same attribute
@@ -4211,7 +4216,8 @@ def _comparison(self, op, value):
42114216
value = self._do_validate(value)
42124217
filters = []
42134218
match_keys = []
4214-
assert self._model_class is not None
4219+
if self._model_class is None:
4220+
raise TypeError("self._model_class cannot be None")
42154221
for prop_name, prop in self._model_class._properties.items():
42164222
subvalue = prop._get_value(value)
42174223
if prop._repeated:
@@ -4264,7 +4270,8 @@ def _IN(self, value, server_op=None):
42644270
IN = _IN
42654271

42664272
def _validate(self, value):
4267-
assert self._model_class is not None
4273+
if self._model_class is None:
4274+
raise TypeError("self._model_class cannot be None")
42684275
if isinstance(value, dict):
42694276
# A dict is assumed to be the result of a _to_dict() call.
42704277
return self._model_class(**value)
@@ -4325,7 +4332,8 @@ def _check_property(self, rest=None, require_indexed=True):
43254332
raise InvalidPropertyError(
43264333
"Structured property %s requires a subproperty" % self._name
43274334
)
4328-
assert self._model_class is not None
4335+
if self._model_class is None:
4336+
raise TypeError("self._model_class cannot be None")
43294337
self._model_class._check_properties([rest], require_indexed=require_indexed)
43304338

43314339
def _to_base_type(self, value):
@@ -4340,7 +4348,8 @@ def _to_base_type(self, value):
43404348
Raises:
43414349
TypeError: If ``value`` is not the correct ``Model`` type.
43424350
"""
4343-
assert self._model_class is not None
4351+
if self._model_class is None:
4352+
raise TypeError("self._model_class cannot be None")
43444353
if not isinstance(value, self._model_class):
43454354
raise TypeError(
43464355
"Cannot convert to protocol buffer. Expected {} value; "
@@ -4475,7 +4484,8 @@ def _validate(self, value):
44754484
Raises:
44764485
exceptions.BadValueError: If ``value`` is not a given class.
44774486
"""
4478-
assert self._model_class is not None
4487+
if self._model_class is None:
4488+
raise TypeError("self._model_class cannot be None")
44794489
if isinstance(value, dict):
44804490
# A dict is assumed to be the result of a _to_dict() call.
44814491
return self._model_class(**value)
@@ -4504,7 +4514,8 @@ def _to_base_type(self, value):
45044514
Raises:
45054515
TypeError: If ``value`` is not the correct ``Model`` type.
45064516
"""
4507-
assert self._model_class is not None
4517+
if self._model_class is None:
4518+
raise TypeError("self._model_class cannot be None")
45084519
if not isinstance(value, self._model_class):
45094520
raise TypeError(
45104521
"Cannot convert to bytes expected {} value; "
@@ -4522,7 +4533,8 @@ def _from_base_type(self, value):
45224533
Returns:
45234534
The converted value with given class.
45244535
"""
4525-
assert self._model_class is not None
4536+
if self._model_class is None:
4537+
raise TypeError("self._model_class cannot be None")
45264538
if isinstance(value, bytes):
45274539
pb = entity_pb2.Entity()
45284540
pb._pb.MergeFromString(value)
@@ -4699,7 +4711,8 @@ def _get_value(self, entity):
46994711
# UnprojectedPropertyError which will just bubble up.
47004712
if entity._projection and self._name in entity._projection:
47014713
return super(ComputedProperty, self)._get_value(entity)
4702-
assert self._func is not None
4714+
if self._func is None:
4715+
raise TypeError("self._func cannot be None")
47034716
value = self._func(entity)
47044717
self._store_value(entity, value)
47054718
return value
@@ -5035,7 +5048,8 @@ def _fake_property(self, p, next, indexed=True):
50355048
# A custom 'meaning' for compressed properties.
50365049
_MEANING_URI_COMPRESSED = "ZLIB"
50375050
self._clone_properties()
5038-
assert self._properties is not None
5051+
if self._properties is None:
5052+
raise TypeError("self._properties cannot be None")
50395053
prop: Property
50405054
if p.name() != next.encode("utf-8") and not p.name().endswith(
50415055
b"." + next.encode("utf-8")
@@ -5349,13 +5363,15 @@ def _check_properties(cls, property_names, require_indexed=True):
53495363
InvalidPropertyError: if one of the properties is invalid.
53505364
AssertionError: if the argument is not a list or tuple of strings.
53515365
"""
5352-
assert isinstance(property_names, (list, tuple)), repr(property_names)
5366+
if not isinstance(property_names, (list, tuple)):
5367+
raise TypeError(f"Expected list or tuple, got {type(property_names)}")
53535368
for name in property_names:
53545369
if "." in name:
53555370
name, rest = name.split(".", 1)
53565371
else:
53575372
rest = None
5358-
assert cls._properties is not None
5373+
if cls._properties is None:
5374+
raise TypeError("cls._properties cannot be None")
53595375
prop = cls._properties.get(name)
53605376
if prop is None:
53615377
raise InvalidPropertyError("Unknown property {}".format(name))
@@ -6199,7 +6215,8 @@ def _to_dict(self, include=None, exclude=None):
61996215
to exclude. Default is to not exclude any names.
62006216
"""
62016217
values = {}
6202-
assert self._properties is not None
6218+
if self._properties is None:
6219+
raise TypeError("self._properties cannot be None")
62036220
for prop in self._properties.values():
62046221
name = prop._code_name
62056222
if include is not None and name not in include:
@@ -6221,7 +6238,8 @@ def _to_dict(self, include=None, exclude=None):
62216238
def _code_name_from_stored_name(cls, name):
62226239
"""Return the code name from a property when it's different from the
62236240
stored name. Used in deserialization from datastore."""
6224-
assert cls._properties is not None
6241+
if cls._properties is None:
6242+
raise TypeError("cls._properties cannot be None")
62256243
if name in cls._properties:
62266244
return cls._properties[name]._code_name
62276245

@@ -6323,14 +6341,16 @@ def _set_attributes(self, kwds):
63236341
setattr(self, name, value)
63246342

63256343
def __getattr__(self, name):
6326-
assert self._properties is not None
6344+
if self._properties is None:
6345+
raise TypeError("self._properties cannot be None")
63276346
prop = self._properties.get(name)
63286347
if prop is None:
63296348
return super(Expando, self).__getattribute__(name)
63306349
return prop._get_value(self)
63316350

63326351
def __setattr__(self, name, value):
6333-
assert self._properties is not None
6352+
if self._properties is None:
6353+
raise TypeError("self._properties cannot be None")
63346354
if (
63356355
name.startswith("_")
63366356
or isinstance(getattr(self.__class__, name, None), (Property, property))
@@ -6365,7 +6385,8 @@ def __setattr__(self, name, value):
63656385
prop._set_value(self, value)
63666386

63676387
def __delattr__(self, name):
6368-
assert self._properties is not None
6388+
if self._properties is None:
6389+
raise TypeError("self._properties cannot be None")
63696390
if name.startswith("_") or isinstance(
63706391
getattr(self.__class__, name, None), (Property, property)
63716392
):

0 commit comments

Comments
 (0)