mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-14 04:56:33 +03:00
Merge branch 'python2' into python3
Conflicts: ChangeLog NEWS-2.3 lib/extensions.py psycopg/microprotocols.c setup.py
This commit is contained in:
commit
3e94375cf7
|
@ -3,6 +3,12 @@
|
||||||
* connection.h: added codec attribute to avoid repeated codec name
|
* connection.h: added codec attribute to avoid repeated codec name
|
||||||
lookups during unicode query/params manipulations.
|
lookups during unicode query/params manipulations.
|
||||||
|
|
||||||
|
* setup.py: bumped to version 2.3.2.dev0
|
||||||
|
|
||||||
|
* psycopg/connection_int.c: applied patch from Marti Raudsepp to close
|
||||||
|
ticket #24. Fixed segfault in connection when DateStyle not available
|
||||||
|
(e.g. pgbouncer appars not passing it to the client)
|
||||||
|
|
||||||
2010-12-15 Daniele Varrazzo <daniele.varrazzo@gmail.com>
|
2010-12-15 Daniele Varrazzo <daniele.varrazzo@gmail.com>
|
||||||
|
|
||||||
* psycopg/utils.c: Added psycopg_strdup function.
|
* psycopg/utils.c: Added psycopg_strdup function.
|
||||||
|
|
5
Makefile
5
Makefile
|
@ -62,6 +62,9 @@ docs-html: doc/html/genindex.html
|
||||||
|
|
||||||
docs-txt: doc/psycopg2.txt
|
docs-txt: doc/psycopg2.txt
|
||||||
|
|
||||||
|
# for PyPI documentation
|
||||||
|
docs-zip: doc/docs.zip
|
||||||
|
|
||||||
sdist: $(SDIST)
|
sdist: $(SDIST)
|
||||||
|
|
||||||
# The environment is currently required to build the documentation.
|
# The environment is currently required to build the documentation.
|
||||||
|
@ -119,6 +122,8 @@ doc/html/genindex.html: $(PLATLIB) $(PURELIB) $(SOURCE_DOC)
|
||||||
doc/psycopg2.txt: $(PLATLIB) $(PURELIB) $(SOURCE_DOC)
|
doc/psycopg2.txt: $(PLATLIB) $(PURELIB) $(SOURCE_DOC)
|
||||||
PYTHONPATH=$(ENV_LIB):$(BUILD_DIR) $(MAKE) SPHINXBUILD=$(ENV_BIN)/sphinx-build -C doc text
|
PYTHONPATH=$(ENV_LIB):$(BUILD_DIR) $(MAKE) SPHINXBUILD=$(ENV_BIN)/sphinx-build -C doc text
|
||||||
|
|
||||||
|
doc/docs.zip: doc/html/genindex.html
|
||||||
|
(cd doc/html && zip -r ../docs.zip *)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf build MANIFEST
|
rm -rf build MANIFEST
|
||||||
|
|
16
NEWS-2.3
16
NEWS-2.3
|
@ -1,12 +1,26 @@
|
||||||
What's new in psycopg 2.3.2
|
What's new in psycopg 2.3.3
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
* Changes:
|
||||||
|
|
||||||
- Improved PostgreSQL-Python encodings mapping. Added a few
|
- Improved PostgreSQL-Python encodings mapping. Added a few
|
||||||
missing encodings: EUC_CN, EUC_JIS_2004, ISO885910, ISO885916,
|
missing encodings: EUC_CN, EUC_JIS_2004, ISO885910, ISO885916,
|
||||||
LATIN10, SHIFT_JIS_2004.
|
LATIN10, SHIFT_JIS_2004.
|
||||||
- Dropped repeated dictionary lookups with unicode query/parameters.
|
- Dropped repeated dictionary lookups with unicode query/parameters.
|
||||||
- Empty lists correctly roundtrip Python -> PostgreSQL -> Python.
|
- Empty lists correctly roundtrip Python -> PostgreSQL -> Python.
|
||||||
|
|
||||||
|
* Bug fixes
|
||||||
|
|
||||||
|
- Fixed adaptation of None in composite types (ticket #26). Bug report by
|
||||||
|
Karsten Hilbert.
|
||||||
|
|
||||||
|
|
||||||
|
What's new in psycopg 2.3.2
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- Fixed segfault with middleware not passing DateStyle to the client
|
||||||
|
(ticket #24). Bug report and patch by Marti Raudsepp.
|
||||||
|
|
||||||
|
|
||||||
What's new in psycopg 2.3.1
|
What's new in psycopg 2.3.1
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
# their work without bothering about the module dependencies.
|
# their work without bothering about the module dependencies.
|
||||||
|
|
||||||
|
|
||||||
ALLOWED_PSYCOPG_VERSIONS = ('2.3.0','2.3.1')
|
ALLOWED_PSYCOPG_VERSIONS = ('2.3.0','2.3.1','2.3.2')
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
|
@ -82,6 +82,7 @@ from _psycopg import __version__
|
||||||
|
|
||||||
import psycopg2.extensions as _ext
|
import psycopg2.extensions as _ext
|
||||||
_ext.register_adapter(tuple, _ext.SQL_IN)
|
_ext.register_adapter(tuple, _ext.SQL_IN)
|
||||||
|
_ext.register_adapter(type(None), _ext.NoneAdapter)
|
||||||
|
|
||||||
__all__ = filter(lambda k: not k.startswith('_'), locals().keys())
|
__all__ = filter(lambda k: not k.startswith('_'), locals().keys())
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,19 @@ class SQL_IN(object):
|
||||||
__str__ = getquoted
|
__str__ = getquoted
|
||||||
|
|
||||||
|
|
||||||
|
class NoneAdapter(object):
|
||||||
|
"""Adapt None to NULL.
|
||||||
|
|
||||||
|
This adapter is not used normally as a fast path in mogrify uses NULL,
|
||||||
|
but it makes easier to adapt composite types.
|
||||||
|
"""
|
||||||
|
def __init__(self, obj):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def getquoted(self):
|
||||||
|
return "NULL"
|
||||||
|
|
||||||
|
|
||||||
# Add the "cleaned" version of the encodings to the key.
|
# Add the "cleaned" version of the encodings to the key.
|
||||||
# When the encoding is set its name is cleaned up from - and _ and turned
|
# When the encoding is set its name is cleaned up from - and _ and turned
|
||||||
# uppercase, so an encoding not respecting these rules wouldn't be found in the
|
# uppercase, so an encoding not respecting these rules wouldn't be found in the
|
||||||
|
@ -146,4 +159,5 @@ for k, v in encodings.items():
|
||||||
k = k.replace('_', '').replace('-', '').upper()
|
k = k.replace('_', '').replace('-', '').upper()
|
||||||
encodings[k] = v
|
encodings[k] = v
|
||||||
|
|
||||||
|
|
||||||
__all__ = filter(lambda k: not k.startswith('_'), locals().keys())
|
__all__ = filter(lambda k: not k.startswith('_'), locals().keys())
|
||||||
|
|
|
@ -373,6 +373,10 @@ conn_is_datestyle_ok(PGconn *pgconn)
|
||||||
ds = PQparameterStatus(pgconn, "DateStyle");
|
ds = PQparameterStatus(pgconn, "DateStyle");
|
||||||
Dprintf("conn_connect: DateStyle %s", ds);
|
Dprintf("conn_connect: DateStyle %s", ds);
|
||||||
|
|
||||||
|
/* pgbouncer does not pass on DateStyle */
|
||||||
|
if (ds == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Return true if ds starts with "ISO"
|
/* Return true if ds starts with "ISO"
|
||||||
* e.g. "ISO, DMY" is fine, "German" not. */
|
* e.g. "ISO, DMY" is fine, "German" not. */
|
||||||
return (ds[0] == 'I' && ds[1] == 'S' && ds[2] == 'O');
|
return (ds[0] == 'I' && ds[1] == 'S' && ds[2] == 'O');
|
||||||
|
|
|
@ -135,11 +135,6 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
|
||||||
because the ISQLQuote type is abstract and there is no way to get a
|
because the ISQLQuote type is abstract and there is no way to get a
|
||||||
quotable object to be its instance */
|
quotable object to be its instance */
|
||||||
|
|
||||||
/* None is always adapted to NULL */
|
|
||||||
|
|
||||||
if (obj == Py_None)
|
|
||||||
return Bytes_FromString("NULL");
|
|
||||||
|
|
||||||
Dprintf("microprotocols_adapt: trying to adapt %s",
|
Dprintf("microprotocols_adapt: trying to adapt %s",
|
||||||
Py_TYPE(obj)->tp_name);
|
Py_TYPE(obj)->tp_name);
|
||||||
|
|
||||||
|
|
6
setup.py
6
setup.py
|
@ -66,7 +66,7 @@ except ImportError:
|
||||||
# Take a look at http://www.python.org/dev/peps/pep-0386/
|
# Take a look at http://www.python.org/dev/peps/pep-0386/
|
||||||
# for a consistent versioning pattern.
|
# for a consistent versioning pattern.
|
||||||
|
|
||||||
PSYCOPG_VERSION = '2.3.2.dev0'
|
PSYCOPG_VERSION = '2.3.3.dev0'
|
||||||
|
|
||||||
version_flags = ['dt', 'dec']
|
version_flags = ['dt', 'dec']
|
||||||
|
|
||||||
|
@ -471,8 +471,8 @@ setup(name="psycopg2",
|
||||||
maintainer_email="fog@initd.org",
|
maintainer_email="fog@initd.org",
|
||||||
author="Federico Di Gregorio",
|
author="Federico Di Gregorio",
|
||||||
author_email="fog@initd.org",
|
author_email="fog@initd.org",
|
||||||
url="http://initd.org/tracker/psycopg",
|
url="http://initd.org/psycopg/",
|
||||||
download_url = "http://initd.org/pub/software/psycopg2",
|
download_url = "http://initd.org/psycopg/download/",
|
||||||
license="GPL with exceptions or ZPL",
|
license="GPL with exceptions or ZPL",
|
||||||
platforms = ["any"],
|
platforms = ["any"],
|
||||||
description=__doc__.split("\n")[0],
|
description=__doc__.split("\n")[0],
|
||||||
|
|
|
@ -35,7 +35,7 @@ class CancelTests(unittest.TestCase):
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
try:
|
try:
|
||||||
self.assertRaises(psycopg2.extensions.QueryCanceledError,
|
self.assertRaises(psycopg2.extensions.QueryCanceledError,
|
||||||
cur.execute, "select pg_sleep(10000)")
|
cur.execute, "select pg_sleep(60)")
|
||||||
# make sure the connection still works
|
# make sure the connection still works
|
||||||
conn.rollback()
|
conn.rollback()
|
||||||
cur.execute("select 1")
|
cur.execute("select 1")
|
||||||
|
|
|
@ -354,6 +354,42 @@ class HstoreTestCase(unittest.TestCase):
|
||||||
ok(dict(zip(ab, ab)))
|
ok(dict(zip(ab, ab)))
|
||||||
|
|
||||||
|
|
||||||
|
class AdaptTypeTestCase(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.conn = psycopg2.connect(tests.dsn)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.conn.close()
|
||||||
|
|
||||||
|
def test_none_in_record(self):
|
||||||
|
curs = self.conn.cursor()
|
||||||
|
s = curs.mogrify("SELECT %s;", [(42, None)])
|
||||||
|
self.assertEqual("SELECT (42, NULL);", s)
|
||||||
|
curs.execute("SELECT %s;", [(42, None)])
|
||||||
|
d = curs.fetchone()[0]
|
||||||
|
self.assertEqual("(42,)", d)
|
||||||
|
|
||||||
|
def test_none_fast_path(self):
|
||||||
|
# the None adapter is not actually invoked in regular adaptation
|
||||||
|
ext = psycopg2.extensions
|
||||||
|
|
||||||
|
class WonkyAdapter(object):
|
||||||
|
def __init__(self, obj): pass
|
||||||
|
def getquoted(self): return "NOPE!"
|
||||||
|
|
||||||
|
curs = self.conn.cursor()
|
||||||
|
|
||||||
|
orig_adapter = ext.adapters[type(None), ext.ISQLQuote]
|
||||||
|
try:
|
||||||
|
ext.register_adapter(type(None), WonkyAdapter)
|
||||||
|
self.assertEqual(ext.adapt(None).getquoted(), "NOPE!")
|
||||||
|
|
||||||
|
s = curs.mogrify("SELECT %s;", (None,))
|
||||||
|
self.assertEqual("SELECT NULL;", s)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
ext.register_adapter(type(None), orig_adapter)
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user