diff --git a/component/__manifest__.py b/component/__manifest__.py index 1dbea4500..99faa0b4a 100644 --- a/component/__manifest__.py +++ b/component/__manifest__.py @@ -5,13 +5,18 @@ "name": "Components", "summary": "Add capabilities to register and use decoupled components," " as an alternative to model classes", - "version": "13.0.1.0.1", + "version": "14.0.1.0.0", "author": "Camptocamp," "Odoo Community Association (OCA)", "website": "https://github.com/OCA/connector", "license": "LGPL-3", "category": "Generic Modules", "depends": ["base"], - "external_dependencies": {"python": ["cachetools"]}, + "external_dependencies": { + "python": [ + "cachetools", + "mock", + ] + }, "installable": True, "development_status": "Stable", "maintainers": ["guewen"], diff --git a/component/builder.py b/component/builder.py index d0f0399a6..9f5cd5f9b 100644 --- a/component/builder.py +++ b/component/builder.py @@ -16,7 +16,7 @@ class ComponentBuilder(models.AbstractModel): - """ Build the component classes + """Build the component classes And register them in a global registry. @@ -79,7 +79,7 @@ def build_registry(self, components_registry, states=None, exclude_addons=None): self.load_components(module.name, components_registry=components_registry) def load_components(self, module, components_registry=None): - """ Build every component known by MetaComponent for an odoo module + """Build every component known by MetaComponent for an odoo module The final component (composed by all the Component classes in this module) will be pushed into the registry. diff --git a/component/components/base.py b/component/components/base.py index 7c4a63328..0996ac03d 100644 --- a/component/components/base.py +++ b/component/components/base.py @@ -5,7 +5,7 @@ class BaseComponent(AbstractComponent): - """ This is the base component for every component + """This is the base component for every component It is implicitely inherited by all components. diff --git a/component/core.py b/component/core.py index 533a08636..a70193d10 100644 --- a/component/core.py +++ b/component/core.py @@ -61,7 +61,7 @@ class ComponentDatabases(dict): class ComponentRegistry(object): - """ Store all the components and allow to find them using criteria + """Store all the components and allow to find them using criteria The key is the ``_name`` of the components. @@ -103,7 +103,7 @@ def load_components(self, module): @cachedmethod(operator.attrgetter("_cache")) def lookup(self, collection_name=None, usage=None, model_name=None): - """ Find and return a list of components for a usage + """Find and return a list of components for a usage If a component is not registered in a particular collection (no ``_collection``), it will be returned in any case (as far as @@ -170,7 +170,7 @@ def lookup(self, collection_name=None, usage=None, model_name=None): class WorkContext(object): - """ Transport the context required to work with components + """Transport the context required to work with components It is propagated through all the components, so any data or instance (like a random RPC client) that need @@ -267,14 +267,14 @@ def __init__( @property def env(self): - """ Return the current Odoo env + """Return the current Odoo env This is the environment of the current collection. """ return self.collection.env def work_on(self, model_name=None, collection=None): - """ Create a new work context for another model keeping attributes + """Create a new work context for another model keeping attributes Used when one need to lookup components for another model. """ @@ -295,7 +295,7 @@ def _component_class_by_name(self, name): return component_class def component_by_name(self, name, model_name=None): - """ Return a component by its name + """Return a component by its name If the component exists, an instance of it will be returned, initialized with the current :class:`WorkContext`. @@ -354,7 +354,7 @@ def _lookup_components(self, usage=None, model_name=None): return [cls for cls in component_classes if cls._component_match(self)] def component(self, usage=None, model_name=None): - """ Find a component by usage and model for the current collection + """Find a component by usage and model for the current collection It searches a component using the rules of :meth:`ComponentRegistry.lookup`. When a component is found, @@ -417,7 +417,7 @@ def component(self, usage=None, model_name=None): return component_classes[0](work_context) def many_components(self, usage=None, model_name=None): - """ Find many components by usage and model for the current collection + """Find many components by usage and model for the current collection It searches a component using the rules of :meth:`ComponentRegistry.lookup`. When components are found, they @@ -444,7 +444,7 @@ def __str__(self): class MetaComponent(type): - """ Metaclass for Components + """Metaclass for Components Every new :class:`Component` will be added to ``_modules_components``, that will be used by the component builder. @@ -487,7 +487,7 @@ def apply_on_models(cls): class AbstractComponent(object, metaclass=MetaComponent): - """ Main Component Model + """Main Component Model All components have a Python inheritance either on :class:`AbstractComponent` or either on :class:`Component`. @@ -665,7 +665,7 @@ def __init__(self, work_context): @classmethod def _component_match(cls, work): - """ Evaluated on candidate components + """Evaluated on candidate components When a component lookup is done and candidate(s) have been found for a usage, a final call is done on this method. @@ -700,21 +700,21 @@ def model(self): return self.work.model def component_by_name(self, name, model_name=None): - """ Return a component by its name + """Return a component by its name Shortcut to meth:`~WorkContext.component_by_name` """ return self.work.component_by_name(name, model_name=model_name) def component(self, usage=None, model_name=None): - """ Return a component + """Return a component Shortcut to meth:`~WorkContext.component` """ return self.work.component(usage=usage, model_name=model_name) def many_components(self, usage=None, model_name=None): - """ Return several components + """Return several components Shortcut to meth:`~WorkContext.many_components` """ @@ -727,7 +727,7 @@ def __str__(self): @classmethod def _build_component(cls, registry): - """ Instantiate a given Component in the components registry. + """Instantiate a given Component in the components registry. This method is called at the end of the Odoo's registry build. The caller is :meth:`component.builder.ComponentBuilder.load_components`. @@ -869,8 +869,7 @@ def _build_component_check_base(cls, extend_cls): @classmethod def _build_component_check_parent(component_class, cls, parent_class): # noqa: B902 - """ Check whether ``model_class`` can inherit from ``parent_class``. - """ + """Check whether ``model_class`` can inherit from ``parent_class``.""" if component_class._abstract and not parent_class._abstract: msg = ( "In %s, the abstract Component %r cannot inherit " @@ -880,7 +879,7 @@ def _build_component_check_parent(component_class, cls, parent_class): # noqa: @classmethod def _complete_component_build(cls): - """ Complete build of the new component class + """Complete build of the new component class After the component has been built from its bases, this method is called, and can be used to customize the class before it can be used. @@ -891,7 +890,7 @@ def _complete_component_build(cls): class Component(AbstractComponent): - """ Concrete Component class + """Concrete Component class This is the class you inherit from when you want your component to be registered in the component collections. diff --git a/component/models/collection.py b/component/models/collection.py index 9b21fd1af..a1e93a09d 100644 --- a/component/models/collection.py +++ b/component/models/collection.py @@ -21,7 +21,7 @@ class Collection(models.AbstractModel): - """ The model on which components are subscribed + """The model on which components are subscribed It would be for instance the ``backend`` for the connectors. @@ -61,7 +61,7 @@ def run(self, magento_id): @contextmanager def work_on(self, model_name, **kwargs): - """ Entry-point for the components, context manager + """Entry-point for the components, context manager Start a work using the components on the model. Any keyword argument will be assigned to the work context. diff --git a/component/tests/common.py b/component/tests/common.py index 510237a0e..8b8a24a68 100644 --- a/component/tests/common.py +++ b/component/tests/common.py @@ -53,7 +53,7 @@ def notready(): class TransactionComponentCase(common.TransactionCase, ComponentMixin): - """ A TransactionCase that loads all the components + """A TransactionCase that loads all the components It it used like an usual Odoo's TransactionCase, but it ensures that all the components of the current addon and its dependencies @@ -75,7 +75,7 @@ def setUp(self): class SavepointComponentCase(common.SavepointCase, ComponentMixin): - """ A SavepointCase that loads all the components + """A SavepointCase that loads all the components It it used like an usual Odoo's SavepointCase, but it ensures that all the components of the current addon and its dependencies @@ -99,7 +99,7 @@ def setUp(self): class ComponentRegistryCase( unittest.TestCase, common.MetaCase("DummyCase", (object,), {}) ): - """ This test case can be used as a base for writings tests on components + """This test case can be used as a base for writings tests on components This test case is meant to test components in a special component registry, where you want to have maximum control on which components are loaded diff --git a/component/tests/test_build_component.py b/component/tests/test_build_component.py index 284513802..e76c3fdb7 100644 --- a/component/tests/test_build_component.py +++ b/component/tests/test_build_component.py @@ -9,7 +9,7 @@ class TestBuildComponent(ComponentRegistryCase): - """ Test build of components + """Test build of components All the tests in this suite are based on the same principle with variations: diff --git a/component/tests/test_component.py b/component/tests/test_component.py index e88457aae..04d8f08af 100644 --- a/component/tests/test_component.py +++ b/component/tests/test_component.py @@ -10,7 +10,7 @@ class TestComponent(TransactionComponentRegistryCase): - """ Test usage of components + """Test usage of components These tests are a bit more broad that mere unit tests. We test the chain odoo Model -> generate a WorkContext instance -> Work @@ -154,8 +154,7 @@ def test_component_by_usage_other_model_env(self): self.assertEqual(self.env["res.users"], comp.model) def test_component_error_several(self): - """ Use component(usage=...) when more than one generic component match - """ + """Use component(usage=...) when more than one generic component match""" # we create 1 new Component with _usage 'for.test', in the same # collection and no _apply_on, and we remove the _apply_on of component # 1 so they are generic components for a collection @@ -182,8 +181,7 @@ class Component1(Component): base.component(usage="for.test") def test_component_error_several_same_model(self): - """ Use component(usage=...) when more than one component match a model - """ + """Use component(usage=...) when more than one component match a model""" # we create a new Component with _usage 'for.test', in the same # collection and no _apply_on class Component3(Component): @@ -202,7 +200,7 @@ class Component3(Component): base.component(usage="for.test") def test_component_specific_model(self): - """ Use component(usage=...) when more than one component match but + """Use component(usage=...) when more than one component match but only one for the specific model""" # we create a new Component with _usage 'for.test', in the same # collection and no _apply_on. This is a generic component for the @@ -225,10 +223,10 @@ class Component3(Component): # override it only for a given model. So in this case, the final # component is component1. comp = base.component(usage="for.test") - self.assertEquals("component1", comp._name) + self.assertEqual("component1", comp._name) def test_component_specific_collection(self): - """ Use component(usage=...) when more than one component match but + """Use component(usage=...) when more than one component match but only one for the specific collection""" # we create a new Component with _usage 'for.test', without collection # and no _apply_on @@ -248,10 +246,10 @@ class Component3(Component): # component3 must be ignored since a component (component1) exists # and is specificaly linked to the expected collection. comp = base.component(usage="for.test") - self.assertEquals("component1", comp._name) + self.assertEqual("component1", comp._name) def test_component_specific_collection_specific_model(self): - """ Use component(usage=...) when more than one component match but + """Use component(usage=...) when more than one component match but only one for the specific model and collection""" # we create a new Component with _usage 'for.test', without collection # and no _apply_on. This is a component generic for all collections and @@ -277,7 +275,7 @@ class Component3(Component): # collection and model. So in this case, the final component is # component1. comp = base.component(usage="for.test") - self.assertEquals("component1", comp._name) + self.assertEqual("component1", comp._name) def test_many_components(self): """ Use many_components(usage=...) on the same model """ @@ -348,7 +346,7 @@ def test_work_on_component(self): self.assertEqual("component1", comp._name) def test_work_on_many_components(self): - """ Check WorkContext.many_components() + """Check WorkContext.many_components() (shortcut to Component.many_components) """ diff --git a/component/tests/test_lookup.py b/component/tests/test_lookup.py index 16e35cd62..555111aef 100644 --- a/component/tests/test_lookup.py +++ b/component/tests/test_lookup.py @@ -7,7 +7,7 @@ class TestLookup(ComponentRegistryCase): - """ Test the ComponentRegistry + """Test the ComponentRegistry Tests in this testsuite mainly do: diff --git a/component/tests/test_work_on.py b/component/tests/test_work_on.py index 3865f2048..3ad1ced58 100644 --- a/component/tests/test_work_on.py +++ b/component/tests/test_work_on.py @@ -7,7 +7,7 @@ class TestWorkOn(TransactionComponentCase): - """ Test on WorkContext + """Test on WorkContext This model is mostly a container, so we check the access to the attributes and properties.