Skip to content

Generate distributable binaries with cargo-dist#2566

Closed
charliermarsh wants to merge 2 commits intomainfrom
charlie/cargo-dist
Closed

Generate distributable binaries with cargo-dist#2566
charliermarsh wants to merge 2 commits intomainfrom
charlie/cargo-dist

Conversation

@charliermarsh
Copy link
Member

No description provided.

carljm pushed a commit that referenced this pull request Jan 20, 2026
Fix issue #2566 where assigning to an instance attribute in a decorated
method (like @cache) incorrectly resulted in `Unknown | int` instead of
just `int` when the attribute was declared in `__init__`.

The bug was in the `is_valid_scope` closure in `implicit_attribute_inner`.
When looking up class members for the descriptor protocol, it calls
`implicit_attribute` with `MethodDecorator::ClassMethod`. The closure
determines which method scopes are valid for a given target decorator.

For methods wrapped by decorators like `@cache`, the method type becomes
`_lru_cache_wrapper[...]` instead of `FunctionLiteral`. The previous code
fell through to `_ => {}` and always returned `true`, incorrectly accepting
these methods when looking for classmethods.

The fix adds explicit handling for non-FunctionLiteral types:
- For dynamic types (Unknown), be permissive since the decorator could be
  anything including a classmethod alias
- For known concrete types (like `_lru_cache_wrapper`), reject them when
  looking for ClassMethod/StaticMethod since we know they aren't
carljm added a commit that referenced this pull request Jan 20, 2026
…corated method

Add a regression test for issue #2566 to ensure that when an attribute is
declared with a type annotation in `__init__` and assigned in a decorated
method (like `@cache`), we respect the declared type from `__init__`.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
carljm added a commit that referenced this pull request Jan 20, 2026
Fix issue #2566 where assigning to an instance attribute in a decorated
method (like @cache) incorrectly resulted in `Unknown | int` instead of
just `int` when the attribute was declared in `__init__`.

The bug was in the `is_valid_scope` closure in `implicit_attribute_inner`.
When looking up class members for the descriptor protocol, it calls
`implicit_attribute` with `MethodDecorator::ClassMethod`. The previous code
relied on the final evaluated type of the method (after all decorators are
applied) to determine if it's a classmethod. For methods wrapped by `@cache`,
the final type becomes `_lru_cache_wrapper[...]` instead of `FunctionLiteral`,
which caused incorrect behavior.

The fix changes the approach to directly iterate through the decorators on
the AST node and check if any of their types evaluate to `classmethod` or
`staticmethod`. This is more reliable because:
- It checks the original decorator types, not the final wrapped result
- It correctly handles methods with multiple decorators like `@cache @classmethod`
- It maintains the gradual typing guarantee for unknown decorators
carljm added a commit that referenced this pull request Jan 20, 2026
Fix issue #2566 where assigning to an instance attribute in a decorated
method (like @cache) incorrectly resulted in `Unknown | int` instead of
just `int` when the attribute was declared in `__init__`.

The bug was in the `is_valid_scope` closure in `implicit_attribute_inner`.
When looking up class members for the descriptor protocol, it calls
`implicit_attribute` with `MethodDecorator::ClassMethod`. The previous code
relied on the final evaluated type of the method (after all decorators are
applied) to determine if it's a classmethod. For methods wrapped by `@cache`,
the final type becomes `_lru_cache_wrapper[...]` instead of `FunctionLiteral`,
which caused incorrect behavior.

The fix changes the approach to directly iterate through the decorators on
the AST node and check if any of their types evaluate to `classmethod` or
`staticmethod`. This is more reliable because:
- It checks the original decorator types, not the final wrapped result
- It correctly handles methods with multiple decorators like `@cache @classmethod`
- It maintains the gradual typing guarantee for unknown decorators
carljm added a commit that referenced this pull request Jan 20, 2026
Fix issue #2566 where assigning to an instance attribute in a decorated
method (like @cache) incorrectly resulted in `Unknown | int` instead of
just `int` when the attribute was declared in `__init__`.

The bug was in the `is_valid_scope` closure in `implicit_attribute_inner`.
When looking up class members for the descriptor protocol, it calls
`implicit_attribute` with `MethodDecorator::ClassMethod`. The previous code
relied on the final evaluated type of the method (after all decorators are
applied) to determine if it's a classmethod. For methods wrapped by `@cache`,
the final type becomes `_lru_cache_wrapper[...]` instead of `FunctionLiteral`,
which caused incorrect behavior.

The fix changes the approach to directly iterate through the decorators on
the AST node and check if any of their types evaluate to `classmethod` or
`staticmethod`. This is more reliable because it checks the original
decorator types, not the final wrapped result.

Also removes the special handling for unknown decorators that assumed they
might be classmethod aliases. This was causing attributes defined in methods
with unknown decorators to pollute class-level lookups.
carljm added a commit that referenced this pull request Jan 20, 2026
Fix issue #2566 where assigning to an instance attribute in a decorated
method (like @cache) incorrectly resulted in `Unknown | int` instead of
just `int` when the attribute was declared in `__init__`.

The bug was in the `is_valid_scope` closure in `implicit_attribute_inner`.
When looking up class members for the descriptor protocol, it calls
`implicit_attribute` with `MethodDecorator::ClassMethod`. The previous code
relied on the final evaluated type of the method (after all decorators are
applied) to determine if it's a classmethod. For methods wrapped by `@cache`,
the final type becomes `_lru_cache_wrapper[...]` instead of `FunctionLiteral`,
which caused incorrect behavior.

The fix changes the approach to directly iterate through the decorators on
the AST node and check if any of their types evaluate to `classmethod` or
`staticmethod`. This is more reliable because it checks the original
decorator types, not the final wrapped result.

Also removes the assumption that unknown decorators might be
classmethod/staticmethod aliases. This caused attributes defined in
methods with unknown decorators to pollute class-level lookups and
potentially override instance-level attributes.
carljm added a commit that referenced this pull request Jan 21, 2026
Fix issue #2566 where assigning to an instance attribute in a decorated
method (like @cache) incorrectly resulted in `Unknown | int` instead of
just `int` when the attribute was declared in `__init__`.

The bug was in the `is_valid_scope` closure in `implicit_attribute_inner`.
When looking up class members for the descriptor protocol, it calls
`implicit_attribute` with `MethodDecorator::ClassMethod`. The previous code
relied on the final evaluated type of the method (after all decorators are
applied) to determine if it's a classmethod. For methods wrapped by `@cache`,
the final type becomes `_lru_cache_wrapper[...]` instead of `FunctionLiteral`,
which caused incorrect behavior.

The fix changes the approach to directly iterate through the decorators on
the AST node and check if any of their types evaluate to `classmethod` or
`staticmethod`. This is more reliable because it checks the original
decorator types, not the final wrapped result.

Also removes the assumption that unknown decorators might be
classmethod/staticmethod aliases. This caused attributes defined in
methods with unknown decorators to pollute class-level lookups and
potentially override instance-level attributes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant