Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python requires with alias #3957

Merged
merged 9 commits into from
Dec 3, 2018
10 changes: 8 additions & 2 deletions conans/client/graph/python_requires.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from collections import namedtuple

from conans.client.loader import parse_conanfile
from conans.client.loader import parse_conanfile, parse_module
from conans.client.recorder.action_recorder import ActionRecorder
from conans.model.ref import ConanFileReference
from conans.model.requires import Requirement
Expand Down Expand Up @@ -34,7 +34,13 @@ def __call__(self, require):
result = self._proxy.get_recipe(r, False, False, remote_name=None,
recorder=ActionRecorder())
path, _, _, reference = result
module, _ = parse_conanfile(path)
module, filename = parse_conanfile(path)

# Check for alias
conanfile = parse_module(module, filename)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would want to use here the ConanFileLoader class, but it requires a python_requires member (and it is where I am!), see instantiation in conan_api.py here:

        python_requires = ConanPythonRequire(self._proxy, resolver)
        self._loader = ConanFileLoader(self._runner, self._user_io.out, python_requires)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'll prefer to really have an injected loader object into PythonRequires (yes, runtime cycle between objects).
We could make ConanFileLoader be the one that really instantiates PythonRequires object, passing a referent to itself to it.

This can't go to 1.9.2, a bit risky in my opinion.

if getattr(conanfile, "alias", None):
module = self.__call__(require=conanfile.alias) # Will register also the aliased

python_require = PythonRequire(reference, module)
self._cached_requires[require] = python_require
self._requires.append(python_require)
Expand Down
4 changes: 2 additions & 2 deletions conans/client/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def __init__(self, runner, output, python_requires):
def load_class(self, conanfile_path):
loaded, filename = parse_conanfile(conanfile_path)
try:
conanfile = _parse_module(loaded, filename)
conanfile = parse_module(loaded, filename)
conanfile.python_requires = self._python_requires.requires
return conanfile
except Exception as e: # re-raise with file name
Expand Down Expand Up @@ -188,7 +188,7 @@ def load_virtual(self, references, processed_profile, scope_options=True,
return conanfile


def _parse_module(conanfile_module, module_id):
def parse_module(conanfile_module, module_id):
""" Parses a python in-memory module, to extract the classes, mainly the main
class defining the Recipe, but also process possible existing generators
@param conanfile_module: the module to be processed
Expand Down
14 changes: 14 additions & 0 deletions conans/test/integration/python_build_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,20 @@ def package_info(self):
client.save({"conanfile.py": conanfile})
client.run("export . MyConanfileBase/1.1@lasote/testing")

def with_alias_test(self):
client = TestClient(servers={"default": TestServer()},
users={"default": [("lasote", "mypass")]})
self._define_base(client)
client.run("alias MyConanfileBase/LATEST@lasote/testing MyConanfileBase/1.1@lasote/testing")

reuse = """from conans import python_requires
base = python_requires("MyConanfileBase/LATEST@lasote/testing")
class PkgTest(base.MyConanfileBase):
pass
"""
client.save({"conanfile.py": reuse}, clean_first=True)
client.run("create . Pkg/0.1@lasote/testing")

def reuse_test(self):
client = TestClient(servers={"default": TestServer()},
users={"default": [("lasote", "mypass")]})
Expand Down