diff --git a/mypy/checkmember.py b/mypy/checkmember.py
--- a/mypy/checkmember.py
+++ b/mypy/checkmember.py
@@ -654,7 +654,7 @@ def analyze_descriptor_access(descriptor_type: Type, mx: MemberContext) -> Type:
                 analyze_descriptor_access(
                     descriptor_type, mx.copy_modified(original_type=original_type)
                 )
-                for original_type in instance_type.items
+                for original_type in instance_type.relevant_items()
             ]
         )
     elif not isinstance(descriptor_type, Instance):

`mypy_primer -p test.py --bisect --debug --old 'v1.9.0' --new 'v1.10.0'` bisects this to #16604
diff --git a/test-data/unit/check-unions.test b/test-data/unit/check-unions.test
--- a/test-data/unit/check-unions.test
+++ b/test-data/unit/check-unions.test
@@ -1258,3 +1258,34 @@ reveal_type(mix)  # N: Revealed type is "Union[Type[__main__.A], Type[__main__.B
 reveal_type(mix.field_1)  # N: Revealed type is "builtins.list[builtins.int]"
 reveal_type(mix().field_1)  # N: Revealed type is "builtins.int"
 [builtins fixtures/list.pyi]
+
+
+[case testDescriptorAccessForUnionOfTypesWithNoStrictOptional]
+# mypy: no-strict-optional
+from typing import overload, Generic, Any, TypeVar, List, Optional, Union, Type
+
+class Descriptor:
+    @overload
+    def __get__(
+        self, instance: None, owner: type
+    ) -> str:
+        ...
+
+    @overload
+    def __get__(self, instance: object, owner: type) -> int:
+        ...
+
+    def __get__(
+        self, instance: Optional[object], owner: type
+    ) -> Union[str, int]:
+        ...
+
+class A:
+    field = Descriptor()
+
+a_class_or_none: Optional[Type[A]]
+x: str = a_class_or_none.field
+
+a_or_none: Optional[A]
+y: int = a_or_none.field
+[builtins fixtures/list.pyi]

Descriptors that have different behavior on instance and class don't work with `no-strict-optional`
**Bug Report**

Descriptors that detect whether the property is being invoked on an instance or the class itself don't work correctly with `no-strict-optional`, and instead act like they are being invoked on a union of an instance and the class itself.

**To Reproduce**
https://gist.github.com/mypy-play/20278be77b4ecaca10c4e180752808c4

Bug appears on 1.10.0 but not on 1.9.0.

**Expected Behavior**

No errors.

**Actual Behavior**

main.py:21: error: Incompatible types in assignment (expression has type "str | int", variable has type "str")  [assignment]


mypy/test/testcheck.py::TypeCheckSuite::check-unions.test::testDescriptorAccessForUnionOfTypesWithNoStrictOptional