Repository: astral-sh/ruff
File: crates/ty_ide/src/symbols.rs (Rust)

Code before:
                ",
            )
            .build();
        // This is not quite right either because we end up
        // considering the `__all__` in `test.py` to be invalid.
        // Namely, we don't pick up the `foo` that is in scope
        // from the `from parent import *` import. The correct
        // answer should just be `_ZFZFZF` and `_ZYZYZY`.
        insta::assert_snapshot!(
            test.exports_for("test.py"),
            @r"
        _ZFZFZF :: Constant :: Re-exported from `parent.foo`
        foo :: Module :: Re-exported from `parent`
        _ZYZYZY :: Constant
        __all__ :: Variable
        ",
        );
    }

    /// Tests that a work-around which unions `__all__` values lets
    /// us find conditionally exported symbols.
    ///
    /// However, this also means that we may suggest exported symbols
    /// even when they aren't available. What we should ideally do is
    /// evaluate the conditional like ty does, but this requires some
    /// work. (And it's unlikely auto-import will ever get the full
    /// evaluation capabilities as ty, so it's likely this sort of
    /// union work-around will always be something we do in at least
    /// some cases.)
    #[test]
    fn union_all_to_work_around_conditional_symbols() {
        let test = PublicTestBuilder::default()
            .source(
                "test.py",
                "
                import sys
                if sys.version_info >= (3, 11):
                    ZQZQZQ = 1
                else:
                    ZYZYZY = 1

                if sys.version_info >= (3, 11):
                    __all__ = ['ZQZQZQ']
                else:
                    __all__ = ['ZYZYZY]
                ",
            )
            .build();
        insta::assert_snapshot!(
            test.exports(),
            @"ZQZQZQ :: Constant",

Review comment (suggestion):
You could possibly add two versions of this test with two different config files: one that sets `environment.python-version = "3.11"`, and another that sets `environment.python-version = "3.10"`. With the solution that this PR introduces, both of them would behave the same way, but ideally of course we'd only include the `ZQZQZQ` suggestion on 3.11+, and we'd only include the `ZYZYZY` suggestion on <=3.10

Code after:
                 __all__.extend(foo.__all__)
                ",
            )
            .build();
        // This is not quite right either because we end up
        // considering the `__all__` in `test.py` to be invalid.
        // Namely, we don't pick up the `foo` that is in scope
        // from the `from parent import *` import. The correct
        // answer should just be `_ZFZFZF` and `_ZYZYZY`.
        insta::assert_snapshot!(
            test.exports_for("test.py"),
            @r"
        _ZFZFZF :: Constant :: Re-exported from `parent.foo`
        foo :: Module :: Re-exported from `parent`
        _ZYZYZY :: Constant
        __all__ :: Variable
        ",
        );
    }

    /// Tests that a work-around which unions `__all__` values lets
    /// us find conditionally exported symbols.
    ///
    /// However, this also means that we may suggest exported symbols
    /// even when they aren't available. What we should ideally do is
    /// evaluate the conditional like ty does, but this requires some
    /// work. (And it's unlikely auto-import will ever get the full
    /// evaluation capabilities as ty, so it's likely this sort of
    /// union work-around will always be something we do in at least
    /// some cases.)
    #[test]
    fn union_all_to_work_around_conditional_symbols_py311() {
        let test = PublicTestBuilder::default()
            .python_version(PythonVersion::PY311)
            .source(
                "test.py",
                "
                import sys
                if sys.version_info >= (3, 11):
                    ZQZQZQ = 1
                else:
                    ZYZYZY = 1

                if sys.version_info >= (3, 11):
                    __all__ = ['ZQZQZQ']
                else:
                    __all__ = ['ZYZYZY']
                ",
            )
            .build();
        // Ideally this would only have `ZQZQZQ`.