Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
174dd221
Commit
174dd221
authored
May 14, 2005
by
Skip Montanaro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add better datetime support to xmlrpclib module. Closes patch #1120353.
parent
186e739d
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
127 additions
and
30 deletions
+127
-30
Doc/lib/libxmlrpclib.tex
Doc/lib/libxmlrpclib.tex
+35
-13
Lib/test/test_xmlrpc.py
Lib/test/test_xmlrpc.py
+38
-6
Lib/xmlrpclib.py
Lib/xmlrpclib.py
+49
-11
Misc/NEWS
Misc/NEWS
+5
-0
No files found.
Doc/lib/libxmlrpclib.tex
View file @
174dd221
...
...
@@ -19,7 +19,7 @@ objects and XML on the wire.
\begin{classdesc}
{
ServerProxy
}{
uri
\optional
{
, transport
\optional
{
,
encoding
\optional
{
, verbose
\optional
{
,
allow
_
none
}}}}}
allow
_
none
\optional
{
, use
_
datetime
}
}}}}}
A
\class
{
ServerProxy
}
instance is an object that manages communication
with a remote XML-RPC server. The required first argument is a URI
(Uniform Resource Indicator), and will normally be the URL of the
...
...
@@ -33,6 +33,13 @@ default behaviour is for \code{None} to raise a \exception{TypeError}.
This is a commonly-used extension to the XML-RPC specification, but isn't
supported by all clients and servers; see
\url
{
http://ontosys.com/xml-rpc/extensions.php
}
for a description.
The
\var
{
use
_
datetime
}
flag can be used to cause date/time values to be
presented as
\class
{
\refmodule
{
datetime
}
.datetime
}
objects; this is false
by default.
\class
{
\refmodule
{
datetime
}
.datetime
}
,
\class
{
\refmodule
{
datetime
}
.date
}
and
\class
{
\refmodule
{
datetime
}
.time
}
objects may be passed to calls.
\class
{
\refmodule
{
datetime
}
.date
}
objects
are converted with a time of ``00:00:00''.
\class
{
\refmodule
{
datetime
}
.time
}
objects are converted using today's date.
Both the HTTP and HTTPS transports support the URL syntax extension for
HTTP Basic Authentication:
\code
{
http://user:pass@host:port/path
}
. The
...
...
@@ -62,8 +69,11 @@ Python type):
elements. Arrays are returned as lists
}
\lineii
{
structures
}{
A Python dictionary. Keys must be strings,
values may be any conformable type.
}
\lineii
{
dates
}{
in seconds since the epoch; pass in an instance of the
\class
{
DateTime
}
wrapper class
}
\lineii
{
dates
}{
in seconds since the epoch (pass in an instance of the
\class
{
DateTime
}
class) or a
\class
{
\refmodule
{
datetime
}
.datetime
}
,
\class
{
\refmodule
{
datetime
}
.date
}
or
\class
{
\refmodule
{
datetime
}
.time
}
instance
}
\lineii
{
binary data
}{
pass in an instance of the
\class
{
Binary
}
wrapper class
}
\end{tableii}
...
...
@@ -87,6 +97,7 @@ described below.
\class
{
Server
}
is retained as an alias for
\class
{
ServerProxy
}
for backwards
compatibility. New code should use
\class
{
ServerProxy
}
.
\versionchanged
[The \var{use_datetime} flag was added]
{
2.5
}
\end{classdesc}
...
...
@@ -96,7 +107,7 @@ compatibility. New code should use \class{ServerProxy}.
client software in several languages. Contains pretty much
everything an XML-RPC client developer needs to know.
}
\seetitle
[http://xmlrpc-c.sourceforge.net/hacks.php]
{
XML-RPC
-
Hacks page
}{
Extensions for various open-source
{
XML-RPC
Hacks page
}{
Extensions for various open-source
libraries to support introspection and multicall.
}
\end{seealso}
...
...
@@ -149,7 +160,8 @@ returned. The documentation string may contain HTML markup.
Introspection methods are currently supported by servers written in
PHP, C and Microsoft .NET. Partial introspection support is included
in recent updates to UserLand Frontier. Introspection support for
Perl, Python and Java is available at the XML-RPC Hacks page.
Perl, Python and Java is available at the
\ulink
{
XML-RPC
Hacks
}{
http://xmlrpc-c.sourceforge.net/hacks.php
}
page.
\subsection
{
Boolean Objects
\label
{
boolean-objects
}}
...
...
@@ -170,21 +182,23 @@ Write the XML-RPC encoding of this Boolean item to the out stream object.
\subsection
{
DateTime Objects
\label
{
datetime-objects
}}
This class may be initialized with seconds since the epoch, a
time tuple, or an ISO 8601 time/date string. It has the following
methods, supported mainly for internal use by the
marshalling/unmarshalling code:
This class may be initialized with seconds since the epoch, a time tuple, an
ISO 8601 time/date string, or a
{}
\class
{
\refmodule
{
datetime
}
.datetime
}
,
{}
\class
{
\refmodule
{
datetime
}
.date
}
or
{}
\class
{
\refmodule
{
datetime
}
.time
}
instance. It has the following methods, supported mainly for internal use
by the marshalling/unmarshalling code:
\begin{methoddesc}
{
decode
}{
string
}
Accept a string as the instance's new time value.
\end{methoddesc}
\begin{methoddesc}
{
encode
}{
out
}
Write the XML-RPC encoding of this DateTime item to the out stream object.
Write the XML-RPC encoding of this
\class
{
DateTime
}
item to the
\var
{
out
}
stream object.
\end{methoddesc}
It also supports certain of Python's built-in operators through
\method
{__
cmp
__
}
and
\method
{__
repr
__
}
methods.
\method
{__
cmp
__
()
}
and
\method
{__
repr
__
()
}
methods.
\subsection
{
Binary Objects
\label
{
binary-objects
}}
...
...
@@ -296,7 +310,6 @@ Trivially convert any Python string to a \class{Binary} object.
\begin{funcdesc}
{
dumps
}{
params
\optional
{
, methodname
\optional
{
,
methodresponse
\optional
{
, encoding
\optional
{
,
allow
_
none
}}}}}
Convert
\var
{
params
}
into an XML-RPC request.
or into a response if
\var
{
methodresponse
}
is true.
\var
{
params
}
can be either a tuple of arguments or an instance of the
...
...
@@ -308,12 +321,21 @@ used in standard XML-RPC; to allow using it via an extension,
provide a true value for
\var
{
allow
_
none
}
.
\end{funcdesc}
\begin{funcdesc}
{
loads
}{
data
}
\begin{funcdesc}
{
loads
}{
data
\optional
{
, use
_
datetime
}
}
Convert an XML-RPC request or response into Python objects, a
\code
{
(
\var
{
params
}
,
\var
{
methodname
}
)
}
.
\var
{
params
}
is a tuple of argument;
\var
{
methodname
}
is a string, or
\code
{
None
}
if no method name is present in the packet.
If the XML-RPC packet represents a fault condition, this
function will raise a
\exception
{
Fault
}
exception.
The
\var
{
use
_
datetime
}
flag can be used to cause date/time values to be
presented as
\class
{
\refmodule
{
datetime
}
.datetime
}
objects; this is false
by default.
Note that even if you call an XML-RPC method with
\class
{
\refmodule
{
datetime
}
.date
}
or
\class
{
\refmodule
{
datetime
}
.time
}
objects, they are converted to
\class
{
DateTime
}
objects internally, so only
{}
\class
{
\refmodule
{
datetime
}
.datetime
}
objects will be returned.
\versionchanged
[The \var{use_datetime} flag was added]
{
2.5
}
\end{funcdesc}
...
...
Lib/test/test_xmlrpc.py
View file @
174dd221
...
...
@@ -34,16 +34,48 @@ class XMLRPCTestCase(unittest.TestCase):
xmlrpclib
.
loads
(
xmlrpclib
.
dumps
((
alist
,)))[
0
][
0
])
def
test_dump_bare_datetime
(
self
):
# This checks that an unwrapped datetime object can be handled
# by the marshalling code. This can't be done via
#
test_dump_load() since the unmarshaller doesn't produce bas
e
# datetime
instances.
# This checks that an unwrapped datetime
.date
object can be handled
# by the marshalling code. This can't be done via
test_dump_load()
#
since with use_datetime set to 1 the unmarshaller would creat
e
# datetime
objects for the 'datetime[123]' keys as well
dt
=
datetime
.
datetime
(
2005
,
02
,
10
,
11
,
41
,
23
)
s
=
xmlrpclib
.
dumps
((
dt
,))
r
,
m
=
xmlrpclib
.
loads
(
s
)
self
.
assertEquals
(
r
,
(
xmlrpclib
.
DateTime
(
'20050210T11:41:23'
),)
)
(
newdt
,),
m
=
xmlrpclib
.
loads
(
s
,
use_datetime
=
1
)
self
.
assertEquals
(
newdt
,
dt
)
self
.
assertEquals
(
m
,
None
)
(
newdt
,),
m
=
xmlrpclib
.
loads
(
s
,
use_datetime
=
0
)
self
.
assertEquals
(
newdt
,
xmlrpclib
.
DateTime
(
'20050210T11:41:23'
))
def
test_dump_bare_date
(
self
):
# This checks that an unwrapped datetime.date object can be handled
# by the marshalling code. This can't be done via test_dump_load()
# since the unmarshaller produces a datetime object
d
=
datetime
.
datetime
(
2005
,
02
,
10
,
11
,
41
,
23
).
date
()
s
=
xmlrpclib
.
dumps
((
d
,))
(
newd
,),
m
=
xmlrpclib
.
loads
(
s
,
use_datetime
=
1
)
self
.
assertEquals
(
newd
.
date
(),
d
)
self
.
assertEquals
(
newd
.
time
(),
datetime
.
time
(
0
,
0
,
0
))
self
.
assertEquals
(
m
,
None
)
(
newdt
,),
m
=
xmlrpclib
.
loads
(
s
,
use_datetime
=
0
)
self
.
assertEquals
(
newdt
,
xmlrpclib
.
DateTime
(
'20050210T00:00:00'
))
def
test_dump_bare_time
(
self
):
# This checks that an unwrapped datetime.time object can be handled
# by the marshalling code. This can't be done via test_dump_load()
# since the unmarshaller produces a datetime object
t
=
datetime
.
datetime
(
2005
,
02
,
10
,
11
,
41
,
23
).
time
()
s
=
xmlrpclib
.
dumps
((
t
,))
(
newt
,),
m
=
xmlrpclib
.
loads
(
s
,
use_datetime
=
1
)
today
=
datetime
.
datetime
.
now
().
date
().
strftime
(
"%Y%m%d"
)
self
.
assertEquals
(
newt
.
time
(),
t
)
self
.
assertEquals
(
newt
.
date
(),
datetime
.
datetime
.
now
().
date
())
self
.
assertEquals
(
m
,
None
)
(
newdt
,),
m
=
xmlrpclib
.
loads
(
s
,
use_datetime
=
0
)
self
.
assertEquals
(
newdt
,
xmlrpclib
.
DateTime
(
'%sT11:41:23'
%
today
))
def
test_dump_big_long
(
self
):
self
.
assertRaises
(
OverflowError
,
xmlrpclib
.
dumps
,
(
2L
**
99
,))
...
...
Lib/xmlrpclib.py
View file @
174dd221
...
...
@@ -357,7 +357,14 @@ class DateTime:
if
datetime
and
isinstance
(
value
,
datetime
.
datetime
):
self
.
value
=
value
.
strftime
(
"%Y%m%dT%H:%M:%S"
)
return
elif
not
isinstance
(
value
,
(
TupleType
,
time
.
struct_time
)):
if
datetime
and
isinstance
(
value
,
datetime
.
date
):
self
.
value
=
value
.
strftime
(
"%Y%m%dT%H:%M:%S"
)
return
if
datetime
and
isinstance
(
value
,
datetime
.
time
):
today
=
datetime
.
datetime
.
now
().
strftime
(
"%Y%m%d"
)
self
.
value
=
value
.
strftime
(
today
+
"T%H:%M:%S"
)
return
if
not
isinstance
(
value
,
(
TupleType
,
time
.
struct_time
)):
if
value
==
0
:
value
=
time
.
time
()
value
=
time
.
localtime
(
value
)
...
...
@@ -394,6 +401,10 @@ def _datetime(data):
value
.
decode
(
data
)
return
value
def
_datetime_type
(
data
):
t
=
time
.
strptime
(
data
,
"%Y%m%dT%H:%M:%S"
)
return
datetime
.
datetime
(
*
tuple
(
t
)[:
6
])
##
# Wrapper for binary data. This can be used to transport any kind
# of binary data over XML-RPC, using BASE64 encoding.
...
...
@@ -714,6 +725,19 @@ class Marshaller:
write
(
"</dateTime.iso8601></value>
\
n
"
)
dispatch
[
datetime
.
datetime
]
=
dump_datetime
def
dump_date
(
self
,
value
,
write
):
write
(
"<value><dateTime.iso8601>"
)
write
(
value
.
strftime
(
"%Y%m%dT00:00:00"
))
write
(
"</dateTime.iso8601></value>
\
n
"
)
dispatch
[
datetime
.
date
]
=
dump_date
def
dump_time
(
self
,
value
,
write
):
write
(
"<value><dateTime.iso8601>"
)
write
(
datetime
.
datetime
.
now
().
date
().
strftime
(
"%Y%m%dT"
))
write
(
value
.
strftime
(
"%H:%M:%S"
))
write
(
"</dateTime.iso8601></value>
\
n
"
)
dispatch
[
datetime
.
time
]
=
dump_time
def
dump_instance
(
self
,
value
,
write
):
# check for special wrappers
if
value
.
__class__
in
WRAPPERS
:
...
...
@@ -742,7 +766,7 @@ class Unmarshaller:
# and again, if you don't understand what's going on in here,
# that's perfectly ok.
def
__init__
(
self
):
def
__init__
(
self
,
use_datetime
=
0
):
self
.
_type
=
None
self
.
_stack
=
[]
self
.
_marks
=
[]
...
...
@@ -750,6 +774,9 @@ class Unmarshaller:
self
.
_methodname
=
None
self
.
_encoding
=
"utf-8"
self
.
append
=
self
.
_stack
.
append
self
.
_use_datetime
=
use_datetime
if
use_datetime
and
not
datetime
:
raise
ValueError
,
"the datetime module is not available"
def
close
(
self
):
# return response tuple and target method
...
...
@@ -867,6 +894,8 @@ class Unmarshaller:
def
end_dateTime
(
self
,
data
):
value
=
DateTime
()
value
.
decode
(
data
)
if
self
.
_use_datetime
:
value
=
_datetime_type
(
data
)
self
.
append
(
value
)
dispatch
[
"dateTime.iso8601"
]
=
end_dateTime
...
...
@@ -968,17 +997,23 @@ class MultiCall:
#
# return A (parser, unmarshaller) tuple.
def
getparser
():
def
getparser
(
use_datetime
=
0
):
"""getparser() -> parser, unmarshaller
Create an instance of the fastest available parser, and attach it
to an unmarshalling object. Return both objects.
"""
if
use_datetime
and
not
datetime
:
raise
ValueError
,
"the datetime module is not available"
if
FastParser
and
FastUnmarshaller
:
target
=
FastUnmarshaller
(
True
,
False
,
_binary
,
_datetime
,
Fault
)
if
use_datetime
:
mkdatetime
=
_datetime_type
else
:
mkdatetime
=
_datetime
target
=
FastUnmarshaller
(
True
,
False
,
_binary
,
mkdatetime
,
Fault
)
parser
=
FastParser
(
target
)
else
:
target
=
Unmarshaller
()
target
=
Unmarshaller
(
use_datetime
=
use_datetime
)
if
FastParser
:
parser
=
FastParser
(
target
)
elif
SgmlopParser
:
...
...
@@ -1081,7 +1116,7 @@ def dumps(params, methodname=None, methodresponse=None, encoding=None,
# (None if not present).
# @see Fault
def
loads
(
data
):
def
loads
(
data
,
use_datetime
=
0
):
"""data -> unmarshalled data, method name
Convert an XML-RPC packet to unmarshalled data plus a method
...
...
@@ -1090,7 +1125,7 @@ def loads(data):
If the XML-RPC packet represents a fault condition, this function
raises a Fault exception.
"""
p
,
u
=
getparser
()
p
,
u
=
getparser
(
use_datetime
=
use_datetime
)
p
.
feed
(
data
)
p
.
close
()
return
u
.
close
(),
u
.
getmethodname
()
...
...
@@ -1122,6 +1157,9 @@ class Transport:
# client identifier (may be overridden)
user_agent
=
"xmlrpclib.py/%s (by www.pythonware.com)"
%
__version__
def
__init__
(
self
,
use_datetime
=
0
):
self
.
_use_datetime
=
use_datetime
##
# Send a complete request, and parse the response.
#
...
...
@@ -1168,7 +1206,7 @@ class Transport:
def
getparser
(
self
):
# get parser and unmarshaller
return
getparser
()
return
getparser
(
use_datetime
=
self
.
_use_datetime
)
##
# Get authorization info from host parameter
...
...
@@ -1362,7 +1400,7 @@ class ServerProxy:
"""
def
__init__
(
self
,
uri
,
transport
=
None
,
encoding
=
None
,
verbose
=
0
,
allow_none
=
0
):
allow_none
=
0
,
use_datetime
=
0
):
# establish a "logical" server connection
# get the url
...
...
@@ -1376,9 +1414,9 @@ class ServerProxy:
if
transport
is
None
:
if
type
==
"https"
:
transport
=
SafeTransport
()
transport
=
SafeTransport
(
use_datetime
=
use_datetime
)
else
:
transport
=
Transport
()
transport
=
Transport
(
use_datetime
=
use_datetime
)
self
.
__transport
=
transport
self
.
__encoding
=
encoding
...
...
Misc/NEWS
View file @
174dd221
...
...
@@ -123,6 +123,11 @@ Extension Modules
Library
-------
- Patch #1120353: The xmlrpclib module provides better, more transparent,
support for datetime.{datetime,date,time} objects. With use_datetime set
to True, applications shouldn'
t
have
to
fiddle
with
the
DateTime
wrapper
class
at
all
.
-
distutils
.
commands
.
upload
was
added
to
support
uploading
distribution
files
to
PyPI
.
...
...
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