SatelliteQE/robottelo — pull request #1615 by Ichimonji10 (2014-10-23 17:22:26+00:00)
Title: Drop booby, let nil values be submitted to API

Drop dependency on booby.

* Make class `Entity` inherit directly from `object`. Define method
`Entity.__init__`, and make that method handle whatever instantiation logic
booby formerly did. (but better!)
* Make class `Field` inherit directly from `object`. Define method
`Field.__init__`, and make that method capable of recording the instance
attributes `required`, `choices`, `default` and `null`.

This has several positive effects. First, fewer methods are necessary.

* Drop method `robottelo.factory.field_is_required`. The `required` attribute is
guaranteed to exist on all `Field` classes, so it is possible to just call
`SomeField.required` instead.
* Drop method `robottelo.orm.Entity.get_values`. It is now possible to just call
`vars(SomeEntity)` instead.

Second, all classes inheriting from `Entity` and `Field` have a more
comprehensible inheritance tree and sane instantiation process. An `update`
method is no longer inherited from booby, which means that an
`EntityUpdateMixin` may finally be created without MRO issues, and no metaclass
magic is used. Incidentally, a pylint error stating that many `Entity`
subclasses have too many ancestors is now gone.

Third, it is now possible to pass `None` values into classes. This fixes #1082.
Formerly, this behaviour was exhibited:

>>> from robottelo.entities import Organization
>>> for org in (
... Organization(name='ACME'),
... Organization(name='ACME', description=None),
... Organization(name='ACME', description='Better than ACNE!')
... ):
... org.get_values()
...
{'name': 'ACME'}
{'name': 'ACME'}
{'description': 'Better than ACNE!', 'name': 'ACME'}

This is the new behaviour:

>>> from robottelo.entities import Organization
>>> for org in (
... Organization(name='ACME'),
... Organization(name='ACME', description=None),
... Organization(name='ACME', description='Better than ACNE!')
... ):
... vars(org)
...
{'name': 'ACME'}
{'description': None, 'name': 'ACME'}
{'description': 'Better than ACNE!', 'name': 'ACME'}

Drop a `pylint:disable` directive from module `robottelo.entities`. All classes
inheriting from `Entity` now have an `__init__` method.

These changes do not appear to break anything. Module `test_multiple_paths` is
in good shape:

$ python -m unittest tests.foreman.api.test_multiple_paths
…
----------------------------------------------------------------------
Ran 238 tests in 154.352s

FAILED (failures=1, skipped=62)

The one failed test relates to activation keys, which is a known issue. `make
test-robottelo` also succeeds.