diff --git a/mypyc/irbuild/prepare.py b/mypyc/irbuild/prepare.py index eb8288b84818..3800137a3f55 100644 --- a/mypyc/irbuild/prepare.py +++ b/mypyc/irbuild/prepare.py @@ -256,8 +256,12 @@ def prepare_class_def( # Set up the parent class bases = [mapper.type_to_ir[base.type] for base in info.bases if base.type in mapper.type_to_ir] - if not all(c.is_trait for c in bases[1:]): - errors.error("Non-trait bases must appear first in parent list", path, cdef.line) + if len(bases) > 1 and any(not c.is_trait for c in bases) and bases[0].is_trait: + # If the first base is a non-trait, don't ever error here. While it is correct + # to error if a trait comes before the next non-trait base (e.g. non-trait, trait, + # non-trait), it's pointless, confusing noise from the bigger issue: multiple + # inheritance is *not* supported. + errors.error("Non-trait base must appear first in parent list", path, cdef.line) ir.traits = [c for c in bases if c.is_trait] mro = [] # All mypyc base classes diff --git a/mypyc/test-data/commandline.test b/mypyc/test-data/commandline.test index bc2713a20f7d..1ba4b2f4aa04 100644 --- a/mypyc/test-data/commandline.test +++ b/mypyc/test-data/commandline.test @@ -150,7 +150,7 @@ class PureTrait: pass @trait -class Trait1(Concrete1): +class Trait1: pass class Concrete2: @@ -164,9 +164,23 @@ class Trait2(Concrete2): class NonExt(Concrete1): # E: Non-extension classes may not inherit from extension classes pass -class Nope(Trait1, Concrete2): # E: Non-trait bases must appear first in parent list # E: Multiple inheritance is not supported (except for traits) + +class NopeMultipleInheritance(Concrete1, Concrete2): # E: Multiple inheritance is not supported (except for traits) + pass + +class NopeMultipleInheritanceAndBadOrder(Concrete1, Trait1, Concrete2): # E: Multiple inheritance is not supported (except for traits) + pass + +class NopeMultipleInheritanceAndBadOrder2(Concrete1, Concrete2, Trait1): # E: Multiple inheritance is not supported (except for traits) pass +class NopeMultipleInheritanceAndBadOrder3(Trait1, Concrete1, Concrete2): # E: Non-trait base must appear first in parent list # E: Multiple inheritance is not supported (except for traits) + pass + +class NopeBadOrder(Trait1, Concrete2): # E: Non-trait base must appear first in parent list + pass + + @decorator class NonExt2: @property # E: Property setters not supported in non-extension classes