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

import conanfile just once #4095

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions conans/client/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,17 @@ def __init__(self, runner, output, python_requires):
self._runner = runner
self._output = output
self._python_requires = python_requires
sys.modules["conans"].python_requires = self._python_requires
sys.modules["conans"].python_requires = python_requires
self.cached_conanfiles = {}

def load_class(self, conanfile_path):
self._python_requires.valid = True
_, conanfile = parse_conanfile(conanfile_path, self._python_requires)
self._python_requires.valid = False
try:
return self.cached_conanfiles[conanfile_path]
except KeyError:
self._python_requires.valid = True
_, conanfile = parse_conanfile(conanfile_path, self._python_requires)
self._python_requires.valid = False
self.cached_conanfiles[conanfile_path] = conanfile
return conanfile

def load_export(self, conanfile_path, name, version, user, channel):
Expand Down
36 changes: 36 additions & 0 deletions conans/test/optimize_conanfile_load_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import unittest

from conans.test.utils.tools import TestClient


class OptimizeConanFileLoadTest(unittest.TestCase):

def test_multiple_load(self):
""" when a conanfile is used more than once in a dependency graph, the python file
should be read and interpreted just once, then instance 2 different ConanFile
objects. The module global value "mycounter" is global to all instances, this
should be discouraged to use as if it was an instance value.
In this test there are 2 nodes "Build/0.1" as it is a build-requires of both the
conanfile.py and the test_package/conanfile.py
"""
client = TestClient()
conanfile = """from conans import ConanFile
mycounter = 0
class Pkg(ConanFile):
Copy link
Contributor

Choose a reason for hiding this comment

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

Please, add a counter associated with the instance.

mycounter2 = 0
def configure(self):
global mycounter
mycounter += 1
self.mycounter2 += 1
self.output.info("MyCounter1 %s, MyCounter2 %s" % (mycounter, self.mycounter2))
"""
client.save({"conanfile.py": conanfile})

client.run("create . Build/0.1@user/testing")

client.save({"conanfile.py": conanfile,
"test_package/conanfile.py": conanfile + " def test(self): pass",
"myprofile": "[build_requires]\nBuild/0.1@user/testing"})

client.run("create . Pkg/0.1@user/testing -pr=myprofile")
self.assertIn("Build/0.1@user/testing: MyCounter1 2, MyCounter2 1", client.out)
3 changes: 2 additions & 1 deletion conans/test/unittests/model/transitive_reqs_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def setUp(self):
MockRequireResolver(), None, None)

def root(self, content):
self.loader.cached_conanfiles = {}
processed_profile = test_processed_profile()
root_conan = self.retriever.root(content, processed_profile)
deps_graph = self.builder.load_graph(root_conan, False, False, None,
Expand Down Expand Up @@ -430,7 +431,7 @@ class ChatConan(ConanFile):
self.retriever.conan(bye_ref, bye_content2)

with self.assertRaisesRegexp(ConanException, "Conflict in Bye/0.2@user/testing"):
_ = self.root(chat_content)
self.root(chat_content)

def test_diamond_conflict_solved(self):
chat_content = """
Expand Down
1 change: 1 addition & 0 deletions conans/test/unittests/model/version_ranges_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ class SayConan(ConanFile):
self.retriever.conan(say_ref, say_content)

def root(self, content, update=False):
self.loader.cached_conanfiles = {}
processed_profile = test_processed_profile()
root_conan = self.retriever.root(content, processed_profile)
deps_graph = self.builder.load_graph(root_conan, update, update, None, processed_profile)
Expand Down