While I am not at this point dropping the idea of @decorator(expression) targetname
a thought occurred to me yesterday after discussing targetname as a string in
assignments (and I appreciate the continued discussion in a new thread but
this is a new counter proposal so keeping it here).
There is at least one other place where python saves us from retyping the lhs
in an assignment statement: augmented assignment. It is not being used as a
string, true, and it's much more difficult to introduce a subtle bug by mis-typing
the name if one were to use the standard operator instead. But we still have
augmented assignment for all operators IMO because programmers are
productively lazy and came up with a way to not retype their variable.

What if, instead of adding a new magic symbol to the assignment
statement (statements? still not sure which ones are supported in the
counter proposal) we add a new assignment operator and corresponding
dunder method that would perform the real operation behind the syntactic

For now I propose the operator "<==" and dunder "__assign__". Both
very bikeshedable, but allows us to draw some examples

RED <== str

would become

RED = str.__assign__("RED")
# or is this how it's actually done? don't remember
# RED = type(str).__assign__(str, "RED")

where str now has the method

def __assign__(cls, assignment_name):
    return assignment_name

Following the example of augmented assignment, both of these would
be SyntaxErrors:

spam = eggs <== str
spam, eggs <== str

Although there is probably a way to make the second one work, that
can be experimented with in a reference implementation or saved for
a later PEP.

Some more of my original examples with the new operator:

Point <== namedtuple("x y z")

UUIDType: str <== NewType

Colors <== Enum("RED GREEN BLUE")

class Colors(Enum):
    RED <== str
    GREEN <== str
    BLUE< == str

It would also be possible to reuse a factory, similar to the way a
decorator that takes arguments first creates a sort of closure and
is then that is passed the function object in a subsequent call.

SPAM_DB <== get_sql_db(pass=_secret, user=user)

would be the same as

SPAM_DB = get_sql_db(pass=_secret, user=user).__assign__("SPAM_DB")
TABLE1 = SPAM_DB.__assign__("TABLE1")
TABLE2 = SPAM_DB.__assign__("TABLE2")