From 2b10ab052014b22ca21a8a08da7eaa91827cf014 Mon Sep 17 00:00:00 2001 From: Antonin RAFFIN Date: Fri, 26 Sep 2025 09:57:06 +0200 Subject: [PATCH 1/8] feat: make exports explicits --- conan/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conan/__init__.py b/conan/__init__.py index f92037d614d..6fec8063a70 100644 --- a/conan/__init__.py +++ b/conan/__init__.py @@ -4,3 +4,5 @@ __version__ = '2.21.0-dev' conan_version = Version(__version__) + +__all__ = ["ConanFile", "Version", "Workspace", "__version__", "conan_version"] From 54bc7217bb68d95d0a74b887d886b139783ab233 Mon Sep 17 00:00:00 2001 From: Antonin RAFFIN Date: Fri, 26 Sep 2025 10:14:35 +0200 Subject: [PATCH 2/8] feat: expose recipe via ConanFileInterface --- conan/internal/model/conanfile_interface.py | 18 ++++++++++++++++-- conan/internal/model/dependencies.py | 5 +---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/conan/internal/model/conanfile_interface.py b/conan/internal/model/conanfile_interface.py index 76aed619e1f..876adae1002 100644 --- a/conan/internal/model/conanfile_interface.py +++ b/conan/internal/model/conanfile_interface.py @@ -1,5 +1,7 @@ from pathlib import Path -from conan.internal.graph.graph import CONTEXT_BUILD + +from conan.internal.graph.graph import CONTEXT_BUILD, RECIPE_EDITABLE, RECIPE_PLATFORM +from conan.internal.model.conan_file import ConanFile class ConanFileInterface: @@ -10,7 +12,7 @@ class ConanFileInterface: def __str__(self): return str(self._conanfile) - def __init__(self, conanfile): + def __init__(self, conanfile: ConanFile): self._conanfile = conanfile def __eq__(self, other): @@ -142,3 +144,15 @@ def url(self): @property def extension_properties(self): return getattr(self._conanfile, "extension_properties", {}) + + @property + def recipe(self) -> str: + return self._conanfile._conan_node.recipe + + @property + def is_editable(self) -> bool: + return self.recipe == RECIPE_EDITABLE + + @property + def is_platform(self) -> bool: + return self.recipe == RECIPE_PLATFORM diff --git a/conan/internal/model/dependencies.py b/conan/internal/model/dependencies.py index b830e04a0bb..9227447683c 100644 --- a/conan/internal/model/dependencies.py +++ b/conan/internal/model/dependencies.py @@ -1,6 +1,5 @@ from collections import OrderedDict -from conan.internal.graph.graph import RECIPE_PLATFORM from conan.errors import ConanException from conan.api.model import RecipeReference from conan.internal.model.conanfile_interface import ConanFileInterface @@ -117,9 +116,7 @@ def filter_fn(require): data = OrderedDict((k, v) for k, v in self._data.items() if filter_fn(k)) if remove_system: - data = OrderedDict((k, v) for k, v in data.items() - # TODO: Make "recipe" part of ConanFileInterface model - if v._conanfile._conan_node.recipe != RECIPE_PLATFORM) + data = OrderedDict((k, v) for k, v in data.items() if not v.is_platform) return ConanFileDependencies(data, require_filter) def transitive_requires(self, other): From 281cdf77a505e8f64e6bc07e3e161bb76b49240a Mon Sep 17 00:00:00 2001 From: Antonin RAFFIN Date: Fri, 26 Sep 2025 10:36:01 +0200 Subject: [PATCH 3/8] Add basic tests for new exposed variables --- conan/internal/model/conanfile_interface.py | 8 ++++++-- .../graph/test_dependencies_visit.py | 19 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/conan/internal/model/conanfile_interface.py b/conan/internal/model/conanfile_interface.py index 876adae1002..892124cd567 100644 --- a/conan/internal/model/conanfile_interface.py +++ b/conan/internal/model/conanfile_interface.py @@ -1,7 +1,11 @@ +import typing from pathlib import Path from conan.internal.graph.graph import CONTEXT_BUILD, RECIPE_EDITABLE, RECIPE_PLATFORM -from conan.internal.model.conan_file import ConanFile + +if typing.TYPE_CHECKING: + # Avoid circular import + from conan.internal.model.conan_file import ConanFile class ConanFileInterface: @@ -12,7 +16,7 @@ class ConanFileInterface: def __str__(self): return str(self._conanfile) - def __init__(self, conanfile: ConanFile): + def __init__(self, conanfile: "ConanFile"): self._conanfile = conanfile def __eq__(self, other): diff --git a/test/integration/graph/test_dependencies_visit.py b/test/integration/graph/test_dependencies_visit.py index 63d3b4191d2..9654c5645ae 100644 --- a/test/integration/graph/test_dependencies_visit.py +++ b/test/integration/graph/test_dependencies_visit.py @@ -255,11 +255,15 @@ class Pkg(ConanFile): class User(ConanFile): requires = "dep/1.0" def generate(self): - self.output.info("HOME: {}".format(self.dependencies["dep"].homepage)) - self.output.info("URL: {}".format(self.dependencies["dep"].url)) - self.output.info("LICENSE: {}".format(self.dependencies["dep"].license)) - self.output.info("RECIPE: {}".format(self.dependencies["dep"].recipe_folder)) - self.output.info("CONANDATA: {}".format(self.dependencies["dep"].conan_data)) + dep = self.dependencies["dep"] + self.output.info("HOME: {}".format(dep.homepage)) + self.output.info("URL: {}".format(dep.url)) + self.output.info("LICENSE: {}".format(dep.license)) + self.output.info("RECIPE FOLDER: {}".format(dep.recipe_folder)) + self.output.info("CONANDATA: {}".format(dep.conan_data)) + self.output.info("RECIPE: {}".format(dep.recipe)) + self.output.info("IS_EDITABLE: {}".format(dep.is_editable)) + self.output.info("IS_PLATFORM: {}".format(dep.is_platform)) """) c.save({"dep/conanfile.py": conanfile, @@ -270,8 +274,11 @@ def generate(self): assert "conanfile.py: HOME: myhome" in c.out assert "conanfile.py: URL: myurl" in c.out assert "conanfile.py: LICENSE: MIT" in c.out - assert "conanfile.py: RECIPE:" in c.out + assert "conanfile.py: RECIPE FOLDER:" in c.out assert "conanfile.py: CONANDATA: {}" in c.out + assert "conanfile.py: RECIPE: Cache" in c.out + assert "conanfile.py: IS_EDITABLE: False" in c.out + assert "conanfile.py: IS_PLATFORM: False" in c.out def test_dependency_interface_validate(): From 1eba83120687006825f5a4e8371bfc5eac1a1c5c Mon Sep 17 00:00:00 2001 From: Antonin RAFFIN Date: Fri, 26 Sep 2025 11:32:52 +0200 Subject: [PATCH 4/8] Revert unwanted changes --- conan/__init__.py | 2 -- conan/internal/model/conanfile_interface.py | 8 +------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/conan/__init__.py b/conan/__init__.py index 6fec8063a70..f92037d614d 100644 --- a/conan/__init__.py +++ b/conan/__init__.py @@ -4,5 +4,3 @@ __version__ = '2.21.0-dev' conan_version = Version(__version__) - -__all__ = ["ConanFile", "Version", "Workspace", "__version__", "conan_version"] diff --git a/conan/internal/model/conanfile_interface.py b/conan/internal/model/conanfile_interface.py index 892124cd567..fa305c4d165 100644 --- a/conan/internal/model/conanfile_interface.py +++ b/conan/internal/model/conanfile_interface.py @@ -1,13 +1,7 @@ -import typing from pathlib import Path from conan.internal.graph.graph import CONTEXT_BUILD, RECIPE_EDITABLE, RECIPE_PLATFORM -if typing.TYPE_CHECKING: - # Avoid circular import - from conan.internal.model.conan_file import ConanFile - - class ConanFileInterface: """ this is just a protective wrapper to give consumers a limited view of conanfile dependencies, "read" only, @@ -16,7 +10,7 @@ class ConanFileInterface: def __str__(self): return str(self._conanfile) - def __init__(self, conanfile: "ConanFile"): + def __init__(self, conanfile): self._conanfile = conanfile def __eq__(self, other): From 9a65ae805acbe8689a1c3a79f5882402cebbcf37 Mon Sep 17 00:00:00 2001 From: Antonin RAFFIN Date: Wed, 1 Oct 2025 15:47:03 +0200 Subject: [PATCH 5/8] Remove unwanted methods --- conan/internal/model/conanfile_interface.py | 9 +-------- conan/internal/model/dependencies.py | 5 +++-- test/integration/graph/test_dependencies_visit.py | 4 ---- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/conan/internal/model/conanfile_interface.py b/conan/internal/model/conanfile_interface.py index ed80b0b0a59..cc81d3a1886 100644 --- a/conan/internal/model/conanfile_interface.py +++ b/conan/internal/model/conanfile_interface.py @@ -1,6 +1,6 @@ from pathlib import Path -from conan.internal.graph.graph import CONTEXT_BUILD, RECIPE_EDITABLE, RECIPE_PLATFORM +from conan.internal.graph.graph import CONTEXT_BUILD class ConanFileInterface: """ this is just a protective wrapper to give consumers @@ -147,12 +147,5 @@ def extension_properties(self): def recipe(self) -> str: return self._conanfile._conan_node.recipe - @property - def is_editable(self) -> bool: - return self.recipe == RECIPE_EDITABLE - - @property - def is_platform(self) -> bool: - return self.recipe == RECIPE_PLATFORM def conf(self): return self._conanfile.conf diff --git a/conan/internal/model/dependencies.py b/conan/internal/model/dependencies.py index 9227447683c..60e1ed03330 100644 --- a/conan/internal/model/dependencies.py +++ b/conan/internal/model/dependencies.py @@ -1,7 +1,8 @@ from collections import OrderedDict -from conan.errors import ConanException from conan.api.model import RecipeReference +from conan.errors import ConanException +from conan.internal.graph.graph import RECIPE_PLATFORM from conan.internal.model.conanfile_interface import ConanFileInterface @@ -116,7 +117,7 @@ def filter_fn(require): data = OrderedDict((k, v) for k, v in self._data.items() if filter_fn(k)) if remove_system: - data = OrderedDict((k, v) for k, v in data.items() if not v.is_platform) + data = OrderedDict((k, v) for k, v in data.items() if v.recipe != RECIPE_PLATFORM) return ConanFileDependencies(data, require_filter) def transitive_requires(self, other): diff --git a/test/integration/graph/test_dependencies_visit.py b/test/integration/graph/test_dependencies_visit.py index 9654c5645ae..ee8478fafaf 100644 --- a/test/integration/graph/test_dependencies_visit.py +++ b/test/integration/graph/test_dependencies_visit.py @@ -262,8 +262,6 @@ def generate(self): self.output.info("RECIPE FOLDER: {}".format(dep.recipe_folder)) self.output.info("CONANDATA: {}".format(dep.conan_data)) self.output.info("RECIPE: {}".format(dep.recipe)) - self.output.info("IS_EDITABLE: {}".format(dep.is_editable)) - self.output.info("IS_PLATFORM: {}".format(dep.is_platform)) """) c.save({"dep/conanfile.py": conanfile, @@ -277,8 +275,6 @@ def generate(self): assert "conanfile.py: RECIPE FOLDER:" in c.out assert "conanfile.py: CONANDATA: {}" in c.out assert "conanfile.py: RECIPE: Cache" in c.out - assert "conanfile.py: IS_EDITABLE: False" in c.out - assert "conanfile.py: IS_PLATFORM: False" in c.out def test_dependency_interface_validate(): From 72812dd41953013fb92d831451b53f88ae85655d Mon Sep 17 00:00:00 2001 From: Antonin RAFFIN Date: Wed, 1 Oct 2025 15:48:00 +0200 Subject: [PATCH 6/8] Fix formatting --- conan/internal/model/conanfile_interface.py | 1 + 1 file changed, 1 insertion(+) diff --git a/conan/internal/model/conanfile_interface.py b/conan/internal/model/conanfile_interface.py index cc81d3a1886..0131ff8d6ff 100644 --- a/conan/internal/model/conanfile_interface.py +++ b/conan/internal/model/conanfile_interface.py @@ -2,6 +2,7 @@ from conan.internal.graph.graph import CONTEXT_BUILD + class ConanFileInterface: """ this is just a protective wrapper to give consumers a limited view of conanfile dependencies, "read" only, From 4f01db84b3fa74b6abc8f23895bec04d57767608 Mon Sep 17 00:00:00 2001 From: Antonin RAFFIN Date: Wed, 1 Oct 2025 15:52:21 +0200 Subject: [PATCH 7/8] Add warning --- conan/internal/model/conanfile_interface.py | 1 + 1 file changed, 1 insertion(+) diff --git a/conan/internal/model/conanfile_interface.py b/conan/internal/model/conanfile_interface.py index 0131ff8d6ff..dbd2f5f384f 100644 --- a/conan/internal/model/conanfile_interface.py +++ b/conan/internal/model/conanfile_interface.py @@ -146,6 +146,7 @@ def extension_properties(self): @property def recipe(self) -> str: + # IMPORTANT: this should be used only for "informational" purposes, see GH#18996. return self._conanfile._conan_node.recipe def conf(self): From 4c194ffe25f5c3b6306a41261e6fd839320f7be4 Mon Sep 17 00:00:00 2001 From: Antonin RAFFIN Date: Wed, 1 Oct 2025 16:38:25 +0200 Subject: [PATCH 8/8] Fix missing property --- conan/internal/model/conanfile_interface.py | 1 + 1 file changed, 1 insertion(+) diff --git a/conan/internal/model/conanfile_interface.py b/conan/internal/model/conanfile_interface.py index dbd2f5f384f..b84f0b9c5d3 100644 --- a/conan/internal/model/conanfile_interface.py +++ b/conan/internal/model/conanfile_interface.py @@ -149,5 +149,6 @@ def recipe(self) -> str: # IMPORTANT: this should be used only for "informational" purposes, see GH#18996. return self._conanfile._conan_node.recipe + @property def conf(self): return self._conanfile.conf