Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
zodburi
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
zodburi
Commits
3f7bfa1e
Commit
3f7bfa1e
authored
May 02, 2013
by
Tres Seaver
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support Python 3.2 / 3.3, and test them w/ tox.
parent
4c700b17
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
67 additions
and
31 deletions
+67
-31
CHANGES.txt
CHANGES.txt
+2
-0
setup.py
setup.py
+4
-0
tox.ini
tox.ini
+17
-1
zodburi/_compat.py
zodburi/_compat.py
+14
-0
zodburi/resolvers.py
zodburi/resolvers.py
+21
-20
zodburi/tests/test_resolvers.py
zodburi/tests/test_resolvers.py
+9
-10
No files found.
CHANGES.txt
View file @
3f7bfa1e
...
@@ -4,6 +4,8 @@
...
@@ -4,6 +4,8 @@
Unreleased
Unreleased
----------
----------
- Added support for Python 3.2 / 3.3.
- Added ``setup.py docs`` alias (runs ``setup.py develop`` and installs
- Added ``setup.py docs`` alias (runs ``setup.py develop`` and installs
documentation dependencies).
documentation dependencies).
...
...
setup.py
View file @
3f7bfa1e
...
@@ -29,8 +29,12 @@ setup(name='zodburi',
...
@@ -29,8 +29,12 @@ setup(name='zodburi',
classifiers
=
[
classifiers
=
[
"Intended Audience :: Developers"
,
"Intended Audience :: Developers"
,
"Programming Language :: Python"
,
"Programming Language :: Python"
,
"Programming Language :: Python :: 2"
,
"Programming Language :: Python :: 2.6"
,
"Programming Language :: Python :: 2.6"
,
"Programming Language :: Python :: 2.7"
,
"Programming Language :: Python :: 2.7"
,
"Programming Language :: Python :: 3"
,
"Programming Language :: Python :: 3.2"
,
"Programming Language :: Python :: 3.3"
,
"License :: Repoze Public License"
,
"License :: Repoze Public License"
,
],
],
keywords
=
'zodb zodbconn'
,
keywords
=
'zodb zodbconn'
,
...
...
tox.ini
View file @
3f7bfa1e
[tox]
[tox]
envlist
=
envlist
=
py26,py27,cover,docs
py26,py27,
py32,py33,
cover,docs
[testenv]
[testenv]
commands
=
commands
=
python
setup.py
test
-q
python
setup.py
test
-q
[py3]
deps
=
# Py3k compatible ZODB not yet released
git+https://github.com/zopefoundation/ZODB.git@py3
#egg=ZODB
git+https://github.com/zopefoundation/ZEO.git@py3
#egg=ZEO
[testenv:py32]
commands
=
python
setup.py
test
-q
deps
=
{[py3]deps}
[testenv:py33]
commands
=
python
setup.py
test
-q
deps
=
{[py3]deps}
[testenv:cover]
[testenv:cover]
basepython
=
basepython
=
python2.6
python2.6
...
...
zodburi/_compat.py
0 → 100644
View file @
3f7bfa1e
try
:
from
urllib.parse
import
parse_qsl
except
ImportError
:
#pragma NO COVER
from
cgi
import
parse_qsl
try
:
from
urllib.parse
import
quote
except
ImportError
:
#pragma NO COVER
from
urllib
import
quote
try
:
from
urllib.parse
import
urlsplit
except
ImportError
:
#pragma NO COVER
from
urlparse
import
urlsplit
zodburi/resolvers.py
View file @
3f7bfa1e
import
cgi
from
io
import
BytesIO
from
cStringIO
import
StringIO
import
os
import
os
import
sys
import
sys
import
urlparse
from
ZODB.config
import
ZODBDatabase
from
ZConfig
import
loadConfig
from
ZConfig
import
loadSchemaFile
from
ZEO.ClientStorage
import
ClientStorage
from
ZEO.ClientStorage
import
ClientStorage
from
ZODB.FileStorage.FileStorage
import
FileStorage
from
ZODB.blob
import
BlobStorage
from
ZODB.config
import
ZODBDatabase
from
ZODB.DemoStorage
import
DemoStorage
from
ZODB.DemoStorage
import
DemoStorage
from
ZODB.FileStorage.FileStorage
import
FileStorage
from
ZODB.MappingStorage
import
MappingStorage
from
ZODB.MappingStorage
import
MappingStorage
from
ZODB.blob
import
BlobStorage
import
ZConfig
from
zodburi.datatypes
import
convert_bytesize
from
zodburi.datatypes
import
convert_bytesize
from
zodburi.datatypes
import
convert_int
from
zodburi.datatypes
import
convert_int
from
zodburi.datatypes
import
convert_tuple
from
zodburi.datatypes
import
convert_tuple
from
zodburi._compat
import
parse_qsl
from
zodburi._compat
import
urlsplit
class
Resolver
(
object
):
class
Resolver
(
object
):
...
@@ -55,7 +56,7 @@ class MappingStorageURIResolver(Resolver):
...
@@ -55,7 +56,7 @@ class MappingStorageURIResolver(Resolver):
query
=
''
query
=
''
else
:
else
:
name
,
query
=
result
name
,
query
=
result
kw
=
dict
(
cgi
.
parse_qsl
(
query
))
kw
=
dict
(
parse_qsl
(
query
))
kw
,
unused
=
self
.
interpret_kwargs
(
kw
)
kw
,
unused
=
self
.
interpret_kwargs
(
kw
)
args
=
(
name
,)
args
=
(
name
,)
def
factory
():
def
factory
():
...
@@ -70,7 +71,7 @@ class FileStorageURIResolver(Resolver):
...
@@ -70,7 +71,7 @@ class FileStorageURIResolver(Resolver):
_bytesize_args
=
(
'quota'
,)
_bytesize_args
=
(
'quota'
,)
def
__call__
(
self
,
uri
):
def
__call__
(
self
,
uri
):
# we can't use url
parse.url
split here due to Windows filenames
# we can't use urlsplit here due to Windows filenames
prefix
,
rest
=
uri
.
split
(
'file://'
,
1
)
prefix
,
rest
=
uri
.
split
(
'file://'
,
1
)
result
=
rest
.
split
(
'?'
,
1
)
result
=
rest
.
split
(
'?'
,
1
)
if
len
(
result
)
==
1
:
if
len
(
result
)
==
1
:
...
@@ -80,7 +81,7 @@ class FileStorageURIResolver(Resolver):
...
@@ -80,7 +81,7 @@ class FileStorageURIResolver(Resolver):
path
,
query
=
result
path
,
query
=
result
path
=
os
.
path
.
normpath
(
path
)
path
=
os
.
path
.
normpath
(
path
)
args
=
(
path
,)
args
=
(
path
,)
kw
=
dict
(
cgi
.
parse_qsl
(
query
))
kw
=
dict
(
parse_qsl
(
query
))
kw
,
unused
=
self
.
interpret_kwargs
(
kw
)
kw
,
unused
=
self
.
interpret_kwargs
(
kw
)
demostorage
=
False
demostorage
=
False
...
@@ -127,10 +128,10 @@ class ClientStorageURIResolver(Resolver):
...
@@ -127,10 +128,10 @@ class ClientStorageURIResolver(Resolver):
_bytesize_args
=
(
'cache_size'
,
)
_bytesize_args
=
(
'cache_size'
,
)
def
__call__
(
self
,
uri
):
def
__call__
(
self
,
uri
):
# url
parse
doesnt understand zeo URLs so force to something that
# url
split
doesnt understand zeo URLs so force to something that
# doesn't break
# doesn't break
uri
=
uri
.
replace
(
'zeo://'
,
'http://'
,
1
)
uri
=
uri
.
replace
(
'zeo://'
,
'http://'
,
1
)
(
scheme
,
netloc
,
path
,
query
,
frag
)
=
url
parse
.
url
split
(
uri
)
(
scheme
,
netloc
,
path
,
query
,
frag
)
=
urlsplit
(
uri
)
if
netloc
:
if
netloc
:
# TCP URL
# TCP URL
if
':'
in
netloc
:
if
':'
in
netloc
:
...
@@ -144,7 +145,7 @@ class ClientStorageURIResolver(Resolver):
...
@@ -144,7 +145,7 @@ class ClientStorageURIResolver(Resolver):
# Unix domain socket URL
# Unix domain socket URL
path
=
os
.
path
.
normpath
(
path
)
path
=
os
.
path
.
normpath
(
path
)
args
=
(
path
,)
args
=
(
path
,)
kw
=
dict
(
cgi
.
parse_qsl
(
query
))
kw
=
dict
(
parse_qsl
(
query
))
kw
,
unused
=
self
.
interpret_kwargs
(
kw
)
kw
,
unused
=
self
.
interpret_kwargs
(
kw
)
if
'demostorage'
in
kw
:
if
'demostorage'
in
kw
:
kw
.
pop
(
'demostorage'
)
kw
.
pop
(
'demostorage'
)
...
@@ -158,7 +159,7 @@ class ClientStorageURIResolver(Resolver):
...
@@ -158,7 +159,7 @@ class ClientStorageURIResolver(Resolver):
class
ZConfigURIResolver
(
object
):
class
ZConfigURIResolver
(
object
):
schema_xml_template
=
"""
schema_xml_template
=
b
"""
<schema>
<schema>
<import package="ZODB"/>
<import package="ZODB"/>
<multisection type="ZODB.storage" attribute="storages" />
<multisection type="ZODB.storage" attribute="storages" />
...
@@ -167,16 +168,16 @@ class ZConfigURIResolver(object):
...
@@ -167,16 +168,16 @@ class ZConfigURIResolver(object):
"""
"""
def
__call__
(
self
,
uri
):
def
__call__
(
self
,
uri
):
(
scheme
,
netloc
,
path
,
query
,
frag
)
=
url
parse
.
url
split
(
uri
)
(
scheme
,
netloc
,
path
,
query
,
frag
)
=
urlsplit
(
uri
)
if
sys
.
version_info
[:
3
]
<
(
2
,
7
,
4
):
#pragma NO COVER
if
sys
.
version_info
[:
3
]
<
(
2
,
7
,
4
):
#pragma NO COVER
# url
parse
used not to allow fragments in non-standard schemes,
# url
split
used not to allow fragments in non-standard schemes,
# stuffed everything into 'path'
# stuffed everything into 'path'
(
scheme
,
netloc
,
path
,
query
,
frag
(
scheme
,
netloc
,
path
,
query
,
frag
)
=
url
parse
.
url
split
(
'http:'
+
path
)
)
=
urlsplit
(
'http:'
+
path
)
path
=
os
.
path
.
normpath
(
path
)
path
=
os
.
path
.
normpath
(
path
)
schema_xml
=
self
.
schema_xml_template
schema_xml
=
self
.
schema_xml_template
schema
=
ZConfig
.
loadSchemaFile
(
String
IO
(
schema_xml
))
schema
=
loadSchemaFile
(
Bytes
IO
(
schema_xml
))
config
,
handler
=
ZConfig
.
loadConfig
(
schema
,
path
)
config
,
handler
=
loadConfig
(
schema
,
path
)
for
config_item
in
config
.
databases
+
config
.
storages
:
for
config_item
in
config
.
databases
+
config
.
storages
:
if
not
frag
:
if
not
frag
:
# use the first defined in the file
# use the first defined in the file
...
@@ -198,7 +199,7 @@ class ZConfigURIResolver(object):
...
@@ -198,7 +199,7 @@ class ZConfigURIResolver(object):
dbkw
[
'database_name'
]
=
config
.
database_name
dbkw
[
'database_name'
]
=
config
.
database_name
else
:
else
:
factory
=
config_item
factory
=
config_item
dbkw
=
dict
(
cgi
.
parse_qsl
(
query
))
dbkw
=
dict
(
parse_qsl
(
query
))
return
factory
.
open
,
dbkw
return
factory
.
open
,
dbkw
...
...
zodburi/tests/test_resolvers.py
View file @
3f7bfa1e
...
@@ -27,8 +27,7 @@ class Base:
...
@@ -27,8 +27,7 @@ class Base:
for
name
in
names
:
for
name
in
names
:
kwargs
[
name
]
=
'10'
kwargs
[
name
]
=
'10'
args
=
resolver
.
interpret_kwargs
(
kwargs
)[
0
]
args
=
resolver
.
interpret_kwargs
(
kwargs
)[
0
]
keys
=
args
.
keys
()
keys
=
sorted
(
args
.
keys
())
keys
.
sort
()
self
.
assertEqual
(
sorted
(
keys
),
sorted
(
names
))
self
.
assertEqual
(
sorted
(
keys
),
sorted
(
names
))
for
name
,
value
in
args
.
items
():
for
name
,
value
in
args
.
items
():
self
.
assertEqual
(
value
,
10
)
self
.
assertEqual
(
value
,
10
)
...
@@ -160,8 +159,8 @@ class TestFileStorageURIResolver(Base, unittest.TestCase):
...
@@ -160,8 +159,8 @@ class TestFileStorageURIResolver(Base, unittest.TestCase):
def
test_invoke_factory_blobstorage
(
self
):
def
test_invoke_factory_blobstorage
(
self
):
import
os
import
os
from
urllib
import
quote
as
q
from
ZODB.blob
import
BlobStorage
from
ZODB.blob
import
BlobStorage
from
.._compat
import
quote
as
q
DB_FILE
=
os
.
path
.
join
(
self
.
tmpdir
,
'db.db'
)
DB_FILE
=
os
.
path
.
join
(
self
.
tmpdir
,
'db.db'
)
BLOB_DIR
=
os
.
path
.
join
(
self
.
tmpdir
,
'blob'
)
BLOB_DIR
=
os
.
path
.
join
(
self
.
tmpdir
,
'blob'
)
self
.
assertFalse
(
os
.
path
.
exists
(
DB_FILE
))
self
.
assertFalse
(
os
.
path
.
exists
(
DB_FILE
))
...
@@ -177,8 +176,8 @@ class TestFileStorageURIResolver(Base, unittest.TestCase):
...
@@ -177,8 +176,8 @@ class TestFileStorageURIResolver(Base, unittest.TestCase):
def
test_invoke_factory_blobstorage_and_demostorage
(
self
):
def
test_invoke_factory_blobstorage_and_demostorage
(
self
):
import
os
import
os
from
urllib
import
quote
as
q
from
ZODB.DemoStorage
import
DemoStorage
from
ZODB.DemoStorage
import
DemoStorage
from
.._compat
import
quote
as
q
DB_FILE
=
os
.
path
.
join
(
self
.
tmpdir
,
'db.db'
)
DB_FILE
=
os
.
path
.
join
(
self
.
tmpdir
,
'db.db'
)
BLOB_DIR
=
os
.
path
.
join
(
self
.
tmpdir
,
'blob'
)
BLOB_DIR
=
os
.
path
.
join
(
self
.
tmpdir
,
'blob'
)
self
.
assertFalse
(
os
.
path
.
exists
(
DB_FILE
))
self
.
assertFalse
(
os
.
path
.
exists
(
DB_FILE
))
...
@@ -290,7 +289,7 @@ class TestZConfigURIResolver(unittest.TestCase):
...
@@ -290,7 +289,7 @@ class TestZConfigURIResolver(unittest.TestCase):
self
.
tmp
.
close
()
self
.
tmp
.
close
()
def
test_named_storage
(
self
):
def
test_named_storage
(
self
):
self
.
tmp
.
write
(
"""
self
.
tmp
.
write
(
b
"""
<demostorage foo>
<demostorage foo>
</demostorage>
</demostorage>
...
@@ -305,7 +304,7 @@ class TestZConfigURIResolver(unittest.TestCase):
...
@@ -305,7 +304,7 @@ class TestZConfigURIResolver(unittest.TestCase):
self
.
assertTrue
(
isinstance
(
storage
,
MappingStorage
),
storage
)
self
.
assertTrue
(
isinstance
(
storage
,
MappingStorage
),
storage
)
def
test_anonymous_storage
(
self
):
def
test_anonymous_storage
(
self
):
self
.
tmp
.
write
(
"""
self
.
tmp
.
write
(
b
"""
<mappingstorage>
<mappingstorage>
</mappingstorage>
</mappingstorage>
...
@@ -321,7 +320,7 @@ class TestZConfigURIResolver(unittest.TestCase):
...
@@ -321,7 +320,7 @@ class TestZConfigURIResolver(unittest.TestCase):
self
.
assertEqual
(
dbkw
,
{})
self
.
assertEqual
(
dbkw
,
{})
def
test_query_string_args
(
self
):
def
test_query_string_args
(
self
):
self
.
tmp
.
write
(
"""
self
.
tmp
.
write
(
b
"""
<mappingstorage>
<mappingstorage>
</mappingstorage>
</mappingstorage>
...
@@ -334,7 +333,7 @@ class TestZConfigURIResolver(unittest.TestCase):
...
@@ -334,7 +333,7 @@ class TestZConfigURIResolver(unittest.TestCase):
self
.
assertEqual
(
dbkw
,
{
'foo'
:
'bar'
})
self
.
assertEqual
(
dbkw
,
{
'foo'
:
'bar'
})
def
test_storage_not_found
(
self
):
def
test_storage_not_found
(
self
):
self
.
tmp
.
write
(
"""
self
.
tmp
.
write
(
b
"""
<mappingstorage x>
<mappingstorage x>
</mappingstorage>
</mappingstorage>
"""
)
"""
)
...
@@ -343,7 +342,7 @@ class TestZConfigURIResolver(unittest.TestCase):
...
@@ -343,7 +342,7 @@ class TestZConfigURIResolver(unittest.TestCase):
self
.
assertRaises
(
KeyError
,
resolver
,
'zconfig://%s#y'
%
self
.
tmp
.
name
)
self
.
assertRaises
(
KeyError
,
resolver
,
'zconfig://%s#y'
%
self
.
tmp
.
name
)
def
test_anonymous_database
(
self
):
def
test_anonymous_database
(
self
):
self
.
tmp
.
write
(
"""
self
.
tmp
.
write
(
b
"""
<zodb>
<zodb>
<mappingstorage>
<mappingstorage>
</mappingstorage>
</mappingstorage>
...
@@ -360,7 +359,7 @@ class TestZConfigURIResolver(unittest.TestCase):
...
@@ -360,7 +359,7 @@ class TestZConfigURIResolver(unittest.TestCase):
'connection_pool_size'
:
7
})
'connection_pool_size'
:
7
})
def
test_named_database
(
self
):
def
test_named_database
(
self
):
self
.
tmp
.
write
(
"""
self
.
tmp
.
write
(
b
"""
<zodb x>
<zodb x>
<mappingstorage>
<mappingstorage>
</mappingstorage>
</mappingstorage>
...
...
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