Merge branch 'main' into alex/protocol-property-check-2

This commit is contained in:
Alex Waygood 2025-08-27 19:28:46 +01:00
commit 8c9732531e
8 changed files with 902 additions and 479 deletions

View File

@ -74,3 +74,36 @@ DatasetOrTimeSchedule()
# airflow.utils.dag_parsing_context
get_parsing_context()
from airflow.decorators.base import (
DecoratedMappedOperator,
DecoratedOperator,
TaskDecorator,
get_unique_task_id,
task_decorator_factory,
)
# airflow.decorators.base
DecoratedMappedOperator()
DecoratedOperator()
TaskDecorator()
get_unique_task_id()
task_decorator_factory()
from airflow.models import Param
# airflow.models
Param()
from airflow.sensors.base import (
BaseSensorOperator,
PokeReturnValue,
poke_mode_only,
)
# airflow.sensors.base
BaseSensorOperator()
PokeReturnValue()
poke_mode_only()

View File

@ -9,7 +9,6 @@ from airflow.operators.empty import EmptyOperator
from airflow.operators.latest_only import LatestOnlyOperator
from airflow.operators.trigger_dagrun import TriggerDagRunOperator
from airflow.operators.weekday import BranchDayOfWeekOperator
from airflow.sensors.date_time import DateTimeSensor
FSHook()
PackageIndexHook()
@ -22,7 +21,6 @@ EmptyOperator()
LatestOnlyOperator()
BranchDayOfWeekOperator()
DateTimeSensor()
from airflow.operators.python import (
BranchPythonOperator,
@ -30,16 +28,23 @@ from airflow.operators.python import (
PythonVirtualenvOperator,
ShortCircuitOperator,
)
from airflow.sensors.bash import BashSensor
from airflow.sensors.date_time import DateTimeSensor
BranchPythonOperator()
PythonOperator()
PythonVirtualenvOperator()
ShortCircuitOperator()
BashSensor()
DateTimeSensor()
from airflow.sensors.date_time import DateTimeSensorAsync
from airflow.sensors.external_task import (
ExternalTaskMarker,
ExternalTaskSensor,
)
from airflow.sensors.time_sensor import (
TimeSensor,
TimeSensorAsync,
)
from airflow.sensors.filesystem import FileSensor
from airflow.sensors.python import PythonSensor
BranchPythonOperator()
PythonOperator()
@ -49,6 +54,13 @@ DateTimeSensorAsync()
ExternalTaskMarker()
ExternalTaskSensor()
FileSensor()
PythonSensor()
from airflow.sensors.time_sensor import (
TimeSensor,
TimeSensorAsync,
)
TimeSensor()
TimeSensorAsync()

View File

@ -215,6 +215,12 @@ fn check_names_moved_to_provider(checker: &Checker, expr: &Expr, ranged: TextRan
version: "0.0.1",
}
}
["airflow", "sensors", "bash", "BashSensor"] => ProviderReplacement::AutoImport {
module: "airflow.providers.standard.sensor.bash",
name: "BashSensor",
provider: "standard",
version: "0.0.1",
},
[
"airflow",
"sensors",
@ -243,6 +249,12 @@ fn check_names_moved_to_provider(checker: &Checker, expr: &Expr, ranged: TextRan
provider: "standard",
version: "0.0.2",
},
["airflow", "sensors", "python", "PythonSensor"] => ProviderReplacement::AutoImport {
module: "airflow.providers.standard.sensors.python",
name: "PythonSensor",
provider: "standard",
version: "0.0.1",
},
[
"airflow",
"sensors",

View File

@ -227,6 +227,19 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
module: "airflow.sdk",
name: (*rest).to_string(),
},
[
"airflow",
"decorators",
"base",
rest @ ("DecoratedMappedOperator"
| "DecoratedOperator"
| "TaskDecorator"
| "get_unique_task_id"
| "task_decorator_factory"),
] => Replacement::SourceModuleMoved {
module: "airflow.sdk.bases.decorator",
name: (*rest).to_string(),
},
// airflow.io
["airflow", "io", "path", "ObjectStoragePath"] => Replacement::SourceModuleMoved {
@ -245,6 +258,10 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
name: (*rest).to_string(),
}
}
["airflow", "models", "Param"] => Replacement::AutoImport {
module: "airflow.sdk.definitions.param",
name: "Param",
},
// airflow.models.baseoperator
[
@ -260,16 +277,30 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
module: "airflow.sdk",
name: "BaseOperatorLink",
},
// airflow.model..DAG
["airflow", "models", .., "DAG"] => Replacement::SourceModuleMoved {
module: "airflow.sdk",
name: "DAG".to_string(),
},
// airflow.sensors.base
[
"airflow",
"sensors",
"base",
rest @ ("BaseSensorOperator" | "PokeReturnValue" | "poke_mode_only"),
] => Replacement::SourceModuleMoved {
module: "airflow.sdk",
name: (*rest).to_string(),
},
// airflow.timetables
["airflow", "timetables", "datasets", "DatasetOrTimeSchedule"] => Replacement::AutoImport {
module: "airflow.timetables.assets",
name: "AssetOrTimeSchedule",
},
// airflow.utils
[
"airflow",

View File

@ -614,6 +614,8 @@ AIR311 [*] `airflow.utils.dag_parsing_context.get_parsing_context` is removed in
75 | # airflow.utils.dag_parsing_context
76 | get_parsing_context()
| ^^^^^^^^^^^^^^^^^^^
77 |
78 | from airflow.decorators.base import (
|
help: Use `get_parsing_context` from `airflow.sdk` instead.
@ -626,3 +628,211 @@ help: Use `get_parsing_context` from `airflow.sdk` instead.
71 71 |
72 72 | # airflow.timetables.datasets
73 73 | DatasetOrTimeSchedule()
AIR311 [*] `airflow.decorators.base.DecoratedMappedOperator` is removed in Airflow 3.0; It still works in Airflow 3.0 but is expected to be removed in a future version.
--> AIR311_names.py:87:1
|
86 | # airflow.decorators.base
87 | DecoratedMappedOperator()
| ^^^^^^^^^^^^^^^^^^^^^^^
88 | DecoratedOperator()
89 | TaskDecorator()
|
help: Use `DecoratedMappedOperator` from `airflow.sdk.bases.decorator` instead.
Unsafe fix
76 76 | get_parsing_context()
77 77 |
78 78 | from airflow.decorators.base import (
79 |- DecoratedMappedOperator,
80 79 | DecoratedOperator,
81 80 | TaskDecorator,
82 81 | get_unique_task_id,
83 82 | task_decorator_factory,
84 83 | )
84 |+from airflow.sdk.bases.decorator import DecoratedMappedOperator
85 85 |
86 86 | # airflow.decorators.base
87 87 | DecoratedMappedOperator()
AIR311 [*] `airflow.decorators.base.DecoratedOperator` is removed in Airflow 3.0; It still works in Airflow 3.0 but is expected to be removed in a future version.
--> AIR311_names.py:88:1
|
86 | # airflow.decorators.base
87 | DecoratedMappedOperator()
88 | DecoratedOperator()
| ^^^^^^^^^^^^^^^^^
89 | TaskDecorator()
90 | get_unique_task_id()
|
help: Use `DecoratedOperator` from `airflow.sdk.bases.decorator` instead.
Unsafe fix
77 77 |
78 78 | from airflow.decorators.base import (
79 79 | DecoratedMappedOperator,
80 |- DecoratedOperator,
81 80 | TaskDecorator,
82 81 | get_unique_task_id,
83 82 | task_decorator_factory,
84 83 | )
84 |+from airflow.sdk.bases.decorator import DecoratedOperator
85 85 |
86 86 | # airflow.decorators.base
87 87 | DecoratedMappedOperator()
AIR311 [*] `airflow.decorators.base.TaskDecorator` is removed in Airflow 3.0; It still works in Airflow 3.0 but is expected to be removed in a future version.
--> AIR311_names.py:89:1
|
87 | DecoratedMappedOperator()
88 | DecoratedOperator()
89 | TaskDecorator()
| ^^^^^^^^^^^^^
90 | get_unique_task_id()
91 | task_decorator_factory()
|
help: Use `TaskDecorator` from `airflow.sdk.bases.decorator` instead.
Unsafe fix
78 78 | from airflow.decorators.base import (
79 79 | DecoratedMappedOperator,
80 80 | DecoratedOperator,
81 |- TaskDecorator,
82 81 | get_unique_task_id,
83 82 | task_decorator_factory,
84 83 | )
84 |+from airflow.sdk.bases.decorator import TaskDecorator
85 85 |
86 86 | # airflow.decorators.base
87 87 | DecoratedMappedOperator()
AIR311 [*] `airflow.decorators.base.get_unique_task_id` is removed in Airflow 3.0; It still works in Airflow 3.0 but is expected to be removed in a future version.
--> AIR311_names.py:90:1
|
88 | DecoratedOperator()
89 | TaskDecorator()
90 | get_unique_task_id()
| ^^^^^^^^^^^^^^^^^^
91 | task_decorator_factory()
|
help: Use `get_unique_task_id` from `airflow.sdk.bases.decorator` instead.
Unsafe fix
79 79 | DecoratedMappedOperator,
80 80 | DecoratedOperator,
81 81 | TaskDecorator,
82 |- get_unique_task_id,
83 82 | task_decorator_factory,
84 83 | )
84 |+from airflow.sdk.bases.decorator import get_unique_task_id
85 85 |
86 86 | # airflow.decorators.base
87 87 | DecoratedMappedOperator()
AIR311 [*] `airflow.decorators.base.task_decorator_factory` is removed in Airflow 3.0; It still works in Airflow 3.0 but is expected to be removed in a future version.
--> AIR311_names.py:91:1
|
89 | TaskDecorator()
90 | get_unique_task_id()
91 | task_decorator_factory()
| ^^^^^^^^^^^^^^^^^^^^^^
|
help: Use `task_decorator_factory` from `airflow.sdk.bases.decorator` instead.
Unsafe fix
80 80 | DecoratedOperator,
81 81 | TaskDecorator,
82 82 | get_unique_task_id,
83 |- task_decorator_factory,
84 83 | )
84 |+from airflow.sdk.bases.decorator import task_decorator_factory
85 85 |
86 86 | # airflow.decorators.base
87 87 | DecoratedMappedOperator()
AIR311 [*] `airflow.models.Param` is removed in Airflow 3.0; It still works in Airflow 3.0 but is expected to be removed in a future version.
--> AIR311_names.py:97:1
|
96 | # airflow.models
97 | Param()
| ^^^^^
|
help: Use `Param` from `airflow.sdk.definitions.param` instead.
Unsafe fix
91 91 | task_decorator_factory()
92 92 |
93 93 |
94 |-from airflow.models import Param
94 |+from airflow.sdk.definitions.param import Param
95 95 |
96 96 | # airflow.models
97 97 | Param()
AIR311 [*] `airflow.sensors.base.BaseSensorOperator` is removed in Airflow 3.0; It still works in Airflow 3.0 but is expected to be removed in a future version.
--> AIR311_names.py:107:1
|
106 | # airflow.sensors.base
107 | BaseSensorOperator()
| ^^^^^^^^^^^^^^^^^^
108 | PokeReturnValue()
109 | poke_mode_only()
|
help: Use `BaseSensorOperator` from `airflow.sdk` instead.
Unsafe fix
98 98 |
99 99 |
100 100 | from airflow.sensors.base import (
101 |- BaseSensorOperator,
102 101 | PokeReturnValue,
103 102 | poke_mode_only,
104 103 | )
104 |+from airflow.sdk import BaseSensorOperator
105 105 |
106 106 | # airflow.sensors.base
107 107 | BaseSensorOperator()
AIR311 [*] `airflow.sensors.base.PokeReturnValue` is removed in Airflow 3.0; It still works in Airflow 3.0 but is expected to be removed in a future version.
--> AIR311_names.py:108:1
|
106 | # airflow.sensors.base
107 | BaseSensorOperator()
108 | PokeReturnValue()
| ^^^^^^^^^^^^^^^
109 | poke_mode_only()
|
help: Use `PokeReturnValue` from `airflow.sdk` instead.
Unsafe fix
99 99 |
100 100 | from airflow.sensors.base import (
101 101 | BaseSensorOperator,
102 |- PokeReturnValue,
103 102 | poke_mode_only,
104 103 | )
104 |+from airflow.sdk import PokeReturnValue
105 105 |
106 106 | # airflow.sensors.base
107 107 | BaseSensorOperator()
AIR311 [*] `airflow.sensors.base.poke_mode_only` is removed in Airflow 3.0; It still works in Airflow 3.0 but is expected to be removed in a future version.
--> AIR311_names.py:109:1
|
107 | BaseSensorOperator()
108 | PokeReturnValue()
109 | poke_mode_only()
| ^^^^^^^^^^^^^^
|
help: Use `poke_mode_only` from `airflow.sdk` instead.
Unsafe fix
100 100 | from airflow.sensors.base import (
101 101 | BaseSensorOperator,
102 102 | PokeReturnValue,
103 |- poke_mode_only,
104 103 | )
104 |+from airflow.sdk import poke_mode_only
105 105 |
106 106 | # airflow.sensors.base
107 107 | BaseSensorOperator()

View File

@ -398,7 +398,7 @@ def f_okay(c: Callable[[], None]):
c.__qualname__ = "my_callable"
result = getattr_static(c, "__qualname__")
reveal_type(result) # revealed: Never
reveal_type(result) # revealed: property
if isinstance(result, property) and result.fset:
c.__qualname__ = "my_callable" # okay
```

View File

@ -3395,19 +3395,14 @@ impl<'db> Type<'db> {
let name_str = name.as_str();
match self {
Type::Union(union) => union
.map_with_boundness(db, |elem| {
elem.member_lookup_with_policy(db, name_str.into(), policy)
.place
})
.into(),
Type::Union(union) => union.map_with_boundness_and_qualifiers(db, |elem| {
elem.member_lookup_with_policy(db, name_str.into(), policy)
}),
Type::Intersection(intersection) => intersection
.map_with_boundness(db, |elem| {
.map_with_boundness_and_qualifiers(db, |elem| {
elem.member_lookup_with_policy(db, name_str.into(), policy)
.place
})
.into(),
}),
Type::Dynamic(..) | Type::Never => Place::bound(self).into(),
@ -10177,8 +10172,8 @@ impl<'db> IntersectionType<'db> {
let mut builder = IntersectionBuilder::new(db);
let mut qualifiers = TypeQualifiers::empty();
let mut any_unbound = false;
let mut any_possibly_unbound = false;
let mut all_unbound = true;
let mut any_definitely_bound = false;
for ty in self.positive_elements_or_object(db) {
let PlaceAndQualifiers {
place: member,
@ -10186,12 +10181,11 @@ impl<'db> IntersectionType<'db> {
} = transform_fn(&ty);
qualifiers |= new_qualifiers;
match member {
Place::Unbound => {
any_unbound = true;
}
Place::Unbound => {}
Place::Type(ty_member, member_boundness) => {
if member_boundness == Boundness::PossiblyUnbound {
any_possibly_unbound = true;
all_unbound = false;
if member_boundness == Boundness::Bound {
any_definitely_bound = true;
}
builder = builder.add_positive(ty_member);
@ -10200,15 +10194,15 @@ impl<'db> IntersectionType<'db> {
}
PlaceAndQualifiers {
place: if any_unbound {
place: if all_unbound {
Place::Unbound
} else {
Place::Type(
builder.build(),
if any_possibly_unbound {
Boundness::PossiblyUnbound
} else {
if any_definitely_bound {
Boundness::Bound
} else {
Boundness::PossiblyUnbound
},
)
},