PEP 505: status?

I’m new here, but I did a search and wasn’t able to find anything in this forum on PEP 505 ( Is this PEP dead? or just unloved? The page says “deferred” but it doesn’t explain why.


PEP 505 is controversial as it’s using ? (the question mark), one of the last few printable non-alphanumeric characters from the 7-bit ASCII subset. The other example being $ (the dollar sign).

You can search archives of the python-ideas and python-dev mailing lists for previous discussion on this PEP.


It was mostly controversial because nobody agreed on whether “None” was special or not.

The conversation didn’t make it to python-dev, but searching python-ideas for “PEP 505” should find the last round of discussion.

1 Like

Thanks all. I’ll take a look there.

I think most deferred PEPs have a small writeup in a section titled “PEP defferal” or something similar right at the top. Would it be possible to add something similar to this PEP?


That seems absurd to me. I was just looking for discussion about it to suggest adding a typing addition for Optional where you could have a type annotation using the None-aware syntax (e.g., def test(a: int?):).

Was there a feeling of consensus from other core devs? Were there more people in favor than not?


I am not a core dev, but I feel the community consensus is that None is not “special enough” to warrant a new syntax, but def test(a: int | None) is good enough (which is going to happen in 3.10).

1 Like

Being one of four singletons builtin, it seems pretty special. That’s good to know about the new syntax, though. I like that. Null operators would still help ergonomics a lot especially as I swap between C#/Rust and Python at work these days quite a bit.


I hope this PEP is revived. I think the ergonomic and type-safety value of safe ? references justify making None special even if it isn’t currently considered to be so.


As others noted, the main semantic sticking point was that the specific is None check was seen as too limiting, but the proposals to offer a more flexible underlying protocol based approach (e.g. ) were seen as too complicated. (There was also a syntactic sticking point, which is that ??, ?., and ?[] don’t really meet anyone’s definition of “executable pseudocode”, which is a standard we aspire to for new Python syntax)

Something we didn’t seriously consider at the time, but may want to think about now is whether making the short circuiting check be for x == None rather than x is None might offer enough runtime flexibility to get past the "None is special, but it isn’t that special" objection.

While most of the arguments for withdrawing PEP 531 ( would also applying to defining PEP 505 that way (since x == None would effectively become the “existence checking protocol” that PEP 531 suggested), it might be more palatable when it’s just adapting an existing protocol to a new purpose, rather than defining a completely new one.

1 Like

Hello all!

I was wondering - what was the justification behind Python core developers rejecting maybe builtin in PEP 505? At first glance, it meets the pro tanto criterion of “executable pseudocode” for syntax additions to Python, makes an obnoxious idiom much more readable, and can trace its homage to a well-known feature in Haskell:

data = [] if data is None else data
files = [] if files is None else files
headers = {} if headers is None else headers


data = maybe data else []
files = maybe files else []
headers = maybe headers else {}

That’s a question for the PEP authors, as they are the ones who have rejected a “maybe” builtin.

But some thoughts come to mind.

First, we need to distinguish between a maybe builtin type and a “maybe” builtin operator.

You seem to be asking about a maybe operator:

data = maybe data else []

This is a binary operator (it takes two arguments, data and []) but it is written using two keywords, one prefix maybe data and one infix data else []. That seems extravagently verbose, possibly even wasteful.

Python code often reads like executable pseudocode, but not like natural language. Using two keywords for a binary operator is something I would expect from a language like Hypertalk, where we might write things like:

add 1 to x
put 2*x into y

Also, as a native English speaker, the else part doesn’t feel right to me. maybe data or [] reads better, but of course that leads to precedence issues with the binary or operator.

Most other languages with a null-coalescing operator seem to be converging on using question marks. It seems wasteful to use two key words to accomplish what a single infix symbol can do:

data ?? []
maybe data else []

And how would you chain these expressions?

data ?? info ?? []
maybe data else maybe info else []
maybe maybe data else info else []

And what about the maybe dot operator?


Coming back to the PEP, I’m not one of the authors but my reading of that section is that pymaybe has a function maybe() that returns either a Something instance or a Nothing instance. The PEP suggests that instead of using a function and two types, they could use a single builtin maybe type to work the same way.

The PEP already gives the disadvantages of this:

I expect that getting this sort of proxying right is much harder than giving the interpreter a binary infix operator ?? and supporting chaining.

The Haskell docs for maybe might as well be written in Martian. But if I am interpreting them correctly, it seems that maybe is used for falsey/truthy checks, with the added twist that you can define any values you like as falsey. Using the word maybe may mislead people into thinking we have Haskell’s maybe functor when we don’t.

1 Like

Perhaps maybe could go to much shallower lengths than Haskell-esque pymaybe? Consider something like this:

def maybe(nullable, *args):
    """A 'readable pseudo-code' implementation of null-coalescing operator (??)."""

    for j in (i for i in [nullable, *args] if i is not None):
        return j

Now we’re comparing:

data = data if data is not None else info if info is not None else []
files = [] if files is None else files
headers = {} if headers is None else headers


data = maybe(data, info, [])
files = maybe(files, [])
headers = maybe(headers, {})

It seems like nowadays, typescript, flutter, kotlin already supports ? and ?? operator very well.

By using ? operator:

a_class = None

> this function won't get called since "a_class_instance == None"

By using ?? operator:

response = {}
response.a_variable = None

new_variable = response.a_variable?? True

> new_variable would be equal to True since "response.a_variable == None"

1 Like

6 posts were split to a new topic: Questions about ? syntax

Any updated status on PEP 505?

The status, as shown in the PEP, remains “deferred”. You can refer to PEP 1 – PEP Purpose and Guidelines | to understand the PEP workflow and what this means.

1 Like