question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[bug] `python_requires_extend` in base class should extend base class but extends sub class

See original GitHub issue

I stumbled upon a little quirk in the implementation of python_requires_extend. I am not sure whether it is worthy to be called a bug, but I think it is unintuitive at the least.

Let’s say that we have a ConanFile subclass ProjectBaseConanFile which serves as the base class for some project variants with their classes VariantAConanFile, VariantBConanFile, VariantCConanFile.

Instances of these VariantXConanFile classes have the following inheritance hierarchy (packages ommitted):

<object>
<class 'ConanFile'>
<class 'ProjectBaseConanFile'>
<class 'VariantXConanFile'>

Now, let’s say that we have a new company-wide Conan base class CompanyConanFile and we want to use python_requires and python_requires_extend in all of our ConanFile implementations (including ProjectBaseConanFile) to inject CompanyConanFile as their respective base class.

Issue description

When we now set python_requires_extend = "companyconan.CompanyConanFile" in ProjectBaseConanFile, then Conan currently injects CompanyConanFile as the base class of self.__class__, so at this position:

<object>
<class 'ConanFile'>
<class 'ProjectBaseConanFile'>
<class 'CompanyConanFile'>      <-- injected here
<class 'VariantXConanFile'>     <-- self

But that means that the custom implementations of ProjectBaseConanFile would be overridden by the default implementations of CompanyConanFile when in fact it should be the other way around.

Expected behavior / workaround

You could work around this and inject the base class at the expected location by adding the following to the ProjectBaseConanFile class:

class ProjectBaseConanFile(ConanFile):
    python_requires = "companyconan/0.1@Company/stable"
    # Intentionally commented-out, injection done manually in init()
    # python_requires_extend = "companyconan.CompanyConanFile"

    def init(self):
        CompanyConanFile = self.python_requires["companyConan"].module.CompanyConanFile
        ProjectBaseConanFile.__bases__ = (CompanyConanFile,) + ProjectBaseConanFile.__bases__

(Workaround deduced from here) https://github.com/conan-io/conan/blob/ebed0370c439a8274c2992ee41e424438eebd455/conans/client/graph/python_requires.py#L103

This injects CompanyConanFile at the correct position:

<object>
<ConanFile>
<CompanyConanFile>      <-- injected here
<ProjectBaseConanFile>
<VariantXConanFile>     <-- self

Environment Details

  • Operating System+version: macOS Catalina 10.15.7
  • Compiler+version: Apple clang version 12.0.0 (clang-1200.0.32.29)
  • Conan version: 1.43.0
  • Python version: 3.9.9

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
bazizsaficommented, Feb 8, 2022

Cool! I consider this issue closed then.

0reactions
memshardedcommented, Feb 8, 2022
Read more comments on GitHub >

github_iconTop Results From Across the Web

No results found

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found