Skip to content

PEP XXX: None-aware access operators [DRAFT] - #1

Closed
cdce8p wants to merge 13 commits into
mainfrom
none-aware-access-operators
Closed

PEP XXX: None-aware access operators [DRAFT]#1
cdce8p wants to merge 13 commits into
mainfrom
none-aware-access-operators

Conversation

@cdce8p

@cdce8p cdce8p commented Jan 2, 2026

Copy link
Copy Markdown
Owner

@cdce8p
cdce8p marked this pull request as draft January 2, 2026 21:01
@Dutcho

Dutcho commented Jan 3, 2026

Copy link
Copy Markdown

In Motivation / Nested objects

  • I don’t understand what you mean by “Would for example Machine overwrite __eq__ to return False”? Should that be __bool__ perhaps?
  • The various examples are not equivalents for emails == [], which is falsey but not None; the first snippet handles that correctly, the is not None variants don’t, the try variant does (thanks to IndexError), the match does by list unpacking), but the ?. version doesn’t. For understanding I recommend consistency
  • The “IDE” remark only became clear after some thinking. Suggest rephrasing to “would be able to help with identifying potentially None valued fields

@Dutcho

Dutcho commented Jan 3, 2026

Copy link
Copy Markdown

In Motivation / Other

  • I suggest “plain sight
  • Presented pairs often aren’t exact equivalents
    • a and a.b == val: a might be a class instance with a __bool__ method returning False and val could be None
    • a and a.b and a.b.c: a could be falsey
    • d: dict | None

@picnixz

picnixz commented Jan 4, 2026

Copy link
Copy Markdown

I think this should mention what has changed since PEP-505. For instance, the rejected ideas are just copied from PEP-505. So I think you should contact past authors to ask them if you can just C/C their text.

@cdce8p

cdce8p commented Jan 11, 2026

Copy link
Copy Markdown
Owner Author

Thanks for the review @Dutcho! I've addressed your comments in 092e36f.

The various examples are not equivalents for emails == [], which is falsey but not None

That's absolutely correct and I believe something which contributed to the confusion especially regarding the ?[ ] operator. I believe in order to avoid additional confusion, it makes sense to specify that emails is either None or a list with at least one item. That way we can ignore the IndexError for now. Yes, some of the examples would either knowingly or unknowingly work for it, e.g. match, but that's not the point in the motivation section. I've added a Note block to the draft to make this clear.

Presented pairs often aren’t exact equivalents

Yes, though that is by design. Something I'd like to point out with this section is that these patterns often hide in plain sight and while not identical, using ?. or ?[ ] is actually the intended logic behind these. The None-aware access operators just make it more clear / obvious what is going to happen. I've added another Note block to point that out.

@cdce8p

cdce8p commented Jan 11, 2026

Copy link
Copy Markdown
Owner Author

I think this should mention what has changed since PEP-505. For instance, the rejected ideas are just copied from PEP-505. So I think you should contact past authors to ask them if you can just C/C their text.

Yes, some parts form the rejected ideas sections, are more or less identical to PEP 505. I've chosen to omit mentioning the original authors (e.g. in an Acknowledgements section) as he has changed his mind since writing PEP 505 so I'm not sure he'd want to be associated with a followup PEP.

His opinion if I understand it correctly, boils down to the Proliferation of None in code bases argument I listed in the Common objections section.

The link to his response regarding the status of PEP 505 at EuroPython 2022: https://youtu.be/0m2Cy5X6lcE?t=1521

@cdce8p
cdce8p force-pushed the none-aware-access-operators branch from 163d0d6 to d305adf Compare January 21, 2026 19:16
@cdce8p

cdce8p commented Jan 31, 2026

Copy link
Copy Markdown
Owner Author

I've open the PR in the python/peps repo. Going to close this one now.

@cdce8p cdce8p closed this Jan 31, 2026
@cdce8p
cdce8p deleted the none-aware-access-operators branch January 31, 2026 21:56
@KonradStanski

Copy link
Copy Markdown

Hey Marc,
sorry to revive the closed PR. I didn’t want to add an unrelated tangent to the official PEP 823 PR.

There’s one adjacent use case I’ve been thinking about: type narrowing when None would be an invariant violation rather than an acceptable result.

?. works well when a missing value should propagate and the final result remains optional. But sometimes the annotations say T | None, while at a particular point the programmer knows it must be T. Currently that can require breaking a chain into temporary variables:

state_machine = agent.state_machine
assert state_machine is not None
server_wrapper = state_machine.server_wrapper
assert server_wrapper is not None
server = server_wrapper.server
assert server is not None
address = server.address

I was wondering whether a postfix non-None assertion operator, perhaps !!, could cover this:

address = agent.state_machine!!.server_wrapper!!.server!!.address

The idea would be that x!!, where x has type T | None, evaluates x once, raises if it is None, and otherwise returns it narrowed to T.

So the distinction would roughly be:

x?.y   # None is acceptable; propagate it
x!!.y  # None is a bug; fail here and narrow the type

I noticed the draft discussion briefly mentioned a possible future not-None assertion operator as out of scope. Have you thought about this use case much? Does it seem like a natural follow-up to you?

I have a rough write-up, but wanted to ask you informally before starting another public Ideas discussion.

@cdce8p

cdce8p commented Sep 1, 2026

Copy link
Copy Markdown
Owner Author

Hi @KonradStanski, no problem!

Yeah, I've thought about that, too since I've come across that exact use case myself. Unfortunately, I'm not sure there is much hope for that being added anytime soon. So far new syntax just for typing was almost always rejected. And if we condense your example a bit, it technically is just for typing. The AssertionError is just on top.

Personally I'd recommend to wait and see how the PEP discussion for 823 will go and whether or not it will be accepted before exploring anything else on top of that. I hope that I can start the discussions for the PEPs later this month. Just waiting on a last round of reviews at the moment.

On a technical note, I'd drop the double exclamation mark in exchange for just !. That's the syntax dart uses. https://dart.dev/null-safety/understanding-null-safety#not-null-assertion-operator
Another topic to think about will be what happens if Python is run with -O. As that removes any assert, I'd think !. would probably become a no-op / normal attribute access.

If you want to discuss that further, feel free to message me on https://discuss.python.org.

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.

4 participants