prestring
.. image:: https://travis-ci.org/podhmo/prestring.svg?branch=master
:target: https://travis-ci.org/podhmo/prestring
this package is heavily inspired by srcgen <https://github.com/tomerfiliba/srcgen>
_ .
(todo: gentle introduction)
features
- generating code with with-syntax
- string injection after writing string
generating code with with-syntax
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
from prestring.python import PythonModule
m = PythonModule()
with m.class_("Point", metaclass="InterfaceMeta"):
with m.def_("init", "self", "value"):
m.stmt("self.value = value")
with m.def_("__str__", "self"):
m.return_("self.value")
output is.
.. code-block:: python
class Point(object, metaclass=InterfaceMeta)
def init(self, value):
self.value = value
def __str__(self):
return self.value
string injection after writing string
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
from prestring.python import PythonModule
m = PythonModule()
with m.def_("setup", "config"):
import_area = m.submodule()
m.sep()
for k in ["a", "b", "c", "d", "e"]:
import_area.stmt("from .plugins import {k}_plugin", k=k)
m.stmt("config.activate({}_plugin)", k)
print(m)
.. code-block:: python
def setup(config):
from .plugins import(
a_plugin,
b_plugin,
c_plugin,
d_plugin,
e_plugin
)
config.activate(a_plugin)
config.activate(b_plugin)
config.activate(c_plugin)
config.activate(d_plugin)
config.activate(e_plugin)
sub modules
- prestring.output
- prestring.python.transform, prestring.text.transform
prestring.output
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
prestring.output can write multiple files.
.. code-block:: python
import sys
from prestring.python import Module
from prestring.output import output, cleanup_all # noqa
dst = sys.argv[1]
with output(root=dst) as fs:
with fs.open("projects/x.txt", "w") as wf:
print("hello x", file=wf)
print("bye x", file=wf)
with fs.open("projects/y.txt", "w") as wf:
print("hello y", file=wf)
print("bye y", file=wf)
with fs.open("projects/z.py", "w", opener=Module) as m:
with m.def_("hello"):
m.stmt("print('hello')")
Above code will generate three files. if creating directory is needed, it will be created automatically.
.. code-block:: console
$ python src/main.py dst
[D] create dst/projects
[F] create dst/projects/x.txt
[F] create dst/projects/y.txt
[F] create dst/projects/z.py
On rerun, no message is displayed. And rerun with VERBOSE=1
var env to see more detailed output.
.. code-block:: console
$ python src/main.py dst
$ VERBOSE=1 python src/main.py dst
[F] no change dst/projects/x.txt
[F] no change dst/projects/y.txt
[F] no change dst/projects/z.py
dry-run
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Running with CONSOLE=1
varenv or calling with use_console=True
option, doesn't save files.
.. code-block:: console
$ CONSOLE=1 python src/main.py dst
[F] update dst/projects/x.txt
[F] update dst/projects/y.txt
[F] update dst/projects/z.py
more verbose output
VERBOSE=1 CONSOLE=1 python src/00/main.py dst/00/create
dst/00/create/projects/x.txt
hello x
bye x
dst/00/create/projects/y.txt
hello y
bye y
dst/00/create/projects/z.py
def hello():
print('hello')
prestring.python.transform, prestring.text.transform
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
the Transform function means converting raw source code (or text) to prestring's code.
And you can use python -m prestring.python
(or running python -m prestring.text
) as a CLI command, as follows.
.. code-block:: console
$ cat hello.py
def hello(name: str, *, message: str = "hello world"):
"""
greeting message
"""
print(f"{name}: {message}")
if name == "main":
hello("foo")
$ python -m prestring.python hello.py
from prestring.python import PythonModule
def gen(*, m=None, indent=' '):
m = m or PythonModule(indent=indent)
import textwrap
with m.def_('hello', 'name: str', '*', 'message: str = "hello world"'):
m.docstring(textwrap.dedent("""
greeting message
""").strip())
m.stmt('print(f"{name}: {message}")')
with m.if_('__name__ == "__main__"'):
m.stmt('hello("foo")')
return m
if name == "main":
m = gen(indent=' ')
print(m)
Of course, reversible.
.. code-block:: console
$ python <(python -m prestring.python hello.py)
def hello(name: str, *, message: str = "hello world"):
"""
greeting message
"""
print(f"{name}: {message}")
if name == "main":
hello("foo")
$ python hello.py
foo: hello world
$ python <(python <(python -m prestring.python hello.py))
foo: hello world
prestring.text
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you want to prestring's expression as first step, in other language, prestring.text is probably useful.
.. code-block:: console
$ python -m prestring.text --tab hello.go
from prestring.text import Module
def gen(*, m=None, indent='\t'):
m = m or Module(indent=indent)
m.stmt('package main')
m.sep()
m.stmt('import (')
with m.scope():
m.stmt('"fmt"')
m.stmt('"os"')
m.stmt(')')
m.sep()
m.stmt('// Hello is print Hello')
m.stmt('func Hello(name string) {')
with m.scope():
m.stmt('fmt.Printf("%s: Hello", name)')
m.stmt('}')
m.sep()
m.stmt('func main() {')
with m.scope():
m.stmt('var name string')
m.stmt('if len(os.Args) > 1 {')
with m.scope():
m.stmt('name = os.Args[1]')
m.stmt('} else {')
with m.scope():
m.stmt('name = "foo"')
m.stmt('}')
m.stmt('// with block')
m.stmt('{')
with m.scope():
m.stmt('Hello(name)')
m.stmt('}')
m.stmt('}')
return m
if name == "main":
m = gen(indent='\t')
print(m)
0.9.0
- codeobject module
- some refactoring
0.8.3, 0.8.4, 0.8.5
0.8.2
- add codeobject module, PythonModule.import_() returns symbol object
- remove unused methods
0.8.1
- prestring.python, async/await support
0.8.0
- typing (but this is not completely strict)
0.7.3
- In prestring.text, use tab default indent 1 (#47)
0.7.2
0.7.1
- "python -m prestring.python" support typed function definition
0.7.0
- changes "python -m prestring.python.transform" to "python -m prestring.python"
- some logging adjustments and fix bugs (prestring.output)
- add prestring.text
0.6.0
- support only python3.6+
- refactoring prestring.output
0.5.3
- rollback, python's import part output
0.5.1, 0.5.2
0.5.0
- add prestring.python.transform
0.4.7
- add prestring.output.SeparatedOutput
- LazyKeywords is sorted
0.4.3
- clear if empty (e.g. go-module's import_group)
0.4.2
- bug fix LazyArgumentsAndKeywords
0.4
- more lazy (python module)
- lazy object is cached
0.3.3
0.3.1
0.3.0