Added support for synthesized __slots__ symbol in dataclasses that are constructed using the slots=True argument. This addresses https://github.com/microsoft/pylance-release/issues/4147.

This commit is contained in:
Eric Traut 2023-03-24 18:09:21 -06:00
parent 8a93373e6b
commit 14f458717d
3 changed files with 44 additions and 1 deletions

View File

@ -625,6 +625,26 @@ export function synthesizeDataClassMethods(
classType.details.localSlotsNames = localDataClassEntries.map((entry) => entry.name);
}
// Should we synthesize a __slots__ symbol?
if (ClassType.isGeneratedDataClassSlots(classType)) {
let iterableType = evaluator.getTypingType(node, 'Iterable') ?? UnknownType.create();
if (isInstantiableClass(iterableType)) {
iterableType = ClassType.cloneAsInstance(
ClassType.cloneForSpecialization(
iterableType,
[evaluator.getBuiltInObject(node, 'str')],
/* isTypeArgumentExplicit */ true
)
);
}
symbolTable.set(
'__slots__',
Symbol.createWithType(SymbolFlags.ClassMember | SymbolFlags.ClassVar, iterableType)
);
}
// If this dataclass derived from a NamedTuple, update the NamedTuple with
// the specialized entry types.
updateNamedTupleBaseClass(

View File

@ -44,3 +44,26 @@ class D:
D(1, "bar")
@dataclass(slots=True)
class E:
a: int
E.__slots__
E(1).__slots__
reveal_type(E.__slots__, expected_text="Iterable[str]")
@dataclass
class F:
a: int
# This should generate an error.
F.__slots__
# This should generate an error.
F(1).__slots__

View File

@ -621,7 +621,7 @@ test('DataClass17', () => {
configOptions.defaultPythonVersion = PythonVersion.V3_10;
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['dataclass17.py'], configOptions);
TestUtils.validateResults(analysisResults, 3);
TestUtils.validateResults(analysisResults, 5);
});
test('DataClass18', () => {