Updated dataclass_transform to support parameter name field_specifiers, which replaces the older parameter named field_descriptors. For now, we'll support both to retain backward compatibility with libraries that shipped with the older form.

This commit is contained in:
Eric Traut 2022-05-19 23:04:17 -07:00
parent 020d41ecab
commit 8a1932bf51
7 changed files with 25 additions and 20 deletions

View File

@ -706,7 +706,12 @@ export function validateDataClassTransformDecorator(
break;
}
case 'field_descriptors': {
// Earlier versions of the dataclass_transform spec used the name "field_descriptors"
// rather than "field_specifiers". The older name is now deprecated but still supported
// for the time being because some libraries shipped with the older __dataclass_transform__
// form that supported this older parameter name.
case 'field_descriptors':
case 'field_specifiers': {
const valueType = evaluator.getTypeOfExpression(arg.valueExpression).type;
if (
!isClassInstance(valueType) ||
@ -720,7 +725,7 @@ export function validateDataClassTransformDecorator(
)
) {
evaluator.addError(
Localizer.Diagnostic.dataClassTransformFieldDescriptor().format({
Localizer.Diagnostic.dataClassTransformFieldSpecifier().format({
type: evaluator.printType(valueType),
}),
arg.valueExpression

View File

@ -301,8 +301,8 @@ export namespace Localizer {
export const dataClassSlotsOverwrite = () => getRawString('Diagnostic.dataClassSlotsOverwrite');
export const dataClassTransformExpectedBoolLiteral = () =>
getRawString('Diagnostic.dataClassTransformExpectedBoolLiteral');
export const dataClassTransformFieldDescriptor = () =>
new ParameterizedString<{ type: string }>(getRawString('Diagnostic.dataClassTransformFieldDescriptor'));
export const dataClassTransformFieldSpecifier = () =>
new ParameterizedString<{ type: string }>(getRawString('Diagnostic.dataClassTransformFieldSpecifier'));
export const dataClassTransformPositionalParam = () =>
getRawString('Diagnostic.dataClassTransformPositionalParam');
export const dataClassTransformUnknownArgument = () =>

View File

@ -76,7 +76,7 @@
"dataClassPostInitType": "Dataclass __post_init__ method parameter type mismatch for field \"{fieldName}\"",
"dataClassSlotsOverwrite": "__slots__ is already defined in class",
"dataClassTransformExpectedBoolLiteral": "Expected expression that statically evaluates to True or False",
"dataClassTransformFieldDescriptor": "Expected tuple of classes or functions but received type \"{type}\"",
"dataClassTransformFieldSpecifier": "Expected tuple of classes or functions but received type \"{type}\"",
"dataClassTransformPositionalParam": "All arguments to \"dataclass_transform\" must be keyword arguments",
"dataClassTransformUnknownArgument": "Argument \"{name}\" is not supported by dataclass_transform",
"declaredReturnTypePartiallyUnknown": "Declared return type, \"{returnType}\", is partially unknown",

View File

@ -20,7 +20,7 @@ def model_field(
@dataclass_transform(
kw_only_default=True,
field_descriptors=(ModelField, model_field),
field_specifiers=(ModelField, model_field),
)
class ModelMeta(type):
def __init_subclass__(

View File

@ -11,7 +11,7 @@ def __dataclass_transform__(
eq_default: bool = True,
order_default: bool = False,
kw_only_default: bool = False,
field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()),
field_specifiers: Tuple[Union[type, Callable[..., Any]], ...] = (()),
) -> Callable[[_T], _T]:
return lambda a: a
@ -29,7 +29,7 @@ def model_field(
@__dataclass_transform__(
kw_only_default=True,
field_descriptors=(ModelField, model_field),
field_specifiers=(ModelField, model_field),
)
class ModelBase:
def __init_subclass__(

View File

@ -61,14 +61,14 @@ def __dataclass_transform__(
eq_default: bool = True,
order_default: bool = False,
kw_only_default: bool = False,
field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()),
field_specifiers: Tuple[Union[type, Callable[..., Any]], ...] = (()),
) -> Callable[[T], T]:
# If used within a stub file, the following implementation can be
# replaced with "...".
return lambda a: a
@__dataclass_transform__(kw_only_default=True, field_descriptors=(field,))
@__dataclass_transform__(kw_only_default=True, field_specifiers=(field,))
def create_model(*, init: bool = True) -> Callable[[Type[T]], Type[T]]:
...

View File

@ -162,7 +162,7 @@ def dataclass_transform(
eq_default: bool = True,
order_default: bool = False,
kw_only_default: bool = False,
field_descriptors: Tuple[type, ...] = (()),
field_specifiers: Tuple[type, ...] = (()),
) -> Callable[[_T], _T]: ...
```
@ -178,7 +178,7 @@ to False (the default assumption for dataclass).
assumed to be True or False if it is omitted by the caller. If not specified,
it will default to False (the default assumption for dataclass).
`field_descriptors` specifies a static list of supported classes that describe
`field_specifiers` specifies a static list of supported classes that describe
fields. Some libraries also supply functions to allocate instances of field
descriptors, and those functions may also be specified in this tuple. If not
specified, it will default to an empty tuple (no field descriptors supported).
@ -319,7 +319,7 @@ def model_field(
init: bool = True,
) -> Any: ...
@typing.dataclass_transform(kw_only_default=True, field_descriptors=(model_field, ))
@typing.dataclass_transform(kw_only_default=True, field_specifiers=(model_field, ))
def create_model(
*,
init: bool = True
@ -349,7 +349,7 @@ def dataclass_transform(
eq_default: bool = True,
order_default: bool = False,
kw_only_default: bool = False,
field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()),
field_specifiers: Tuple[Union[type, Callable[..., Any]], ...] = (()),
) -> Callable[[_T], _T]:
return lambda a: a
```
@ -422,7 +422,7 @@ def __dataclass_transform__(
eq_default: bool = True,
order_default: bool = False,
kw_only_default: bool = False,
field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()),
field_specifiers: Tuple[Union[type, Callable[..., Any]], ...] = (()),
) -> Callable[[_T], _T]:
# If used within a stub file, the following implementation can be
# replaced with "...".
@ -516,7 +516,7 @@ def __dataclass_transform__(
eq_default: bool = True,
order_default: bool = False,
kw_only_default: bool = False,
field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()),
field_specifiers: Tuple[Union[type, Callable[..., Any]], ...] = (()),
) -> Callable[[_T], _T]: ...
```
@ -525,7 +525,7 @@ It is an overloaded function with two overloads. Paste the following line
between `@overload` and `def attrs(`. Repeat this for each of the two overloads.
```python
@__dataclass_transform__(order_default=True, field_descriptors=(attrib, field))
@__dataclass_transform__(order_default=True, field_specifiers=(attrib, field))
```
Step 3: Within the same file, search for the definition of the `define`
@ -533,7 +533,7 @@ function. Paste the following line between `@overload` and `def define(`. Repeat
this for each of the two overloads.
```python
@__dataclass_transform__(field_descriptors=(attrib, field))
@__dataclass_transform__(field_specifiers=(attrib, field))
```
@ -554,7 +554,7 @@ def __dataclass_transform__(
eq_default: bool = True,
order_default: bool = False,
kw_only_default: bool = False,
field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()),
field_specifiers: Tuple[Union[type, Callable[..., Any]], ...] = (()),
) -> Callable[[_T], _T]:
return lambda a: a
```
@ -562,7 +562,7 @@ def __dataclass_transform__(
Step 2: Add the following decorator to the `ModelMetaclass` class definition:
```python
@__dataclass_transform__(kw_only_default=True, field_descriptors=(Field, FieldInfo))
@__dataclass_transform__(kw_only_default=True, field_specifiers=(Field, FieldInfo))
```