Repository: astral-sh/ruff
File: crates/ty_python_semantic/src/place.rs (Rust)

Code before:
                db,
                scope,
                symbol.into(),
                requires_explicit_reexport,
                considered_definitions,
            )
        })
        .unwrap_or_default();

    if name == "platform"
        && file_to_module(db, scope.file(db))
            .is_some_and(|module| module.is_known(db, KnownModule::Sys))
    {
        match Program::get(db).python_platform(db) {
            crate::PythonPlatform::Identifier(platform) => {
                return Place::bound(Type::string_literal(db, platform.as_str())).into();
            }
            crate::PythonPlatform::All => {
                // Fall through to the looked up type
            }
        }
    } else if name == "__file__" {
        // We special-case `__file__` here because we know that for a successfully imported
        // Python module, that hasn't been explicitly overridden it is always a string,
        // even though typeshed says `str | None`.
        // This is not assumed to be the case for stubs though, where we will stick with typeshed
        if let Some(module) = file_to_module(db, scope.file(db)) {
            if let Some(f) = module.file(db) {
                if !f.is_stub(db) {
                    let implicit_type = KnownClass::Str.to_instance(db);

                    match place.place {
                        // If explicitly Undefined we assume str
                        Place::Undefined => {
                            return Place::bound(implicit_type).into();
                        }
                        // If possibly undefined, union with the implicit type
                        Place::Defined(ty, origin, Definedness::PossiblyUndefined, widening) => {
                            let new_type = UnionType::from_elements(db, [ty, implicit_type]);
                            return Place::Defined(
                                new_type,
                                origin,
                                Definedness::AlwaysDefined,
                                widening,
                            )
                            .with_qualifiers(place.qualifiers);
                        }
                        // If explicitly defined, respect the definition
                        Place::Defined(_, _, Definedness::AlwaysDefined, _) => {
                            return place;
                        }

Review comment (security):
This comment is _nearly_ accurate!

The way it works at runtime is that a pure-Python non-namespace-package module will always have `__file__` set to a string; a namespace-package module will always have `__file__` set to `None`, and a C extension might not have it set at all:

```pycon
% uv pip install google-cloud-ndb           
Using Python 3.13.8 environment at: test-env
Resolved 22 packages in 647ms
Prepared 9 packages in 1.07s
Installed 21 packages in 92ms
 + certifi==2026.1.4
 + charset-normalizer==3.4.4
 + google-api-core==2.29.0
 + google-auth==2.47.0
 + google-cloud-core==2.5.0
 + google-cloud-datastore==2.23.0
 + google-cloud-ndb==2.4.0
 + googleapis-common-protos==1.72.0
 + grpcio==1.76.0
 + grpcio-status==1.76.0
 + idna==3.11
 + proto-plus==1.27.0
 + protobuf==6.33.4
 + pyasn1==0.6.1
 + pyasn1-modules==0.4.2
 + pymemcache==4.0.0
 + pytz==2025.2
 + redis==6.4.0
 + requests==2.32.5
 + rsa==4.9.1
 + urllib3==2.6.3
(test-env) ~/dev % py
Python 3.13.8 (main, Oct 10 2025, 12:46:18) [Clang 20.1.4 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import google
>>> google.__file__ is None  # `google` is a namespace package
True
>>> 
>>> import itertools
>>> itertools.__file__  # `itertools` is a C extension
Traceback (most recent call last):
  File "<python-input-3>", line 1, in <module>
    itertools.__file__
AttributeError: module 'itertools' has no attribute '__file__'. Did you mean: '__name__'?
```

It looks to me like your code is correct for the namespace package case, because you only apply the special case here if `module.file(db)` is `Some()`, and `module.file(db)` will only be `None` if it's a namespace package. But the comment here needs to be revised, and you could also consider adding an explicit test for the namespace-package case. (Namespace packages are pure-Python packages that have no `__init__.py(i)` file in them -- they are _just_ directories that contain other Python modules/packages.)

We could also possibly get rid of the exemption for stubs that you have here? The rationale for treating stubs separately is that they might represent C extensions, and C extensions won't necessarily set `__file__`. But that doesn't affect the _type_ of the `__file__` member, it just affects whether the module _has_ the `__file__` member to begin with. We could consider emitting a `possibly-unresolved-attribute` warning about that, but I think it would probably be too noisy: just because a module is represented by a stub file doesn't mean that it _definitely_ is a C extension, it just _could_ be a C extension.

Code after:
                || is_module_global
                || scope_has_private_visibility
                || in_stub_file
            {
                inferred.into()
            } else {
                // Gradual typing guarantee: Mark undeclared public symbols for widening.
                // The actual union with `Unknown` is applied lazily when converting to
                // LookupResult via `into_lookup_result`.
                inferred.with_widening(Widening::WithUnknown).into()
            }
        }
    }

    // TODO (ticket: https://github.com/astral-sh/ruff/issues/14297) Our handling of boundness
    // currently only depends on bindings, and ignores declarations. This is inconsistent, since
    // we only look at bindings if the place may be undeclared. Consider the following example:
    // ```py
    // x: int
    //
    // if flag:
    //     y: int
    // else
    //     y = 3
    // ```
    // If we import from this module, we will currently report `x` as a definitely-bound place
    // (even though it has no bindings at all!) but report `y` as possibly-unbound (even though
    // every path has either a binding or a declaration for it.)
}

/// Implementation of [`symbol`].
fn symbol_impl<'db>(
    db: &'db dyn Db,
    scope: ScopeId<'db>,
    name: &str,
    requires_explicit_reexport: RequiresExplicitReExport,
    considered_definitions: ConsideredDefinitions,
) -> PlaceAndQualifiers<'db> {
    let _span = tracing::trace_span!("symbol", ?name).entered();
    let place = place_table(db, scope)
        .symbol_id(name)
        .map(|symbol| {
            place_by_id(
                db,
                scope,
                symbol.into(),
                requires_explicit_reexport,
                considered_definitions,
            )
        })
        .unwrap_or_default();