r1chardj0n3s / parse

Parse strings using a specification based on the Python format() syntax.
http://pypi.python.org/pypi/parse
MIT License
1.71k stars 101 forks source link

Allow using a Parser as a formatter #172

Closed ymost closed 11 months ago

ymost commented 12 months ago

I think it would nice and elegant if the same object could be used both as a formatter and a parser. This can be achieved by adding a format method:

>>> p = compile("It's {}, I love it!")
>>> p.parse("It's spam, I love it!")
<Result ('spam',) {}>
>>> p.format('spam')    # <----  This is the new suggested method
"It's spam, I love it!"

Granted, one could simply hold on to the original string and use that, but I think it's useful if we only needed the Parser object for both of these. For example, if you pass the Parser as an argument to a function, currently you need to pass the format string as well, otherwise you have to access the internal _format field. At the very least, we should have a get_format method to retrieve the internal _format field.

Another reason is that if we are using two different objects for formatting and for parsing, it increases the chance that someone creates a bug by changing one of the objects and forgetting to change the other one.

wimglenn commented 12 months ago

Similar was suggested in https://github.com/r1chardj0n3s/parse/issues/100

ymost commented 11 months ago

I think what I'm suggesting is much simpler. It could hardly be considered new functionality, just exposing existing functionality. Basically what I have in mind is:

def format(self, *args, **kwargs) -> str:
    return self._format.format(*args, **kwargs)

Does this seem reasonable?

wimglenn commented 11 months ago

It seems reasonable, one thing does occur to me though that the Parser supports some "extra" types which do not make sense for a formatter, e.g.

>>> p = compile("{:w}")
>>> r = p.parse("xyz")
>>> p._format.format("abc")
ValueError: Unknown format code 'w' for object of type 'str'

So the format method may be more difficult to implement in a full-featured way, rather than just exposing ._format.format().

Looking at the Parser class, I also don't see any obvious reason why the ._format attr is internal, perhaps a (read-only) property could just be added to return the format template string, instead of a format method?

class Parser(object):
    ...

    @property
    def format(self):
        return self._format
ymost commented 11 months ago

Wow, I didn't know about the extra types. I guess parse() is not exactly the opposite of format()... Anyway a read-only property seems good!