Skip to content

Commit

Permalink
Merge pull request #1709 from jgsogo/doc/python_requires_extend
Browse files Browse the repository at this point in the history
Add 'python_requires_extend' to the reference. Minor changes to pyreqs docs
  • Loading branch information
czoido authored Jun 9, 2020
2 parents be71e39 + 5fb0e84 commit 5b9cc54
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 11 deletions.
28 changes: 20 additions & 8 deletions extending/python_requires.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ code that we want to reuse.
$ conan export . pyreq/0.1@user/channel
We can reuse the above recipe functionality with:
We can reuse the above recipe functionality declaring the dependency in the ``python_requires``
attribute and we can access its members using ``self.python_requires["<name>"].module``:

.. code-block:: python
Expand All @@ -65,7 +66,7 @@ We can reuse the above recipe functionality with:
def build(self):
v = self.python_requires["pyreq"].module.myvar # v will be 123
f = self.python_requires["pyreq"].module.myfunct() # f will be 234
self.output.info("%s,%s" % (v, f))
self.output.info("%s, %s" % (v, f))
.. code-block:: bash
Expand All @@ -92,7 +93,8 @@ to address the functionality:
Extending base classes
----------------------

A common use case would be to reuse methods of a base class. So we could write a recipe like:
A common use case would be to declare a base class with methods we want to reuse in several
recipes via inheritance. We'd write this base class in a python-requires package:

.. code-block:: python
Expand All @@ -116,14 +118,22 @@ And make it available for reuse with:

.. code-block:: bash
$ conan export . user/channel
$ conan export . pyreq/0.1@user/channel
Note that there are two classes in the recipe file:

* ``MyBase`` is the one intended for inheritance and doesn't extend ``ConanFile``.
* ``PyReq`` is the one that defines the current package being exported, it is the recipe
for the reference ``pyreq/0.1@user/channel``.

Note that there are 2 classes, ``MyBase`` is the one intended for inheritance, and do not
extend ``ConanFile``. The other ``PyReq`` is the one that defines the current package being
exported.

Now, other packages, could ``python_require`` it, and inherit from ``MyBase`` class with:
Once the package with the base class we want to reuse is available we can use it in other
recipes to inherit the functionality from that base class. We'd need to declare the
``python_requires`` as we did before and we'd need to tell Conan the base classes to use
in the attribute ``python_requires_extend``. Here our recipe will inherit from the
class ``MyBase``:


.. code-block:: python
Expand All @@ -134,6 +144,7 @@ Now, other packages, could ``python_require`` it, and inherit from ``MyBase`` cl
python_requires_extend = "pyreq.MyBase"
The resulting inheritance is equivalent to declare our ``Pkg`` class as ``class Pkg(pyreq.MyBase, ConanFile)``.
So creating the package we can see how the methods from the base class are reused:

.. code-block:: bash
Expand All @@ -146,6 +157,7 @@ So creating the package we can see how the methods from the base class are reuse
pkg/0.1@user/channel: My cool package_info!
...
If there is extra logic needed to extend from a base class, like composing the base class settings
with the current recipe, the ``init()`` method can be used for it:

Expand Down
26 changes: 26 additions & 0 deletions reference/conanfile/attributes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,32 @@ Its basic syntax is:
Read more about this attribute in :ref:`python_requires`


python_requires_extend
----------------------

.. warning::

This is an **experimental** feature subject to breaking changes in future releases.


This class attribute defines one or more classes that will be injected in runtime as base classes of
the recipe class. Syntax for each of these classes should be a string like ``pyreq.MyConanfileBase``
where the ``pyreq`` is the name of a ``python_requires`` and ``MyConanfileBase`` is the name of the class
to use.

.. code-block:: python
from conans import ConanFile
class Pkg(ConanFile):
python_requires = "pyreq/0.1@user/channel", "utils/0.1@user/channel"
python_requires_extend = "pyreq.MyConanfileBase", "utils.UtilsBase" # class/es to inject
Read more about this attribute in :ref:`python_requires`


.. _conandata_attribute:

conan_data
Expand Down
11 changes: 8 additions & 3 deletions reference/conanfile/methods.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1071,24 +1071,29 @@ The ``deploy()`` method is designed to work on a package that is installed direc
> pkg/0.1@user/testing deploy(): Copied 1 '.dll' files: mylib.dll
> pkg/0.1@user/testing deploy(): Copied 1 '.exe' files: myexe.exe
All other packages and dependencies, even transitive dependencies of "pkg/0.1@user/testing" will not be deployed, it is the responsibility
All other packages and dependencies, even transitive dependencies of ``pkg/0.1@user/testing`` will not be deployed, it is the responsibility
of the installed package to deploy what it needs from its dependencies.

.. _method_init:

init()
------

This is an optional method for initializing conanfile values, designed for inheritance from ``python_requires``.
This is an optional method for initializing conanfile values, designed for inheritance from :ref:`python requires <python_requires>`.
Assuming we have a ``base/1.1@user/testing`` recipe:

.. code-block:: python
class MyConanfileBase(ConanFile):
class MyConanfileBase(object):
license = "MyLicense"
settings = "os", # tuple!
class PyReq(ConanFile):
name = "base"
version = "1.1"
We could reuse and inherit from it with:

.. code-block:: python
Expand Down

0 comments on commit 5b9cc54

Please sign in to comment.