0

I'm working with this library, which (very reasonably because it is translating from another language's idioms) makes heavy use of operator redefinition.

Usage begins with from parsec import * which in general, I try to avoid, and rather keep my namespace. Something more like import parsec as p then using the sub functions and every operator, explicitly.

This works for some functions, like p.many1() or p.spaces() or p.regex().

However, this also leaves me trying to import name-spaced operators, and that looks even less pythonic.

For example, the bitwise >> and << are redefined. Here is a real-world usage.

Not only does trying to use a namespace to call these operators also look unpythonic, it's not even clear to me how to do it: p.>>? As you can see, this is a syntax error:

>>> import parsec as p
>>> p.>> p.many()
  File "<stdin>", line 1
    p.>>
       ^
SyntaxError: invalid syntax

This leaves me deciding I want to import the operators implicitly, that is, to call >> without a namespace, but to import the non-operators inside a p namespace.

edit update

To be clear, my question is:

How can I import the functions like many1() with a namespace as p.many1(), and import the operator functions like "+" ">>" "<<" nakedly, without a namespace?

end update

While I can do

import parsec as p

To get the non-operator functions, it's not clear to me how to say:

from parsec import >>

As the following attempts at explicitly importing operators all fail:

>>> from parsec import >>
  File "<stdin>", line 1
    from parsec import >>
                        ^
SyntaxError: invalid syntax
>>> from parsec import (>>)
  File "<stdin>", line 1
    from parsec import (>>)
                         ^
SyntaxError: invalid syntax
>>> from parsec import ">>"
  File "<stdin>", line 1
    from parsec import ">>"
                          ^
SyntaxError: invalid syntax
>>> from parsec import __lshift__, __rshift__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name '__lshift__' from 'parsec' ()

How can I import these?

Mittenchops
  • 18,633
  • 33
  • 128
  • 246
  • 2
    Redefined operators are not importable from the module. They are implemented as special methods of the left-side operand class, sometimes with a fallback to the right side operand class. – Klaus D. Aug 14 '19 at 04:04
  • 1
    Could you provide a minimal executable example? Btw why not `p >> p.many()`? `>>` is actually calling a function `p.__rshift__`. So you should call it like `p.__rshift__(p.many())` – Sraw Aug 14 '19 at 04:05
  • Thank you, @Sraw. Can you explain what you would like to see an example of? I provided minimal examples of the 4 imports I tried not working, and a description of what I’d like to see work. Maybe I misunderstand your comment, but if I could provide any more than that, I wouldn’t have a question left to ask. – Mittenchops Aug 14 '19 at 04:26
  • @Sraw, I added an update infix. – Mittenchops Aug 14 '19 at 04:34
  • I... I am really confused. The things you want to import don't even exist in the module. I'm not an expert on Haskell. Mainly I use Scala as FP language. But if you take a look at the source code. You will see that you need to either use raw functions like `compose` or construct a `Parser` which supports the operators you want: https://github.com/sighingnow/parsec.py/blob/706ee10cd4a426dbbebbe2246a23172aebb5691f/src/parsec/__init__.py#L359 – Sraw Aug 14 '19 at 04:47
  • Please see the example I linked, which has lines like: “tag_start = spaces >> string('<') >> name << string('>') << spaces” This is not default behavior for the bitshift operators. – Mittenchops Aug 14 '19 at 04:56
  • @Mittenchops That is because `spaces` is a `Parser` which constructed by `regex`. See the source code: https://github.com/sighingnow/parsec.py/blob/706ee10cd4a426dbbebbe2246a23172aebb5691f/src/parsec/__init__.py#L660 – Sraw Aug 14 '19 at 05:19

1 Answers1

0

I think the operators are defined as methods on the parser objects, so you don't import them as operators explicitly. If you import the other objects with a p namespace, and you perform the operator operations on them, it will "just work" because the Parser class has these defined.

Mittenchops
  • 18,633
  • 33
  • 128
  • 246