Changeset 1881:7ff025dbc5a3 in livinglogic.python.xist

Show
Ignore:
Timestamp:
07/04/03 12:30:03 (17 years ago)
Author:
Walter Doerwald <walter@…>
Branch:
default
Message:

Update requirements in INSTALL.xml.

Use the _makestring() method in more spots in the parser, this might
allow us to use XMLUnicodeParser someday in the future.

Now that Python 2.3 is required use the warnings module directly.

Rewrote handling of entity and character references. Now both
SGMLOPParser and BadEntityParser? should work correctly. Added tests
to verify that.

Files:
5 modified

Legend:

Unmodified
Added
Removed
  • INSTALL.xml

    r1858 r1881  
    33<par>To use &xist; you need the following software packages:</par> 
    44<olist> 
    5 <item>Python 2.2.1 (available from <link href="http://www.python.org/">http://www.python.org/</link>),</item> 
     5<item>Python 2.3 (available from <link href="http://www.python.org/">http://www.python.org/</link>),</item> 
    66<item>The Python &xml; package (available from <link href="http://pyxml.sf.net/">http://pyxml.sf.net/</link>) 
    7 (a version that includes <app>sgmlop</app> and <app>expat</app>),</item> 
     7(at least version 0.8.2),</item> 
    88<item>the Python Imaging Library (available from 
    99<link href="http://www.pythonware.com/products/pil/">http://www.pythonware.com/products/pil/</link>)</item> 
     
    1212<item>URL (available from <link href="root:url/index.html">http://www.livinglogic.de/Python/url/</link>),</item> 
    1313<item>ANSIStyle (available from <link href="root:ansistyle/index.html">http://www.livinglogic.de/Python/ansistyle/</link>),</item> 
    14 <item>and a C++ compiler supported by <app>distutils</app>, if you want 
     14<item>and a C compiler supported by <app>distutils</app>, if you want 
    1515to install the source distribution.</item> 
    1616</olist> 
  • _xist/errors.py

    r1827 r1881  
    2323 
    2424import xsc, presenters 
    25  
    26 def warn(warning, level=3): # stacklevel==3, i.e. report the caller of our caller 
    27     warnings.warn(warning, None, level) 
    2825 
    2926class Error(Exception): 
     
    253250        return s 
    254251 
    255 class MalformedCharRefError(Error): 
     252class MalformedCharRefWarning(Warning): 
    256253    """ 
    257254    exception that is raised when a character reference is malformed (e.g. <lit>&amp;#foo;</lit>) 
     
    262259 
    263260    def __str__(self): 
    264         return "malformed character reference: &#%s;" % self.name 
     261        return "malformed character reference: &%s;" % self.name 
    265262 
    266263class IllegalCommentContentError(Error): 
  • _xist/parsers.py

    r1875 r1881  
    1818""" 
    1919 
    20 import sys, os, os.path, types, urllib 
     20import sys, os, os.path, types, urllib, warnings 
    2121 
    2222from xml import sax 
     
    153153    def handle_charref(self, data): 
    154154        data = self._makestring(data) 
    155         if data[:1] == "x": 
     155        if data.startswith(u"x"): 
    156156            data = unichr(int(data[1:], 16)) 
    157157        else: 
     
    180180 
    181181    def handle_entityref(self, name): 
    182         if name=="lt": 
    183             self._cont_handler.characters(u"<") 
    184         elif name=="gt": 
    185             self._cont_handler.characters(u">") 
    186         elif name=="amp": 
    187             self._cont_handler.characters(u"&") 
    188         elif name=="quot": 
    189             self._cont_handler.characters(u'"') 
    190         elif name=="apos": 
    191             self._cont_handler.characters(u"'") 
    192         else: 
    193             self._cont_handler.skippedEntity(unicode(name, self.encoding)) 
     182        try: 
     183            c = {"lt": u"<", "gt": u">", "amp": u"&", "quot": u'"', "apos": u"'"}[name] 
     184        except KeyError: 
     185            self._cont_handler.skippedEntity(self._makestring(name)) 
     186        else: 
     187            self._cont_handler.characters(c) 
    194188        self.headerJustRead = False 
    195189 
     
    200194                attrvalue = attrname 
    201195            else: 
    202                 attrvalue = self._string2Fragment(unicode(attrvalue, self.encoding)) 
    203             newattrs._attrs[unicode(attrname, self.encoding)] = attrvalue 
    204         self._cont_handler.startElement(unicode(name, self.encoding), newattrs) 
     196                attrvalue = self._string2Fragment(self._makestring(attrvalue)) 
     197            newattrs._attrs[self._makestring(attrname)] = attrvalue 
     198        self._cont_handler.startElement(self._makestring(name), newattrs) 
    205199        self.headerJustRead = False 
    206200 
    207201    def finish_endtag(self, name): 
    208         self._cont_handler.endElement(unicode(name, self.encoding)) 
     202        self._cont_handler.endElement(self._makestring(name)) 
    209203        self.headerJustRead = False 
    210204 
     
    218212        ct = self._cont_handler.createText 
    219213        node = xsc.Frag() 
    220         while 1: 
    221             try: 
    222                 i = text.index("&") 
    223                 if i != 0: 
    224                     node.append(ct(text[:i])) 
    225                     text = text[i:] 
     214        while True: 
     215            texts = text.split(u"&", 1) 
     216            text = texts[0] 
     217            if text: 
     218                node.append(ct(text)) 
     219            if len(texts)==1: 
     220                break 
     221            texts = texts[1].split(u";", 1) 
     222            name = texts[0] 
     223            if len(texts)==1: 
     224                raise errors.MalformedCharRefWarning(name) 
     225            if name.startswith(u"#"): 
    226226                try: 
    227                     i = text.index(";") 
    228                     if text[1] == "#": 
    229                         if text[2] == "x": 
    230                             node.append(ct(unichr(int(text[3:i], 16)))) 
    231                         else: 
    232                             node.append(ct(unichr(int(text[2:i])))) 
     227                    if name.startswith(u"#x"): 
     228                        node.append(ct(unichr(int(name[2:], 16)))) 
    233229                    else: 
    234                         node.append(self._cont_handler.createEntity(text[1:i])) 
    235                     text = text[i+1:] 
     230                        node.append(ct(unichr(int(name[1:])))) 
    236231                except ValueError: 
    237                     raise errors.MalformedCharRefError(text) 
    238             except ValueError: 
    239                 if len(text): 
    240                     node.append(ct(text)) 
    241                 break 
    242         if not len(node): 
    243             node.append(ct("")) 
     232                    raise errors.MalformedCharRefWarning(name) 
     233            else: 
     234                try: 
     235                    c = {"lt": u"<", "gt": u">", "amp": u"&", "quot": u'"', "apos": u"'"}[name] 
     236                except KeyError: 
     237                    node.append(self._cont_handler.createEntity(name)) 
     238                else: 
     239                    node.append(ct(c)) 
     240            text = texts[1] 
     241        if not node: 
     242            node.append(ct(u"")) 
    244243        return node 
    245244 
     
    250249    entities to the handler literally.</par> 
    251250    """ 
     251 
     252    def handle_entityref(self, name): 
     253        try: 
     254            c = {"lt": u"<", "gt": u">", "amp": u"&", "quot": u'"', "apos": u"'"}[name] 
     255        except KeyError: 
     256            name = self._makestring(name) 
     257            try: 
     258                self._cont_handler.skippedEntity(name) 
     259            except errors.IllegalEntityError: 
     260                try: 
     261                    entity = html.entity(name, xml=True) 
     262                except errors.IllegalEntityError: 
     263                    self._cont_handler.characters(u"&%s;" % name) 
     264                else: 
     265                    if issubclass(entity, xsc.CharRef): 
     266                        self._cont_handler.characters(unichr(entity.codepoint)) 
     267                    else: 
     268                        self._cont_handler.characters(u"&%s;" % name) 
     269        else: 
     270            self._cont_handler.characters(c) 
     271        self.headerJustRead = False 
    252272 
    253273    def _string2Fragment(self, text): 
     
    259279        node = xsc.Frag() 
    260280        ct = self._cont_handler.createText 
    261         parts = text.split(u"&") 
    262         node.append(ct(parts[0])) 
    263         del parts[0] 
    264         for part in parts: 
    265             pos = part.find(u";") 
    266             if pos == -1: # no ; found, so it's no entity => append it literally 
    267                 node.append(ct(u"&"+part)) 
    268             else: # ; found 
    269                 if part[0] != "#": # named entity 
    270                     name = part[:pos] 
     281        while True: 
     282            texts = text.split(u"&", 1) 
     283            text = texts[0] 
     284            if text: 
     285                node.append(ct(text)) 
     286            if len(texts)==1: 
     287                break 
     288            texts = texts[1].split(u";", 1) 
     289            name = texts[0] 
     290            if len(texts)==1: # no ; found, so it's no entity => append it literally 
     291                name = u"&" + name 
     292                warnings.warn(errors.MalformedCharRefWarning(name)) 
     293                node.append(ct(name)) 
     294                break 
     295            else: 
     296                if name.startswith(u"#"): # character reference 
    271297                    try: 
    272                         entity = self._cont_handler.createEntity(name) 
    273                     except errors.IllegalEntityError: 
     298                        if name.startswith(u"#x"): # hexadecimal character reference 
     299                            node.append(ct(unichr(int(name[2:], 16)))) 
     300                        else: # decimal character reference 
     301                            node.append(ct(unichr(int(name[1:])))) 
     302                    except (ValueError, OverflowError): # illegal format => append it literally 
     303                        name = u"&%s;" % name 
     304                        warnings.warn(errors.MalformedCharRefWarning(name)) 
     305                        node.append(ct(name)) 
     306                else: # entity reference 
     307                    try: 
     308                        entity = {"lt": u"<", "gt": u">", "amp": u"&", "quot": u'"', "apos": u"'"}[name] 
     309                    except KeyError: 
    274310                        try: 
    275                             entity = html.entity(name, xml=True)() 
     311                            entity = self._cont_handler.createEntity(name) 
    276312                        except errors.IllegalEntityError: 
    277313                            try: 
    278                                 entity = xsc.xmlns.entity(name, xml=True)() 
     314                                entity = html.entity(name, xml=True) 
     315                                if issubclass(entity, xsc.CharRef): 
     316                                    entity = ct(unichr(entity.codepoint)) 
     317                                else: 
     318                                    entity = entity() 
    279319                            except errors.IllegalEntityError: 
    280                                 entity = xsc.Frag(ct(u"&"+part)) 
    281                     node.append(entity, ct(part[pos+1:])) 
    282                 else: # numeric entity 
    283                     try: 
    284                         if part[1] == "x": # hex entity 
    285                             node.append(ct(unichr(int(part[2:pos], 16)) + part[pos+1:])) 
    286                         else: # decimal entity 
    287                             node.append(ct(unichr(int(part[1:pos])) + part[pos+1:])) 
    288                     except ValueError: # illegal format => append it literally 
    289                         node.append(ct(u"&"+part)) 
     320                                name = u"&%s;" % name 
     321                                warnings.warn(errors.MalformedCharRefWarning(name)) 
     322                                entity = ct(name) 
     323                    else: 
     324                        entity = ct(entity) 
     325                    node.append(entity) 
     326            text = texts[1] 
    290327        return node 
     328 
     329    def handle_charref(self, data): 
     330        data = self._makestring(data) 
     331        try: 
     332            if data.startswith("x"): 
     333                data = unichr(int(data[1:], 16)) 
     334            else: 
     335                data = unichr(int(data)) 
     336        except (ValueError, OverflowError): 
     337            data = u"&#%s;" % data 
     338        if not self.headerJustRead or not data.isspace(): 
     339            self._cont_handler.characters(data) 
     340            self.headerJustRead = False 
    291341 
    292342class HTMLParser(BadEntityParser): 
     
    321371        # Check whether this element is allowed in the current context 
    322372        if self._stack and name not in htmldtd.HTML_DTD.get(self._stack[-1], []): 
    323             errors.warn(errors.IllegalDTDChildWarning(name, self._stack[-1])) 
     373            warnings.warn(errors.IllegalDTDChildWarning(name, self._stack[-1])) 
    324374 
    325375        # Skip unknown attributes (but warn about them) 
     
    331381                newattrs[attrname] = attrvalue 
    332382            else: 
    333                 errors.warn(errors.IllegalAttrError(element.Attrs, attrname)) 
     383                warnings.warn(errors.IllegalAttrError(element.Attrs, attrname)) 
    334384        BadEntityParser.finish_starttag(self, name, newattrs) 
    335385 
     
    355405            del self._stack[-1] 
    356406        else: 
    357             errors.warn(errors.IllegalCloseTagWarning(name)) 
     407            warnings.warn(errors.IllegalCloseTagWarning(name)) 
    358408 
    359409class ExpatParser(expatreader.ExpatParser): 
     
    509559    def skippedEntity(self, name): 
    510560        node = self.createEntity(name) 
    511         node.parsed(self) 
    512561        if isinstance(node, xsc.CharRef): 
    513562            self.characters(unichr(node.codepoint)) 
    514563        else: 
     564            node.parsed(self) 
    515565            self.__appendNode(node) 
    516566        self.skippingWhitespace = False 
     
    527577    def error(self, exception): 
    528578        "Handle a recoverable error." 
     579        # This doesn't work properly with expat, as expat fiddles with the traceback 
    529580        raise self.__decorateException(exception) 
    530581 
    531582    def fatalError(self, exception): 
    532583        "Handle a non-recoverable error." 
     584        # This doesn't work properly with expat, as expat fiddles with the traceback 
    533585        raise self.__decorateException(exception) 
    534586 
  • _xist/xsc.py

    r1877 r1881  
    1717# $Source$ 
    1818 
    19 import os, sys, random, copy 
     19import os, sys, random, copy, warnings 
    2020 
    2121from ll import url, ansistyle 
     
    5050    elif isinstance(value, url.URL): 
    5151        return Text(value) 
    52     errors.warn(errors.IllegalObjectWarning(value)) # none of the above, so we report it and maybe throw an exception 
     52    warnings.warn(errors.IllegalObjectWarning(value)) # none of the above, so we report it and maybe throw an exception 
    5353    return Null 
    5454 
     
    817817 
    818818    def withSep(self, separator, clone=False): 
    819         errors.warn(DeprecationWarning("withSep() is deprecated, use withsep() instead")) 
     819        warnings.warn(DeprecationWarning("withSep() is deprecated, use withsep() instead")) 
    820820        return self.withsep(separator, clone) 
    821821 
     
    15231523            value = unicode(self) 
    15241524            if value not in values: 
    1525                 errors.warn(errors.IllegalAttrValueWarning(self)) 
     1525                warnings.warn(errors.IllegalAttrValueWarning(self)) 
    15261526 
    15271527    def _walk(self, filter, path, filterpath, walkpath, skiproot): 
     
    18911891        # are there any required attributes remaining that haven't been specified? => warn about it 
    18921892        if attrs: 
    1893             errors.warn(errors.RequiredAttrMissingWarning(self, attrs.keys())) 
     1893            warnings.warn(errors.RequiredAttrMissingWarning(self, attrs.keys())) 
    18941894 
    18951895    def publish(self, publisher): 
     
    19091909        # are there any required attributes remaining that haven't been specified? => warn about it 
    19101910        if attrs: 
    1911             errors.warn(errors.RequiredAttrMissingWarning(self, attrs.keys())) 
     1911            warnings.warn(errors.RequiredAttrMissingWarning(self, attrs.keys())) 
    19121912 
    19131913    def __unicode__(self): 
     
    20232023 
    20242024    def copydefaults(self, fromMapping): 
    2025         errors.warn(DeprecationWarning("Attrs.copydefaults() is deprecated, use Attrs.updateexisting() instead")) 
     2025        warnings.warn(DeprecationWarning("Attrs.copydefaults() is deprecated, use Attrs.updateexisting() instead")) 
    20262026        return self.updateexisting(fromMapping) 
    20272027 
     
    21882188        def __new__(cls, name, bases, dict): 
    21892189            if "name" in dict and isinstance(dict["name"], basestring): 
    2190                 errors.warn(DeprecationWarning("name is deprecated, use xmlname instead")) 
     2190                warnings.warn(DeprecationWarning("name is deprecated, use xmlname instead")) 
    21912191                dict["xmlname"] = dict["name"] 
    21922192                del dict["name"] 
    21932193            if "attrHandlers" in dict: 
    2194                 errors.warn(DeprecationWarning("attrHandlers is deprecated, use a nested Attrs class instead")) 
     2194                warnings.warn(DeprecationWarning("attrHandlers is deprecated, use a nested Attrs class instead")) 
    21952195            return Node.__metaclass__.__new__(cls, name, bases, dict) 
    21962196        def __repr__(self): 
     
    23892389            size = url.openread().imagesize 
    23902390        except IOError, exc: 
    2391             errors.warn(errors.FileNotFoundWarning("can't read image", url, exc)) 
     2391            warnings.warn(errors.FileNotFoundWarning("can't read image", url, exc)) 
    23922392        else: 
    23932393            for attr in (heightattr, widthattr): 
     
    25412541 
    25422542    def hasAttr(self, attrname, xml=False): 
    2543         errors.warn(DeprecationWarning("foo.hasAttr() is deprecated, use foo.attrs.has() instead")) 
     2543        warnings.warn(DeprecationWarning("foo.hasAttr() is deprecated, use foo.attrs.has() instead")) 
    25442544        return self.attrs.has(attrname, xml=xml) 
    25452545 
    25462546    def hasattr(self, attrname, xml=False): 
    2547         errors.warn(DeprecationWarning("foo.hasattr() is deprecated, use foo.attrs.has() instead")) 
     2547        warnings.warn(DeprecationWarning("foo.hasattr() is deprecated, use foo.attrs.has() instead")) 
    25482548        return self.attrs.has(attrname, xml=xml) 
    25492549 
     
    25522552        <par>return whether the attribute named <arg>attrname</arg> is allowed for <self/>.</par> 
    25532553        """ 
    2554         errors.warn(DeprecationWarning("foo.isallowedattr() is deprecated, use foo.Attrs.isallowed() instead")) 
     2554        warnings.warn(DeprecationWarning("foo.isallowedattr() is deprecated, use foo.Attrs.isallowed() instead")) 
    25552555        return cls.Attrs.isallowed(attrname) 
    25562556    isallowedattr = classmethod(isallowedattr) 
    25572557 
    25582558    def getAttr(self, attrname, default=None): 
    2559         errors.warn(DeprecationWarning("foo.getAttr() is deprecated, use foo.attrs.get() instead")) 
     2559        warnings.warn(DeprecationWarning("foo.getAttr() is deprecated, use foo.attrs.get() instead")) 
    25602560        return self.getattr(attrname, default) 
    25612561 
    25622562    def getattr(self, attrname, default=None): 
    2563         errors.warn(DeprecationWarning("foo.getattr() is deprecated, use foo.attrs.get() instead")) 
     2563        warnings.warn(DeprecationWarning("foo.getattr() is deprecated, use foo.attrs.get() instead")) 
    25642564        return self.attrs.get(attrname, default) 
    25652565 
    25662566    def setDefaultAttr(self, attrname, default=None): 
    2567         errors.warn(DeprecationWarning("foo.setDefaultAttr() is deprecated, use foo.attrs.setdefault() instead")) 
     2567        warnings.warn(DeprecationWarning("foo.setDefaultAttr() is deprecated, use foo.attrs.setdefault() instead")) 
    25682568        return self.setdefault(attrname, default=default) 
    25692569 
    25702570    def setdefaultattr(self, attrname, default=None): 
    2571         errors.warn(DeprecationWarning("foo.setDefaultAttr() is deprecated, use foo.attrs.setdefault() instead")) 
     2571        warnings.warn(DeprecationWarning("foo.setDefaultAttr() is deprecated, use foo.attrs.setdefault() instead")) 
    25722572        return self.attrs.setdefault(attrname, default) 
    25732573 
    25742574    def attrkeys(self, xml=False): 
    2575         errors.warn(DeprecationWarning("foo.attrkeys() is deprecated, use foo.attrs.keys() instead")) 
     2575        warnings.warn(DeprecationWarning("foo.attrkeys() is deprecated, use foo.attrs.keys() instead")) 
    25762576        return self.attrs.keys(xml=xml) 
    25772577 
    25782578    def attrvalues(self): 
    2579         errors.warn(DeprecationWarning("foo.attrvalues() is deprecated, use foo.attrs.values() instead")) 
     2579        warnings.warn(DeprecationWarning("foo.attrvalues() is deprecated, use foo.attrs.values() instead")) 
    25802580        return self.attrs.values() 
    25812581 
    25822582    def attritems(self, xml=False): 
    2583         errors.warn(DeprecationWarning("foo.attritems() is deprecated, use foo.attrs.items() instead")) 
     2583        warnings.warn(DeprecationWarning("foo.attritems() is deprecated, use foo.attrs.items() instead")) 
    25842584        return self.attrs.items(xml=xml) 
    25852585 
    25862586    def iterattrkeys(self, xml=False): 
    2587         errors.warn(DeprecationWarning("foo.iterattrkeys() is deprecated, use foo.attrs.iterkeys() instead")) 
     2587        warnings.warn(DeprecationWarning("foo.iterattrkeys() is deprecated, use foo.attrs.iterkeys() instead")) 
    25882588        return self.attrs.iterkeys(xml=xml) 
    25892589 
    25902590    def iterattrvalues(self): 
    2591         errors.warn(DeprecationWarning("foo.iterattrvalues() is deprecated, use foo.attrs.itervalues() instead")) 
     2591        warnings.warn(DeprecationWarning("foo.iterattrvalues() is deprecated, use foo.attrs.itervalues() instead")) 
    25922592        return self.attrs.itervalues() 
    25932593 
    25942594    def iterattritems(self, xml=False): 
    2595         errors.warn(DeprecationWarning("foo.iterattritems() is deprecated, use foo.attrs.iteritems() instead")) 
     2595        warnings.warn(DeprecationWarning("foo.iterattritems() is deprecated, use foo.attrs.iteritems() instead")) 
    25962596        return self.attrs.iteritems(xml=xml) 
    25972597 
    25982598    def allowedattrkeys(cls, xml=False): 
    2599         errors.warn(DeprecationWarning("foo.allowedattrkeys() is deprecated, use foo.attrs.allowedkeys() instead")) 
     2599        warnings.warn(DeprecationWarning("foo.allowedattrkeys() is deprecated, use foo.attrs.allowedkeys() instead")) 
    26002600        return cls.Attrs.allowedkeys(xml=xml) 
    26012601    allowedattrkeys = classmethod(allowedattrkeys) 
    26022602 
    26032603    def allowedattrvalues(cls): 
    2604         errors.warn(DeprecationWarning("foo.allowedattrvalues() is deprecated, use foo.attrs.allowedvalues() instead")) 
     2604        warnings.warn(DeprecationWarning("foo.allowedattrvalues() is deprecated, use foo.attrs.allowedvalues() instead")) 
    26052605        return cls.Attrs.allowedvalues() 
    26062606    allowedattrvalues = classmethod(allowedattrvalues) 
    26072607 
    26082608    def allowedattritems(cls, xml=False): 
    2609         errors.warn(DeprecationWarning("foo.allowedattritems() is deprecated, use foo.attrs.alloweditems() instead")) 
     2609        warnings.warn(DeprecationWarning("foo.allowedattritems() is deprecated, use foo.attrs.alloweditems() instead")) 
    26102610        return cls.Attrs.alloweditems(xml=xml) 
    26112611    allowedattritems = classmethod(allowedattritems) 
    26122612 
    26132613    def iterallowedattrkeys(cls, xml=False): 
    2614         errors.warn(DeprecationWarning("foo.iterallowedattrkeys() is deprecated, use foo.attrs.iterattrkeys() instead")) 
     2614        warnings.warn(DeprecationWarning("foo.iterallowedattrkeys() is deprecated, use foo.attrs.iterattrkeys() instead")) 
    26152615        return cls.Attrs.iterallowedkeys(xml=xml) 
    26162616    iterallowedattrkeys = classmethod(iterallowedattrkeys) 
    26172617 
    26182618    def iterallowedattrvalues(cls): 
    2619         errors.warn(DeprecationWarning("foo.iterallowedattrvalues() is deprecated, use foo.attrs.iterattrvalues() instead")) 
     2619        warnings.warn(DeprecationWarning("foo.iterallowedattrvalues() is deprecated, use foo.attrs.iterattrvalues() instead")) 
    26202620        return cls.Attrs.iterallowedvalues() 
    26212621    iterallowedattrvalues = classmethod(iterallowedattrvalues) 
    26222622 
    26232623    def iterallowedattritems(cls, xml=False): 
    2624         errors.warn(DeprecationWarning("foo.iterallowedattritems() is deprecated, use foo.attrs.iterattritems() instead")) 
     2624        warnings.warn(DeprecationWarning("foo.iterallowedattritems() is deprecated, use foo.attrs.iterattritems() instead")) 
    26252625        return cls.Attrs.iteralloweditems(xml=xml) 
    26262626    iterallowedattritems = classmethod(iterallowedattritems) 
     
    27052705        """ 
    27062706 
    2707         errors.warn(DeprecationWarning("foo.copyDefaultAttrs() is deprecated, use foo.attrs.updateexisting() instead")) 
     2707        warnings.warn(DeprecationWarning("foo.copyDefaultAttrs() is deprecated, use foo.attrs.updateexisting() instead")) 
    27082708        self.attrs.updateexisting(fromMapping) 
    27092709 
  • test/test.py

    r1880 r1881  
    1212 
    1313from xml.sax import saxlib 
     14from xml.parsers import expat 
    1415 
    1516from ll import url 
     
    14651466 
    14661467class ParseTest(unittest.TestCase): 
     1468    def assertSAXRaises(self, exception, func, *args, **kwargs): 
     1469        # assert that func(*args, **kwargs) raises exception either directly or wrapped in a SAXParseException 
     1470        try: 
     1471            func(*args, **kwargs) 
     1472        except exception: 
     1473            pass 
     1474        except saxlib.SAXParseException, exc: 
     1475            realexc = exc.getException() 
     1476            self.assert_(isinstance(realexc, exception)) 
     1477        else: 
     1478            self.fail() 
     1479 
    14671480    def test_parselocationsgmlop(self): 
    14681481        node = parsers.parseString("<z>gurk&amp;hurz&#42;hinz&#x666;hunz</z>", parser=parsers.SGMLOPParser()) 
     
    15211534 
    15221535        warnings.filterwarnings("error", category=errors.RequiredAttrMissingWarning) 
    1523         try: 
    1524             node = parsers.parseString('<Test/>', prefixes=prefixes) 
    1525         except saxlib.SAXParseException, exc: 
    1526             self.assert_(isinstance(exc.getException(), errors.RequiredAttrMissingWarning)) 
    1527         else: 
    1528             self.fail() 
     1536        self.assertSAXRaises(errors.RequiredAttrMissingWarning, parsers.parseString, '<Test/>', prefixes=prefixes) 
    15291537 
    15301538    def test_parsevalueattrs(self): 
     
    15401548        node = parsers.parseString('<Test withvalues="bar"/>', prefixes=prefixes) 
    15411549        self.assertEqual(str(node[0]["withvalues"]), "bar") 
    1542         try: 
    1543             node = parsers.parseString('<Test withvalues="baz"/>', prefixes=prefixes) 
    1544         except saxlib.SAXParseException, exc: 
    1545             self.assert_(isinstance(exc.getException(), errors.IllegalAttrValueWarning)) 
    1546             pass 
    1547         else: 
    1548             self.fail() 
     1550        self.assertSAXRaises(errors.IllegalAttrValueWarning, parsers.parseString, '<Test withvalues="baz"/>', prefixes=prefixes) 
     1551 
     1552    class xmlns(xsc.Namespace): 
     1553        xmlname = "foo" 
     1554        xmlurl = "http://www.foo.com/foo" 
     1555        class a(xsc.Element): 
     1556            class Attrs(xsc.Element.Attrs): 
     1557                class title(xsc.TextAttr): pass 
     1558        class foo(xsc.Entity): 
     1559            def __unicode__(self): 
     1560                return u"FOO" 
     1561        class bar(xsc.CharRef): 
     1562            codepoint = 0x42 
     1563 
     1564    def check_parseentities(self, source, result, **parseargs): 
     1565        node = parsers.parseString("""<a title="%s">%s</a>""" % (source, source), **parseargs) 
     1566        node = node.findfirst(xsc.FindType(xsc.Element)) 
     1567        self.assertEqual(unicode(node), result) 
     1568        self.assertEqual(unicode(node["title"]), result) 
     1569 
     1570    def check_parsestrictentities(self, source, result, parserfactory): 
     1571        # in the strict parser the errors will always be raised, so ignore them to verify that 
     1572        warnings.filterwarnings("ignore", category=errors.MalformedCharRefWarning) 
     1573 
     1574        prefixes = xsc.Prefixes().addPrefixMapping(None, self.__class__.xmlns) 
     1575        self.check_parseentities(source, result, prefixes=prefixes, parser=parserfactory()) 
     1576        for bad in ("&", "&#x", "&&", "&#x;", "&#fg;", "&#999999999;", "&#;", "&#x;"): 
     1577            self.assertSAXRaises((errors.MalformedCharRefWarning, expat.ExpatError), self.check_parseentities, bad, u"", prefixes=prefixes, parser=parserfactory()) 
     1578        self.assertSAXRaises(errors.IllegalEntityError, self.check_parseentities, "&baz;", u"", prefixes=prefixes, parser=parserfactory()) 
     1579 
     1580    def test_parsestrictentities_sgmlop(self): 
     1581        self.check_parsestrictentities( 
     1582            "a&amp;b&foo;&bar;c&#32;d&#x20;&#30000;;&lt;&gt;&quot;&apos;", 
     1583            u"""a&bFOO\x42c d %c;<>"'""" % 30000, 
     1584            parsers.SGMLOPParser 
     1585        ) 
     1586 
     1587    def test_parsestrictentities_expat(self): 
     1588        self.check_parsestrictentities( 
     1589            "a&amp;bc&#32;d&#x20;&#30000;;&lt;&gt;&quot;&apos;", 
     1590            u"""a&bc d %c;<>"'""" % 30000, 
     1591            parsers.ExpatParser 
     1592        ) 
     1593 
     1594    def check_parsebadentities(self, parserfactory): 
     1595        warnings.filterwarnings("ignore", category=errors.MalformedCharRefWarning) 
     1596 
     1597        prefixes = xsc.Prefixes().addPrefixMapping(None, self.__class__.xmlns) 
     1598        tests = [ 
     1599            ("&amp;", u"&"), 
     1600            ("&amp;amp;", u"&amp;"), 
     1601            ("x&foo;&bar;y", u"xFOO\x42y"), 
     1602            ("x&foobar;y", u"x&foobar;y"), 
     1603            ("&uuml;", u"ü"), 
     1604            ("x&x", u"x&x"), 
     1605            ("x&x;", u"x&x;"), 
     1606            ("a&amp;b&lt;c&gt;d&quot;e&apos;f", u"a&b<c>d\"e'f"), 
     1607            ("x&#;y", u"x&#;y"), 
     1608            ("x&#32;y", u"x y"), 
     1609            ("x&#x20;y", u"x y"), 
     1610            ("x&#-32;y", u"x&#-32;y"), 
     1611            ("x&#999999999;y", "x&#999999999;y"), 
     1612            ("x&#xffffffff;y", "x&#xffffffff;y"), 
     1613            ("x&#xffffffff;y", "x&#xffffffff;y"), 
     1614            ("x&#xffffffff;y&#", "x&#xffffffff;y&#") 
     1615        ] 
     1616        for (source, result) in tests: 
     1617            self.check_parseentities(source, result, prefixes=prefixes, parser=parserfactory()) 
     1618 
     1619    def test_parsebadentities_badentity(self): 
     1620        self.check_parsebadentities(parsers.BadEntityParser) 
     1621 
     1622    def test_parsebadentities_html(self): 
     1623        self.check_parsebadentities(parsers.HTMLParser) 
    15491624 
    15501625class DTD2XSCTest(unittest.TestCase): 
    1551  
    15521626    def dtd2ns(self, s, xmlname, xmlurl=None, shareattrs=None): 
    15531627        from xml.parsers.xmlproc import dtdparser 
     
    17291803 
    17301804class TLD2XSCTest(unittest.TestCase): 
    1731  
    17321805    def tld2ns(self, s, xmlname, shareattrs=None): 
    17331806        node = parsers.parseString(s, prefixes=xsc.Prefixes().addElementPrefixMapping(None, tld)) 
     
    17951868 
    17961869class XNDLTest(unittest.TestCase): 
    1797  
    17981870    def xndl2ns(self, node): 
    17991871        data = node.asdata()