Skip to content

Commit 82cb33d

Browse files
committed
[mypyc] Raise "non-trait base must be first..." error less frequently
It would raise even if there were only non-trait bases leading to this slightly confusing situation: class A: pass class B: pass class C(A, B): pass # E: Non-trait bases must appear first in parent list # E: Multiple inheritance is not supported (except for traits) Now the bases must include a trait *and* the first base must be a trait to error. This leads to some false-negative when there's more than one non-trait base, but in that case, it's better to only tell the user multiple inheritance is not supported. I also fixed the pre-existing commandline test. A trait was inheriting from a non-trait class which is not allowed.
1 parent f37a0ae commit 82cb33d

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

mypyc/irbuild/prepare.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,13 @@ def prepare_class_def(
256256

257257
# Set up the parent class
258258
bases = [mapper.type_to_ir[base.type] for base in info.bases if base.type in mapper.type_to_ir]
259-
if not all(c.is_trait for c in bases[1:]):
260-
errors.error("Non-trait bases must appear first in parent list", path, cdef.line)
261259
ir.traits = [c for c in bases if c.is_trait]
260+
if len(bases) > 1 and ir.traits and bases[0].is_trait:
261+
# If the first base is a non-trait, don't ever error here. While it is correct
262+
# to error if a trait comes before the next non-trait base (e.g. non-trait, trait,
263+
# non-trait), it's pointless, confusing noise from the bigger issue: multiple
264+
# inheritance is *not* supported.
265+
errors.error("Non-trait base must appear first in parent list", path, cdef.line)
262266

263267
mro = [] # All mypyc base classes
264268
base_mro = [] # Non-trait mypyc base classes

mypyc/test-data/commandline.test

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class PureTrait:
150150
pass
151151

152152
@trait
153-
class Trait1(Concrete1):
153+
class Trait1:
154154
pass
155155

156156
class Concrete2:
@@ -164,9 +164,23 @@ class Trait2(Concrete2):
164164
class NonExt(Concrete1): # E: Non-extension classes may not inherit from extension classes
165165
pass
166166

167-
class Nope(Trait1, Concrete2): # E: Non-trait bases must appear first in parent list # E: Multiple inheritance is not supported (except for traits)
167+
168+
class NopeMultipleInheritance(Concrete1, Concrete2): # E: Multiple inheritance is not supported (except for traits)
169+
pass
170+
171+
class NopeMultipleInheritanceAndBadOrder(Concrete1, Trait1, Concrete2): # E: Multiple inheritance is not supported (except for traits)
172+
pass
173+
174+
class NopeMultipleInheritanceAndBadOrder2(Concrete1, Concrete2, Trait1): # E: Multiple inheritance is not supported (except for traits)
168175
pass
169176

177+
class NopeMultipleInheritanceAndBadOrder3(Trait1, Concrete1, Concrete2): # E: Non-trait base must appear first in parent list # E: Multiple inheritance is not supported (except for traits)
178+
pass
179+
180+
class NopeBadOrder(Trait1, Concrete2): # E: Non-trait base must appear first in parent list
181+
pass
182+
183+
170184
@decorator
171185
class NonExt2:
172186
@property # E: Property setters not supported in non-extension classes

0 commit comments

Comments
 (0)