Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
8510adec
Commit
8510adec
authored
Jun 16, 2006
by
Stefan H. Holek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Made DateTime.DateTime marshallable via XML-RPC.
Fixes
http://www.zope.org/Collectors/Zope/2109
parent
a0bae348
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
172 additions
and
10 deletions
+172
-10
doc/CHANGES.txt
doc/CHANGES.txt
+2
-0
lib/python/DateTime/DateTime.py
lib/python/DateTime/DateTime.py
+8
-0
lib/python/ZPublisher/tests/test_xmlrpc.py
lib/python/ZPublisher/tests/test_xmlrpc.py
+136
-0
lib/python/ZPublisher/xmlrpc.py
lib/python/ZPublisher/xmlrpc.py
+26
-10
No files found.
doc/CHANGES.txt
View file @
8510adec
...
...
@@ -18,6 +18,8 @@ Zope Changes
Bugs fixed
- Collector #2109: XML-RPC did not handle DateTime.DateTime objects.
- Collector #2016: DemoStorage couldn't wrap base storages without
an '_oid' attribute.
...
...
lib/python/DateTime/DateTime.py
View file @
8510adec
...
...
@@ -1805,6 +1805,14 @@ class DateTime:
d1
=
((
d4
-
L
)
%
365
)
+
L
return
d1
/
7
+
1
def
encode
(
self
,
out
):
"""
Encode value for XML-RPC
"""
out
.
write
(
'<value><dateTime.iso8601>'
)
out
.
write
(
self
.
ISO8601
())
out
.
write
(
'</dateTime.iso8601></value>
\
n
'
)
class
strftimeFormatter
:
...
...
lib/python/ZPublisher/tests/test_xmlrpc.py
View file @
8510adec
import
unittest
from
DateTime
import
DateTime
class
FauxResponse
:
...
...
@@ -12,6 +13,9 @@ class FauxResponse:
def
setHeader
(
self
,
name
,
value
):
self
.
_headers
[
name
]
=
value
def
setStatus
(
self
,
status
):
self
.
_status
=
status
class
FauxInstance
:
def
__init__
(
self
,
**
kw
):
self
.
__dict__
.
update
(
kw
)
...
...
@@ -55,6 +59,138 @@ class XMLRPCResponseTests(unittest.TestCase):
data
,
method
=
xmlrpclib
.
loads
(
faux
.
_body
)
self
.
assert_
(
data
[
0
][
'public'
]
is
None
)
def
test_instance
(
self
):
# Instances are turned into dicts with their private
# attributes removed.
import
xmlrpclib
body
=
FauxInstance
(
_secret
=
'abc'
,
public
=
'def'
)
faux
=
FauxResponse
()
response
=
self
.
_makeOne
(
faux
)
response
.
setBody
(
body
)
data
,
method
=
xmlrpclib
.
loads
(
faux
.
_body
)
data
=
data
[
0
]
self
.
assertEqual
(
data
,
{
'public'
:
'def'
})
def
test_instanceattribute
(
self
):
# While the removal of private ('_') attributes works fine for the
# top-level instance, how about attributes that are themselves
# instances?
import
xmlrpclib
body
=
FauxInstance
(
public
=
FauxInstance
(
_secret
=
'abc'
,
public
=
'def'
))
faux
=
FauxResponse
()
response
=
self
.
_makeOne
(
faux
)
response
.
setBody
(
body
)
data
,
method
=
xmlrpclib
.
loads
(
faux
.
_body
)
data
=
data
[
0
][
'public'
]
self
.
assertEqual
(
data
,
{
'public'
:
'def'
})
def
test_instanceattribute_recursive
(
self
):
# Instance "flattening" should work recursively, ad infinitum
import
xmlrpclib
body
=
FauxInstance
(
public
=
FauxInstance
(
public
=
FauxInstance
(
_secret
=
'abc'
,
public
=
'def'
)))
faux
=
FauxResponse
()
response
=
self
.
_makeOne
(
faux
)
response
.
setBody
(
body
)
data
,
method
=
xmlrpclib
.
loads
(
faux
.
_body
)
data
=
data
[
0
][
'public'
][
'public'
]
self
.
assertEqual
(
data
,
{
'public'
:
'def'
})
def
test_instance_in_list
(
self
):
# Instances are turned into dicts with their private
# attributes removed, even when embedded in another
# data structure.
import
xmlrpclib
body
=
[
FauxInstance
(
_secret
=
'abc'
,
public
=
'def'
)]
faux
=
FauxResponse
()
response
=
self
.
_makeOne
(
faux
)
response
.
setBody
(
body
)
data
,
method
=
xmlrpclib
.
loads
(
faux
.
_body
)
data
=
data
[
0
][
0
]
self
.
assertEqual
(
data
,
{
'public'
:
'def'
})
def
test_instance_in_dict
(
self
):
# Instances are turned into dicts with their private
# attributes removed, even when embedded in another
# data structure.
import
xmlrpclib
body
=
{
'faux'
:
FauxInstance
(
_secret
=
'abc'
,
public
=
'def'
)}
faux
=
FauxResponse
()
response
=
self
.
_makeOne
(
faux
)
response
.
setBody
(
body
)
data
,
method
=
xmlrpclib
.
loads
(
faux
.
_body
)
data
=
data
[
0
][
'faux'
]
self
.
assertEqual
(
data
,
{
'public'
:
'def'
})
def
test_zopedatetimeinstance
(
self
):
# DateTime instance at top-level
import
xmlrpclib
body
=
DateTime
(
'2006-05-24 07:00:00 GMT+0'
)
faux
=
FauxResponse
()
response
=
self
.
_makeOne
(
faux
)
response
.
setBody
(
body
)
data
,
method
=
xmlrpclib
.
loads
(
faux
.
_body
)
data
=
data
[
0
]
self
.
failUnless
(
isinstance
(
data
,
xmlrpclib
.
DateTime
))
self
.
assertEqual
(
data
.
value
,
u'2006-05-24T07:00:00+00:00'
)
def
test_zopedatetimeattribute
(
self
):
# DateTime instance as attribute
import
xmlrpclib
body
=
FauxInstance
(
public
=
DateTime
(
'2006-05-24 07:00:00 GMT+0'
))
faux
=
FauxResponse
()
response
=
self
.
_makeOne
(
faux
)
response
.
setBody
(
body
)
data
,
method
=
xmlrpclib
.
loads
(
faux
.
_body
)
data
=
data
[
0
][
'public'
]
self
.
failUnless
(
isinstance
(
data
,
xmlrpclib
.
DateTime
))
self
.
assertEqual
(
data
.
value
,
u'2006-05-24T07:00:00+00:00'
)
def
test_zopedatetimeattribute_recursive
(
self
):
# DateTime encoding should work recursively
import
xmlrpclib
body
=
FauxInstance
(
public
=
FauxInstance
(
public
=
DateTime
(
'2006-05-24 07:00:00 GMT+0'
)))
faux
=
FauxResponse
()
response
=
self
.
_makeOne
(
faux
)
response
.
setBody
(
body
)
data
,
method
=
xmlrpclib
.
loads
(
faux
.
_body
)
data
=
data
[
0
][
'public'
][
'public'
]
self
.
failUnless
(
isinstance
(
data
,
xmlrpclib
.
DateTime
))
self
.
assertEqual
(
data
.
value
,
u'2006-05-24T07:00:00+00:00'
)
def
test_zopedatetimeinstance_in_list
(
self
):
# DateTime instance embedded in a list
import
xmlrpclib
body
=
[
DateTime
(
'2006-05-24 07:00:00 GMT+0'
)]
faux
=
FauxResponse
()
response
=
self
.
_makeOne
(
faux
)
response
.
setBody
(
body
)
data
,
method
=
xmlrpclib
.
loads
(
faux
.
_body
)
data
=
data
[
0
][
0
]
self
.
failUnless
(
isinstance
(
data
,
xmlrpclib
.
DateTime
))
self
.
assertEqual
(
data
.
value
,
u'2006-05-24T07:00:00+00:00'
)
def
test_zopedatetimeinstance_in_dict
(
self
):
# DateTime instance embedded in a dict
import
xmlrpclib
body
=
{
'date'
:
DateTime
(
'2006-05-24 07:00:00 GMT+0'
)}
faux
=
FauxResponse
()
response
=
self
.
_makeOne
(
faux
)
response
.
setBody
(
body
)
data
,
method
=
xmlrpclib
.
loads
(
faux
.
_body
)
data
=
data
[
0
][
'date'
]
self
.
failUnless
(
isinstance
(
data
,
xmlrpclib
.
DateTime
))
self
.
assertEqual
(
data
.
value
,
u'2006-05-24T07:00:00+00:00'
)
def
test_functionattribute
(
self
):
# Cannot marshal functions or methods, obviously
import
xmlrpclib
def
foo
():
pass
body
=
FauxInstance
(
public
=
foo
)
faux
=
FauxResponse
()
response
=
self
.
_makeOne
(
faux
)
response
.
setBody
(
body
)
self
.
assertRaises
(
xmlrpclib
.
Fault
,
xmlrpclib
.
loads
,
faux
.
_body
)
def
test_suite
():
return
unittest
.
TestSuite
((
unittest
.
makeSuite
(
XMLRPCResponseTests
),))
...
...
lib/python/ZPublisher/xmlrpc.py
View file @
8510adec
...
...
@@ -25,6 +25,28 @@ from HTTPResponse import HTTPResponse
import
xmlrpclib
from
zExceptions
import
Unauthorized
from
ZODB.POSException
import
ConflictError
# Make DateTime.DateTime marshallable via XML-RPC
# http://www.zope.org/Collectors/Zope/2109
from
DateTime
import
DateTime
WRAPPERS
=
xmlrpclib
.
WRAPPERS
+
(
DateTime
,)
def
dump_instance
(
self
,
value
,
write
):
# Check for special wrappers
if
value
.
__class__
in
WRAPPERS
:
self
.
write
=
write
value
.
encode
(
self
)
del
self
.
write
else
:
# Store instance attributes as a struct (really?).
# We want to avoid disclosing private attributes.
# Private attributes are by convention named with
# a leading underscore character.
value
=
dict
([(
k
,
v
)
for
(
k
,
v
)
in
value
.
__dict__
.
items
()
if
k
[
0
]
!=
'_'
])
self
.
dump_struct
(
value
,
write
)
xmlrpclib
.
Marshaller
.
dispatch
[
types
.
InstanceType
]
=
dump_instance
def
parse_input
(
data
):
"""Parse input data and return a method path and argument tuple
...
...
@@ -100,16 +122,6 @@ class Response:
# Convert Fault object to XML-RPC response.
body
=
xmlrpclib
.
dumps
(
body
,
methodresponse
=
1
,
allow_none
=
True
)
else
:
if
type
(
body
)
==
types
.
InstanceType
:
# Avoid disclosing private members. Private members are
# by convention named with a leading underscore char.
orig
=
body
.
__dict__
dict
=
{}
for
key
in
orig
.
keys
():
if
key
[:
1
]
!=
'_'
:
dict
[
key
]
=
orig
[
key
]
body
=
dict
# Marshall our body as an XML-RPC response. Strings will be sent
# strings, integers as integers, etc. We do *not* convert
# everything to a string first.
...
...
@@ -119,6 +131,8 @@ class Response:
try
:
body
=
xmlrpclib
.
dumps
(
(
body
,),
methodresponse
=
1
,
allow_none
=
True
)
except
ConflictError
:
raise
except
:
self
.
exception
()
return
...
...
@@ -165,6 +179,8 @@ class Response:
f
=
Fault
(
-
1
,
'Unexpected Zope exception: %s'
%
value
)
else
:
f
=
Fault
(
-
2
,
'Unexpected Zope error value: %s'
%
value
)
except
ConflictError
:
raise
except
:
f
=
Fault
(
-
3
,
"Unknown Zope fault type"
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment