Pull requests

#3 Declined
Repository
Deleted repository
Branch
patch-mako-render-python-path (4a37ab353a4b)
Repository
zzzeek/mako mako
Branch
master

Alter mako-render to add template_dir directories to sys.path

Author
  1. Derek Harland
Reviewers
Description

The python interpreter will prepend sys.path with the parent directory of the script it is running (or the current directory if the script comes from stdin).

It would be nice for mako-render to behave similarly. As it stands, we cannot easily import local python modules (via the <namespace> tag) that sit along side templates. Thus a template can't import helper functions that have been defined in a python module, unless we manage to put that module into the "global" python path.

This patch extends my previous patch, that added --template-dir, to also add these directories to the python path

Comments (8)

  1. Derek Harland author

    Not sure whether python paths should go into a separate option instead. As it stands, the default behavior of template-dir is to

    • add the parent directory of the template file if it exists
    • add the current directory if the template is on stdin

    which meshes nicely with the default behavior we'd like for the python path as well, hence I'm just using it.

  2. Mike Bayer repo owner

    well I'm not sure I agree that importable Python modules should be encouraged to be in the same directory as that of the template files themselves. I'd never do it that way. Additionally, maybe another argument --module-path, but then PYTHONPATH already accomplishes this? e.g. "export PYTONPATH=/path/to/modules; mako-render ...".

  3. Derek Harland author

    I'm on the fence … if those python modules exist solely to provide functionality to templates, and will only be imported by such templates … then is there really much difference between a template that defines a bunch of <%def > and a python module that defines them instead?

    In any case, I'm not sure the usual use-case (of generating html within a web framework) applies to mako-render ? To me, mako-render looks far more useful just as a general file generator and as such it would be great if it "just worked" in a few more cases. I think people using it would probably expect that, like python, it would just find python modules that are next to templates it's run on etc, without having to specify it explicitly (although I might just be projecting my views on to others!)

  4. Mike Bayer repo owner

    look at the environment that a system like sphinx generates for you....it puts every type of file in a separate directory. _templates is where templates go, _static is where static files go, if you want to add modules you have to add those paths to conf.py in any case. I'd never build out a system, even a quick oneoff, where I put .mako files and .py in the same directory. If you want to be able to import the .py files you need an init.py there too. I dont see how that case deserves special compatibility when in all likelihood people would be using PYTHONPATH to point to the modules somewhere else anyway. A --flag is much more appropriate here, but then, how do we justify that vs. the fact that PYTHONPATH does the same thing.

  5. Derek Harland author

    Agreed … for large things documentation projects, web apps, buildouts etc … but is that the target use case for mako-render ? It's a command line tool and I think the path of least surprise is probably for mako-render to find python modules next to a template file that its run on, rather than requiring additional environment settings.

    Its also great tool for quick and easy file generation tasks, for example, having some simple templates that can be used to generate other more complex files. For example, suppose I want to generate python/c++/rust boilerplate code, and it needs some common data to do so, then I might have something like:

    project_name/generators/some_common_stuff.py
    project_name/generators/cpp_boilerplate.mako
    project_name/generators/rust_boilerplate.mako
    

    and its great to just be able to generate it as mako-render project_name/generators/rust_boilerplate.mako rather than PYTHONPATH=project_name/generators mako-render project_name/generators/rust_boilerplate.mako which feels repetitious.

    But I can understand your dislike and I'll stop badgering you now :-)

  6. Mike Bayer repo owner

    if I had a whole setup like that including some_common_stuff, I'd be putting the command runner into my own .py file and not be calling mako-render directly, in fact.

    Which points to something significant. When I wrote mako-render, I was not as savvy about packaging scripts with Python modules. Nowadays I know there is a better way, which is to put a function within the mako/* package itself, you then produce a script using a "console_scripts" entrypoint. The function in mako/* is something like "from mako.cmd import cmdline", something like that, then your own runner script can run it.

    I think that's the way to go here - move mako-render out of scripts/ as far as the source directory, make it into a module, and then mako-render itself is setup as a console_script in setup.py like this:

    entry_points = {'console_scripts': ['mako-render = mako.cmd:cmdline']}
    

    how's that sound?

  7. Derek Harland author

    I've created another branch that generates mako-render via an entry point.

    I wonder if we could reach a compromise on this issue though … what if I added another boolean option to mako-render so that sys.path is only extended with the template lookup path if you provide it. e.g.

    mako-render --augment-py-path
    
  8. Mike Bayer repo owner

    when we pull in #5 you're never going to need it, you'll have your own script that just runs mako.cmd and does whatever you want with sys.path.