Skip to content

Commit

Permalink
Fix transitive python requires (#8604)
Browse files Browse the repository at this point in the history
* test transitive python requires

* moving test and fixing issue

* Add diamond test

Co-authored-by: memsharded <james@conan.io>
  • Loading branch information
danimtb and memsharded committed Mar 16, 2021
1 parent e4af39e commit 12fdc0b
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 12 deletions.
7 changes: 6 additions & 1 deletion conans/client/graph/python_requires.py
Expand Up @@ -54,7 +54,12 @@ def __getitem__(self, item):
try:
return self._pyrequires[item]
except KeyError:
raise ConanException("'%s' is not a python_require" % item)
# https://github.com/conan-io/conan/issues/8546
# Transitive pyrequires are accessed by inheritance derived classes
try:
return self._transitive[item]
except KeyError:
raise ConanException("'%s' is not a python_require" % item)

def __setitem__(self, key, value):
# single item assignment, direct
Expand Down
138 changes: 127 additions & 11 deletions conans/test/integration/py_requires/python_requires_test.py
Expand Up @@ -149,8 +149,8 @@ class MyConanfileBase(ConanFile):
self.assertIn("Pkg/0.1@user/testing: My cool package!", client.out)
self.assertIn("Pkg/0.1@user/testing: My cool package_info!", client.out)

def test_transitive_access_error(self):
# https://github.com/conan-io/conan/issues/5529
@staticmethod
def test_transitive_access():
client = TestClient()
client.save({"conanfile.py": GenConanfile()})
client.run("export . base/1.0@user/channel")
Expand All @@ -171,18 +171,18 @@ def build(self):
self.python_requires["base"]
""")
client.save({"conanfile.py": conanfile})
client.run("create . pkg/0.1@user/channel", assert_error=True)
self.assertIn("'base' is not a python_require", client.out)
client.run("create . pkg/0.1@user/channel")
assert "pkg/0.1@user/channel: Created package" in client.out

conanfile = textwrap.dedent("""
from conans import ConanFile
class Pkg(ConanFile):
python_requires = "helper/1.0@user/channel"
python_requires_extend = "base.HelloConan"
""")
from conans import ConanFile
class Pkg(ConanFile):
python_requires = "helper/1.0@user/channel"
python_requires_extend = "base.HelloConan"
""")
client.save({"conanfile.py": conanfile})
client.run("create . pkg/0.1@user/channel", assert_error=True)
self.assertIn("'base' is not a python_require", client.out)
client.run("create . pkg/0.1@user/channel")
assert "pkg/0.1@user/channel: Created package" in client.out

def test_multiple_requires_error(self):
client = TestClient()
Expand Down Expand Up @@ -853,3 +853,119 @@ def build_id(self):
self.assertIn("Pkg/0.1@user/testing: My cool build!", client.out)
self.assertIn("Pkg/0.1@user/testing: My cool package!", client.out)
self.assertIn("Pkg/0.1@user/testing: My cool package_info!", client.out)


def test_transitive_python_requires():
# https://github.com/conan-io/conan/issues/8546
client = TestClient()
conanfile = textwrap.dedent("""
from conans import ConanFile
myvar = 123
def myfunct():
return 234
class SharedFunction(ConanFile):
name = "shared-function"
version = "1.0"
""")
client.save({"conanfile.py": conanfile})
client.run("export . @user/channel")

conanfile = textwrap.dedent("""
from conans import ConanFile
class BaseClass(ConanFile):
name = "base-class"
version = "1.0"
python_requires = "shared-function/1.0@user/channel"
def build(self):
pyreqs = self.python_requires
v = pyreqs["shared-function"].module.myvar # v will be 123
f = pyreqs["shared-function"].module.myfunct() # f will be 234
self.output.info("%s, %s" % (v, f))
""")
client.save({"conanfile.py": conanfile})
client.run("export . user/channel")

conanfile = textwrap.dedent("""
from conans import ConanFile
class Consumer(ConanFile):
name = "consumer"
version = "1.0"
python_requires = "base-class/1.0@user/channel"
python_requires_extend = "base-class.BaseClass"
""")
client.save({"conanfile.py": conanfile})
client.run("create . @user/channel")
assert "consumer/1.0@user/channel: Calling build()\nconsumer/1.0@user/channel: 123, 234" in \
client.out


def test_transitive_diamond_python_requires():
client = TestClient()
conanfile = textwrap.dedent("""
from conans import ConanFile
myvar = 123
def myfunct():
return 234
class SharedFunction(ConanFile):
name = "shared-function"
version = "1.0"
""")
client.save({"conanfile.py": conanfile})
client.run("export . @user/channel")

conanfile = textwrap.dedent("""
from conans import ConanFile
myvar = 222
def myfunct():
return 2222
class SharedFunction2(ConanFile):
name = "shared-function2"
version = "1.0"
""")
client.save({"conanfile.py": conanfile})
client.run("export . @user/channel")

conanfile = textwrap.dedent("""
from conans import ConanFile
class BaseClass(ConanFile):
name = "base-class"
version = "1.0"
python_requires = "shared-function/1.0@user/channel", "shared-function2/1.0@user/channel"
def build(self):
pyreqs = self.python_requires
v = pyreqs["shared-function"].module.myvar # v will be 123
f = pyreqs["shared-function2"].module.myfunct() # f will be 2222
self.output.info("%s, %s" % (v, f))
""")
client.save({"conanfile.py": conanfile})
client.run("export . user/channel")

conanfile = textwrap.dedent("""
from conans import ConanFile
class BaseClass2(ConanFile):
name = "base-class2"
version = "1.0"
python_requires = "shared-function/1.0@user/channel", "shared-function2/1.0@user/channel"
def package(self):
pyreqs = self.python_requires
v = pyreqs["shared-function2"].module.myvar # v will be 222
f = pyreqs["shared-function"].module.myfunct() # f will be 234
self.output.info("%s, %s" % (v, f))
""")
client.save({"conanfile.py": conanfile})
client.run("export . user/channel")

conanfile = textwrap.dedent("""
from conans import ConanFile
class Consumer(ConanFile):
name = "consumer"
version = "1.0"
python_requires = "base-class/1.0@user/channel", "base-class2/1.0@user/channel"
python_requires_extend = "base-class.BaseClass", "base-class2.BaseClass2"
""")
client.save({"conanfile.py": conanfile})
client.run("create . @user/channel")
assert "consumer/1.0@user/channel: Calling build()\nconsumer/1.0@user/channel: 123, 2222" in \
client.out
assert "consumer/1.0@user/channel: Calling package()\nconsumer/1.0@user/channel: 222, 234" in \
client.out

0 comments on commit 12fdc0b

Please sign in to comment.