Limited Python

LimPy parses a limited version of the Python grammar. It supports basic Python syntax, but is known not to support the following:

  • classes
  • function definition
  • multi-variable assignment
  • list and generator comprehensions

The goal is to be able to expose various Python objects to a scripting environment where non-professional programmers can write simple code to solve various problems.


LimPy originated in a survey system at YouGov where it gave the users scripting questionnaires the ability to include various bits of Python code that is executed during survey interviews.

A previous version of the survey system allowed Python code but it was not type checked and non-syntactical bugs were only reached at run time.

LimPy was successful in still offering much of the power of Python at runtime but checking types, operations on types, and function/method call signatures before runtime to ensure that an entire class of bugs was avoided.


LimPy checks code. You supply it with a namespace of helper objects, another namespace of variables and source code and it will raise various LimPy exceptions if there are problems or return the parsed code and the updated namespace of variables if there were new variables defined in the source.

LimPy does not execute the code. That is up to your runtime system to handle. The returned variables namespace contains only types as values, not real runtime values. Deciding what to do with that namespace is up to your runtime code.

Because LimPy is a strict subset of Python, it can typically be exec'd directly by Python.


LimPy includes some unit tests. To run them, simply invoke test or install the latest pytest. See the jenkins script for the routine used at YouGov to perform continuous integration testing on this project.



  • Use importlib instead of __import__ for programmatic imports.


  • Added .insert on lists.


  • Added limpy.types.Signature, which replaces build_sig, SigInfo, and signature functions. Any code that uses or references these deprecated functions will need to be updated.
  • TypeSpecification.add_method now only accepts a Signature instance.
  • LimPy now expects all dynamically-dispatched types to be classes that must provide IDynamicType (and need not necessarily be subclasses of DynamicDispatch).

Clients upgrading to LimPy 2.0 will typically just need to update their @limpy.types.signature decorators to instead use @limpy.types.Signature. Any calls to a TypeSpecification.add_method will need to first construct a Signature instance (with the same parameters).

For libraries that do more intimate things with the signatures, it will be necessary to update those references. See the repository changelog for details on how this was done within the LimPy project itself.


  • Improved newline counting and tests.
  • Empty source or source only comments is now valid LimPy.


  • Restored Python 2.5 compatibility.


  • Updated to PLY 3.4
  • Now by default LimPy does not write files to the current directory.


  • LimPy no longer allows assignment to Python reserved words.