Skip to content

Commit

Permalink
Don't create descriptor for symmetric converters
Browse files Browse the repository at this point in the history
  • Loading branch information
debonte committed Jun 20, 2023
1 parent 1315572 commit 9c0b2c5
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
24 changes: 14 additions & 10 deletions packages/pyright-internal/src/analyzer/dataClasses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import {
isFunction,
isInstantiableClass,
isOverloadedFunction,
isTypeSame,
NoneType,
OverloadedFunctionType,
TupleTypeArgument,
Expand Down Expand Up @@ -516,17 +517,20 @@ export function synthesizeDataClassMethods(
if (entry.converter) {
const fieldType = effectiveType;
effectiveType = getConverterInputType(evaluator, entry.converter, effectiveType, entry.name);
symbolTable.set(
entry.name,
getDescriptorForConverterField(
evaluator,
node,
entry.converter,

if (!isTypeSame(fieldType, effectiveType)) {
symbolTable.set(
entry.name,
fieldType,
effectiveType
)
);
getDescriptorForConverterField(
evaluator,
node,
entry.converter,
entry.name,
fieldType,
effectiveType
)
);
}
}

const effectiveName = entry.alias || entry.name;
Expand Down
22 changes: 14 additions & 8 deletions packages/pyright-internal/src/tests/samples/dataclassConverter2.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,24 @@
from dataclasses import dataclass, field


def converter_simple(s: str) -> int:
return int(s)

def converter_simple(s: str) -> int: ...
def converter_passThru(x: str | int) -> str | int: ...

@dataclass
class Foo:
# This should generate an error because "converter" is not an official property yet.
field0: int = field(converter=converter_simple)
asymmetric: int = field(converter=converter_simple)
# This should generate an error because "converter" is not an official property yet.
symmetric: str | int = field(converter=converter_passThru)

foo = Foo("1")
reveal_type(foo.field0, expected_text="int")
foo.field0 = "2"
foo = Foo("1", 1)

reveal_type(foo.asymmetric, expected_text="int")
foo.asymmetric = "2"
reveal_type(foo.asymmetric, expected_text="int") # Asymmetric -- type narrowing should not occur
# This should generate an error because only strs can be assigned to field0.
foo.field0 = 2
foo.asymmetric = 2

reveal_type(foo.symmetric, expected_text="str | int")
foo.symmetric = "1"
reveal_type(foo.symmetric, expected_text="Literal['1']") # Symmetric -- type narrowing should occur
2 changes: 1 addition & 1 deletion packages/pyright-internal/src/tests/typeEvaluator4.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ test('DataClassConverter1', () => {
test('DataClassConverter2', () => {
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['dataclassConverter2.py']);

TestUtils.validateResults(analysisResults, 2);
TestUtils.validateResults(analysisResults, 3);
});

test('DataClassPostInit1', () => {
Expand Down

0 comments on commit 9c0b2c5

Please sign in to comment.