Changeset 3189:14819c3c96f8 in livinglogic.python.xist

Show
Ignore:
Timestamp:
01/28/08 17:28:47 (12 years ago)
Author:
Walter Doerwald <walter@…>
Branch:
default
Message:

Move ll-core and ll-toxic into ll-xist.

Files:
29 added
10 modified
1 copied
28 moved

Legend:

Unmodified
Added
Removed
  • INSTALL.rst

    r3182 r3189  
    66    1.  `Python 2.5`_; 
    77 
    8     3.  `Python Imaging Library`_; 
     8    2.  `Python Imaging Library`_; 
    99 
    10     4.  `libxml2`_ and its Python wrapper (if you want to parse "broken" HTML); 
     10    3.  `libxml2`_ and its Python wrapper (if you want to parse "broken" HTML); 
    1111 
    12     5.  `elinks`_ (if you want want to use the function 
     12    4.  `elinks`_ (if you want want to use the function 
    1313        :func:`ll.xist.ns.html.astext`); 
    1414 
    15     6.  `setuptools`_ (if you want to install this package as an egg); 
     15    5.  `setuptools`_ (if you want to install this package as an egg); 
    1616 
    17     7.  `py.test`_ (if you want to run the test suite) 
     17    6.  `py.test`_ (if you want to run the test suite) 
    1818 
    19     8.  and a C compiler supported by distutils, if you want to install the 
     19    7.  and a C compiler supported by distutils, if you want to install the 
    2020        source distribution. 
    2121 
  • MANIFEST.in

    r3124 r3189  
    22include NEWS.rst 
    33include NEWS.xml 
     4include OLDNEWS.rst 
     5include OLDNEWS.xml 
    46include INSTALL.rst 
    57include INSTALL.xml 
    68include MIGRATION.rst 
    79include MIGRATION.xml 
     10include OLDMIGRATION.rst 
     11include OLDMIGRATION.xml 
    812include CREDITS.rst 
    913recursive-include docs *.rst 
  • NEWS.rst

    r3171 r3189  
    22------------------------------------ 
    33 
    4 *   :class:`ll.xist.xsc.Pool` doesn't use a :class:`WeakValueDictionary` any 
    5     longer. This means it can now store *any* object. A method :meth:`clear` 
    6     has been added, which removes all registered objects. 
     4*   The core package has been moved into XIST, installing XIST now only requires 
     5    one package. 
     6 
     7*   :mod:`ll.toxic` has been moved into XIST and is now available as 
     8    :mod:`ll.xist.ns.toxic`. 
     9 
     10*   When a :class:`ll.make.XISTParseAction` object is executed the content of 
     11    the pool will now be extended by the content of the pool from the 
     12    :class:`XISTPoolAction` instead of being replaced. 
     13 
     14*   :class:`ll.make.Pool` and :class:`ll.xist.xsc.Pool` no longer use a 
     15    :class:`WeakValueDictionary`, but a simple :class:`dict`. This means they 
     16    can now store *any* object. A method :meth:`clear` has been added, which 
     17    removes all registered objects. 
    718 
    819 
     
    1526    will no longer transform the URL in any way. 
    1627 
    17 *   Fixed a parser bug, where attributes were dropped when the attribute value 
     28*   Fixed a parser bug where attributes were dropped when the attribute value 
    1829    was empty. 
    1930 
  • README.rst

    r3117 r3189  
    66Python class and these Python classes provide a conversion method to transform 
    77the XML tree (e.g. into HTML). XIST can be considered 'object oriented XSLT'. 
     8 
     9XIST also includes the following modules: 
     10 
     11*   ``astyle`` can be used for colored terminal output (via ANSI escape 
     12    sequences). 
     13 
     14*   ``color`` provides classes and functions for handling RGB color values. 
     15    This includes the ability to convert between different color models 
     16    (RGB, HSV, HLS) as well as to and from CSS format, and several functions 
     17    for modifying and mixing colors. 
     18 
     19*   ``make`` is an object oriented make replacement. Like make it allows you 
     20    to specify dependencies between files and actions to be executed 
     21    when files don't exist or are out of date with respect to one 
     22    of their sources. But unlike make you can do this in a object oriented 
     23    way and targets are not only limited to files, but you can implement 
     24    e.g. dependencies on database records. 
     25 
     26*   ``misc`` provides several small utility functions and classes. 
     27 
     28*   ``sisyphus`` provides classes for running Python scripts as cron jobs. 
     29 
     30*   ``daemon`` can be used on UNIX to fork a daemon process. 
     31 
     32*   ``url`` provides classes for parsing and constructing RFC 2396 
     33    compliant URLs. 
     34 
     35*   ``xpit`` is a module that makes it possible to embed Python expressions 
     36    in text (as XML style processing instructions). 
     37 
     38*   ``xml_codec`` contains a complete codec for encoding and decoding XML. 
    839 
    940 
     
    2556 
    2657__ http://www.livinglogic.de/Python/xist/History.html 
     58 
     59For a list of old features and bugfixes read ``OLDNEWS`` or the 
     60`old history web page`__. 
     61 
     62__ http://www.livinglogic.de/Python/xist/OldHistory.html 
    2763 
    2864For the license read ``__init__.py``. 
  • docs/XIST_Advanced.xml

    r3131 r3189  
    8686<mod>html2</mod>:</p> 
    8787 
    88 <example><h>Automatic pool chaining (<filename>html2.py</filename>)</h> 
     88<example><h>Automatic pool chaining (<file>html2.py</file>)</h> 
    8989<prog> 
    9090from ll.xist.ns import html 
  • setup.py

    r3150 r3189  
    1010    from distutils import core as tools 
    1111 
    12 import textwrap 
     12import textwrap, re 
    1313 
    1414 
     
    1818Python class and these Python classes provide a conversion method to transform 
    1919the XML tree (e.g. into HTML). XIST can be considered 'object oriented XSLT'. 
     20 
     21XIST also includes the following modules: 
     22 
     23*   :mod:`ll.astyle` can be used for colored terminal output (via ANSI escape 
     24    sequences). 
     25 
     26*   :mod:`color` provides classes and functions for handling RGB color values. 
     27    This includes the ability to convert between different color models 
     28    (RGB, HSV, HLS) as well as to and from CSS format, and several functions 
     29    for modifying and mixing colors. 
     30 
     31*   :mod:`ll.make` is an object oriented make replacement. Like make it allows 
     32    you to specify dependencies between files and actions to be executed 
     33    when files don't exist or are out of date with respect to one 
     34    of their sources. But unlike make you can do this in a object oriented 
     35    way and targets are not only limited to files, but you can implement 
     36    e.g. dependencies on database records. 
     37 
     38*   :mod:`ll.misc` provides several small utility functions and classes. 
     39 
     40*   :mod:`ll.sisyphus` provides classes for running Python scripts as cron jobs. 
     41 
     42*   :mod:`ll.daemon` can be used on UNIX to fork a daemon process. 
     43 
     44*   :mod:`ll.url` provides classes for parsing and constructing RFC 2396 
     45    compliant URLs. 
     46 
     47*   :mod:`ll.xpit` is a module that makes it possible to embed Python 
     48    expressions in text (as XML style processing instructions). 
     49 
     50*   :mod:`ll.xml_codec` contains a complete codec for encoding and decoding XML. 
    2051""" 
    2152 
    2253CLASSIFIERS=""" 
     54# Common 
    2355Development Status :: 5 - Production/Stable 
    24 Environment :: Web Environment 
    2556Intended Audience :: Developers 
    2657License :: OSI Approved :: MIT License 
    2758Operating System :: OS Independent 
    2859Programming Language :: Python 
     60Topic :: Software Development :: Libraries :: Python Modules 
     61 
     62# ansistyle 
     63Topic :: Terminals 
     64Topic :: Text Processing :: General 
     65 
     66# color 
     67Topic :: Multimedia :: Graphics 
     68 
     69# make 
     70Topic :: Software Development :: Build Tools 
     71 
     72# daemon 
     73Environment :: No Input/Output (Daemon) 
     74Operating System :: POSIX 
     75 
     76# url 
     77Topic :: Internet 
     78Topic :: Internet :: File Transfer Protocol (FTP) 
     79Topic :: Internet :: WWW/HTTP 
     80 
     81# xpit 
     82Topic :: Text Processing :: Filters 
     83 
     84# xml_codec 
     85Topic :: Text Processing :: Markup :: XML 
     86 
     87# XIST 
     88Environment :: Web Environment 
    2989Topic :: Internet :: WWW/HTTP :: Dynamic Content 
    3090Topic :: Internet :: WWW/HTTP :: Site Management 
    31 Topic :: Software Development :: Libraries :: Python Modules 
    3291Topic :: Text Processing :: Markup :: HTML 
    3392Topic :: Text Processing :: Markup :: XML 
     93 
     94# TOXIC 
     95Topic :: Database 
    3496""" 
    3597 
    3698KEYWORDS = """ 
     99# misc 
     100property 
     101decorator 
     102iterator 
     103 
     104# ansistyle 
     105ANSI 
     106escape sequence 
     107color 
     108terminal 
     109 
     110# color 
     111RGB 
     112HSV 
     113HSB 
     114HLS 
     115CSS 
     116red 
     117green 
     118blue 
     119hue 
     120saturation 
     121value 
     122brightness 
     123luminance 
     124 
     125# make 
     126make 
     127build 
     128 
     129# sisyphus 
     130cron 
     131job 
     132 
     133# daemon 
     134daemon 
     135UNIX 
     136fork 
     137 
     138# url 
     139URL 
     140RFC 2396 
     141HTTP 
     142FTP 
     143ssh 
     144py.execnet 
     145 
     146# xpit 
     147text 
     148template 
     149processing instruction 
     150 
     151# xml_codec 
     152XML 
     153codec 
     154decoding 
     155 
     156# XIST 
    37157XML 
    38158HTML 
     
    45165iHTML 
    46166Relax NG 
     167 
     168# TOXIC 
     169Oracle 
     170user defined function 
     171PL/SQL 
     172XML 
     173HTML 
     174processing instruction 
     175PI 
     176embed 
    47177""" 
    48178 
     
    52182    description = DESCRIPTION.strip() 
    53183else: 
     184    # Extract the first section (which are the changes for the current version) 
    54185    underlines = [i for (i, line) in enumerate(news) if line.startswith("---")] 
    55186    news = news[underlines[0]-1:underlines[1]-1] 
    56187    news = "".join(news) 
    57     description = "%s\n\n\n%s" % (DESCRIPTION.strip(), news) 
     188    descr = "%s\n\n\n%s" % (DESCRIPTION.strip(), news) 
     189 
     190    # Get rid of text roles PyPI doesn't know about 
     191    descr = re.subn(":[a-z]+:`([a-zA-Z0-9_.]+)`", "``\\1``", descr)[0] 
     192 
    58193 
    59194 
    60195args = dict( 
    61196    name="ll-xist", 
    62     version="3.1", 
     197    version="3.2", 
    63198    description="Extensible HTML/XML generator", 
    64     long_description=description, 
     199    long_description=descr, 
    65200    author="Walter Doerwald", 
    66201    author_email="walter@livinglogic.de", 
     
    68203    download_url="http://www.livinglogic.de/Python/xist/Download.html", 
    69204    license="MIT", 
    70     classifiers=CLASSIFIERS.strip().splitlines(), 
    71     keywords=",".join(KEYWORDS.strip().splitlines()), 
     205    classifiers=sorted(set(c for c in CLASSIFIERS.strip().splitlines() if c.strip() and not c.strip().startswith("#"))), 
     206    keywords=", ".join(sorted(set(k.strip() for k in KEYWORDS.strip().splitlines() if k.strip() and not k.strip().startswith("#")))), 
    72207    package_dir={"": "src"}, 
    73     packages=["ll", "ll.xist", "ll.xist.ns", "ll.xist.scripts"], 
     208    packages=["ll", "ll.scripts", "ll.xist", "ll.xist.ns", "ll.xist.scripts"], 
    74209    ext_modules=[ 
     210        tools.Extension("ll._url", ["src/ll/_url.c"]), 
     211        tools.Extension("ll._ansistyle", ["src/ll/_ansistyle.c"]), 
     212        tools.Extension("ll._misc", ["src/ll/_misc.c"]), 
     213        tools.Extension("ll._xml_codec", ["src/ll/_xml_codec.c", "src/ll/_xml_codec_include.c"]), 
    75214        tools.Extension("ll.xist.helpers", ["src/ll/xist/helpers.c", "src/ll/xist/helpers_include.c"]), 
    76215        tools.Extension("ll.xist.sgmlop", ["src/ll/xist/sgmlop.c"], define_macros=[("SGMLOP_UNICODE_SUPPORT", None)]), 
     
    78217    entry_points=dict( 
    79218        console_scripts=[ 
     219            "ucp = ll.scripts.ucp:main", 
    80220            "dtd2xsc = ll.xist.scripts.dtd2xsc:main", 
    81221            "tld2xsc = ll.xist.scripts.tld2xsc:main", 
     
    85225    ), 
    86226    scripts=[ 
     227        "scripts/ucp.py", 
    87228        "scripts/dtd2xsc.py", 
    88229        "scripts/tld2xsc.py", 
     
    91232    ], 
    92233    install_requires=[ 
    93         "ll-core >= 1.11", 
    94         "cssutils == 0.9.4b1", 
     234        "cssutils >= 0.9.4a1, <0.9.5", 
    95235    ], 
    96236    namespace_packages=["ll"], 
  • src/ll/__init__.py

    r3151 r3189  
    1 #! /usr/bin/env python 
    21# -*- coding: utf-8 -*- 
    32 
    43## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    54## Copyright 1999-2008 by Walter Dörwald 
     5## 
     6## All Rights Reserved 
    67## 
    78## Permission is hereby granted, free of charge, to any person obtaining a copy 
     
    2829except Exception: 
    2930    pass 
    30  
  • src/ll/xist/ns/doc.py

    r3184 r3189  
    5353    text = "\n".join(lines) 
    5454 
    55     if format.lower() == "plaintext": 
     55    if inspect.ismethod(thing): 
     56        base = "METHOD-DOCSTRING(%s.%s.%s)" % (_getmodulename(thing), thing.im_class.__name__, thing.__name__) 
     57    elif isinstance(thing, property): 
     58        base = "PROPERTY-DOCSTRING(%s.%s)" % (_getmodulename(thing), "unknown") 
     59    elif inspect.isfunction(thing): 
     60        base = "FUNCTION-DOCSTRING(%s.%s)" % (_getmodulename(thing), thing.__name__) 
     61    elif inspect.isclass(thing): 
     62        base = "CLASS-DOCSTRING(%s.%s)" % (_getmodulename(thing), thing.__name__) 
     63    elif inspect.ismodule(thing): 
     64        base = "MODULE-DOCSTRING(%s)" % _getmodulename(thing) 
     65    else: 
     66        base = "DOCSTRING" 
     67 
     68    lformat = format.lower() 
     69    if lformat == "plaintext": 
    5670        return xsc.Text(text) 
    57     elif format.lower() == "restructuredtext": 
     71    elif lformat == "restructuredtext": 
    5872        from ll.xist.ns import rest 
    59         return rest.fromstring(text).conv() 
    60     elif format.lower() == "xist": 
    61         if inspect.ismethod(thing): 
    62             base = "METHOD-DOCSTRING(%s.%s.%s)" % (_getmodulename(thing), thing.im_class.__name__, thing.__name__) 
    63         elif isinstance(thing, property): 
    64             base = "PROPERTY-DOCSTRING(%s.%s)" % (_getmodulename(thing), "unknown") 
    65         elif inspect.isfunction(thing): 
    66             base = "FUNCTION-DOCSTRING(%s.%s)" % (_getmodulename(thing), thing.__name__) 
    67         elif inspect.isclass(thing): 
    68             base = "CLASS-DOCSTRING(%s.%s)" % (_getmodulename(thing), thing.__name__) 
    69         elif inspect.ismodule(thing): 
    70             base = "MODULE-DOCSTRING(%s)" % _getmodulename(thing) 
    71         else: 
    72             base = "DOCSTRING" 
     73        return rest.fromstring(text, base=base) 
     74    elif lformat == "xist": 
    7375        node = parsers.parsestring(text, base=base, prefixes=xsc.docprefixes()) 
    7476        if not node[p]: # optimization: one paragraph docstrings don't need a <p> element. 
  • src/ll/xist/ns/ruby.py

    r3180 r3189  
    4242class rbc(xsc.Element): 
    4343    """ 
    44     The :class:`rbc` (<z>ruby base component</z>) element is the container for <pyref class="rb">:class:`rb`</pyref> elements. 
     44    The :class:`rbc` (ruby base component) element is the container for 
     45    :class:`rb` elements. 
    4546    """ 
    4647    xmlns = xmlns 
  • src/ll/xist/xsc.py

    r3187 r3189  
    734734    def clone(self): 
    735735        """ 
    736         return a clone of ``self``. Compared to :meth:`deepcopy` :meth:`clone` 
     736        return a clone of :var:`self`. Compared to :meth:`deepcopy` :meth:`clone` 
    737737        will create multiple instances of objects that can be found in the tree 
    738738        more than once. :meth:`clone` can't clone trees that contain cycles. 
     
    742742    def copy(self): 
    743743        """ 
    744         Return a shallow copy of ``self``. 
     744        Return a shallow copy of :var:`self`. 
    745745        """ 
    746746        return self.__copy__() 
     
    751751    def deepcopy(self): 
    752752        """ 
    753         Return a deep copy of ``self``. 
     753        Return a deep copy of :var:`self`. 
    754754        """ 
    755755        return self.__deepcopy__() 
     
    773773        Convenience method for calling :meth:`convert`. 
    774774 
    775         :meth:`conv` will automatically set ``:var:`converter`.node`` to ``self`` 
     775        :meth:`conv` will automatically set ``:var:`converter`.node`` to :var:`self` 
    776776        to remember the "document root node" for which :meth:`conv` has been 
    777777        called, this means that you should not call :meth:`conv` in any of the 
     
    796796 
    797797        This method must return an instance of :class:`Node`. It may *not* change 
    798         ``self``. 
     798        :var:`self`. 
    799799        """ 
    800800 
     
    802802    def __unicode__(self): 
    803803        """ 
    804         Return the character content of ``self`` as a unicode string. This means 
     804        Return the character content of :var:`self` as a unicode string. This means 
    805805        that comments and processing instructions will be filtered out. For 
    806806        elements you'll get the element content. 
     
    813813    def __str__(self): 
    814814        """ 
    815         Return the character content of ``self`` as a string (if possible, i.e. 
     815        Return the character content of :var:`self` as a string (if possible, i.e. 
    816816        there are no characters that are unencodable in the default encoding). 
    817817        """ 
     
    820820    def __int__(self): 
    821821        """ 
    822         Convert the character content of ``self`` to an :class:`int`. 
     822        Convert the character content of :var:`self` to an :class:`int`. 
    823823        """ 
    824824        return int(unicode(self)) 
     
    826826    def __long__(self): 
    827827        """ 
    828         Convert the character content of ``self`` to an :class:`long`. 
     828        Convert the character content of :var:`self` to an :class:`long`. 
    829829        """ 
    830830        return long(unicode(self)) 
     
    832832    def asFloat(self, decimal=".", ignore=""): 
    833833        """ 
    834         Convert the character content of ``self`` to an :class:`float`. 
     834        Convert the character content of :var:`self` to an :class:`float`. 
    835835        :var:`decimal` specifies which decimal separator is used in the value 
    836836        (e.g. ``"."`` (the default) or ``","``). :var:`ignore` specifies which 
    837         characters will be ignored.</p> 
     837        characters will be ignored. 
    838838        """ 
    839839        s = unicode(self) 
     
    846846    def __float__(self): 
    847847        """ 
    848         Convert the character content of ``self`` to an :class:`float`. 
     848        Convert the character content of :var:`self` to an :class:`float`. 
    849849        """ 
    850850        return self.asFloat() 
     
    852852    def __complex__(self): 
    853853        """ 
    854         Convert the character content of ``self`` to an :class:`complex`. 
     854        Convert the character content of :var:`self` to an :class:`complex`. 
    855855        """ 
    856856        return complex(unicode(self)) 
     
    859859        """ 
    860860        This method will be called by the parser :var:`parser` once after 
    861         ``self`` is created by the parser and must return the node that is to be 
    862         put into the tree (in most cases this is ``self``, it's used e.g. by 
    863         :class:`URLAttr` to incorporate the base URL into the attribute. 
     861        :var:`self` is created by the parser and must return the node that is to 
     862        be put into the tree (in most cases this is :var:`self`, it's used e.g. 
     863        by :class:`URLAttr` to incorporate the base URL into the attribute. 
    864864 
    865865        For elements :func:`parsed` will be called twice: Once at the beginning 
    866866        (i.e. before the content is parsed) with :var:`start` being :const:`True` 
    867867        and once at the end after parsing of the content is finished with 
    868         ``:var:`start` being :const:`False`. For the second call the return value 
     868        :var:`start` being :const:`False`. For the second call the return value 
    869869        will be ignored. 
    870870        """ 
     
    874874        """ 
    875875        This method will be called when parsing or publishing to check whether 
    876         ``self`` is valid. 
    877  
    878         If ``self`` is found to be invalid a warning should be issued through 
     876        :var`self` is valid. 
     877 
     878        If :var:`self` is found to be invalid a warning should be issued through 
    879879        the Python warning framework. 
    880880        """ 
     
    903903    def bytes(self, base=None, publisher=None, **publishargs): 
    904904        """ 
    905         Return ``self`` as a serialized byte string. 
     905        Return :var:`self` as a serialized byte string. 
    906906 
    907907        For the possible parameters see the :class:`ll.xist.publishers.Publisher` 
     
    912912    def iterstring(self, base=None, publisher=None, **publishargs): 
    913913        """ 
    914         A generator that will produce a serialized byte string of ``self``. 
     914        A generator that will produce a serialized byte string of :var:`self`. 
    915915 
    916916        For the possible parameters see the :class:`ll.xist.publishers.Publisher` 
     
    930930    def string(self, base=None, publisher=None, **publishargs): 
    931931        """ 
    932         Return a serialized unicode string for ``self``. 
     932        Return a serialized unicode string for :var:`self`. 
    933933 
    934934        For the possible parameters see the :class:`ll.xist.publishers.Publisher` 
     
    943943    def write(self, stream, *args, **publishargs): 
    944944        """ 
    945         Write ``self`` to the file-like object :var:`stream` (which must provide 
     945        Write :var:`self` to the file-like object :var:`stream` (which must provide 
    946946        a :meth:`write` method). 
    947947 
     
    962962    def walk(self, walkfilter=(True, entercontent)): 
    963963        """ 
    964         Return an iterator for traversing the tree rooted at ``self``. 
     964        Return an iterator for traversing the tree rooted at :var:`self`. 
    965965 
    966966        :var:`walkfilter` is used for specifying whether or not a node should be 
     
    10281028    def compact(self): 
    10291029        """ 
    1030         Return a version of ``self``, where textnodes or character references 
     1030        Return a version of :var:`self`, where textnodes or character references 
    10311031        that contain only linefeeds are removed, i.e. potentially needless 
    10321032        whitespace is removed. 
     
    10361036    def _decoratenode(self, node): 
    10371037        # Decorate the :class:`Node` :var:`node` with the same location 
    1038         # information as ``self``. 
     1038        # information as :var:`self`. 
    10391039 
    10401040        node.startloc = self.startloc 
     
    10471047        works recursively (for :class:`Frag` and :class:`Element`). 
    10481048 
    1049         When you want an unmodified node you simply can return ``self``. 
     1049        When you want an unmodified node you simply can return :var:`self`. 
    10501050        :meth:`mapped` will make a copy of it and fill the content recursively. 
    10511051        Note that element attributes will not be mapped. When you return a 
     
    10611061    def normalized(self): 
    10621062        """ 
    1063         Return a normalized version of ``self``, which means that consecutive 
     1063        Return a normalized version of :var:`self`, which means that consecutive 
    10641064        :class:`Text` nodes are merged. 
    10651065        """ 
     
    10821082    def pretty(self, level=0, indent="\t"): 
    10831083        """ 
    1084         Return a prettyfied version of ``self``, i.e. one with properly nested 
     1084        Return a prettyfied version of :var:`self`, i.e. one with properly nested 
    10851085        and indented tags (as far as possible). If an element has mixed content 
    10861086        (i.e. :class:`Text` and non-:class:`Text` nodes) the content will be 
     
    14131413    def _create(self): 
    14141414        """ 
    1415         internal helper that is used to create an empty clone of ``self``. 
     1415        internal helper that is used to create an empty clone of :var:`self`. 
    14161416        """ 
    14171417        # This is overwritten by :class:`Attr` to insure that attributes don't 
     
    14221422    def clear(self): 
    14231423        """ 
    1424         Make ``self`` empty. 
     1424        Make :var:`self` empty. 
    14251425        """ 
    14261426        del self[:] 
     
    14761476        Return the :var:`index`'th node for the content of the fragment. If 
    14771477        :var:`index` is a list :meth:`__getitem__` will work recursively. 
    1478         If :var:`index` is an empty list, ``self`` will be returned. 
     1478        If :var:`index` is an empty list, :var:`self` will be returned. 
    14791479        :meth:`__getitem__` also supports walk filters. 
    14801480        """ 
     
    15421542        exception will be raised. Anything except :class:`list`, :class:`int` and 
    15431543        :class:`slice` objects will be turned into a walk filter and any child 
    1544         node matching this filter will be deleted from ``self``. 
     1544        node matching this filter will be deleted from :var:`self`. 
    15451545        """ 
    15461546        if isinstance(index, list): 
     
    15751575    def __mul__(self, factor): 
    15761576        """ 
    1577         Return a :class:`Frag` with :var:`factor` times the content of ``self``. 
     1577        Return a :class:`Frag` with :var:`factor` times the content of :var:`self`. 
    15781578        Note that no copies of the content will be generated, so this is a 
    15791579        "shallow :meth:`__mul__`". 
     
    15931593    def append(self, *others): 
    15941594        """ 
    1595         Append every item in :var:`others` to ``self``. 
     1595        Append every item in :var:`others` to :var:`self`. 
    15961596        """ 
    15971597        for other in others: 
     
    16041604    def extend(self, items): 
    16051605        """ 
    1606         Append all items from the sequence :var:`items` to ``self``. 
     1606        Append all items from the sequence :var:`items` to :var:`self`. 
    16071607        """ 
    16081608        self.append(items) 
     
    16351635    def withsep(self, separator, clone=False): 
    16361636        """ 
    1637         Return a version of ``self`` with a separator node between the nodes of 
    1638         ``self``. 
     1637        Return a version of :var:`self` with a separator node between the nodes of 
     1638        :var:`self`. 
    16391639 
    16401640        if :var:`clone` is false one node will be inserted several times, if 
     
    16531653    def sorted(self, cmp=None, key=None, reverse=False): 
    16541654        """ 
    1655         Return a sorted version of the ``self``. :var:`cmp`, :var:`key` and 
     1655        Return a sorted version of the :var:`self`. :var:`cmp`, :var:`key` and 
    16561656        :var:`reverse` have to same meaning as for the builtin function 
    16571657        :func:`sorted`. 
     
    16611661    def reversed(self): 
    16621662        """ 
    1663         Return a reversed version of the ``self``. 
     1663        Return a reversed version of the :var:`self`. 
    16641664        """ 
    16651665        node = list(self) 
     
    16691669    def filtered(self, function): 
    16701670        """ 
    1671         Return a filtered version of the ``self``, i.e. a copy of ``self``, 
     1671        Return a filtered version of the :var:`self`, i.e. a copy of :var:`self`, 
    16721672        where only content nodes for which :func:`function` returns true will 
    16731673        be copied. 
     
    16791679    def shuffled(self): 
    16801680        """ 
    1681         Return a shuffled version of ``self``, i.e. a copy of ``self`` where the 
     1681        Return a shuffled version of :var:`self`, i.e. a copy of :var:`self` where the 
    16821682        content nodes are randomly reshuffled. 
    16831683        """ 
     
    18701870 
    18711871    def __repr__(self): 
    1872         return "<null>" 
     1872        return "ll.xist.xsc.Null" 
    18731873 
    18741874 
     
    19331933    def isfancy(self): 
    19341934        """ 
    1935         Return whether ``self`` contains nodes other than :class:`Text`. 
     1935        Return whether :var:`self` contains nodes other than :class:`Text`. 
    19361936        """ 
    19371937        for child in self: 
     
    19491949    def checkvalid(self): 
    19501950        """ 
    1951         Check whether ``self`` has an allowed value, i.e. one that is specified 
     1951        Check whether :var:`self` has an allowed value, i.e. one that is specified 
    19521952        in the class attribute ``values``. If the value is not allowed a warning 
    19531953        will be issued through the Python warning framework. 
    19541954 
    1955         If ``self`` is "fancy" (i.e. contains non-:class:`Text` nodes), no check 
     1955        If :var:`self` is "fancy" (i.e. contains non-:class:`Text` nodes), no check 
    19561956        will be done. 
    19571957        """ 
     
    21372137    def asURL(self): 
    21382138        """ 
    2139         Return ``self`` as a :class:`URL` object (note that non-:class:`Text` 
     2139        Return :var:`self` as a :class:`URL` object (note that non-:class:`Text` 
    21402140        content will be filtered out). 
    21412141        """ 
     
    21452145        """ 
    21462146        return a :class:`URL` pointing to the real location of the referenced 
    2147         resource. :var:`root` must be the root URL relative to which ``self`` 
     2147        resource. :var:`root` must be the root URL relative to which :var:`self` 
    21482148        will be interpreted and usually comes from the ``root`` attribute of the 
    21492149        :var:`converter` argument in :meth:`convert`. 
     
    24082408    def has(self, name): 
    24092409        """ 
    2410         Return whether ``self`` has an attribute with a Python name :var:`name`. 
     2410        Return whether :var:`self` has an attribute with a Python name :var:`name`. 
    24112411        :var:`name` may also be an attribute class (either from ``self.Attrs`` 
    24122412        or a global attribute). 
     
    24352435        """ 
    24362436        works like the dictionary method :meth:`get`, it returns the attribute 
    2437         with the Python name :var:`name`, or :var:`default` if ``self`` has no 
     2437        with the Python name :var:`name`, or :var:`default` if :var:`self` has no 
    24382438        such attribute. :var:`name` may also be an attribute class (either from 
    24392439        ``self.Attrs`` or a global attribute). 
     
    24782478        """ 
    24792479        Works like the dictionary method :meth:`setdefault`, it returns the 
    2480         attribute with the Python name :var:`name`. If ``self`` has no such 
     2480        attribute with the Python name :var:`name`. If :var:`self` has no such 
    24812481        attribute, it will be set to :var:`default` and :var:`default` will be 
    24822482        returned as the new attribute value. 
     
    26132613    def filtered(self, function): 
    26142614        """ 
    2615         Return a filtered version of the ``self``. 
     2615        Return a filtered version of the :var:`self`. 
    26162616        """ 
    26172617        node = self._create() 
     
    26452645    def withnames(self, *names): 
    26462646        """ 
    2647         Return a copy of ``self`` where only the attributes with Python names 
     2647        Return a copy of :var:`self` where only the attributes with Python names 
    26482648        in :var:`names` are kept, all others are removed. 
    26492649        """ 
     
    26562656    def withnames_xml(self, *names): 
    26572657        """ 
    2658         Return a copy of ``self`` where only the attributes with XML names 
     2658        Return a copy of :var:`self` where only the attributes with XML names 
    26592659        in :var:`names` are kept, all others are removed. 
    26602660        """ 
     
    26672667    def withoutnames(self, *names): 
    26682668        """ 
    2669         Return a copy of ``self`` where all the attributes with Python names 
     2669        Return a copy of :var:`self` where all the attributes with Python names 
    26702670        in :var:`names` are removed. 
    26712671        """ 
     
    26782678    def withoutnames_xml(self, *names): 
    26792679        """ 
    2680         Return a copy of ``self`` where all the attributes with XML names 
     2680        Return a copy of :var:`self` where all the attributes with XML names 
    26812681        in :var:`names` are removed. 
    26822682        """ 
     
    31093109    def withsep(self, separator, clone=False): 
    31103110        """ 
    3111         Return a version of ``self`` with a separator node between the child 
    3112         nodes of ``self``. For more info see :meth:`Frag.withsep`. 
     3111        Return a version of :var:`self` with a separator node between the child 
     3112        nodes of :var:`self`. For more info see :meth:`Frag.withsep`. 
    31133113        """ 
    31143114        node = self.__class__() 
     
    31193119    def sorted(self, cmp=None, key=None, reverse=False): 
    31203120        """ 
    3121         Return a sorted version of ``self``. :var:`compare` is a comparison 
     3121        Return a sorted version of :var:`self`. :var:`compare` is a comparison 
    31223122        function. The arguments :var:`cmp`, :var:`key` and :var:`reverse` have 
    31233123        the same meaning as fot the builtin :func:`sorted` function. 
     
    31303130    def reversed(self): 
    31313131        """ 
    3132         Return a reversed version of ``self``. 
     3132        Return a reversed version of :var:`self`. 
    31333133        """ 
    31343134        node = self.__class__() 
     
    31393139    def filtered(self, function): 
    31403140        """ 
    3141         Return a filtered version of the ``self``. 
     3141        Return a filtered version of the :var:`self`. 
    31423142        """ 
    31433143        node = self.__class__() 
     
    31483148    def shuffled(self): 
    31493149        """ 
    3150         Return a shuffled version of the ``self``. 
     3150        Return a shuffled version of the :var:`self`. 
    31513151        """ 
    31523152        node = self.__class__() 
     
    35063506    def haselement(self, name, xmlns): 
    35073507        """ 
    3508         Is there a registered element class in ``self`` for the element type 
     3508        Is there a registered element class in :var:`self` for the element type 
    35093509        with the Python name :var:`name` and the namespace :var:`xmlns`? 
    35103510        """ 
     
    35133513    def haselement_xml(self, name, xmlns): 
    35143514        """ 
    3515         Is there a registered element class in ``self`` for the element type 
     3515        Is there a registered element class in :var:`self` for the element type 
    35163516        with the XML name :var:`name` and the namespace :var:`xmlns`? 
    35173517        """ 
     
    35723572    def hasprocinst(self, name): 
    35733573        """ 
    3574         Is there a registered processing instruction class in ``self`` for the 
     3574        Is there a registered processing instruction class in :var:`self` for the 
    35753575        PI with the Python name :var:`name`? 
    35763576        """ 
     
    35793579    def hasprocinst_xml(self, name): 
    35803580        """ 
    3581         Is there a registered processing instruction class in ``self`` for the 
     3581        Is there a registered processing instruction class in :var:`self` for the 
    35823582        PI with the XML name :var:`name`? 
    35833583        """ 
     
    36343634    def hasentity(self, name): 
    36353635        """ 
    3636         Is there a registered entity class in ``self`` for the entity with the 
     3636        Is there a registered entity class in :var:`self` for the entity with the 
    36373637        Python name :var:`name`? 
    36383638        """ 
     
    36413641    def hasentity_xml(self, name): 
    36423642        """ 
    3643         Is there a registered entity class in ``self`` for the entity with the 
     3643        Is there a registered entity class in :var:`self` for the entity with the 
    36443644        XML name :var:`name`? 
    36453645        """ 
     
    37063706    def hascharref(self, name): 
    37073707        """ 
    3708         Is there a registered character entity class in ``self`` with the Python 
     3708        Is there a registered character entity class in :var:`self` with the Python 
    37093709        name or codepoint :var:`name`? 
    37103710        """ 
     
    37173717    def hascharref_xml(self, name): 
    37183718        """ 
    3719         Is there a registered character entity class in ``self`` with the XML 
     3719        Is there a registered character entity class in :var:`self` with the XML 
    37203720        name or codepoint :var:`name`? 
    37213721        """ 
     
    37903790    def clear(self): 
    37913791        """ 
    3792         Make <self/> empty. 
     3792        Make :var:`self` empty. 
    37933793        """ 
    37943794        self._elementsbyxmlname.clear() 
     
    38073807    def clone(self): 
    38083808        """ 
    3809         Return a copy of ``self``. 
     3809        Return a copy of :var:`self`. 
    38103810        """ 
    38113811        copy = Pool.clone(self) 
  • test/test_url.py

    r3144 r3189  
    1 #! /usr/bin/env/python 
     1#!/usr/bin/env python 
    22# -*- coding: utf-8 -*- 
    33 
    4 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    5 ## Copyright 1999-2008 by Walter Dörwald 
     4## Copyright 2005/2006 by LivingLogic AG, Bayreuth/Germany. 
     5## Copyright 2005/2006 by Walter Dörwald 
    66## 
    77## All Rights Reserved 
    88## 
    9 ## See xist/__init__.py for the license 
     9## See __init__.py for the license 
    1010 
    1111 
    1212import py.test 
    1313 
    14 from ll.xist import xsc, parsers 
    15 from ll.xist.ns import specials, html, jsp 
    16  
    17  
    18 def test_url(): 
    19     node = parsers.parsestring("<?url root:images/gurk.gif?>") 
    20     assert node.bytes(base="root:about/us.html") == "../images/gurk.gif" 
    21  
    22     node = parsers.parsestring('<img src="root:images/gurk.gif"/>') 
    23     assert node.bytes(base="root:about/us.html") == '<img src="../images/gurk.gif" />' 
    24  
    25  
    26 def test_fancyurl():     
    27     node = html.a("gurk", href=("http://", jsp.expression("server"))) 
    28     assert node.bytes(base="root:about/us.html") == '<a href="http://<%= server %>">gurk</a>' 
     14from ll import url 
     15 
     16 
     17def test_fileext(): 
     18    u = url.URL("/gurk/hurz") 
     19    assert u.file == u"hurz" 
     20    assert u.ext is None 
     21    u.file = u"nöx.png" 
     22    assert u.file == u"nöx.png" 
     23    assert u.ext == u"png" 
     24    assert unicode(u.path) == u"/gurk/n%c3%b6x.png" 
     25    u.ext = "gif" 
     26    assert u.file == u"nöx.gif" 
     27    assert u.ext == u"gif" 
     28 
     29    u = url.URL("/gurk/hurz.") 
     30    assert u.file == u"hurz." 
     31    assert u.ext == u"" 
     32    u.ext = "gif" 
     33    assert u.file == u"hurz.gif" 
     34    assert u.ext == u"gif" 
     35 
     36    u = url.URL("/gurk/hurz.png") 
     37    assert u.file == u"hurz.png" 
     38    assert u.ext == u"png" 
     39 
     40    u = url.URL("/gurk/hurz/") 
     41    assert u.file == u"" 
     42    assert u.ext is None 
     43    u.ext = "gif" 
     44    assert u.file == u".gif" 
     45    assert u.ext == u"gif" 
     46 
     47    assert url.URL(".gif").withoutext() == url.URL("./") 
     48 
     49 
     50def test_join_list(): 
     51    assert ["", "gurk", "gurk/"]/url.URL("index.html") == map(url.URL, ["index.html", "index.html", "gurk/index.html"]) 
     52 
     53    assert url.URL("gurk/")/["", "hinz", "kunz"] == map(url.URL, ["gurk/", "gurk/hinz", "gurk/kunz"]) 
     54 
     55 
     56def test_withfile(): 
     57    def check(org, file, exp): 
     58        org = url.URL(org) 
     59        exp = url.URL(exp) 
     60        res = org.withfile(file) 
     61        assert exp == res 
     62 
     63    yield check, "", "gurk", "gurk" 
     64    yield check, "/", "gurk", "/gurk" 
     65    yield check, "/hurz", "gurk", "/gurk" 
     66    yield check, "/hurz.gif", "gurk.gif", "/gurk.gif" 
     67 
     68 
     69def test_withoutfile(): 
     70    def check(org, exp): 
     71        org = url.URL(org) 
     72        exp = url.URL(exp) 
     73        res = org.withoutfile() 
     74        assert exp == res 
     75 
     76    yield check, "", "./" 
     77    yield check, "/", "/" 
     78    yield check, "/hurz", "/" 
     79    yield check, "hurz", "./" 
     80    yield check, "/gurk/hurz/hinz/", "/gurk/hurz/hinz/" 
     81    yield check, "/gurk/hurz/hinz/kunz", "/gurk/hurz/hinz/" 
     82 
     83 
     84def test_withext(): 
     85    def check(org, ext, exp): 
     86        org = url.URL(org) 
     87        exp = url.URL(exp) 
     88        res = org.withext(ext) 
     89        assert exp == res 
     90 
     91    yield check, "", "py", ".py" 
     92    yield check, "/", "py", "/.py" 
     93    yield check, "/hurz", "py", "/hurz.py" 
     94    yield check, "/hurz.", "py", "/hurz.py" 
     95    yield check, "/hurz.gif", "py", "/hurz.py" 
     96    yield check, "/hurz.gif.png", "py", "/hurz.gif.py" 
     97    yield check, "/hurz.gif.png", "pyc.py", "/hurz.gif.pyc.py" 
     98 
     99 
     100def test_withoutext(): 
     101    def check(org, exp): 
     102        org = url.URL(org) 
     103        exp = url.URL(exp) 
     104        res = org.withoutext() 
     105        assert exp == res 
     106 
     107    yield check, "", "" 
     108    yield check, "/", "/" 
     109    yield check, "/gurk.1/hurz", "/gurk.1/hurz" 
     110    yield check, "/gurk.2/hurz.gif", "/gurk.2/hurz" 
     111    yield check, "/gurk.3/hurz.gif.png", "/gurk.3/hurz.gif" 
     112    yield check, "/gurk.4/hurz.", "/gurk.4/hurz" 
     113 
     114 
     115def test_parse(): 
     116    base = "http://a/b/c/d;p?q#f" 
     117    u = url.URL(base) 
     118    assert u.scheme == "http" 
     119    assert u.userinfo is None 
     120    assert u.host == "a" 
     121    assert u.port is None 
     122    assert u.hostport == "a" 
     123    assert u.server == "a" 
     124    assert u.authority == "a" 
     125    assert u.reg_name is None 
     126    assert u.path == "/b/c/d;p" 
     127    assert u.path.segments == [("b",), ("c",), ("d", "p")] 
     128    assert u.isabspath is True 
     129    assert u.query == "q" 
     130    assert u.query_parts is False 
     131    assert u.frag == "f" 
     132    assert u.opaque_part is None 
     133    assert u.url == base 
     134 
     135    base = "http://a/b/c/d;p?q=x#f" 
     136    u = url.URL(base) 
     137    assert u.query == "q=x" 
     138    assert u.query_parts == {"q": ["x"]} 
     139 
     140 
     141def test_join_rfc2396(): 
     142    base = "http://a/b/c/d;p?q" 
     143    baseurl = url.URL(base) 
     144 
     145    def check(rel, res): 
     146        relurl = url.URL(rel) 
     147        resurl = url.URL(res) 
     148        assert baseurl/relurl == resurl, "%r/%r is %r, but should be %r" % (baseurl, relurl, baseurl/relurl, resurl) 
     149        # This checks rdiv 
     150        assert str(baseurl)/relurl == resurl, "%r/%r is %r, but should be %r" % (baseurl, relurl, str(baseurl)/relurl, resurl) 
     151 
     152    # RFC2396 Section C.1: Normal Examples 
     153    yield check, "g:h",           "g:h" 
     154    yield check, "g",             "http://a/b/c/g" 
     155    yield check, "./g",           "http://a/b/c/g" 
     156    yield check, "g/",            "http://a/b/c/g/" 
     157    yield check, "/g",            "http://a/g" 
     158    yield check, "//g",           "http://g" 
     159    yield check, "?y",            "http://a/b/c/?y" 
     160    yield check, "g?y",           "http://a/b/c/g?y" 
     161    yield check, "#s",            "http://a/b/c/d;p?q#s" 
     162    yield check, "g#s",           "http://a/b/c/g#s" 
     163    yield check, "g?y#s",         "http://a/b/c/g?y#s" 
     164    yield check, ";x",            "http://a/b/c/;x" 
     165    yield check, "g;x",           "http://a/b/c/g;x" 
     166    yield check, "g;x?y#s",       "http://a/b/c/g;x?y#s" 
     167    yield check, ".",             "http://a/b/c/" 
     168    yield check, "./",            "http://a/b/c/" 
     169    yield check, "..",            "http://a/b/" 
     170    yield check, "../",           "http://a/b/" 
     171    yield check, "../g",          "http://a/b/g" 
     172    yield check, "../..",         "http://a/" 
     173    yield check, "../../",        "http://a/" 
     174    yield check, "../../g",       "http://a/g" 
     175 
     176    # RFC2396 Section C.2: Abnormal Examples 
     177    yield check, "",              "http://a/b/c/d;p?q" 
     178    yield check, "../../../g",    "http://a/../g" 
     179    yield check, "../../../../g", "http://a/../../g" 
     180    yield check, "/./g",          "http://a/./g" 
     181    yield check, "/../g",         "http://a/../g" 
     182    yield check, "g.",            "http://a/b/c/g." 
     183    yield check, ".g",            "http://a/b/c/.g" 
     184    yield check, "g..",           "http://a/b/c/g.." 
     185    yield check, "..g",           "http://a/b/c/..g" 
     186    yield check, "./../g",        "http://a/b/g" 
     187    yield check, "./g/.",         "http://a/b/c/g/" 
     188    yield check, "g/./h",         "http://a/b/c/g/h" 
     189    yield check, "g/../h",        "http://a/b/c/h" 
     190    yield check, "g;x=1/./y",     "http://a/b/c/g;x=1/y" 
     191    yield check, "g;x=1/../y",    "http://a/b/c/y" 
     192    yield check, "g?y/./x",       "http://a/b/c/g?y/./x" 
     193    yield check, "g?y/../x",      "http://a/b/c/g?y/../x" 
     194    yield check, "g#s/./x",       "http://a/b/c/g#s/./x" 
     195    yield check, "g#s/../x",      "http://a/b/c/g#s/../x" 
     196    yield check, "http:g",        "http:g" # use the validating version here 
     197 
     198 
     199def test_join(): 
     200    def check(base, rel, res): 
     201        baseurl = url.URL(base) 
     202        relurl = url.URL(rel) 
     203        resurl = url.URL(res) 
     204        assert baseurl/relurl == resurl, "%r/%r is %r, but should be %r" % (baseurl, relurl, baseurl/relurl, resurl) 
     205        # This checks rdiv 
     206        assert str(baseurl)/relurl == resurl, "%r/%r is %r, but should be %r" % (baseurl, relurl, str(baseurl)/relurl, resurl) 
     207 
     208    yield check, "http://test.com/index.html", "impress.html", "http://test.com/impress.html" 
     209    yield check, "http://test.com/index.html", "", "http://test.com/index.html" 
     210    yield check, "/bb/cc/", "http:", "http:" 
     211    yield check, "mailto:x@y.z", "index.html", "index.html" 
     212    yield check, "mailto:x@y.z", "", "mailto:x@y.z" 
     213    yield check, "javascript:return ':/:/:';", "index.html", "index.html" 
     214    yield check, "javascript:document.write('http://foo@bar.com:81/foo;bar/bar;foo?x=y#frag');", "index.html", "index.html" 
     215    yield check, "mailto:x@y", "", "mailto:x@y" 
     216    yield check, "http://test.com/gurk/hurz.gif", "/index.html", "http://test.com/index.html" 
     217    yield check, "http://test.com/gurk/hurz.gif", "../", "http://test.com/" 
     218    yield check, "http://test.com/gurk/hurz.gif", "../gurk.gif?foo=bar#nix", "http://test.com/gurk.gif?foo=bar#nix" 
     219    yield check, "http://test.com/gurk/hurz.gif", "../../gurk.gif?foo=bar#nix", "http://test.com/../gurk.gif?foo=bar#nix" 
     220    yield check, "http://test.com/gurk/hurz.gif", "root:gurk.gif", "root:gurk.gif" 
     221    yield check, "root:gurk.gif", "http://test.com/gurk/hurz.gif", "http://test.com/gurk/hurz.gif" 
     222    yield check, "root:gurk/hurz/hinz.gif", "hinz/kunz.gif", "root:gurk/hurz/hinz/kunz.gif" 
     223    yield check, "root:gurk/hurz/hinz.gif", "root:hinz/kunz.gif", "root:hinz/kunz.gif" 
     224    yield check, "http://test.com", "gurk", "http://test.com/gurk" 
     225 
     226 
     227def test_normalize(): 
     228    def check(u, u2): 
     229        u = url.URL(u) 
     230        u1 = u.clone() 
     231        u1.path.normalize() 
     232        u2 = url.URL(u2) 
     233        assert u1 == u2, "%r normalized is %r, but should be %r" % (u, u1, u2) 
     234 
     235    yield check, "", "" 
     236    yield check, "./", "" 
     237    yield check, "/./", "/" 
     238    yield check, "xx", "xx" 
     239    yield check, "xx/yy", "xx/yy" 
     240    yield check, "xx/..", "" 
     241    yield check, "xx/../.", "" 
     242    yield check, "./xx/..", "" 
     243    yield check, "./xx/../.", "" 
     244    yield check, "xx/./..", "" 
     245    yield check, "xx/yy/..", "xx/" 
     246    yield check, "xx//yy/../..", "" 
     247    yield check, "xx//yy/./..", "xx/" 
     248    yield check, "xx//yy//../", "xx/" 
     249    yield check, "xx/../..//", "../" 
     250    yield check, "xx/.././..", ".." # ".." parts above the root loose their "directoryness", otherwise this would be "../" 
     251    yield check, "xx/.", "xx/" 
     252    yield check, "./xx", "xx" 
     253    yield check, "/xx", "/xx" 
     254    yield check, "/./xx", "/xx" 
     255    yield check, "xx/../xx/../xx", "xx" 
     256 
     257 
     258def test_str(): 
     259    s = "ftp://ftp.livinglogic.de/pub/livinglogic/xist/XIST-42.105.tar.bz2" 
     260    u = url.URL(s) 
     261    assert unicode(u) == s 
     262    assert str(u) == s 
     263 
     264 
     265def test_relative(): 
     266    def check(base, rel, res): 
     267        baseurl = url.URL(base) 
     268        relurl = url.URL(rel) 
     269        resurl = url.URL(res) 
     270        assert relurl.relative(baseurl) == resurl, "%r.relative(%r) is %r, but should be %r" % (relurl, baseurl, relurl.relative(baseurl), resurl) 
     271 
     272    yield check, "./", "./", "./" 
     273    yield check, "cc.html", "./", "./" 
     274    yield check, "./cc.html", "./", "./" 
     275    yield check, "file:./cc.html", "file:./", "./" 
     276    yield check, "root:./cc.html", "file:./", "file:./" 
     277    yield check, "root:xist/Documentation.html", "http://server/", "http://server/" 
     278    yield check, "root:cc.html", "root:", "./" 
     279    yield check, "root:cc.html", "./", "./" 
     280    yield check, "cc.html", "#mark", "#mark" 
     281    yield check, "root:cc.html", "root:#mark", "./#mark" 
     282    yield check, "root:cc.html", "#mark", "#mark" 
     283    yield check, "root:cc.html", "root:cc.html#mark", "#mark" 
     284    yield check, "root:cc.html", "root:dd.html#mark", "dd.html#mark" 
     285    yield check, "root:aa/bb/cc.html", "root:", "../../" 
     286    yield check, "", "", "" 
     287    yield check, "http://server/aa/bb.html", "http://server/aa/cc.html", "cc.html" 
     288    yield check, "/aa/bb.html", "/xx.html", "/xx.html" # we don't handle URLs without scheme 
     289 
     290 
     291def test_query(): 
     292    u = url.URL("/search?id=13&id") 
     293    assert u.query == "id=13&id" 
     294    assert u.query_parts == 0 
     295 
     296    u.query += "=17" 
     297    assert u.query == "id=13&id=17" 
     298    assert u.query_parts == {u"id": [u"13", u"17"]} 
     299 
     300    del u.query_parts["id"] 
     301    u.query_parts["name"] = "gurk" 
     302    assert u.query == "name=gurk" 
     303    assert u.query_parts == {u"name": u"gurk"} 
     304 
     305    u.query_parts["name"] = [u"gÃŒrk"] 
     306    assert u.query == "name=g%c3%bcrk" 
     307    assert u.query_parts == {u"name": [u"gÃŒrk"]} 
     308 
     309    u.query_parts["name"] = u"gÃŒrk" 
     310    assert u.query == "name=g%c3%bcrk" 
     311    assert u.query_parts == {u"name": u"gÃŒrk"} 
     312 
     313 
     314def test_eq(): 
     315    u1 = url.URL("HTTP://www.FOO.com/gurk") 
     316    u2 = url.URL("http://www.foo.com:80/gurk") 
     317    assert u1 == u2 
     318    assert hash(u1) == hash(u2) 
     319 
     320    u1 = url.URL("http://www.foo.com/gurk?id=13&id=17") 
     321    u2 = url.URL("http://www.foo.com/gurk?id=17&id=13") 
     322    assert u1 == u2 
     323    assert hash(u1) == hash(u2) 
     324 
     325    u1 = url.URL("http://www.foo.com/gurk?gurk=hurz&hinz=kunz") 
     326    u2 = url.URL("http://www.foo.com/gurk?hinz=kunz&gurk=hurz") 
     327    assert u1 == u2 
     328    assert hash(u1) == hash(u2) 
     329 
     330 
     331def test_withfrag(): 
     332    u1a = url.URL("x#y") 
     333    u1b = url.URL("x#y") 
     334    u2 = url.URL("x#z") 
     335    assert u1a.withfrag("z") == u2 
     336    assert u1a == u1b # make sure withfrag created a new URL 
     337 
     338 
     339def test_without(): 
     340    u1a = url.URL("x#y") 
     341    u1b = url.URL("x#y") 
     342    u2 = url.URL("x") 
     343    u3 = url.URL("x#") 
     344    assert u1a.withoutfrag() == u2 
     345    assert u1a.withoutfrag() != u3 
     346    assert u1a == u1b # make sure withfrag created a new URL 
     347 
     348 
     349def test_relpathauthority(): 
     350    u = url.URL("http://www.foo.com/bar/baz;baz") 
     351    u2 = u.clone() 
     352    u2.path = [ map(unicode.upper, seg) for seg in u2.path.segments ] 
     353    assert not u2.path.isabs 
     354    assert str(u2) == "http://www.foo.com/BAR/BAZ;BAZ" 
     355 
     356    del u2.scheme 
     357    del u2.authority 
     358    assert str(u2) == "BAR/BAZ;BAZ" 
  • test/test_xist_basics.py

    r3080 r3189  
    2222from ll.xist.ns import wml, ihtml, html, chars, abbr, specials, htmlspecials, meta, form, php, xml, tld, docbook 
    2323 
    24 import common 
     24import xist_common as common 
    2525 
    2626 
  • test/test_xist_comparisons.py

    • Property exe deleted
  • test/test_xist_walk.py

    r3087 r3189  
    1414from ll.xist.ns import html, xml 
    1515 
    16 import common 
     16import xist_common as common 
    1717 
    1818