Skip to content

Commit

Permalink
[develop2] Improve error messages for wrong methods (#12962)
Browse files Browse the repository at this point in the history
  • Loading branch information
memsharded authored Jan 24, 2023
1 parent 66af1da commit 8ae78c5
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 22 deletions.
6 changes: 2 additions & 4 deletions conans/model/conan_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,8 @@ def __init__(self, display_name=""):
self.generators = [self.generators]
if isinstance(self.settings, str):
self.settings = [self.settings]
self.requires = Requirements(getattr(self, "requires", None),
getattr(self, "build_requires", None),
getattr(self, "test_requires", None),
getattr(self, "tool_requires", None))
self.requires = Requirements(self.requires, self.build_requires, self.test_requires,
self.tool_requires)

self.options = Options(self.options or {}, self.default_options)

Expand Down
50 changes: 35 additions & 15 deletions conans/model/requires.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,27 +422,47 @@ def __init__(self, declared=None, declared_build=None, declared_test=None,
# Construct from the class definitions
if declared is not None:
if isinstance(declared, str):
declared = [declared, ]
for item in declared:
if not isinstance(item, str):
# TODO (2.X): Remove protection after transition from 1.X
raise ConanException(f"Incompatible 1.X requires declaration '{item}'")
self.__call__(item)
self.__call__(declared)
else:
try:
for item in declared:
if not isinstance(item, str):
# TODO (2.X): Remove protection after transition from 1.X
raise ConanException(f"Incompatible 1.X requires declaration '{item}'")
self.__call__(item)
except TypeError:
raise ConanException("Wrong 'requires' definition, "
"did you mean 'requirements()'?")
if declared_build is not None:
if isinstance(declared_build, str):
declared_build = [declared_build, ]
for item in declared_build:
self.build_require(item)
self.build_require(declared_build)
else:
try:
for item in declared_build:
self.build_require(item)
except TypeError:
raise ConanException("Wrong 'build_requires' definition, "
"did you mean 'build_requirements()'?")
if declared_test is not None:
if isinstance(declared_test, str):
declared_test = [declared_test, ]
for item in declared_test:
self.test_require(item)
self.test_require(declared_test)
else:
try:
for item in declared_test:
self.test_require(item)
except TypeError:
raise ConanException("Wrong 'test_requires' definition, "
"did you mean 'build_requirements()'?")
if declared_build_tool is not None:
if isinstance(declared_build_tool, str):
declared_build_tool = [declared_build_tool, ]
for item in declared_build_tool:
self.build_require(item, run=True)
self.build_require(declared_build_tool, run=True)
else:
try:
for item in declared_build_tool:
self.build_require(item, run=True)
except TypeError:
raise ConanException("Wrong 'tool_requires' definition, "
"did you mean 'build_requirements()'?")

def values(self):
return self._requires.values()
Expand Down
10 changes: 7 additions & 3 deletions conans/model/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,14 @@ def __init__(self, value):

def bump(self, index):
"""
Increments by 1 the version field at the specified index, setting to 0 the fields
:meta private:
Bump the version
Increments by 1 the version field at the specified index, setting to 0 the fields
on the right.
2.5 => bump(1) => 2.6
1.5.7 => bump(0) => 2.0.0
2.5 => bump(1) => 2.6
1.5.7 => bump(0) => 2.0.0
:param index:
"""
# this method is used to compute version ranges from tilde ~1.2 and caret ^1.2.1 ranges
# TODO: at this moment it only works for digits, cannot increment pre-release or builds
Expand Down
23 changes: 23 additions & 0 deletions conans/test/integration/conanfile/conanfile_errors_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import textwrap
import unittest

import pytest

from conans.test.utils.tools import TestClient


Expand Down Expand Up @@ -137,6 +139,27 @@ class HelloConan(ConanFile):
self.assertIn("Duplicated requirement", client.out)


class TestWrongMethods:
# https://github.com/conan-io/conan/issues/12961
@pytest.mark.parametrize("requires", ["requires", "tool_requires",
"test_requires", "build_requires"])
def test_wrong_method_requires(self, requires):
""" this is expected to be a relatively frequent user error, and the trace was
very ugly and debugging complicated
"""
c = TestClient()
conanfile = textwrap.dedent(f"""
from conan import ConanFile
class Pkg(ConanFile):
def {requires}(self):
pass
""")
c.save({"conanfile.py": conanfile})
c.run("install .", assert_error=True)
expected = "requirements" if requires == "requires" else "build_requirements"
assert f" Wrong '{requires}' definition, did you mean '{expected}()'?" in c.out


def test_notduplicate_requires_py():
client = TestClient()
conanfile = textwrap.dedent('''
Expand Down

0 comments on commit 8ae78c5

Please sign in to comment.