397 def __setattr__(self, par, val):
398 """Sets an object attribute or relationship.
399
400 This method overrides the default setattr method, so it can apply
401 existence and type verification on class attributes. If the attribute
402 to be set starts with '__', or the passed value is None,
403 no verification is performed. If the value to set an attribute is a
404 list, the type verification is performed in every component of that
405 list.
406
407 N.B.: This method takes a reference to the object being passed. It does
408 not copy the value, so, if you do a.b = c, and then you apply changes
409 to 'c', these changes will be also applied to 'a.b'.
410
411 Parameters:
412
413 par -- The name of the parameter (attribute or relationship)
414
415 val -- The value that will be attributed to 'par'.
416
417 Raises AttributeError if the parameter does not exist.
418
419 Raises ValueError if the value you passed cannot be coerced to a
420 compatible OKS python type for the attribute or relationship you are
421 trying to set.
422 """
423 from .schema import coerce, check_relation, check_cardinality
424 from . import dalproperty
425
426
427 if par[0:2] == '__':
428 self.__dict__[par] = val
429 return
430
431
432 if par == 'id':
433 if isinstance(val, str):
434 prop = getattr(self.__class__, par)
435 prop.__set__(self, val)
436 self.__reset_identity__()
437 return
438 else:
439 raise ValueError(
440 'The "id" attribute of a DAL object must be a string')
441
442 if par in list(self.__schema__['attribute'].keys()):
443
444
445 if val is None:
446 self.__dict__[par] = val
447
448 try:
449 if val is not None:
450 check_cardinality(val, self.__schema__['attribute'][par])
451 if self.__schema__['attribute'][par]['multivalue']:
452 result = \
453 [coerce(v, self.__schema__['attribute'][par])
454 for v in val]
455 else:
456 result = coerce(val, self.__schema__['attribute'][par])
457 else:
458 result = val
459
460 try:
461 prop = getattr(self.__class__, par)
462
463 except AttributeError:
464
465 prop = property(dalproperty._return_attribute(par),
466 dalproperty._assign_attribute(par))
467 setattr(self.__class__, par, prop)
468
469 prop.__set__(self, result)
470
471 except ValueError as e:
472 raise ValueError('Problems setting attribute "%s" '
473 'at object %s: %s' %
474 (par, self.fullName(), str(e)))
475
476 elif par in list(self.__schema__['relation'].keys()):
477
478 try:
479
480 if val is not None:
481 check_cardinality(val, self.__schema__['relation'][par])
482
483 tmpval = \
484 val if self.__schema__[
485 'relation'][par]['multivalue'] else [val]
486 for v in tmpval:
487 check_relation(v, self.__schema__['relation'][par])
488
489 try:
490 prop = getattr(self.__class__, par)
491
492 except AttributeError:
493
494 multi = self.__schema__['relation'][par]['multivalue']
495 prop = property(
496 dalproperty._return_relation(par, multi=multi),
497 dalproperty._assign_relation(par))
498 setattr(self.__class__, par, prop)
499
500 prop.__set__(self, val)
501 self.__touched__.append(par)
502
503 except ValueError as e:
504 raise ValueError('Problems setting relation "%s" at '
505 'object %s: %s' %
506 (par, self.fullName(), str(e)))
507
508 else:
509 raise AttributeError('Parameter "%s" is not ' % par +
510 'part of class "%s" or any of its '
511 'parent classes' %
512 (self.className()))
513
514