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

[question] Propagating options through python_requires in Conan 2.0 #13486

Closed
1 task done
TimZoet opened this issue Mar 20, 2023 · 2 comments · Fixed by #13487
Closed
1 task done

[question] Propagating options through python_requires in Conan 2.0 #13486

TimZoet opened this issue Mar 20, 2023 · 2 comments · Fixed by #13487
Assignees
Milestone

Comments

@TimZoet
Copy link

TimZoet commented Mar 20, 2023

What is your question?

I am trying to create a base package to be reused through python_requires. In Conan 1.58, the options from the base package were propagated. In Conan 2.0.2, I am getting errors during install.

The base package:

# base/conanfile.py
from conan import ConanFile

class BaseConan:
    options = {"base": [True, False]}
    default_options = {"base": True}

class PyReq(ConanFile):
    name = "base"
    version = "1.0.0"
    package_type = "python-require"

The consumer package:

# derived/conanfile.py
import conan

class DerivedConan(conan.ConanFile):
    name = "derived"
    python_requires = "base/1.0.0@tim/test"
    python_requires_extend = "base.BaseConan"
    options = {"derived": [True, False]}
    default_options = {"derived": False}

    def init(self):
        base = self.python_requires["base"].module.BaseConan
        if conan.__version__ >= '2':
            self.options.update(base.options)
            self.default_options.update(base.default_options)
        else:
            self.options = {**self.options, **base.options}
            self.default_options = {**self.default_options, **base.default_options}

When exporting the base package and trying to run install for the derived package:

conan export --user tim --channel test base/
mkdir build && cd build
conan install ../derived

I get the following error:

======== Input profiles ========
Profile host:
<omitted>

Profile build:
<omitted>

======== Computing dependency graph ========
Graph root
    conanfile.py (derived/None): C:\Users\timzo\dev\tmp\conan2\derived\conanfile.py
Python requires
    base/1.0.0@tim/test#aa5464ceebb466e0ef1c8c83fd14c78d - Cache

======== Computing necessary packages ========

======== Installing packages ========

======== Finalizing install (deploy, generators) ========
ERROR: conanfile.py (derived/None): Invalid ID: Invalid: 'options.base' value not defined

To better understand what was going on, I added a call to traceback.print_stack() on the line that throws the above exception:

# conans/model/options.py line 85
    def validate(self):
        # check that this has a valid option value defined
        if self._value is not None:
            return
        if None not in self._possible_values:
            import traceback
            traceback.print_stack()
            raise ConanException("'options.%s' value not defined" % self._name)

This traceback is printed under the Computing necessary packages section:

<omitted>
======== Computing necessary packages ========
  File "C:\Users\timzo\dev\pyenv\Scripts\conan-script.py", line 33, in <module>
    sys.exit(load_entry_point('conan==2.0.2', 'console_scripts', 'conan')())
  File "C:\Users\timzo\dev\pyenv\Lib\site-packages\conans\conan.py", line 7, in run
    main(sys.argv[1:])
  File "C:\Users\timzo\dev\pyenv\Lib\site-packages\conan\cli\cli.py", line 272, in main
    cli.run(args)
  File "C:\Users\timzo\dev\pyenv\Lib\site-packages\conan\cli\cli.py", line 171, in run
    command.run(self._conan_api, self._commands[command_argument].parser, args[0][1:])
  File "C:\Users\timzo\dev\pyenv\Lib\site-packages\conan\cli\command.py", line 156, in run
    info = self._method(conan_api, parser, *args)
  File "C:\Users\timzo\dev\pyenv\Lib\site-packages\conan\cli\commands\install.py", line 74, in install
    conan_api.graph.analyze_binaries(deps_graph, args.build, remotes=remotes, update=args.update,
  File "C:\Users\timzo\dev\pyenv\Lib\site-packages\conan\api\subapi\graph.py", line 190, in analyze_binaries
    binaries_analyzer.evaluate_graph(graph, build_mode, lockfile, remotes, update)
  File "C:\Users\timzo\dev\pyenv\Lib\site-packages\conans\client\graph\graph_binaries.py", line 316, in evaluate_graph
    self._evaluate_package_id(node)
  File "C:\Users\timzo\dev\pyenv\Lib\site-packages\conans\client\graph\graph_binaries.py", line 292, in _evaluate_package_id
    compute_package_id(node, self._cache.new_config)  # TODO: revise compute_package_id()
  File "C:\Users\timzo\dev\pyenv\Lib\site-packages\conans\client\graph\compute_pid.py", line 59, in compute_package_id
    run_validate_package_id(conanfile)
  File "C:\Users\timzo\dev\pyenv\Lib\site-packages\conans\client\graph\compute_pid.py", line 81, in run_validate_package_id
    conanfile.info.validate()
  File "C:\Users\timzo\dev\pyenv\Lib\site-packages\conans\model\info.py", line 399, in validate
    self.options.validate()
  File "C:\Users\timzo\dev\pyenv\Lib\site-packages\conans\model\options.py", line 147, in validate
    child.validate()
  File "C:\Users\timzo\dev\pyenv\Lib\site-packages\conans\model\options.py", line 91, in validate
    traceback.print_stack()
<omitted>

This was not happening in Conan 1.58.0. Also note that there are no issues stitching together the two collections of options in the init method of the deriving conanfile.

From the newest documentation, it is not clear to me if this should still be supported in 2.0 or not. The 1.58 docs already make no mention of inheriting options anymore.

Have you read the CONTRIBUTING guide?

  • I've read the CONTRIBUTING guide
@memsharded
Copy link
Member

Hi @TimZoet

Thanks for your report.
The correct syntax seems to be:

def init(self):
       base = self.python_requires["base"].module.BaseConan
       self.options.update(base.options, base.default_options)

When init() is called, the options object is already created. Updating the default_options has no effect, the values can be passed to the self.options.update() as second argument.

I'll add a unit test to make this explicit and to introduce a note in the docs.

@TimZoet
Copy link
Author

TimZoet commented Mar 20, 2023

Indeed, this seems to do the trick. Much appreciated.

@TimZoet TimZoet closed this as completed Mar 20, 2023
AbrilRBS added a commit that referenced this issue Mar 22, 2023
Changelog: Fix: Define a way to update ``default_options`` in
``python_requires_extend`` extension.
Docs: conan-io/docs#3120

Close #13486
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants