-
Notifications
You must be signed in to change notification settings - Fork 239
fix Reading __v from the outside of the class, pyrefly doesn't give any error while Python interpreter gives error #1971 #1980
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds static analysis to detect attempts to access private attributes (names starting with __ but not ending with __) from outside their defining context, addressing issue #1971 where pyrefly was not catching errors that Python's interpreter would raise.
- Implements a new check for private attribute access in the binding phase
- Adds test case covering module-level and class-body access to private attributes
- Reports errors when private attributes are accessed outside function scopes
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| pyrefly/lib/binding/expr.rs | Adds check_private_attribute_usage method to detect and report errors when accessing private attributes, integrated into the ensure_expr flow for attribute expressions |
| pyrefly/lib/test/attributes.rs | Adds test case test_private_attribute_outside_class to verify error reporting for private attribute access from module level and within other class bodies |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
pyrefly/lib/binding/expr.rs
Outdated
| if self.scopes.in_function_scope() { | ||
| return; |
Copilot
AI
Jan 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic for detecting invalid private attribute access appears incorrect. Using in_function_scope() will allow access from any function (including functions outside the defining class), but Python's name mangling rules mean that __secret is only accessible within the class body where it's defined. The check should verify whether the access is happening within the defining class's scope, not just any function scope. For example, a function at module level or inside a different class should still be flagged as an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but Python's name mangling rules mean that __secret is only accessible within the class body where it's defined.
well, this will be lated after other post issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asukaminato0721 this seems buggy:
we can't simply allow all function scope accesses. for example,
class A:
__v = 100
def f():
a = A()
print(a.__v)
f()
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
I like this error. I wonder if we should also come up with a way to allow accessing name-mangled references to this private attribute. python allows accessing this with the |
pyrefly/lib/binding/expr.rs
Outdated
| if self.scopes.in_function_scope() { | ||
| return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asukaminato0721 this seems buggy:
we can't simply allow all function scope accesses. for example,
class A:
__v = 100
def f():
a = A()
print(a.__v)
f()
|
This is a bit complex, since I impl it more strict first, but the stat tells me it's not proper. one of the example is |
|
@asukaminato0721 IMO it's reasonable for pyrefly to emit an error on https://github.com/DataDog/dd-trace-py/blob/d18e59ecf2f12cc407eb4dd4e1d647dee3276533/ddtrace/appsec/_iast/_handlers.py#L276. The runtime magic that the code is doing to patch pyrefly/pyrefly/lib/binding/scope.rs Line 805 in ab7ce84
|
rchen152
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Marking this as changes requested to clear it from my queue.)
|
I can't visit fb website so this is pub link pyrefly/pyrefly/lib/binding/scope.rs Line 805 in ab7ce84
I have seem this pattern: class F:
...
def __eq__(self, o):
return self.__v == o.__v |
| "#, | ||
| ); | ||
|
|
||
| testcase!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is turning out to be pretty involved, it would be good to have more test cases:
__secretbeing accessed in a function outside the defining class (should error)__secretbeing accessed in the defining class (should not error)__secretbeing accessed in a subclass (should error)
Sorry about that! I've updated the link XD
Oh hmm. To support that case, I think it would be easier to defer the check to the answers phase, which can be done like so:
|
well Update pyrefly/lib/binding/expr.rs Co-authored-by: Copilot <[email protected]> Update pyrefly/lib/test/attributes.rs Co-authored-by: Copilot <[email protected]> fix typo
|
Diff from mypy_primer, showing the effect of this PR on open source code: nionutils (https://github.com/nion-software/nionutils)
+ ERROR nion/utils/Event.py:82:23-45: Private attribute `__weak_listeners_mutex` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/Event.py:83:22-38: Private attribute `__weak_listeners` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/Event.py:90:26-37: Private attribute `__listeners` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/ListModel.py:614:46-64: Private attribute `__master_items_key` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/ListModel.py:615:76-87: Private attribute `__items_key` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/ListModel.py:618:46-64: Private attribute `__master_items_key` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/ListModel.py:619:74-85: Private attribute `__items_key` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/ListModel.py:620:53-65: Private attribute `__selections` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/ListModel.py:622:64-83: Private attribute `__selection_changes` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/ListModel.py:785:42-60: Private attribute `__master_items_key` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/ListModel.py:789:42-60: Private attribute `__master_items_key` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/Stream.py:238:20-35: Private attribute `__value_changed` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/Stream.py:288:20-35: Private attribute `__value_changed` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/Stream.py:355:20-43: Private attribute `__source_object_changed` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/Stream.py:370:24-42: Private attribute `__property_changed` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/Stream.py:393:20-35: Private attribute `__value_changed` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/Stream.py:441:20-35: Private attribute `__value_changed` cannot be accessed outside of its defining class [no-access]
+ ERROR nion/utils/Stream.py:458:15-30: Private attribute `__value_changed` cannot be accessed outside of its defining class [no-access]
+ ::error file=nion/utils/Event.py,line=82,col=23,endLine=82,endColumn=45,title=Pyrefly no-access::Private attribute `__weak_listeners_mutex` cannot be accessed outside of its defining class
+ ::error file=nion/utils/Event.py,line=83,col=22,endLine=83,endColumn=38,title=Pyrefly no-access::Private attribute `__weak_listeners` cannot be accessed outside of its defining class
+ ::error file=nion/utils/Event.py,line=90,col=26,endLine=90,endColumn=37,title=Pyrefly no-access::Private attribute `__listeners` cannot be accessed outside of its defining class
+ ::error file=nion/utils/ListModel.py,line=614,col=46,endLine=614,endColumn=64,title=Pyrefly no-access::Private attribute `__master_items_key` cannot be accessed outside of its defining class
+ ::error file=nion/utils/ListModel.py,line=615,col=76,endLine=615,endColumn=87,title=Pyrefly no-access::Private attribute `__items_key` cannot be accessed outside of its defining class
+ ::error file=nion/utils/ListModel.py,line=618,col=46,endLine=618,endColumn=64,title=Pyrefly no-access::Private attribute `__master_items_key` cannot be accessed outside of its defining class
+ ::error file=nion/utils/ListModel.py,line=619,col=74,endLine=619,endColumn=85,title=Pyrefly no-access::Private attribute `__items_key` cannot be accessed outside of its defining class
+ ::error file=nion/utils/ListModel.py,line=620,col=53,endLine=620,endColumn=65,title=Pyrefly no-access::Private attribute `__selections` cannot be accessed outside of its defining class
+ ::error file=nion/utils/ListModel.py,line=622,col=64,endLine=622,endColumn=83,title=Pyrefly no-access::Private attribute `__selection_changes` cannot be accessed outside of its defining class
+ ::error file=nion/utils/ListModel.py,line=785,col=42,endLine=785,endColumn=60,title=Pyrefly no-access::Private attribute `__master_items_key` cannot be accessed outside of its defining class
+ ::error file=nion/utils/ListModel.py,line=789,col=42,endLine=789,endColumn=60,title=Pyrefly no-access::Private attribute `__master_items_key` cannot be accessed outside of its defining class
+ ::error file=nion/utils/Stream.py,line=238,col=20,endLine=238,endColumn=35,title=Pyrefly no-access::Private attribute `__value_changed` cannot be accessed outside of its defining class
+ ::error file=nion/utils/Stream.py,line=288,col=20,endLine=288,endColumn=35,title=Pyrefly no-access::Private attribute `__value_changed` cannot be accessed outside of its defining class
+ ::error file=nion/utils/Stream.py,line=355,col=20,endLine=355,endColumn=43,title=Pyrefly no-access::Private attribute `__source_object_changed` cannot be accessed outside of its defining class
+ ::error file=nion/utils/Stream.py,line=370,col=24,endLine=370,endColumn=42,title=Pyrefly no-access::Private attribute `__property_changed` cannot be accessed outside of its defining class
+ ::error file=nion/utils/Stream.py,line=393,col=20,endLine=393,endColumn=35,title=Pyrefly no-access::Private attribute `__value_changed` cannot be accessed outside of its defining class
+ ::error file=nion/utils/Stream.py,line=441,col=20,endLine=441,endColumn=35,title=Pyrefly no-access::Private attribute `__value_changed` cannot be accessed outside of its defining class
+ ::error file=nion/utils/Stream.py,line=458,col=15,endLine=458,endColumn=30,title=Pyrefly no-access::Private attribute `__value_changed` cannot be accessed outside of its defining class
AutoSplit (https://github.com/Toufool/AutoSplit)
+ ERROR src/AutoSplit.py:214:26-46: Private attribute `__reload_start_image` cannot be accessed outside of its defining class [no-access]
+ ERROR src/AutoSplit.py:246:26-53: Private attribute `__update_live_image_details` cannot be accessed outside of its defining class [no-access]
+ ERROR src/menu_bar.py:416:26-37: Private attribute `__set_value` cannot be accessed outside of its defining class [no-access]
+ ERROR src/menu_bar.py:422:26-37: Private attribute `__set_value` cannot be accessed outside of its defining class [no-access]
+ ERROR src/menu_bar.py:422:61-85: Private attribute `__capture_method_changed` cannot be accessed outside of its defining class [no-access]
+ ERROR src/menu_bar.py:427:26-37: Private attribute `__set_value` cannot be accessed outside of its defining class [no-access]
+ ERROR src/menu_bar.py:432:26-37: Private attribute `__set_value` cannot be accessed outside of its defining class [no-access]
+ ERROR src/menu_bar.py:438:26-52: Private attribute `__update_default_threshold` cannot be accessed outside of its defining class [no-access]
+ ERROR src/menu_bar.py:443:26-37: Private attribute `__set_value` cannot be accessed outside of its defining class [no-access]
+ ERROR src/menu_bar.py:446:26-37: Private attribute `__set_value` cannot be accessed outside of its defining class [no-access]
+ ERROR src/menu_bar.py:449:26-37: Private attribute `__set_value` cannot be accessed outside of its defining class [no-access]
+ ERROR src/menu_bar.py:452:26-37: Private attribute `__set_value` cannot be accessed outside of its defining class [no-access]
+ ERROR src/menu_bar.py:458:26-37: Private attribute `__set_value` cannot be accessed outside of its defining class [no-access]
+ ::error file=src/AutoSplit.py,line=214,col=26,endLine=214,endColumn=46,title=Pyrefly no-access::Private attribute `__reload_start_image` cannot be accessed outside of its defining class
+ ::error file=src/AutoSplit.py,line=246,col=26,endLine=246,endColumn=53,title=Pyrefly no-access::Private attribute `__update_live_image_details` cannot be accessed outside of its defining class
+ ::error file=src/menu_bar.py,line=416,col=26,endLine=416,endColumn=37,title=Pyrefly no-access::Private attribute `__set_value` cannot be accessed outside of its defining class
+ ::error file=src/menu_bar.py,line=422,col=26,endLine=422,endColumn=37,title=Pyrefly no-access::Private attribute `__set_value` cannot be accessed outside of its defining class
+ ::error file=src/menu_bar.py,line=422,col=61,endLine=422,endColumn=85,title=Pyrefly no-access::Private attribute `__capture_method_changed` cannot be accessed outside of its defining class
+ ::error file=src/menu_bar.py,line=427,col=26,endLine=427,endColumn=37,title=Pyrefly no-access::Private attribute `__set_value` cannot be accessed outside of its defining class
+ ::error file=src/menu_bar.py,line=432,col=26,endLine=432,endColumn=37,title=Pyrefly no-access::Private attribute `__set_value` cannot be accessed outside of its defining class
+ ::error file=src/menu_bar.py,line=438,col=26,endLine=438,endColumn=52,title=Pyrefly no-access::Private attribute `__update_default_threshold` cannot be accessed outside of its defining class
+ ::error file=src/menu_bar.py,line=443,col=26,endLine=443,endColumn=37,title=Pyrefly no-access::Private attribute `__set_value` cannot be accessed outside of its defining class
+ ::error file=src/menu_bar.py,line=446,col=26,endLine=446,endColumn=37,title=Pyrefly no-access::Private attribute `__set_value` cannot be accessed outside of its defining class
+ ::error file=src/menu_bar.py,line=449,col=26,endLine=449,endColumn=37,title=Pyrefly no-access::Private attribute `__set_value` cannot be accessed outside of its defining class
+ ::error file=src/menu_bar.py,line=452,col=26,endLine=452,endColumn=37,title=Pyrefly no-access::Private attribute `__set_value` cannot be accessed outside of its defining class
+ ::error file=src/menu_bar.py,line=458,col=26,endLine=458,endColumn=37,title=Pyrefly no-access::Private attribute `__set_value` cannot be accessed outside of its defining class
dd-trace-py (https://github.com/DataDog/dd-trace-py)
+ ERROR ddtrace/appsec/_iast/_handlers.py:277:22-37: Private attribute `__saved_getattr` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/contrib/celery/test_utils.py:41:25-39: Private attribute `__dd_task_span` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/contrib/celery/test_utils.py:66:25-39: Private attribute `__dd_task_span` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/contrib/futures/test_propagation.py:436:42-57: Private attribute `__datadog_patch` cannot be accessed outside of its defining class [no-access]
+ ::error file=ddtrace/appsec/_iast/_handlers.py,line=277,col=22,endLine=277,endColumn=37,title=Pyrefly no-access::Private attribute `__saved_getattr` cannot be accessed outside of its defining class
+ ::error file=tests/contrib/celery/test_utils.py,line=41,col=25,endLine=41,endColumn=39,title=Pyrefly no-access::Private attribute `__dd_task_span` cannot be accessed outside of its defining class
+ ::error file=tests/contrib/celery/test_utils.py,line=66,col=25,endLine=66,endColumn=39,title=Pyrefly no-access::Private attribute `__dd_task_span` cannot be accessed outside of its defining class
+ ::error file=tests/contrib/futures/test_propagation.py,line=436,col=42,endLine=436,endColumn=57,title=Pyrefly no-access::Private attribute `__datadog_patch` cannot be accessed outside of its defining class
aiortc (https://github.com/aiortc/aiortc)
+ ERROR src/aiortc/rtcpeerconnection.py:709:26-32: Private attribute `__sctp` cannot be accessed outside of its defining class [no-access]
+ ERROR src/aiortc/rtcrtpreceiver.py:303:51-57: Private attribute `__kind` cannot be accessed outside of its defining class [no-access]
+ ERROR src/aiortc/rtcrtpsender.py:135:49-55: Private attribute `__kind` cannot be accessed outside of its defining class [no-access]
+ ::error file=src/aiortc/rtcpeerconnection.py,line=709,col=26,endLine=709,endColumn=32,title=Pyrefly no-access::Private attribute `__sctp` cannot be accessed outside of its defining class
+ ::error file=src/aiortc/rtcrtpreceiver.py,line=303,col=51,endLine=303,endColumn=57,title=Pyrefly no-access::Private attribute `__kind` cannot be accessed outside of its defining class
+ ::error file=src/aiortc/rtcrtpsender.py,line=135,col=49,endLine=135,endColumn=55,title=Pyrefly no-access::Private attribute `__kind` cannot be accessed outside of its defining class
Expression (https://github.com/cognitedata/Expression)
+ ERROR expression/core/mailbox.py:130:18-34: Private attribute `__process_events` cannot be accessed outside of its defining class [no-access]
+ ::error file=expression/core/mailbox.py,line=130,col=18,endLine=130,endColumn=34,title=Pyrefly no-access::Private attribute `__process_events` cannot be accessed outside of its defining class
discord.py (https://github.com/Rapptz/discord.py)
+ ERROR discord/abc.py:149:47-57: Private attribute `__iterator` cannot be accessed outside of its defining class [no-access]
+ ERROR discord/shard.py:552:96-104: Private attribute `__shards` cannot be accessed outside of its defining class [no-access]
+ ERROR discord/shard.py:557:18-25: Private attribute `__queue` cannot be accessed outside of its defining class [no-access]
+ ::error file=discord/abc.py,line=149,col=47,endLine=149,endColumn=57,title=Pyrefly no-access::Private attribute `__iterator` cannot be accessed outside of its defining class
+ ::error file=discord/shard.py,line=552,col=96,endLine=552,endColumn=104,title=Pyrefly no-access::Private attribute `__shards` cannot be accessed outside of its defining class
+ ::error file=discord/shard.py,line=557,col=18,endLine=557,endColumn=25,title=Pyrefly no-access::Private attribute `__queue` cannot be accessed outside of its defining class
PyGithub (https://github.com/PyGithub/PyGithub)
+ ERROR tests/Framework.py:251:43-61: Private attribute `__request_callback` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/GithubIntegration.py:310:67-78: Private attribute `__requester` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Github_.py:638:43-54: Private attribute `__requester` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:268:33-52: Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:269:33-52: Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:270:33-52: Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:271:33-52: Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:272:33-52: Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:273:33-52: Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:274:33-52: Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:275:33-52: Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:276:33-52: Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:277:33-52: Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:280:33-52: Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:281:33-52: Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:286:40-49: Private attribute `__domains` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:297:23-41: Private attribute `__assertUrlAllowed` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:307:27-45: Private attribute `__assertUrlAllowed` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:312:40-49: Private attribute `__domains` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:319:23-41: Private attribute `__assertUrlAllowed` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:337:27-45: Private attribute `__assertUrlAllowed` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:342:40-49: Private attribute `__domains` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:350:23-41: Private attribute `__assertUrlAllowed` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:368:27-45: Private attribute `__assertUrlAllowed` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:374:45-62: Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:375:45-62: Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:376:45-62: Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:377:45-62: Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:378:38-55: Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:382:49-66: Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:383:49-66: Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:384:49-66: Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:385:49-66: Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class [no-access]
+ ERROR tests/Requester.py:388:38-55: Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class [no-access]
+ ::error file=tests/Framework.py,line=251,col=43,endLine=251,endColumn=61,title=Pyrefly no-access::Private attribute `__request_callback` cannot be accessed outside of its defining class
+ ::error file=tests/GithubIntegration.py,line=310,col=67,endLine=310,endColumn=78,title=Pyrefly no-access::Private attribute `__requester` cannot be accessed outside of its defining class
+ ::error file=tests/Github_.py,line=638,col=43,endLine=638,endColumn=54,title=Pyrefly no-access::Private attribute `__requester` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=268,col=33,endLine=268,endColumn=52,title=Pyrefly no-access::Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=269,col=33,endLine=269,endColumn=52,title=Pyrefly no-access::Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=270,col=33,endLine=270,endColumn=52,title=Pyrefly no-access::Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=271,col=33,endLine=271,endColumn=52,title=Pyrefly no-access::Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=272,col=33,endLine=272,endColumn=52,title=Pyrefly no-access::Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=273,col=33,endLine=273,endColumn=52,title=Pyrefly no-access::Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=274,col=33,endLine=274,endColumn=52,title=Pyrefly no-access::Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=275,col=33,endLine=275,endColumn=52,title=Pyrefly no-access::Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=276,col=33,endLine=276,endColumn=52,title=Pyrefly no-access::Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=277,col=33,endLine=277,endColumn=52,title=Pyrefly no-access::Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=280,col=33,endLine=280,endColumn=52,title=Pyrefly no-access::Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=281,col=33,endLine=281,endColumn=52,title=Pyrefly no-access::Private attribute `__hostnameHasDomain` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=286,col=40,endLine=286,endColumn=49,title=Pyrefly no-access::Private attribute `__domains` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=297,col=23,endLine=297,endColumn=41,title=Pyrefly no-access::Private attribute `__assertUrlAllowed` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=307,col=27,endLine=307,endColumn=45,title=Pyrefly no-access::Private attribute `__assertUrlAllowed` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=312,col=40,endLine=312,endColumn=49,title=Pyrefly no-access::Private attribute `__domains` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=319,col=23,endLine=319,endColumn=41,title=Pyrefly no-access::Private attribute `__assertUrlAllowed` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=337,col=27,endLine=337,endColumn=45,title=Pyrefly no-access::Private attribute `__assertUrlAllowed` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=342,col=40,endLine=342,endColumn=49,title=Pyrefly no-access::Private attribute `__domains` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=350,col=23,endLine=350,endColumn=41,title=Pyrefly no-access::Private attribute `__assertUrlAllowed` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=368,col=27,endLine=368,endColumn=45,title=Pyrefly no-access::Private attribute `__assertUrlAllowed` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=374,col=45,endLine=374,endColumn=62,title=Pyrefly no-access::Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=375,col=45,endLine=375,endColumn=62,title=Pyrefly no-access::Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=376,col=45,endLine=376,endColumn=62,title=Pyrefly no-access::Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=377,col=45,endLine=377,endColumn=62,title=Pyrefly no-access::Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=378,col=38,endLine=378,endColumn=55,title=Pyrefly no-access::Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=382,col=49,endLine=382,endColumn=66,title=Pyrefly no-access::Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=383,col=49,endLine=383,endColumn=66,title=Pyrefly no-access::Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=384,col=49,endLine=384,endColumn=66,title=Pyrefly no-access::Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=385,col=49,endLine=385,endColumn=66,title=Pyrefly no-access::Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class
+ ::error file=tests/Requester.py,line=388,col=38,endLine=388,endColumn=55,title=Pyrefly no-access::Private attribute `__makeAbsoluteUrl` cannot be accessed outside of its defining class
apprise (https://github.com/caronc/apprise)
+ ERROR apprise/persistent_store.py:1360:35-46: Private attribute `__valid_key` cannot be accessed outside of its defining class [no-access]
+ ::error file=apprise/persistent_store.py,line=1360,col=35,endLine=1360,endColumn=46,title=Pyrefly no-access::Private attribute `__valid_key` cannot be accessed outside of its defining class
paasta (https://github.com/yelp/paasta)
+ ERROR paasta_tools/mesos/framework.py:74:38-45: Private attribute `__items` cannot be accessed outside of its defining class [no-access]
+ ::error file=paasta_tools/mesos/framework.py,line=74,col=38,endLine=74,endColumn=45,title=Pyrefly no-access::Private attribute `__items` cannot be accessed outside of its defining class
sockeye (https://github.com/awslabs/sockeye)
+ ERROR sockeye/decoder.py:63:17-27: Private attribute `__registry` cannot be accessed outside of its defining class [no-access]
+ ::error file=sockeye/decoder.py,line=63,col=17,endLine=63,endColumn=27,title=Pyrefly no-access::Private attribute `__registry` cannot be accessed outside of its defining class
aiohttp (https://github.com/aio-libs/aiohttp)
+ ERROR aiohttp/test_utils.py:603:20-30: Private attribute `__app_dict` cannot be accessed outside of its defining class [no-access]
+ ERROR aiohttp/test_utils.py:606:13-23: Private attribute `__app_dict` cannot be accessed outside of its defining class [no-access]
+ ::error file=aiohttp/test_utils.py,line=603,col=20,endLine=603,endColumn=30,title=Pyrefly no-access::Private attribute `__app_dict` cannot be accessed outside of its defining class
+ ::error file=aiohttp/test_utils.py,line=606,col=13,endLine=606,endColumn=23,title=Pyrefly no-access::Private attribute `__app_dict` cannot be accessed outside of its defining class
anyio (https://github.com/agronholm/anyio)
+ ERROR src/anyio/_backends/_asyncio.py:1346:37-49: Private attribute `__raw_socket` cannot be accessed outside of its defining class [no-access]
+ ERROR src/anyio/_backends/_asyncio.py:1356:37-49: Private attribute `__raw_socket` cannot be accessed outside of its defining class [no-access]
+ ERROR src/anyio/_backends/_asyncio.py:1570:65-77: Private attribute `__raw_socket` cannot be accessed outside of its defining class [no-access]
+ ::error file=src/anyio/_backends/_asyncio.py,line=1346,col=37,endLine=1346,endColumn=49,title=Pyrefly no-access::Private attribute `__raw_socket` cannot be accessed outside of its defining class
+ ::error file=src/anyio/_backends/_asyncio.py,line=1356,col=37,endLine=1356,endColumn=49,title=Pyrefly no-access::Private attribute `__raw_socket` cannot be accessed outside of its defining class
+ ::error file=src/anyio/_backends/_asyncio.py,line=1570,col=65,endLine=1570,endColumn=77,title=Pyrefly no-access::Private attribute `__raw_socket` cannot be accessed outside of its defining class
mypy (https://github.com/python/mypy)
+ ERROR mypyc/build_setup.py:73:10-17: Private attribute `__spawn` cannot be accessed outside of its defining class [no-access]
+ ERROR mypyc/lib-rt/build_setup.py:73:10-17: Private attribute `__spawn` cannot be accessed outside of its defining class [no-access]
+ ::error file=mypyc/build_setup.py,line=73,col=10,endLine=73,endColumn=17,title=Pyrefly no-access::Private attribute `__spawn` cannot be accessed outside of its defining class
+ ::error file=mypyc/lib-rt/build_setup.py,line=73,col=10,endLine=73,endColumn=17,title=Pyrefly no-access::Private attribute `__spawn` cannot be accessed outside of its defining class
kopf (https://github.com/nolar/kopf)
+ ERROR kopf/_kits/webhacks.py:88:22-34: Private attribute `__generators` cannot be accessed outside of its defining class [no-access]
+ ERROR kopf/_kits/webhacks.py:92:22-34: Private attribute `__generators` cannot be accessed outside of its defining class [no-access]
+ ::error file=kopf/_kits/webhacks.py,line=88,col=22,endLine=88,endColumn=34,title=Pyrefly no-access::Private attribute `__generators` cannot be accessed outside of its defining class
+ ::error file=kopf/_kits/webhacks.py,line=92,col=22,endLine=92,endColumn=34,title=Pyrefly no-access::Private attribute `__generators` cannot be accessed outside of its defining class
pwndbg (https://github.com/pwndbg/pwndbg)
+ ERROR pwndbg/gdblib/tui/context.py:223:47-61: Private attribute `___ansi_substr` cannot be accessed outside of its defining class [no-access]
+ ::error file=pwndbg/gdblib/tui/context.py,line=223,col=47,endLine=223,endColumn=61,title=Pyrefly no-access::Private attribute `___ansi_substr` cannot be accessed outside of its defining class
antidote (https://github.com/Finistere/antidote)
+ ERROR src/antidote/core/_catalog.py:536:54-63: Private attribute `__catalog` cannot be accessed outside of its defining class [no-access]
+ ERROR src/antidote/core/_catalog.py:538:54-63: Private attribute `__catalog` cannot be accessed outside of its defining class [no-access]
+ ERROR src/antidote/core/_catalog.py:540:23-37: Private attribute `__test_context` cannot be accessed outside of its defining class [no-access]
+ ERROR src/antidote/lib/interface_ext/_function.py:123:26-37: Private attribute `__signature` cannot be accessed outside of its defining class [no-access]
+ ERROR src/antidote/lib/interface_ext/_function.py:150:26-37: Private attribute `__signature` cannot be accessed outside of its defining class [no-access]
+ ERROR src/antidote/lib/interface_ext/_interface.py:461:29-38: Private attribute `__prepare` cannot be accessed outside of its defining class [no-access]
+ ERROR src/antidote/lib/interface_ext/_interface.py:462:18-43: Private attribute `__register_implementation` cannot be accessed outside of its defining class [no-access]
+ ERROR src/antidote/lib/interface_ext/_interface.py:485:29-38: Private attribute `__prepare` cannot be accessed outside of its defining class [no-access]
+ ERROR src/antidote/lib/interface_ext/_interface.py:486:29-38: Private attribute `__catalog` cannot be accessed outside of its defining class [no-access]
+ ERROR src/antidote/lib/interface_ext/_interface.py:486:78-89: Private attribute `__interface` cannot be accessed outside of its defining class [no-access]
+ ::error file=src/antidote/core/_catalog.py,line=536,col=54,endLine=536,endColumn=63,title=Pyrefly no-access::Private attribute `__catalog` cannot be accessed outside of its defining class
+ ::error file=src/antidote/core/_catalog.py,line=538,col=54,endLine=538,endColumn=63,title=Pyrefly no-access::Private attribute `__catalog` cannot be accessed outside of its defining class
+ ::error file=src/antidote/core/_catalog.py,line=540,col=23,endLine=540,endColumn=37,title=Pyrefly no-access::Private attribute `__test_context` cannot be accessed outside of its defining class
+ ::error file=src/antidote/lib/interface_ext/_function.py,line=123,col=26,endLine=123,endColumn=37,title=Pyrefly no-access::Private attribute `__signature` cannot be accessed outside of its defining class
+ ::error file=src/antidote/lib/interface_ext/_function.py,line=150,col=26,endLine=150,endColumn=37,title=Pyrefly no-access::Private attribute `__signature` cannot be accessed outside of its defining class
+ ::error file=src/antidote/lib/interface_ext/_interface.py,line=461,col=29,endLine=461,endColumn=38,title=Pyrefly no-access::Private attribute `__prepare` cannot be accessed outside of its defining class
+ ::error file=src/antidote/lib/interface_ext/_interface.py,line=462,col=18,endLine=462,endColumn=43,title=Pyrefly no-access::Private attribute `__register_implementation` cannot be accessed outside of its defining class
+ ::error file=src/antidote/lib/interface_ext/_interface.py,line=485,col=29,endLine=485,endColumn=38,title=Pyrefly no-access::Private attribute `__prepare` cannot be accessed outside of its defining class
+ ::error file=src/antidote/lib/interface_ext/_interface.py,line=486,col=29,endLine=486,endColumn=38,title=Pyrefly no-access::Private attribute `__catalog` cannot be accessed outside of its defining class
+ ::error file=src/antidote/lib/interface_ext/_interface.py,line=486,col=78,endLine=486,endColumn=89,title=Pyrefly no-access::Private attribute `__interface` cannot be accessed outside of its defining class
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ScopeKind::Function(_) if !in_method_scope => { | ||
| return None; | ||
| } |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic correctly returns None when encountering a Function scope before finding a Method scope, which prevents private attribute access in nested functions defined inside methods. However, this behavior may be overly restrictive. In Python, nested functions defined inside a method should still have access to private attributes through closure, similar to how they access self. Consider whether this restriction aligns with Python's actual runtime behavior for closures.
| ScopeKind::Function(_) if !in_method_scope => { | |
| return None; | |
| } |
kinto0
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review automatically exported from Phabricator review in Meta.
…ny error while Python interpreter gives error facebook#1971 (facebook#1980) Summary: Fixes facebook#1971 Added a scope-aware scan for attribute expressions, raising a clear NoAccess error when a double-underscore attribute is used while the binder is not inside any function scope. Pull Request resolved: facebook#1980 Test Plan: add related tests Reviewed By: kinto0 Differential Revision: D90122102 Pulled By: rchen152 fbshipit-source-id: daf147a24463f0e95b1363fa8a16efaf3d3ed7b3
Summary
Fixes #1971
Added a scope-aware scan for attribute expressions, raising a clear NoAccess error when a double-underscore attribute is used while the binder is not inside any function scope.
Test Plan
add related tests