Why am I getting a syntax error when using the >>= operator?

Because >>= is a statement, not an expression. It doesn't evaluate to a result that can be assigned to testp.

Perhaps you were looking for this?

testp = digit >> id

It is a design mistake.

I have turned to use >= as the operator for bind() and deprecated >>=. A new release of parsec.py has been upload to pypi.


I have used neither Parsec nor Haskell, so I can't speak to the intended use in the context of this library. However, I believe the main root of your confusion here is that augmented assignment statements work differently than operators, and therefore reimplementing them works slightly differently as well. (Unlike in C and many other languages, assignment is not an operator in Python.)

So you've seen this code:

def __irshift__(self, other):
    '''Implements the `(>>=)` operator, means `bind`.'''
    return self.bind(other)

What isn't immediately obvious is that, because this is overriding augmented assignment, not an operator, the returned value is used to reassign the original item on the left. In other words, this code:

a >>= b

is not the same as simply:

a.bind(b)

Instead, it is (essentially) equivalent to:

a = a.bind(b)

As mentioned in Alexander's answer, the resulting assignment is a statement, not an expression, and can't ultimately return a value at all (not even None). The right half of an assignment statement has to be an expression; it can't be another assignment statement1. Just as in Python you can't do things like2:

a = b += c

So you also can't do:

a = b >>= c

...even when you've reimplemented >>=.


1 The only partial exception is the recently added assignment expression, but it is (intentionally) limited in use, and won't help you here.

2 On the other hand, "chained assignment", e.g. a = b = c, does work. It's something of a special case, in that it's not simply a series of operators that return their values; a = (b = c) is still a syntax error. Instead, it's all parsed as one assignment statement.