Migration
This document describes how to update your code to each version of XIST. Only incompatible changes are listed here. For a list of all changes see History.
Migrating to version 5.76
Changes to ll.ul4c
The output infrastructure for UL4 (which was using generator before) has been switched to a stream API. The new API is incompatible with the old one.
Migrating to version 5.73
Changes to ll.pysql
Some PySQL commands have been renamed:
resetsequencetoreset_sequence,checkerrorstocheck_errors,raiseexceptionstoraise_exceptions,pushraiseexceptionstopush_raise_exceptionsandpopraiseexceptionstopop_raise_exceptions.The argument
raiseexceptionsto various PySQL commands has been renamed toraise_exceptions.
Migrating to version 5.67
Changes to ll.orasql
The method
ll.orasql.Connection.getobject()has been renamed toll.orasql.Connection.object_named().
Migrating to version 5.66
Changes to ll.color
The color method
abslum()has been renamed toabslight()and the methodrellum()has been renamed torellight().
Changes to UL4
UL4 functions and methods have been updated to use positional-only or keyword-only arguments to match the signature of the corresponding Python function/method.
Subclasses of
ll.ul4c.ASThave been renamed so that their name matches the name of the corresponding class in the Java implementation. (for examplell.ul4c.Addhas been renamed toll.ul4c.AddAST)The UL4 function
type()now returns type objects instead of simple strings. To get the name of the type use the type objects__name__attribute, i.e. replacetype(foo)withtype(foo).__name__.Naming of attributes that are used to implement UL4 functionality is more uniform now. This affects the following attributes: The methods
ul4_getattr(),ul4_setattr()andul4_hasattr()for implementing object attribute access from UL4; the methodsul4_call(),ul4_render()and ,ul4_renders()for making objects callable or renderable from UL4; the class attributeul4_attrsfor exposing a number of readonly attributes to UL4; the attributesul4_contextthat is used for marking a callable as needing the context as an argument in the call.Support for using custom tag delimiters for UL4 templates tag has been removed, i.e. now the tag delimiters will always be
<?and?>.The color method
abslum()has been renamed toabslight()and the methodrellum()has been renamed torellight().
Changes to ll.misc and ll.ul4on
Some function now use positional-only arguments:
ll.misc.item(iterable, index, /, default=None)ll.misc.first(iterable, /, default=None)ll.misc.last(iterable, /, default=None)ll.misc.count(iterable, /)ll.misc.isfirst(iterable, /)ll.misc.islast(iterable, /)ll.misc.isfirstlast(iterable, /)ll.misc.monthdelta.__init__(self, months=0, /)ll.ul4on.dumps(obj, /, indent)ll.ul4on.dump(obj, /, stream, indent)ll.ul4on.load(stream, /, registry=None)ll.ul4on.loads(dump, /, registry=None)ll.ul4on.loadclob(clob, /, bufsize=1024*1024, registry=None)
Update your calls accordingly.
Migrating to version 5.58
Changes to ll.sisyphus
The method
healthcheck()should no longer be implemented. Instead the option--maxhealthcheckageor the class/instance attributemaxhealthcheckagecan be used to configure the maximum allowed age.The method
failed()is no longer supported. If you need its functionality wrap the content of yourexecute()method in atryblock and put the content of youfailed()method into anexceptblock (and reraise the exception at the end of theexceptblock).The filenames for log files can no longer be changed via options or job attributes, instead one of the following methods must be overwritten:
basedir()logfilename()currentloglinkname()lastsuccessfulloglinkname()lastfailedloglinkname()lastinterruptedloglinkname()lasttimeoutloglinkname()healthfilename()emailfilename()
Those methods must return an absolute path as a
pathlib.Pathobject.
Migrating to version 5.57
Changes to ll.ul4on
ll.ul4on.Encoder and ll.ul4on.Decoder now expect the stream
to be passed in the call to dump() and load() instead of in the
constructor. I.e. change:
Encoder(stream).dump(obj)
to:
Encoder().dump(obj, stream)
and:
obj = Decoder(stream).load()
to:
obj = Decoder().load(stream)
The parameter name for the UL4ON function fromul4on() has changed from
string to dump.
Migrating to version 5.56
Changes to ll.orasql
ll.orasql.Comment has been renamed to ll.orasql.ColumnComment.
Migrating to version 5.52
Changes to ll.orasql
The method getobject() for ll.orasql.Synonym has been renamed to
object().
Migrating to version 5.45
Changes to UL4
The UL4 AST node attribute line and col have been renamed to
startline and startcol.
Migrating to version 5.44
Changes to ll.pysql
The PySQL command compileall has been removed. This same effect can
simply be achieved by calling utl_recomp.recomp_parallel() or
dbms_utility.compile_schema().
The PySQL terminator comment (-- @@@) can now no longer be specified
via a command line option.
The connectstring argument for the pysql script is now optional,
so it has to be specified via the optional argument -d/--database.
The --commit argument (with the options record, once and never)
has been replaced with a flag option --rollback. Automatically committing
after every record is no longer available. However manual committing is
available via the commit command.
PySQL no longer supports multiple active database connections via the
connectname key. When using literal SQL this couldn’t be used anyway, so it
has been dropped. If you really need this feature you can implement a workaround
in literal Python blocks.
Migrating to version 5.42
Changes to ll.sisyphus
Returning None from ll.sisyphus.Job.execute() now has a special
meaning: Delete the log file. If this isn’t wanted a string (e.g. "done")
should be returned.
Migrating to version 5.40
Changes to ll.orasql
The class ll.orasql.SchemaObject has been renamed to
ll.orasql.OwnedSchemaObject. (ll.orasql.SchemaObject now
is for objects that don’t have an owner (i.e. ll.orasql.User and
ll.orasql.JobClass).)
Migrating to version 5.37
Changes to UL4
Exception chaining has changed, so the exception you get from calling/rendering
an UL4 template now is the original exception. To get to the information about
the location in the UL4 source code you have to iterate through the
__cause__ chain.
The interal structure of UL4 templates has been simplified, but that should
only concern you if you’ve worked with the UL4 AST itself. Basically
Tag objects are gone now, and instead each AST node has
attributes template (referencing the outermost template) and pos (being
the position of the nodes source code). This also means that blocks no longer
have an endtag attribute.
Migrating to version 5.36
Changes to ll.orasql
As cx_Oracle provides its own Object orasql.Object
has been renamed to orasql.SchemaObject.
Migrating to version 5.34
Changes to XIST
The class ll.xist.ns.html.script.Attrs.async has beend renamed to
async_, because async is a keyword in Python 3.7.
Migrating to version 5.32
Changes to ll.orasql
The default value for the owner parameter in various ll.orasql
methods has changed from ALL to None (i.e. it now returns the objects
from the current schema instead of all schemas).
The changed methods are: Connection.tables(),
Connection.sequences(), Connection.fks(),
Connection.privileges(), Connection.objects(), Object.names(),
Object.objects() (and all subclasses of Object) and
Privilege.objects().
To get the old behaviour back, simply pass owner=orasql.ALL to those methods.
Migrating to version 5.28
Changes to UL4
UL4 now longer tries a disguise objects as dictionaries. I.e. for objects with an
ul4attrsclass attribute the methodsitems,keys,valuesandgetare no longer synthesized. This also means thatlen,list, item access and containment tests no longer work on objects. However iterating over the attribute names of an object can now be done with the new functiondir. To get, set and test attributes, the new functionsgetattr,setattrandhasattrcan be used.
Migrating to version 5.22
Changes to pysql
The values for the option
-v/--verbosehas changed:-v1now is-vdot,-v2is-vtypeand-v3is-vfull.
Migrating to version 5.21
Changes to ll.color
Colors can no longer be added. This was done with the formula:
0.5*(c1.r+c2.r), 0.5*(c1.g+c2.g), 0.5*(c1.b+c2.b), 255-(255-c1.a)*(255-c2.a)/255.)
Changes to ll.orasql
The method
ll.orasql.ForeignKey.pk()has been renamed torefconstraint().
Migrating to version 5.20
Changes to ul4
The variables passed to UL4 templates in rul4 have been moved into a
globalsobjects. The following changes have to be made to the template source:change
oracle.connect(...)toglobals.oracle(...);change
mysql.connect(...)toglobals.mysql(...);change
sqlite.connect(...)toglobals.sqlite(...);change
system.execute(...)toglobals.system(...);change
load(...)toglobals.load(...);change
error(...)toglobals.error(...);change
footoglobals.vars.foofor a variablefoodefined viarul4 -D.
Migrating to version 5.18
Changes to ul4
The UL4 exception
ll.ul4c.Errorhas been renamed toLocationError.The UL4 function
typenow returns the Python class name for date, color, template exception objects.
Migrating to version 5.17
Changes to rul4
The function import has been split into load for loading the content of
a file and compile for compiling a string, so:
<?code template = import("/home/user/template/foo.ul4")?>
has to be replaced with:
<?code template = compile(load("/home/user/template/foo.ul4"))?>
Migrating to version 5.16
Changes to orasql
Some methods in orasql have been renamed: Iterating methods no longer
have iter in their name (e.g. itertables() is now simply called
tables()). The ddl part of some method names has been changed to
sql (e.g. createddl() is now called createsql()).
Migrating to version 5.15
Changes to PySQL
The function
loadhas been replaced by two functionsloadstrfor loading strings andloadbytesfor loading bytes, i.e. replace:load('foo.txt', 'utf-8', 'replace')
with:
loadstr('foo.txt', 'utf-8', 'replace')
and:
load('foo.png')
with:
loadbytes('foo.png')
PySQL no longer supports the
-- !!!command terminator. Use theraiseexceptionscommand instead to specify error handling.
Migrating to version 5.14
Changes to UL4
The boolean parameter
keepwsforul4c.Templatehas been renamed towhitespaceand requires a string value now. Passwhitespace="keep"for the oldkeepws=Trueandwhitespace="strip"for the oldkeepws=False.The
rul4option--keepwshas been renamed to--whitespaceand defaults tosmartnow. So instead of the old--keepws=1pass--whitespace=keepand for--keepws=0pass--whitespace=strip.Rendering an UL4 template from inside a UL4 template is now again done via the
<?render?>tag. So inside a template you have to replace the code:<?code template.render(foo, bar)?>
with:
<?render template(foo, bar)?>
Closures in UL4 templates no longer see the state of the variables at the time when the local template was defined, but at the time when it is called. This is similar to most other languages that support closures.
To emulate the old behaviour pass the variables you want to “freeze” to a locally defined template and define the original template there.
Changes to pysql
SQL commands must be terminated with a
-- @@@(or-- !!!) comment line now, i.e. now the comment after the command determines whether exceptions will be ignored, instead of the comment before the command.
Migrating to version 5.13
Changes to UL4
Locally defined UL4 templates no longer see themselves among the variables of the parent template.
Changes to sisyphus
The option
setproctitlefor sisyphus jobs has been renamed toproctitle.The default for the name parameter in
tasks()for sisyphus jobs has changed fromstrtoNone, i.e. it defaults to unnamed tasks now.
Migrating to version 5.12
Changes to ul4on
The UL4ON serialization format has been reimplemented to be more human-readable and robust. The new format is incompatible to the old. If you update your XIST installation to 5.12 you should update the corresponding UL4ON versions for Java/Javascript too.
Migrating to version 5.10
Changes to misc
The functions
misc.gzip()andmisc.gunzip()have been removed as Python 3.2 has the functionsgzip.compress()andgzip.uncompress(), which do the same.
Migrating to version 5.9
Changes to db2ul4
The script
db2ul4has been renamed torul4.
Changes to ll.url
The argument
patternof the URL methodslistdir(),files(),dirs(),walk(),walkfiles()andwalkdirs()has been renamed toinclude.The method
walk()has been renamed towalkall().
Migrating to version 5.7
Changes to ll.oradd
The
filecommand has been renamed toscp.
Changes to ll.orasql
The methods
ll.orasql.Record.keys()andll.orasql.Record.values()return iterators now.ll.orasql.Record.iterkeys()andll.orasql.Record.itervalues()have been removed.
Migrating to version 5.6
Changes to ll.oradd
Support for
"keys"and"sqls"has been removed fromll.oradd. So{ "type": "procedure", "name": "procname", "args": { "proc_id": "p_10", "proc_date": "sysdate", "keys": {"proc_id": "int"}, "sqls": ["proc_date"] } }
has to be replaced with
{ "type": "procedure", "name": "procname", "args": { "proc_id": var("p_10", int), "proc_date": sql("sysdate") } }
UL4ON dumps are no longer supported by
ll.oradd. They must be reencoded as Pythonreproutputs, which can be done with code that looks like this:import sys from ll import ul4on while True: try: print(repr(ul4on.load(sys.stdin))) except EOFError: break
Migrating to version 5.4
Changes to ll.url
The
remotepythonparameter forsshURLs has been renamed topython.
Migrating to version 5.2
Changes to sisyphus
The method
prefix()forsisyphusjobs has been replaced withtask()which does something similar.
Changes to UL4
The names of methods that should be callable for custom objects in UL4 templates must be added to the
ul4attrsattributes.
Changes to oradd
Committing the transactions in
oraddcan now be done after each record with the new option--commit.--rollbackhas been removed, so you have to replace--rollback=1with--commit=never.
Changes to misc
The default argument for the functions
misc.first()andmisc.last()now defaults toNone. I.e. for empty iterators the default value will always be returned instead of generating an exception. To simulate the old behaviour use a unique guard object as the default.Renamed the attributes
scriptnameandshortscriptnameof themisc.sysinfoobject toscript_nameandshort_script_name.
Migrating to version 5.1
Changes to db2ul4
The
querymethod for database connections has changed: Instead of a query and a parameter dictionary, you have to pass in positional arguments that alternate between fragments of the SQL query and parameters. I.e.:db.query("select * from table where x=:x and y=:y", x=23, y=42)
becomes:
db.query("select * from table where x=", 23, " and y=", 42)
This makes
db2ul4independent from the parameter format of the database driver.
Migrating to version 5.0
Changes to XIST
Accessing attributes via
__getattr__(),__setattr__()and__delattr__()now requires the XML name of the attribute instead of the Python name. If you only have the Python name, you can convert it to the XML name with the methodAttrs._pyname2xmlname().For all methods that existed in Python/XML pairs (e.g.
withnames()andwithnames_xml()inxsc.Attrsorelementclass()andelementclass_xml()inxsc.Pooletc.) there is only one version now: A method without the_xmlsuffix in the name, that accepts the XML version of the name.Validation is now off by default, to turn it on pass
validate=Truetoparse.tree()orparse.itertree()for parsing, or to the publisher object or thebytes(),iterbytes(),string()oriterstring()methods for publishing.
Migrating to version 4.10
Changes to UL4
The UL4 tag
<?render?>have been removed. To update your code replace<?render r.render()?>with<?exe r.render()?>.The UL4 functions
varsandgethave been removed.The automatic UL4 variable
stackhas been removed too.
Migrating to version 4.7
Changes to UL4
Compiling a UL4 template to a Java
CompiledTemplateis no longer supported (i.e.template.javasource(interpreted=False)no longer works. Usetemplate.javasource()instead (which creates Java sourcecode for anInterpretedTemplate).
Migrating to version 4.6
Changes to ll.xist
The
walk()method has been changed to return aCursorobject instead of the path, so you have to replace:for path in doc.walk(...): # use path
with:
for cursor in doc.walk(...): # use cursor.path
Furthermore walk filters have been removed. Determining whether an XIST tree is traversed top down or bottom up can instead by specified via distinct parameters to the
walk()method. Replace:for path in doc.walk((xfind.entercontent, xfind.enterattrs, True)): ...
with:
for cursor in doc.walk(entercontent=True, enterattrs=True, startelementnode=False, endelementnode=True): ...
If you want to enter an element only when a condition is true, you can do that by modifying the appropriate cursor attribute inside your loop:
for cursor in doc.walk(entercontent=True, enterattrs=True): if isinstance(cursor.node, html.script, html.textarea): cursor.entercontent = False ...
ll.xist.parse.itertree()now returnsCursorobjects too, instead of path lists.Slicing XIST elements now returns a sliced element, instead of a slice from the content
Frag:>>> from ll.xist.ns import html >>> html.ul(html.li(i) for i in range(5))[1:3].string() '<ul><li>1</li><li>2</li></ul>'
To get a slice from the content simply use:
>>> html.ul(html.li(i) for i in range(5)).content[1:3].string() '<li>1</li><li>2</li>'
Migrating to version 4.4
Changes to the required Python version
Python 3.3 is required now.
Migrating to version 4.2
Changes to ll.ul4c
The UL4 method
joinno longer callsstron the items in the argument list. Replacesep.join(iterable)withsep.join(str(i) for i in iterable)when you have an argument list that contains non-strings.
Migrating to version 4.1
Changes to ll.make
The support for Growl notifications in
ll.makeon the Mac has been replaced by support for Mountain Lions Notification Center.The option has been renamed from
--growlto--notify.For this to work you need to have terminal-notifier installed in its standard location (
/Applications/terminal-notifier.app).
Migrating to version 4.0
Changes to the required Python version
Python 3.2 is required now.
Changes to UL4
Date constants in UL4 have changed again. They are now written like this:
@(2012-04-12)or@(2012-04-12T12:34:56).The function
jsonhas been renamed toasjson.The
<?render?>tag in UL4 now looks like a method call instead of a function call. I.e.<?render t(a=17, b=23)?>has changed to<?render t.render(a=17, b=23)?>.
Changes to scripts
The scripts
oracreate,oradrop,oradelete,oradiff,oramerge,oragrant,orafindanduhppno longer have an-e/--encodingoption. They always use Pythons output encoding.The options
-i/--inputencodingand-o/--outputencodingof the scriptdb2ul4have been replaced with an option-e/--encodingfor the encoding of the template files. For printing the result Pythons output encoding is used.The options
--inputencoding/--inputerrorsand--outputencoding/--outputerrorsofll.sisyphus.Jobhave been replaced with option--encoding/--errorsfor the encoding of the log files.
Migrating to version 3.25
Changes to XIST
The
compact()method has been renamed tocompacted()to avoid collisions with thecompactattribute in HTML elements.
Migrating to version 3.24
Changes to ll.xist.ns.ul4
ll.xist.ns.ul4.attr_ifis now anll.xist.xsc.AttrElementsubclass. Change your code from:html.div(id=(ul4.attr_if("foo"), "bar"))
to:
html.div(id=ul4.attr_if("bar", cond="foo"))
ll.xist.ns.ul4.attr_ifnnhas been removed. Replace it with the equivalentattr_ifcall.
Migrating to version 3.23
Changes to ll.ul4c
The module global functions
ll.ul4c.compile(),ll.ul4c.load()andll.ul4c.loads()have been removed. Instead of them theTemplateconstructor and the class methodsload()andloads()can be used.
Migrating to version 3.20
Changes to ll.orasql
The
schemaargument used by various methods inll.orasqlhas been replaced by aownerargument that can beNone(for the current user), the constantALLfor all users (which uses theDBA_*variant of various meta data views if possible or theALL_*variants otherwise) and a specific user name.
Migrating to version 3.19
Changes to ll.orasql
ll.orasqlnow requires cx_Oracle 5.1 (i.e.UNICODEmode is no longer used).If the
readlobsoption is false forll.orasqlcursors, the CLOBs/BLOBs returned will be wrapped into something that behaves like a Python file. The originalLOBobject is available as thevalueattribute of the returned wrapper object:db = orasql.connect("user/pwd@db") c = db.cursor() c.execute("select theclob from thetable") row = c.fetchone() print row[0].value.read()
Migrating to version 3.18
Changes to db2ul4
The variables available in UL4 templates used by
db2ul4have changed. Instead of aconnectobject, there are now three objects for each supported database (i.e.oracle,sqliteandmysql). To update your template replace:connect["oracle:user/pwd@db"]
with:
oracle["user/pwd@db"]
Changes to scripts
The script
doc2txtnow reads fromstdinand writes tostdoutinstead of requiring file names on the command line.
Migrating to version 3.17
Changes to ll.misc
ll.misc.javastring()has been renamed toll.misc.javaexpr().The UL4 method
formatis now a function instead.
Migrating to version 3.16
Changes to ll.misc
ll.misc.flag()is gone. If the function is still required, here is the source:def flag(value): if value in ("1", "true", "yes"): return True elif value in ("0", "false", "no"): return False raise ValueError("unknown flag value")
Migrating to version 3.15
Changes to ll.xist.ns.jsp
ll.xist.ns.jsp.javastring()has been move toll.misc.
Migrating to version 3.14
Changes to ll.ul4c
Date constants now need a
@as a prefix. I.e. chance2010-11-03Tto@2010-11-03Tetc.The
functionargument forul4c.Template.pythonsource()is gone. The output will always be a full function.
Migrating to version 3.12
Changes to ll.sisyphus
The maximum allowed runtime for jobs is now a hard limit. Previously a running job that exceeded the maximum allowed runtime would only be killed when the next job was started. Now the job will kill itself immediately after
maxtimeseconds. This means you might have to adjust yourmaxtimesetting.The default location of log files has changed again. Now
~/ll.sisyphus/is used as the base directory instead of~/ll.sisyphus/log/.
Migrating to version 3.11
Changes to ll.sisyphus
The method
logLoop()is gone. Replace:self.logLoop("done")
with:
return "done"
The method
logProgress()is gone. Replace:self.logProgress("parsing XML file")
with:
self.log("parsing XML file")
You might also add tags to the logging call via:
self.log.xml("parsing XML")
(This adds the tag
"xml"to the log line.)The method
logError()is gone. Replace:self.logError("Can't parse XML file")
with:
self.log.error("Can't parse XML file")
If the object passed to
self.logis an exception, the logging call will add theexctag automatically.sisyphus.Jobno longer has a constructor. Configuration is now done via class attributes. Replace:class TransmogrifyStuff(sisyphus.Job): def __init__(self, connectstring): sisyphus.Job.__init__(self, 30, "ACME_TransmogrifyStuff", raiseerrors=True)
with:
class TransmogrifyStuff(sisyphus.Job): projectname = "ACME.MyProject" jobname = "TransmogrifyStuff" maxtime = 30
The default location of run/log files has changed. Now
~/ll.sisyphus/logis used for log files and~/ll.sisyphus/runis used for run files.
Migrating to version 3.10
Changes to the required Python version
Python 2.7 is required now.
Changes to ll.make
ll.make.Project.optionparser()has been renamed toargparser()and returns aargparse.ArgumentParserobject now.ll.make.Project.parseoptions()has been renamed toparseargs()and returns aargparse.Namespaceobject now.
Changes to ll.daemon
Migrating to version 3.9
Changes to ll.xist.ns.html
ll.xist.ns.html.htmlwill no longer change thelangandxml:langattributes. This functionality has been moved to the new elementll.xist.ns.htmlspecials.html. Furthermore this new element will not change an attribute if this attribute has already been set.So if you need the functionality replace any use of
ll.xist.ns.html.htmlwithll.xist.ns.htmlspecials.html.ll.xist.ns.html.titleno longer does any manipulation of its content.If you needed this functionality, you can copy it from the old
titleelement and put it into your own element class.
Migrating to version 3.8
Changes to parsing
The parsing infrastructure has been completely rewritten to be more modular and to support iterative parsing (similar to ElementTree). Now parsing XML is done in a pipeline approach.
Previously parsing a string looked like this:
>>> from ll.xist import xsc, parsers >>> from ll.xist.ns import html >>> source = "<a href='http://www.python.org/'>Python</a>" >>> doc = parsers.parsestring(source, pool=xsc.Pool(html))
Now this is done the following way:
>>> from ll.xist import xsc, parse >>> from ll.xist.ns import html >>> source = "<a href='http://www.python.org/'>Python</a>" >>> doc = parse.tree( ... parse.String(source) ... parse.Expat() ... parse.NS(html) ... parse.Node(pool=xsc.Pool(html)) ... )
For more info see the module
ll.xist.parse.Something that no longer works is parsing XML where elements from different namespaces use the same namespace prefix. You will either have to rewrite your XML or implement a new class for the parsing pipeline that handles namespaces prefixes and instantiating XIST classes (i.e. a combination of what
ll.xist.parse.NSandll.xist.parse.Nodedo).The module
ll.xist.parsershas been renamed toparse.The module
ll.xist.presentershas been renamed topresent.The classes
ll.xist.converters.Converterandll.xist.publishers.Publisherhave been moved toll.xist.xsc. The modulesll.xist.convertersandll.xist.publishersno longer exist.
Changes to XISTs walk filters
The walk methods
walknode()andwalkpath()have been renamed towalknodes()andwalkpaths(). The classWalkFilterhas been moved toll.xist.xfind.
Changes to ll.url
ll.url.Pathhas been simplified: Path segments are strings instead of tuples. If you need the path parameters (i.e. part after;in a path segment) you have to split the segment yourself.ll.url.URL.import_()is gone. As a replacementmisc.module()can be used, i.e. replace:>>> from ll import url >>> u = url.File("foo.py") >>> m = u.import_(mode="always")
with:
>>> from ll import url, misc >>> u = url.File("foo.py") >>> m = misc.module(u.openread().read(), u.local())
However, note that
ll.url.URL.import_()has been reintroduced in 3.8.1 based onmisc.import(). This means that the mode argument is no longer supported.ssh URLs now required to standalone
execnetpackage. Thessh_configparameter for ssh URLs is gone.
Changes to ll.make
The two classes
ll.make.PoolActionandll.make.XISTPoolActionhave been dropped. To update your code, replace:make.XISTPoolAction(html)
with:
make.ObjectAction(xsc.Pool).call(html)
The class
XISTParseActionhas been removed. This action can be replaced by a combination ofObjectAction,CallActionandCallAttrActionusing the new parsing infrastructure.
Other changes
ll.xist.ns.specials.zhas been moved to thell.xist.ns.docmodule.
Migrating to version 3.7
Changes to the make module
The division operator for actions is no longer implemented, so instead of:
t1 = make.FileAction(key=url.URL("file:foo.txt")) t2 = t1 / make.DecodeAction("iso-8859-1") / make.EncodeAction("utf-8") / make.FileAction(key=url.URL("bar.txt"))
you now have to write something like the following:
t1 = make.FileAction("file:foo.txt") t2 = t1.callattr("decode", "iso-8859-1") t2 = t2.callattr("encode", "utf-8") t2 = make.FileAction("file:bar.txt", t2)
Also the following classes have been removed from
ll.make:EncodeAction,DecodeAction,EvalAction,GZipAction,GUnzipAction,JavascriptMinifyAction,XISTBytesAction,XISTStringAction,JoinAction,UnpickleAction,PickleAction,TOXICAction,TOXICPrettifyAction,SplatAction,UL4CompileAction,UL4RenderAction,UL4DumpAction,UL4LoadAction,XISTTextActionandXISTConvertAction. All of these actions can be executed by usingCallActionorCallAttrAction.
Migrating to version 3.6
Changes to the color module
The following
Colorclass methods have been dropped:fromrgba,fromrgba4,fromrgba8,fromint4,fromint8.The following
Colorproperties have been dropped:r4,g4,b4,a4,r8,g8,b8,a8,r,g,b,aint4,int8,rgb4,rgba4,rgb8, andrgba8. The new methodsr,g,bandareturn the 8 bit component values.The class methods
fromhsvaandfromhlsahave been renamed tofromhsvandfromhls.The property
csshas been dropped. The CSS string is returned by__str__now.Dividing colors now does a scalar division. Blending colors is now done with the modulo operator.
Removal of XPIT
The XPIT templating language has been removed. You should replace all your XPIT templates with UL4 templates.
Migrating to version 3.5
Changes to UL4
The UL4 function
csvescapehas been renamed tocsv.
Changes to the color module
ll.color.Colorhas been rewritten to create immutable objects with the components being 8 bit values (i.e. 0-255) instead of floating point values between 0 and 1.
Migrating to version 3.4
Changes to the make module
ll.make.CallMethActionhas been renamed toCallAttrAction.ll.make.XISTPublishActionhas been renamed toXISTBytesAction.
Changes to UL4
The templates available to the
<?render?>tag are no longer passed as a separate argument to the render methods, but can be part of the normal variables.
Changes to XIST
Building trees with
withblocks has changed slightly. Unchanged code will lead to the following exception:File "/usr/local/lib/python2.5/site-packages/ll/xist/xsc.py", line 1285, in __enter__ threadlocalnodehandler.handler.enter(self) AttributeError: 'NoneType' object has no attribute 'enter'
To fix this, change your code from:
with html.html() as node: with html.head(): +html.title("Foo") with html.body(): +html.p("The foo page!")
to:
with xsc.build(): with html.html() as node: with html.head(): +html.title("Foo") with html.body(): +html.p("The foo page!")
(i.e. wrap the outermost
withblock in anotherwith xsc.build()block.)
Migrating to version 3.3
Changes to the make module
ll.make.ImportActionhas been dropped as now the module object can be used directly (e.g. as the input for anXISTPoolActionobject).The constructor of most action classes now accept the input action as a parameter again. This means that you might have to change the calls. Usually it’s safest to use keyword arguments. I.e. change:
make.FileAction(url.File("foo.txt"))
to:
make.FileAction(key=url.File("foo.txt"))
The
targetrootparameter forll.make.XISTConvertAction.__init__()has been renamed toroot.
Changes to TOXIC
TOXIC has been split into a compiler and an XIST namespace module. Instead of calling the function
ll.xist.ns.toxic.xml2ora()you now have to usell.toxicc.compile(). (However using TOXIC withll.makehasn’t changed).
Changes to XIST
The default parser for XIST is expat now. To switch back to sgmlop simply pass an
SGMLOPParserobject to the parsing functions:>>> from ll.xist import parsers >>> node = parsers.parsestring("<a>", parser=parsers.SGMLOPParser())
Migrating to version 3.2.6
Changes to escaping
The functions ll.xist.helpers.escapetext and
ll.xist.helpers.escapeattr have been merged into ll.misc.xmlescape
and all the characters <, >, &, " and ' are escaped now.
Migrating to version 3.1
Changes to URL handling
URLs containing processing instructions will no longer be transformed in
any way. If you need the old behaviour you can wrap the initial part of
the attribute value into a specials.url PI.
Migrating to version 3.0
Changes to tree traversal
You can no longer apply xfind expression directly to nodes, so instead of:
for node in root//html.p:
print node
you have to write:
for node in root.walknode(html.p):
print node
If you want the search anchored at the root node, you can do the following:
for node in root.walknode(root/html.p):
print node
This will yield html.p elements only if they are immediate children of
the root node.
Passing a callable to the walk() method now creates a
ll.xist.xfind.CallableSelector. If you want the old tree traversal
logic back, you have to put your code into the filterpath() method of a
WalkFilter object.
Many of the XFind operators have been renamed (and all have been rewritten).
See the xfind documentation for more info.
The death of namespace modules
It’s no longer possible to turn modules into namespaces. Element classes belong
to a namespace (in the XML sense) simply if their xmlns attribute have the
same value. So a module definition like this:
from ll.xist import xsc
class foo(xsc.Element):
def convert(self, converter):
return xsc.Text("foo")
class xmlns(xsc.Namespace):
xmlname = "foo"
xmlurl = "http://xmlns.example.org/foo"
xmlns.makemod(vars())
has to be changed into this:
from ll.xist import xsc
class foo(xsc.Element):
xmlns = "http://xmlns.example.org/foo"
def convert(self, converter):
return xsc.Text("foo")
Renamed doc classes
Many classes in the ll.xist.ns.doc module have been renamed. The
following names have changed:
functiontofunc;methodtometh;moduletomod;propertytoprop;titletoh;partop;olisttool;ulisttoul;dlisttodl;itemtoliordd(depending on whether it’s inside anol,ulordl);termtodt;linktoa.
Migrating to version 2.15
Changes to plain text conversion
The node method asText() has been moved to the html namespace,
so you have to replace:
print node.asText()
with:
from ll.xist.ns import html
print html.astext(node)
Changes to htmlspecials.pixel
If you’ve been using the color attribute for htmlspecials.pixel,
you have to add a # in from of the value, as it is a CSS color value now.
(And if’ve you’ve been using color and a CSS padding of a different color:
This will no longer work).
Migrating to version 2.14
Changes to presenters
Presenters work differently now. Instead of:
print node.asrepr(presenters.CodePresenter)
simply do the following:
print presenters.CodePresenter(node)
Migrating to version 2.13
Changes to ll.xist.xsc
xsc.Namespace.tokenize() no longer has an encoding argument, but
operates on a unicode string directly. You can either use the result of a
asString() call or decode the result of an asBytes() call yourself.
Migrating to version 2.11
Changes to ll.xist.xsc
The function ToNode() has been renamed to tonode().
ll.xist.Context no longer subclasses list. If you need a stack
for your context, simply add the list as an attribute of the context object.
Code rearrangements
The iterator stuff from ll.xist.xfind has been moved to the ll
package/module, i.e. you have to use ll.first() instead of
ll.xist.xfind.first().
Changes to the walk() method
The walk() method has changed again. There are no inmodes and outmodes any
longer. Instead input and output are Cursor objects. If you’re using
your own walk() filters, you have to update them. For different output
modes you can use the methods walknode(), walkpath() or
walkindex() instead of using the cursor yielded by walk().
The node methods find() and findfirst() have been removed. Use
xsc.Frag(node.walk(...)) or node.walk(...)[0] instead.
Changes to publishing
Publishing has changed: If you’ve used the method repr() before to get a
string representation of an XML tree, you have to use asrepr() instead now
(repr() is a generator which will produce the string in pieces).
Changes to the xfind module
The functions item(), first(), last(), count() and
iterone() as well as the class Iterator have been moved to the
ll module.
Migrating to version 2.10
Changes to publishing
Publishing has been changed from using a stream API to using a iterator API. If
you’ve been using Publisher.write() or Publisher.writetext() (in
your own publish() methods) you must update your code by replacing
publisher.write(foo) with yield publisher.encode(foo) and
publisher.writetext(foo) with yield publisher.encodetext(foo).
Changes to the test suite
The test suite now uses py.test, so if you want to run it you’ll need py.test.
Changes to ll.xist.ns.code
The code in a ll.xist.ns.code.pyexec object is no longer executed at
construction time, but at conversion time. So if you relied on this fact (e.g.
to make a namespace available for parsing of the rest of the XML file) you will
have to change your code.
Removed namespaces
The namespace modules ll.xist.ns.css and ll.xist.ns.cssspecials
have been removed.
Migrating to version 2.9
Changes to exceptions
All exception classes have been moved from ll.xist.errors to
ll.xist.xsc.
Changes to XML name handling
The class attribute xmlname no longer gets replaced with a tuple
containing both the Python and the XML name. If you want to get the Python name,
use foo.__class__.__name__.
Changes to the methods walk(), find() and findfirst()
The argument filtermode has been renamed to inmode and (for
walk()) walkmode has been renamed to outmode.
Migrating to version 2.8
Changes to display hooks
The way XIST uses sys.displayhook() has been enhanced. To make use of
this, you might want to update your Python startup script. For more info see the
installation instructions.
Changes to the xmlns attribute
Each element (or entity, or processing instruction) class had an attribute
xmlns that references the namespace module. This attribute has been
renamed to __ns__.
Other minor changes
ll.xist.ns.specials.x has been renamed to
ll.xist.ns.specials.ignore.
ll.xist.xfind.item no longer handles slices. If you’ve used that
functionality, you may now use slices on XFind operators, and materialize the
result, i.e. replace xfind.slice(foo, 1, -1) with list(foo[1:-1]), if
foo is an XFind operator. Otherwise you can use list(foo)[1:-1].
Migrating to version 2.7
Changes to ll.xist.xfind
The functions xfind.first() and xfind.last() now use
xfind.item(), so they will raise an IndexError when no default
value is passed. To get the old behaviour, simply pass None as the default.
Migrating to version 2.6
Changes to the publishing API
The top level publishing method in the publisher has been renamed from
dopublication() to publish(). If you’re using the publishing API
directly (instead of the node methods asBytes() and write()), you’ll
have to update your code.
The method that writes a unicode object to the output stream has been renamed
from publish() to write(). This is only relevant when you’ve
overwritten the publish() method in your own node class (e.g. in JSP tag
library directives or similar stuff, or for special nodes that publish some text
literally).
Changes to the presentation API
The presentation API has been changed too: The top level presentation method in
the presenter has been renamed from dopresentation() to present().
This is only relevant if you’ve written your own presenter, or are using the
presentation API directly (instead of the node method repr()).
Parsing HTML
Parsing HTML is now done via libxml2’s HTML parser, instead of using µTidyLib of
mxTidy. You can no longer pass arguments to tidy. Only the boolean values of the
tidy argument will be used. There are no other visible changes to the API
but the result of parsing might have changed.
Removed APIs and scripts
The script xscmake.py has been removed.
The visit() method has been removed.
ll.xist.xsc.FindOld() has been removed.
ll.xist.ns.xml.header has been renamed to
ll.xist.ns.xml.declaration.
Migrating to version 2.5
Changes to content model
The boolean class attribute empty for element classes has been replaced
by an object model. empty is still supported, but issues a
PendingDeprecationWarning. If you don’t want to specify a proper
content model for your own elements you can replace empty = False with
model = True (which is a shortcut for model = sims.Any()) and
empty = True with model = False (which is a shortcut for
model = sims.Empty()).
Migrating to version 2.4
Changes to parsing
Parsing has changed internally, but the module level parsing functions in
ll.xist.parsers are still available (and will create a parser on the
fly), but a few arguments have changed:
handlerThis argument is no longer available, if you need a special handler, you have to subclass
ll.xist.parsers.Parserand call its parsing methods.parserThis argument has been renamed to
saxparserand is not a SAX2 parser instance any longer, but a callable that will create a SAX2 parser.sysidsysidis now available for all parsing functions not justparseString().
Changes to converter contexts
ll.xist.converters.Converter.__getitem__() now doesn’t use the key passed
in, but key.Context as the real dictionary key. This has the following
consequences:
If you want a unique context for your own element class, you must implement a new
Contextclass (otherwise you’d getll.xist.xsc.Element.Context):class Foo(xsc.Element): empty = False class Context(xsc.Element.Context): def __init_(self): xsc.Element.Context.__init__(self) ...
Subclasses that don’t overwrite
Context(as well as instances of those classes) can be passed toll.xist.converters.Converter.__getitem__()and the unique base class context object will be returned.
Changed namespaces
The character reference classes from ll.xist.ns.ihtml that are duplicates
of those in ll.xist.ns.chars have been removed, so you have to use
ll.xist.ns.chars for those characters in addition to
ll.xist.ns.ihtml
Migrating to version 2.3
Changes in namespace handling
Namespace handling has changed. There are no entity or processing instruction
prefixes any longer and creating a proper Prefixes object has been
simplified. For example:
prefixes = xsc.Prefixes()
prefixes.addElementPrefixMapping(None, html)
prefixes.addElementPrefixMapping("svg", svg)
can be simplified to:
prefixes = xsc.Prefixes(html, svg=svg)
The three arguments elementmode, entitymode and
procinstmode for the publishing methods have been combined into
prefixmode, which is used for elements only.
Changed namespaces
The character reference classes from ll.xist.ns.html have been moved
to a separate namespace ll.xist.ns.chars.
The processing instructions eval_ and exec_ from the
ll.xist.ns.code module have been renamed to pyeval and
pyexec.
Changed method names
The method names beginPublication(), endPublication() and
doPublication() have been lowercased.
Migrating to version 2.2
Attribute methods
The Element methods for accessing attributes have been deprecated. So
instead of node.hasattr("attr"), you should use:
"attr" in node.attrs
The same holds for checking whether an attribute is allowed. You can use the following code:
"attr" in node.Attrs
or:
"attr" in NodeClass.Attrs
or:
NodeClass.isallowed("attr")
Many Attrs methods have gained an additional parameter xml,
which specifies whether an attribute name should be treated as the XML or the
Python name of the attribute. Make sure that you’re not mixing up your arguments
in the function call. The safest method for this is using keyword arguments,
e.g.:
node.attr.get("attr", default=42)
JSP directive page element
A contentType attribute is no longer generated for the
ll.xist.ns.jsp.directive_page. You have to explicitly use an attribute
contentType="text/html" to get a contentType attribute in the resulting
JSP. The charset option is generated automatically from the encoding
specified in the publisher.
autoimg changes
ll.xist.htmlspecials.autoimg will no longer touch existing width or
height` attributes, so e.g. setting the width to twice the image size via
width="2*%(width)s" no longer works. You have to implement your own version
of autoimg if you need this.
find() changes
find() has been completely rewritten to use the new tree traversal
filters. For backwards compatibility a filter functor
ll.xist.xsc.FindOld exists that takes the same arguments as the old
find() method. I.e. you can replace:
node.find(
type=html.a,
attr={"href": None},
searchchildren=True
)
with:
node.find(
xsc.FindOld(
type=html.a,
attr={"href": None},
searchchildren=True
),
skiproot=True
)
But one minor difference remains: when skiproot is set to true in the new
find() method, the attributes of the root element will not be traversed.
With the old method they would be traversed.
doc changes
programlisting has been renamed to prog.
Namespace changes
Namespaces can no longer be instantiated. Instead you have to derive a class
from Namespace. The xmlprefix argument from the constructor
becomes a class attribute xmlname and the argument xmlname
becomes xmlurl.
Adding element classes to the namespace is now done with the Namespace
classmethod update(). If you want the turn a namespace into a module, you
can use the classmethod makemod() instead of update(), i.e. replace:
xmlns = xsc.Namespace("foo", "http://www.foo.com/", vars())
with:
class xmlns(xsc.Namespace):
xmlname = "foo"
xmlurl = "http://www.foo.com/"
xmlns.makemod(vars())
Migrating to version 2.1
The method withSep() has been renamed to withsep().
The argument defaultEncoding for the various parsing functions has been
renamed to encoding.
Migrating to version 2.0
Attribute handling
The biggest change is in the way attributes are defined. In older versions you
had to define a class attribute attrHandlers that mapped attribute names
to attribute classes. This created problems with “illegal” attribute names (e.g.
class and http-equiv in HTML), so for them an ugly workaround was
implemented. With 2.0 this is no longer neccessary. Defining attributes is done
via a class Attrs nested inside the element class like this:
class foo(xsc.Element):
class Attrs(xsc.Element.Attrs):
class bar(xsc.TextAttr)
"The bar attribute"
default = "spam"
values = ("spam", "eggs")
required = True
class baz(xsc.URLAttr):
"The baz attribute"
Default values, set of allowed attributes values and whether the attribute is
required can be defined via class attributes as shown above. You should
(directly or indirecty) inherit from xsc.Element.Attrs, because this
class implements handling of global attributes. If you want to inherit some
attributes (e.g. from your base class), you can derive from the appropriate
Attrs class. Removing an attribute you inherited can be done like
this:
class bar(foo):
class Attrs(foo.Attrs):
baz = None
This removes the attribute baz inherited from foo.
For attribute names that are no legal Python identifiers, the same method can be
used as for element classes: Define the real XML name via a class attribute.
This class attribute has been renamed from name to xmlname.
This also means that you always have to use the Python name when using attributes now. The XML name will only be used for parsing and publishing.
XIST 2.0 tries to be as backwards compatible as possible: An existing
attrHandlers attribute will be converted to an Attrs class on
the fly (and will generate a DeprecationWarning when the class is
created). An Attrs class will automatically generate an
attrHandlers attribute, so it’s possible to derive from new element
classes in the old way. The only situation where this won’t work, is with
attributes where the Python and XML name differ, you have to use “new style”
attributes there.
Namespace support
XIST supports XML namespaces now and for parsing it’s possible to configure
which namespaces should be available for instantiating classes from. For more
info about this refer to the documentation for the class Prefixes.
Before 2.0 the XML name for a namespace object was pretty useless, now it can be
used as the namespace name in xmlns attributes and it will be used for that
when publishing and specifying an elementmode of 2 in the call to the
publishing method or the constructor of the publisher.
Namespace objects should now be named xmlns instead of namespace as
before.
Global attributes
Global attributes are supported now, e.g. the attributes xml:lang and
xml:space can be specified in an element constructor like this:
from ll.xist import xsc
from ll.xist.ns import html, xml
node = html.html(
content,
{(xml, "lang"): "en", (xml, "space"): "preserve"},
lang="en"
)
Instead of the module object (which must contain a namespace object named
xmlns), you can also pass the namespace object itself (i.e. xml.xmlns)
or the namespace name (i.e. "http://www.w3.org/XML/1998/namespace").
Namespace changes
The classes XML and XML10 have been moved from
ll.xist.xsc to ll.xist.ns.xml.
All the classes in ll.xist.ns.specials that are specific to HTML
generation have been moved to the new module ll.xist.ns.htmlspecials.
The module ll.xist.ns.html has been updated to the XHTML specification,
so there might be some changes. The new feature for specifying attribute
restrictions has been used, so e.g. you’ll get warnings for missing alt
attributes in img elements. These warnings are issued via the warning
framework. Refer to the documentation for the warnings module to find out
how to configure the handling of these warnings.
Miscellaneous
XIST now requires at least Python 2.2.1 because the integer constants
True and False are used throughout the code wherever
appropriate. These constants will become instances of the new class
bool in Python 2.3. You might want to change your code too, to use
these new constant (e.g. when setting the element class attribute
empty).
Using mixed case method names was a bad idea, because this conflicts with
Python’s convention of using all lowercase names (without underscores). These
method names will be fixed in the next few XIST versions. The first names that
where changed were the element methods getAttr() and hasAttr(),
which have been renamed to getattr() and hasattr() respectively.
getAttr() and hasAttr() are still there and can be called without
generating deprecation warnings, but they will start to generate warnings in the
upcoming versions.