0. What is istring? =================== istring is an interpolated string class, which means you can substitute variables into a string, like this: >>> j = 3 >>> s = istring("j is $j") >>> s 'j is 3' The istring class requires many features from Python 2.2, so you must install Python 2.2 to use this class. All istring objects are derived from full-fledged Python string objects, so you can do anything to an istring that you can do to a regular string, including take slices and use as a pattern in a regular expression. Although the istring class was created with SQL in mind, it may be used for many purposes. istrings fully support interpolation of dictionary values, list values, and return values from functions or class methods. It is intelligent about variable replacement, so for example it is not confused by: >>> s = istring("$k=3") I.e. it does not try to intepret "=3" as part of the variable. 1. How do I install istring? ============================ Note that Python 2.2 or higher is required. Version 1.0.1 supports distutils, so you can install by becoming root and typing: % python setup.py install from the istring main directory. You should then be able to start python and run the regression tests, as follows: >>> from neo.istring.istring import regression_tests >>> regression_tests() Normally to use istring, you can do: >> from neo.istring import istring [as ] 2. Why would I want to interpolate variables when I could use %s notation? ========================================================================== Ask yourself which query is clearer: (1) db.query("""SELECT foo, bar FROM %s WHERE rsrc_id = %s AND name = '%s'" % (table, rsrc_id, name)) Or: (2) qry = istring("""SELECT foo, bar FROM $table WHERE rsrc_id = $rsrc_id AND name = $.name""") db.query(qry) To make this even cleaner, we could write a function that took a regular raw string with istring interpolation, then made an istring of it and submitted the query, like this: (3) db.iquery("""SELECT foo, bar FROM $table WHERE rsrc_id = $rsrc_id AND name = $.name""") To me, there's no question that (3) is the easiest to read. However, since istring descends from the regular Python string class, you can use % notation intermixed with istring interpolation: >>> m = "abc" >>> n = "def" >>> test_dict = {'foo': 'bar', 'yak': 'lmnop'} >>> istring("value=%(foo)s$m,%(yak)s$n" % test_dict) "value=barabc,lmnopdef" 3. How can I include dictionary or list values in my istrings? What about results of class methods or functions? ========================================================================== istring handles this using a "dot" notation. (Credit note: istring utlizes NameMapper.py which is a file from the Cheetah project located at http://www.cheetahtemplate.org/.) For example: >>> d = {} >>> d['j'] = 5 >>> istring("d['j'] = $d.j") "d['j'] = 5" This also works for class methods and functions: >>> def foo(): return '5' ... >>> class sample: ... def test(self): ... return "sample_result" ... >>> s = sample() >>> istring("foo value == `$foo'; sample value == `$s.test'") "foo value == `5'; sample value == `sample_result'" Note however that parameters to functions or methods is not supported. Thus, the following example would not work: >>> # THIS DOES NOT WORK >>> def foo(param): return param+1 >>> ... >>> istring("$foo(5)") 4. What do the $, $. and & symbols do? ====================================== The $ notation in front of a variable tells istring to directly replace the variable with the variable's value. The $. symbol is useful for strings in SQL. It places the variable's value inside '' quotation marks; thus you do not have to type the quotation marks yourself. The & symbol indicates that a special helper function is to be used. Any function in the istring_std module may be used. For example: >>> l = [1,2,3] >>> istring("l contains: &list_to_str(l)") "l contains: 1,2,3" 5. How do I include a literal $, $. or & in my istrings? ======================================================== Just preceed these symbols with a backslash (`\'). Like this: >>> j = 4 >>> istring("j won't interpolate here: \$j") "j won't interpolate here: $j" 6. What ampersand-style functions are supported? ================================================ &list_to_str(variable) ---------------------- Convert a list to a comma-delimited string. &upper(variable) ---------------- Convert variable to uppercase. &lower(variable) ---------------- Convert variable to lowercase. &length(variable) ----------------- Return the length of the item. 7. My text is all squeezed together. Can I interpolate the string anyway? ========================================================================== Yes. >>> k = 2 >>> istring("The function call is called text$khtml") "The function call is called text2" 8. I'd like to interpolate part of a variable and then have the result itself interpolated. Can I do that? Also: What is $$ and && notation? ========================================================================== Yes. >>> abcde = "one" >>> lmnop = "cde" >>> istring("The value is $ab$$lmnop") "The value is one" When you use $$ and && notation, you're telling istring to use the result in the context of any other interpolations in the string. Thus, lmnop becomes "cde" which is then interpreted as part of $abcde. Compare to $ notation: >>> ab = "someval" >>> istring("The value is $ab$lmnop") "The value is somevalcde" 9. What methods/attributes does istring support? ================================================ raw_str: This attribute will provide the original, uninterpolated string that was used to create the istring. istr: This attribute will return the /current/ interpolation of the raw string. For example, if the value of interpolated variables had changed between the time the istring was created and the time istr was accessed, the return value would be the up-to-date value. vars: This attribute is a dictionary of variables found by the istring and what they were replaced with. 10. Future directions? ====================== I want to add an 'esc' function to escape strings properly for SQL as a way of hardening a web query from attacks by malicious users. I am open to any other special functions or other suggestions by end users.