[Checkins] SVN: Sandbox/shane/republish/zope.publisher/ this version of the publisher uses zope.httpform

Shane Hathaway shane at hathawaymix.org
Fri Feb 6 02:41:03 EST 2009


Log message for revision 96176:
  this version of the publisher uses zope.httpform
  

Changed:
  A   Sandbox/shane/republish/zope.publisher/
  D   Sandbox/shane/republish/zope.publisher/CHANGES.txt
  A   Sandbox/shane/republish/zope.publisher/CHANGES.txt
  D   Sandbox/shane/republish/zope.publisher/setup.py
  A   Sandbox/shane/republish/zope.publisher/setup.py
  U   Sandbox/shane/republish/zope.publisher/src/zope/publisher/browser.py

-=-
Deleted: Sandbox/shane/republish/zope.publisher/CHANGES.txt
===================================================================
--- zope.publisher/trunk/CHANGES.txt	2009-02-04 21:02:45 UTC (rev 96089)
+++ Sandbox/shane/republish/zope.publisher/CHANGES.txt	2009-02-06 07:41:02 UTC (rev 96176)
@@ -1,130 +0,0 @@
-CHANGES
-=======
-
-3.5.5 (unreleased)
-------------------
-
-* LP #322486: setStatus() now allows any int()-able status value.
-
-
-3.5.4 (2008-09-22)
-------------------
-
-Bugs fixed:
-
-* LP #98440: interfaces lost on retried request
-
-* LP #273296: dealing more nicely with malformed HTTP_ACCEPT_LANGUAGE headers
-  within getPreferredLanguages().
-
-* LP #253362: dealing more nicely with malformed HTTP_ACCEPT_CHARSET headers
-  within getPreferredCharsets().
-
-* LP #98284: Pass the ``size`` argument to readline, as the version of
-  twisted used in zope.app.twisted supports it.
-
-* Fix the LP #98284 fix: do not pass ``size`` argument of None that causes
-  cStringIO objects to barf with a TypeError.
-
-
-3.5.3 (2008-06-20)
-------------------
-
-Bugs fixed:
-
-* It turns out that some Web servers (Paste for example) do not send the EOF
-  character after the data has been transmitted and the read() of the cached
-  stream simply hangs if no expected content length has been specified.
-
-
-3.5.2 (2008-04-06)
-------------------
-
-Bugs fixed:
-
-* A previous fix to handle posting of non-form data broke handling of
-  form data with extra information in the content type, as in::
-
-    application/x-www-form-urlencoded; charset=UTF-8
-
-3.5.1 (2008-03-23)
-------------------
-
-Bugs fixed:
-
-* When posting non-form (and non-multipart) data, the request body was
-  consumed and discarded. This makes it impossible to deal with other
-  post types, like xml-rpc or json without resorting to overly complex
-  "request factory" contortions.
-
-* https://bugs.launchpad.net/zope2/+bug/143873
-
-  The zope.publisher.http.HTTPCharsets was confused by the Zope 2
-  publisher, which gives missleading information about which headers
-  it has.
-
-3.5.0 (2008-03-02)
-------------------
-
-Features added:
-
-* Added a PasteDeploy app_factory implementation.  This should make
-  it easier to integrate Zope 3 applications with PasteDeploy.  It
-  also makes it easier to control the publication used, giving far
-  greater control over application policies (e.g. whether or not to
-  use the ZODB).
-
-3.4.2 (2007-12-07)
-------------------
-
-* Made segmentation of URLs not strip (trailing) whitespace from path segments
-  to allow URLs ending in %20 to be handled correctly. (#172742)
-
-3.4.1 (2007-09-29)
-------------------
-
-No changes since 3.4.1b2.
-
-3.4.1b2 (2007-08-02)
---------------------
-
-* zope.publisher now works on Python 2.5.
-
-* Fix a problem with request.get() when the object that's to be
-  retrieved is the request itself.
-
-
-3.4.1b1 (2007-07-13)
---------------------
-
-No changes.
-
-
-3.4.0b2 (2007-07-05)
---------------------
-
-* Fix https://bugs.launchpad.net/zope3/+bug/122054:  
-  HTTPInputStream understands both the CONTENT_LENGTH and
-  HTTP_CONTENT_LENGTH environment variables. It is also now tolerant
-  of empty strings and will treat those as if the variable were
-  absent.
-
-
-3.4.0b1 (2007-07-05)
---------------------
-
-* Fix caching issue. The input stream never got cached in a temp file 
-  because of a wrong content-length header lookup. Added CONTENT_LENGTH 
-  header check in addition to the previous used HTTP_CONTENT_LENGTH. The 
-  ``HTTP_`` prefix is sometimes added by some CGI proxies, but CONTENT_LENGTH
-  is the right header info for the size.
-
-* Fix https://bugs.launchpad.net/zope3/+bug/98413:
-  HTTPResponse.handleException should set the content type
-
-
-3.4.0a1 (2007-04-22)
---------------------
-
-Initial release as a separate project, corresponds to zope.publisher
-from Zope 3.4.0a1

Copied: Sandbox/shane/republish/zope.publisher/CHANGES.txt (from rev 96090, zope.publisher/trunk/CHANGES.txt)
===================================================================
--- Sandbox/shane/republish/zope.publisher/CHANGES.txt	                        (rev 0)
+++ Sandbox/shane/republish/zope.publisher/CHANGES.txt	2009-02-06 07:41:02 UTC (rev 96176)
@@ -0,0 +1,136 @@
+CHANGES
+=======
+
+3.5.6 (unreleased)
+------------------
+
+* ...
+
+
+3.5.5 (2009-02-04)
+------------------
+
+* LP #322486: setStatus() now allows any int()-able status value.
+
+
+3.5.4 (2008-09-22)
+------------------
+
+Bugs fixed:
+
+* LP #98440: interfaces lost on retried request
+
+* LP #273296: dealing more nicely with malformed HTTP_ACCEPT_LANGUAGE headers
+  within getPreferredLanguages().
+
+* LP #253362: dealing more nicely with malformed HTTP_ACCEPT_CHARSET headers
+  within getPreferredCharsets().
+
+* LP #98284: Pass the ``size`` argument to readline, as the version of
+  twisted used in zope.app.twisted supports it.
+
+* Fix the LP #98284 fix: do not pass ``size`` argument of None that causes
+  cStringIO objects to barf with a TypeError.
+
+
+3.5.3 (2008-06-20)
+------------------
+
+Bugs fixed:
+
+* It turns out that some Web servers (Paste for example) do not send the EOF
+  character after the data has been transmitted and the read() of the cached
+  stream simply hangs if no expected content length has been specified.
+
+
+3.5.2 (2008-04-06)
+------------------
+
+Bugs fixed:
+
+* A previous fix to handle posting of non-form data broke handling of
+  form data with extra information in the content type, as in::
+
+    application/x-www-form-urlencoded; charset=UTF-8
+
+3.5.1 (2008-03-23)
+------------------
+
+Bugs fixed:
+
+* When posting non-form (and non-multipart) data, the request body was
+  consumed and discarded. This makes it impossible to deal with other
+  post types, like xml-rpc or json without resorting to overly complex
+  "request factory" contortions.
+
+* https://bugs.launchpad.net/zope2/+bug/143873
+
+  The zope.publisher.http.HTTPCharsets was confused by the Zope 2
+  publisher, which gives missleading information about which headers
+  it has.
+
+3.5.0 (2008-03-02)
+------------------
+
+Features added:
+
+* Added a PasteDeploy app_factory implementation.  This should make
+  it easier to integrate Zope 3 applications with PasteDeploy.  It
+  also makes it easier to control the publication used, giving far
+  greater control over application policies (e.g. whether or not to
+  use the ZODB).
+
+3.4.2 (2007-12-07)
+------------------
+
+* Made segmentation of URLs not strip (trailing) whitespace from path segments
+  to allow URLs ending in %20 to be handled correctly. (#172742)
+
+3.4.1 (2007-09-29)
+------------------
+
+No changes since 3.4.1b2.
+
+3.4.1b2 (2007-08-02)
+--------------------
+
+* zope.publisher now works on Python 2.5.
+
+* Fix a problem with request.get() when the object that's to be
+  retrieved is the request itself.
+
+
+3.4.1b1 (2007-07-13)
+--------------------
+
+No changes.
+
+
+3.4.0b2 (2007-07-05)
+--------------------
+
+* Fix https://bugs.launchpad.net/zope3/+bug/122054:  
+  HTTPInputStream understands both the CONTENT_LENGTH and
+  HTTP_CONTENT_LENGTH environment variables. It is also now tolerant
+  of empty strings and will treat those as if the variable were
+  absent.
+
+
+3.4.0b1 (2007-07-05)
+--------------------
+
+* Fix caching issue. The input stream never got cached in a temp file 
+  because of a wrong content-length header lookup. Added CONTENT_LENGTH 
+  header check in addition to the previous used HTTP_CONTENT_LENGTH. The 
+  ``HTTP_`` prefix is sometimes added by some CGI proxies, but CONTENT_LENGTH
+  is the right header info for the size.
+
+* Fix https://bugs.launchpad.net/zope3/+bug/98413:
+  HTTPResponse.handleException should set the content type
+
+
+3.4.0a1 (2007-04-22)
+--------------------
+
+Initial release as a separate project, corresponds to zope.publisher
+from Zope 3.4.0a1

Deleted: Sandbox/shane/republish/zope.publisher/setup.py
===================================================================
--- zope.publisher/trunk/setup.py	2009-02-04 21:02:45 UTC (rev 96089)
+++ Sandbox/shane/republish/zope.publisher/setup.py	2009-02-06 07:41:02 UTC (rev 96176)
@@ -1,61 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-import os
-from setuptools import setup, find_packages
-
-entry_points = """
-[paste.app_factory]
-main = zope.publisher.paste:Application
-
-[zope.publisher.publication_factory]
-sample = zope.publisher.tests.test_paste:SamplePublication
-"""
-
-setup(name='zope.publisher',
-      version = '3.5.5dev',
-      url='http://pypi.python.org/pypi/zope.publisher',
-      license='ZPL 2.1',
-      author='Zope Corporation and Contributors',
-      author_email='zope-dev at zope.org',
-      description="The Zope publisher publishes Python objects on the web.",
-      long_description=(open('README.txt').read()
-                        + '\n\n'
-                        + open('CHANGES.txt').read()),
-
-      entry_points = entry_points,
-
-      packages=find_packages('src'),
-      package_dir = {'': 'src'},
-
-      namespace_packages=['zope',],
-      install_requires=['setuptools',
-                        'zope.component',
-                        'zope.event',
-                        'zope.exceptions',
-                        'zope.i18n',
-                        'zope.interface',
-                        'zope.location',
-                        'zope.proxy',
-                        'zope.security',
-                        'zope.deprecation',
-                        'zope.deferredimport'],
-      extras_require=dict(
-          test = ['zope.testing',
-                  'zope.app.testing'],
-          ),
-      include_package_data = True,
-
-      zip_safe = False,
-      )

Copied: Sandbox/shane/republish/zope.publisher/setup.py (from rev 96090, zope.publisher/trunk/setup.py)
===================================================================
--- Sandbox/shane/republish/zope.publisher/setup.py	                        (rev 0)
+++ Sandbox/shane/republish/zope.publisher/setup.py	2009-02-06 07:41:02 UTC (rev 96176)
@@ -0,0 +1,63 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import os
+from setuptools import setup, find_packages
+
+entry_points = """
+[paste.app_factory]
+main = zope.publisher.paste:Application
+
+[zope.publisher.publication_factory]
+sample = zope.publisher.tests.test_paste:SamplePublication
+"""
+
+setup(name='zope.publisher',
+      version = '3.5.6dev',
+      url='http://pypi.python.org/pypi/zope.publisher',
+      license='ZPL 2.1',
+      author='Zope Corporation and Contributors',
+      author_email='zope-dev at zope.org',
+      description="The Zope publisher publishes Python objects on the web.",
+      long_description=(open('README.txt').read()
+                        + '\n\n'
+                        + open('CHANGES.txt').read()),
+
+      entry_points = entry_points,
+
+      packages=find_packages('src'),
+      package_dir = {'': 'src'},
+
+      namespace_packages=['zope',],
+      install_requires=['setuptools',
+                        'zope.component',
+                        'zope.event',
+                        'zope.exceptions',
+                        'zope.i18n',
+                        'zope.interface',
+                        'zope.location',
+                        'zope.proxy',
+                        'zope.security',
+                        'zope.deprecation',
+                        'zope.deferredimport',
+                        'zope.httpform',
+                        ],
+      extras_require=dict(
+          test = ['zope.testing',
+                  'zope.app.testing'],
+          ),
+      include_package_data = True,
+
+      zip_safe = False,
+      )

Modified: Sandbox/shane/republish/zope.publisher/src/zope/publisher/browser.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/browser.py	2009-02-04 21:02:45 UTC (rev 96089)
+++ Sandbox/shane/republish/zope.publisher/src/zope/publisher/browser.py	2009-02-06 07:41:02 UTC (rev 96176)
@@ -23,9 +23,6 @@
 __docformat__ = 'restructuredtext'
 
 import re
-from types import ListType, TupleType, StringType
-from cgi import FieldStorage
-import tempfile
 
 import zope.component
 from zope.interface import implements, directlyProvides
@@ -33,6 +30,8 @@
 from zope.i18n.interfaces import IUserPreferredLanguages
 from zope.i18n.interfaces import IUserPreferredCharsets
 from zope.location import Location
+from zope.httpform import FormParser
+from zope.deferredimport import deprecatedFrom
 
 from zope.publisher.interfaces import NotFound
 from zope.publisher.interfaces.browser import IBrowserRequest
@@ -46,118 +45,16 @@
 from zope.publisher.interfaces.http import IHTTPRequest
 from zope.publisher.http import HTTPRequest, HTTPResponse
 
-__ArrayTypes = (ListType, TupleType)
-
 start_of_header_search=re.compile('(<head[^>]*>)', re.I).search
 base_re_search=re.compile('(<base.*?>)',re.I).search
 isRelative = re.compile("[-_.!~*a-zA-z0-9'()@&=+$,]+(/|$)").match
-newlines = re.compile('\r\n|\n\r|\r')
 
 def is_text_html(content_type):
     return content_type.startswith('text/html')
 
-# Flag Constants
-SEQUENCE = 1
-DEFAULT = 2
-RECORD = 4
-RECORDS = 8
-REC = RECORD | RECORDS
-CONVERTED = 32
 DEFAULTABLE_METHODS = 'GET', 'POST', 'HEAD'
 
 
-def field2string(v):
-    if hasattr(v, 'read'):
-        return v.read()
-    return str(v)
-
-def field2text(v, nl=newlines):
-    return nl.sub("\n", field2string(v))
-
-def field2required(v):
-    v = field2string(v)
-    if not v.strip():
-        raise ValueError('No input for required field<p>')
-    return v
-
-def field2int(v):
-    if isinstance(v, __ArrayTypes):
-        return map(field2int, v)
-    v = field2string(v)
-    if not v:
-        raise ValueError('Empty entry when <strong>integer</strong> expected')
-    try:
-        return int(v)
-    except ValueError:
-        raise ValueError("An integer was expected in the value '%s'" % v)
-
-def field2float(v):
-    if isinstance(v, __ArrayTypes):
-        return map(field2float, v)
-    v = field2string(v)
-    if not v:
-        raise ValueError(
-            'Empty entry when <strong>floating-point number</strong> expected')
-    try:
-        return float(v)
-    except ValueError:
-        raise ValueError(
-                "A floating-point number was expected in the value '%s'" % v)
-
-def field2long(v):
-    if isinstance(v, __ArrayTypes):
-        return map(field2long, v)
-    v = field2string(v)
-
-    # handle trailing 'L' if present.
-    if v and v[-1].upper() == 'L':
-        v = v[:-1]
-    if not v:
-        raise ValueError('Empty entry when <strong>integer</strong> expected')
-    try:
-        return long(v)
-    except ValueError:
-        raise ValueError("A long integer was expected in the value '%s'" % v)
-
-def field2tokens(v):
-    return field2string(v).split()
-
-def field2lines(v):
-    if isinstance(v, __ArrayTypes):
-        return [str(item) for item in v]
-    return field2text(v).splitlines()
-
-def field2boolean(v):
-    return bool(v)
-
-type_converters = {
-    'float':    field2float,
-    'int':      field2int,
-    'long':     field2long,
-    'string':   field2string,
-    'required': field2required,
-    'tokens':   field2tokens,
-    'lines':    field2lines,
-    'text':     field2text,
-    'boolean':  field2boolean,
-    }
-
-get_converter = type_converters.get
-
-def registerTypeConverter(field_type, converter, replace=False):
-    """Add a custom type converter to the registry.
-
-    o If 'replace' is not true, raise a KeyError if a converter is
-      already registered for 'field_type'.
-    """
-    existing = type_converters.get(field_type)
-
-    if existing is not None and not replace:
-        raise KeyError('Existing converter for field_type: %s' % field_type)
-
-    type_converters[field_type] = converter
-
-
 isCGI_NAME = {
     # These fields are placed in request.environ instead of request.form.
     'SERVER_SOFTWARE' : 1,
@@ -185,32 +82,7 @@
     'HTTP_CGI_AUTHORIZATION': 1,
     }.has_key
 
-class Record(object):
 
-    _attrs = frozenset(('get', 'keys', 'items', 'values', 'copy',
-                       'has_key', '__contains__'))
-
-    def __getattr__(self, key, default=None):
-        if key in self._attrs:
-            return getattr(self.__dict__, key)
-        raise AttributeError(key)
-
-    def __getitem__(self, key):
-        return self.__dict__[key]
-
-    def __str__(self):
-        items = self.__dict__.items()
-        items.sort()
-        return "{" + ", ".join(["%s: %s" % item for item in items]) + "}"
-
-    def __repr__(self):
-        items = self.__dict__.items()
-        items.sort()
-        return ("{"
-            + ", ".join(["%s: %s" % (key, repr(value))
-            for key, value in items]) + "}")
-
-_get_or_head = 'GET', 'HEAD'
 class BrowserRequest(HTTPRequest):
     implements(IBrowserRequest, IBrowserApplicationRequest)
 
@@ -218,9 +90,6 @@
         '__provides__', # Allow request to directly provide interfaces
         'form', # Form data
         'charsets', # helper attribute
-        '__meth',
-        '__tuple_items',
-        '__defaults',
         '__annotations__',
         )
 
@@ -252,273 +121,11 @@
 
     def processInputs(self):
         'See IPublisherRequest'
+        parser = FormParser(self._environ, self._body_instream, self._decode)
+        self.form = parser.parse()
+        if parser.action:
+            self.setPathSuffix((parser.action,))
 
-        if self.method not in _get_or_head:
-            # Process self.form if not a GET request.
-            fp = self._body_instream
-            if self.method == 'POST':
-                content_type = self._environ.get('CONTENT_TYPE')
-                if content_type and not (
-                    content_type.startswith('application/x-www-form-urlencoded')
-                    or
-                    content_type.startswith('multipart/')
-                    ):
-                    # for non-multi and non-form content types, FieldStorage
-                    # consumes the body and we have no good place to put it.
-                    # So we just won't call FieldStorage. :)
-                    return
-        else:
-            fp = None
-
-        # If 'QUERY_STRING' is not present in self._environ
-        # FieldStorage will try to get it from sys.argv[1]
-        # which is not what we need.
-        if 'QUERY_STRING' not in self._environ:
-            self._environ['QUERY_STRING'] = ''
-
-        fs = ZopeFieldStorage(fp=fp, environ=self._environ,
-                              keep_blank_values=1)
-
-        fslist = getattr(fs, 'list', None)
-        if fslist is not None:
-            self.__meth = None
-            self.__tuple_items = {}
-            self.__defaults = {}
-
-            # process all entries in the field storage (form)
-            for item in fslist:
-                self.__processItem(item)
-
-            if self.__defaults:
-                self.__insertDefaults()
-
-            if self.__tuple_items:
-                self.__convertToTuples()
-
-            if self.__meth:
-                self.setPathSuffix((self.__meth,))
-
-    _typeFormat = re.compile('([a-zA-Z][a-zA-Z0-9_]+|\\.[xy])$')
-
-    def __processItem(self, item):
-        """Process item in the field storage."""
-
-        # Check whether this field is a file upload object
-        # Note: A field exists for files, even if no filename was
-        # passed in and no data was uploaded. Therefore we can only
-        # tell by the empty filename that no upload was made.
-        key = item.name
-        if (hasattr(item, 'file') and hasattr(item, 'filename')
-            and hasattr(item,'headers')):
-            if (item.file and
-                (item.filename is not None and item.filename != ''
-                 # RFC 1867 says that all fields get a content-type.
-                 # or 'content-type' in map(lower, item.headers.keys())
-                 )):
-                item = FileUpload(item)
-            else:
-                item = item.value
-
-        flags = 0
-        converter = None
-
-        # Loop through the different types and set
-        # the appropriate flags
-        # Syntax: var_name:type_name
-
-        # We'll search from the back to the front.
-        # We'll do the search in two steps.  First, we'll
-        # do a string search, and then we'll check it with
-        # a re search.
-
-        while key:
-            pos = key.rfind(":")
-            if pos < 0:
-                break
-            match = self._typeFormat.match(key, pos + 1)
-            if match is None:
-                break
-
-            key, type_name = key[:pos], key[pos + 1:]
-
-            # find the right type converter
-            c = get_converter(type_name, None)
-
-            if c is not None:
-                converter = c
-                flags |= CONVERTED
-            elif type_name == 'list':
-                flags |= SEQUENCE
-            elif type_name == 'tuple':
-                self.__tuple_items[key] = 1
-                flags |= SEQUENCE
-            elif (type_name == 'method' or type_name == 'action'):
-                if key:
-                    self.__meth = key
-                else:
-                    self.__meth = item
-            elif (type_name == 'default_method'
-                    or type_name == 'default_action') and not self.__meth:
-                if key:
-                    self.__meth = key
-                else:
-                    self.__meth = item
-            elif type_name == 'default':
-                flags |= DEFAULT
-            elif type_name == 'record':
-                flags |= RECORD
-            elif type_name == 'records':
-                flags |= RECORDS
-            elif type_name == 'ignore_empty' and not item:
-                # skip over empty fields
-                return
-
-        # Make it unicode if not None
-        if key is not None:
-            key = self._decode(key)
-
-        if type(item) == StringType:
-            item = self._decode(item)
-
-        if flags:
-            self.__setItemWithType(key, item, flags, converter)
-        else:
-            self.__setItemWithoutType(key, item)
-
-    def __setItemWithoutType(self, key, item):
-        """Set item value without explicit type."""
-        form = self.form
-        if key not in form:
-            form[key] = item
-        else:
-            found = form[key]
-            if isinstance(found, list):
-                found.append(item)
-            else:
-                form[key] = [found, item]
-
-    def __setItemWithType(self, key, item, flags, converter):
-        """Set item value with explicit type."""
-        #Split the key and its attribute
-        if flags & REC:
-            key, attr = self.__splitKey(key)
-
-        # defer conversion
-        if flags & CONVERTED:
-            try:
-                item = converter(item)
-            except:
-                if item or flags & DEFAULT or key not in self.__defaults:
-                    raise
-                item = self.__defaults[key]
-                if flags & RECORD:
-                    item = getattr(item, attr)
-                elif flags & RECORDS:
-                    item = getattr(item[-1], attr)
-
-        # Determine which dictionary to use
-        if flags & DEFAULT:
-            form = self.__defaults
-        else:
-            form = self.form
-
-        # Insert in dictionary
-        if key not in form:
-            if flags & SEQUENCE:
-                item = [item]
-            if flags & RECORD:
-                r = form[key] = Record()
-                setattr(r, attr, item)
-            elif flags & RECORDS:
-                r = Record()
-                setattr(r, attr, item)
-                form[key] = [r]
-            else:
-                form[key] = item
-        else:
-            r = form[key]
-            if flags & RECORD:
-                if not flags & SEQUENCE:
-                    setattr(r, attr, item)
-                else:
-                    if not hasattr(r, attr):
-                        setattr(r, attr, [item])
-                    else:
-                        getattr(r, attr).append(item)
-            elif flags & RECORDS:
-                last = r[-1]
-                if not hasattr(last, attr):
-                    if flags & SEQUENCE:
-                        item = [item]
-                    setattr(last, attr, item)
-                else:
-                    if flags & SEQUENCE:
-                        getattr(last, attr).append(item)
-                    else:
-                        new = Record()
-                        setattr(new, attr, item)
-                        r.append(new)
-            else:
-                if isinstance(r, list):
-                    r.append(item)
-                else:
-                    form[key] = [r, item]
-
-    def __splitKey(self, key):
-        """Split the key and its attribute."""
-        i = key.rfind(".")
-        if i >= 0:
-            return key[:i], key[i + 1:]
-        return key, ""
-
-    def __convertToTuples(self):
-        """Convert form values to tuples."""
-        form = self.form
-
-        for key in self.__tuple_items:
-            if key in form:
-                form[key] = tuple(form[key])
-            else:
-                k, attr = self.__splitKey(key)
-
-                # remove any type_names in the attr
-                i = attr.find(":")
-                if i >= 0:
-                    attr = attr[:i]
-
-                if k in form:
-                    item = form[k]
-                    if isinstance(item, Record):
-                        if hasattr(item, attr):
-                            setattr(item, attr, tuple(getattr(item, attr)))
-                    else:
-                        for v in item:
-                            if hasattr(v, attr):
-                                setattr(v, attr, tuple(getattr(v, attr)))
-
-    def __insertDefaults(self):
-        """Insert defaults into form dictionary."""
-        form = self.form
-
-        for keys, values in self.__defaults.iteritems():
-            if not keys in form:
-                form[keys] = values
-            else:
-                item = form[keys]
-                if isinstance(values, Record):
-                    for k, v in values.items():
-                        if not hasattr(item, k):
-                            setattr(item, k, v)
-                elif isinstance(values, list):
-                    for val in values:
-                        if isinstance(val, Record):
-                            for k, v in val.items():
-                                for r in item:
-                                    if not hasattr(r, k):
-                                        setattr(r, k, v)
-                        elif not val in item:
-                            item.append(val)
-
     def traverse(self, obj):
         'See IPublisherRequest'
 
@@ -579,43 +186,7 @@
 
         return super(BrowserRequest, self).get(key, default)
 
-class ZopeFieldStorage(FieldStorage):
 
-    def make_file(self, binary=None):
-        return tempfile.NamedTemporaryFile('w+b')
-
-
-class FileUpload(object):
-    '''File upload objects
-
-    File upload objects are used to represent file-uploaded data.
-
-    File upload objects can be used just like files.
-
-    In addition, they have a 'headers' attribute that is a dictionary
-    containing the file-upload headers, and a 'filename' attribute
-    containing the name of the uploaded file.
-    '''
-
-    def __init__(self, aFieldStorage):
-
-        file = aFieldStorage.file
-        if hasattr(file, '__methods__'):
-            methods = file.__methods__
-        else:
-            methods = ['close', 'fileno', 'flush', 'isatty',
-                'read', 'readline', 'readlines', 'seek',
-                'tell', 'truncate', 'write', 'writelines',
-                'name']
-
-        d = self.__dict__
-        for m in methods:
-            if hasattr(file,m):
-                d[m] = getattr(file,m)
-
-        self.headers = aFieldStorage.headers
-        self.filename = unicode(aFieldStorage.filename, 'UTF-8')
-
 class RedirectingBrowserRequest(BrowserRequest):
     """Browser requests that redirect when the actual and effective URLs differ
     """
@@ -1030,3 +601,17 @@
 
     def __init__(self, request):
         self.request = request
+
+
+deprecatedFrom(
+    'This name has moved to zope.httpform.typeconv.'
+    'zope.httpform.typeconv',
+    'field2string', 'field2text', 'field2required', 'field2int',
+    'field2float', 'field2long', 'field2tokens', 'field2lines',
+    'field2boolean', 'type_converters', 'get_converter',
+    'registerTypeConverter')
+
+deprecatedFrom(
+    'This name has moved to zope.httpform.parser.'
+    'zope.httpform.parser',
+    'Record', 'FileUpload')



More information about the Checkins mailing list