Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

f-strings for Berry #346

Closed
s-hadinger opened this issue Jun 20, 2023 · 7 comments
Closed

f-strings for Berry #346

s-hadinger opened this issue Jun 20, 2023 · 7 comments

Comments

@s-hadinger
Copy link
Contributor

Now that I have some decent experience with programming in Berry, I'm am not completely happy with string formatting. string.format() is slightly verbose. I would like to add an equivalent to Python's f-strings.

Example:
string.format("id=%i cluster=0x%04X name=%s", id, cluster, self.name)

would become:
f"id={id:i} cluster={cluster:04X} name={self.name}"

I made a POC that sounds promising. Changing the parser would be a daunting task. Instead, I use a "transpiler" approach. The lexer contains code to detect f-string syntax and rewrite the code to generate the string.format syntax.

The lexer transforms f"id={id:i} cluster={cluster:04X} name={self.name}" to ("id=%i cluster=0x%04X name=%s", id, cluster, self.name) and then just feeds the normal parser.

@sfromis
Copy link
Contributor

sfromis commented Jun 20, 2023

@s-hadinger
Copy link
Contributor Author

Done: #355

@barbudor
Copy link

barbudor commented Nov 11, 2023

Hi @s-hadinger
Is that working only as compile-time like in python ? which means that I can't use a string variable ?

I'm looking if there is a way to use format string like in python:

# this is Python, not Berry
# fulltopic = "{prefix}/{topic}/{subtopic}"
fulltopic=string.replace(string.replace(tasmota.cmd("fulltopic")['FullTopic'],"%prefix%","{prefix}"),"%topic%","{topic}")+"{subtopic}"
# publish_topic = "cmnd/devname/power"
publish_topic = fulltopic.format(prefix="cmnd", topic="devname", subtopic="power")
# or
publish_topic = fulltopic.format(**{"prefix":"cmnd", "topic":"devname", "subtopic":"power"})

As you imagine the idea is to use named variable in the format string instead of positional values

Thanks

@s-hadinger
Copy link
Contributor Author

f-strings are purely compile time synctactic sugar to the format() function. You could however write a helper function that does something similar.

@barbudor
Copy link

Yes, indeed I simply string replace:

fulltopic=tasmota.cmd("fulltopic")['FullTopic']

def make_topic(prefix, topic, subtopic)
  return string.replace(string.replace(fulltopic,"%prefix%",prefix),"%topic%",topic) + subtopic
end

@sfromis
Copy link
Contributor

sfromis commented Nov 11, 2023

If you really want, you can have non-constant f-strings expanded by going via compile, to get the syntactic sugar sweetness, but that's not very efficient, and does not work well with local vars.

var prefix='stat' var topic='device' var leaf='what'
var fformat=/fst-> compile("return f'" + fst + "'")()
print(fformat('{topic}/{prefix}/{leaf}'))

@s-hadinger
Copy link
Contributor Author

I wouldn't recommend using compile with dynamic content. This is always dangerous ; like eval() in many languages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants