If a connection is destroyed before an async operation is completed, the
`async_cursor` member creates a reference loop, leaving the connection and
the cursor alive. `async_cursor` is now a weak reference.
Don't know why I changed the defaultTest argument into a function when I
converted the test suite into a package: that argument should be really
a string.
Added an adapter for None: it is usually not invoked as adaptation to
NULL is a fast path in mogrify, but can be invoked by composite types.
Notice that composite types still have the option to fast-path None
(e.g. list adapter does).
Dropped cyclic import from modules to tests: they were only working
because a second copy of the package was found in the project dir.
Use relative import so that 2to3 can do a good conversion.
We mangle the encoding names a little bit before asking it to the
backend: be sure to be able to find the equivalent Python code back or
decoding (unicode cast or Py3) will barf.
Explicit comparison with the tuple is required if we want to make
Notify() == (pid, channel) work: item access is not enough (and a test
in the suite fails if we get this wrong).
We don't do somersaults to ensure people can use snowmen as transaction
ids anyway: it would require passing the connection to xid_ensure and
down below to use the correct encoding.
Allow the objects to be recognized as the proper type by Postgres in not
strong contexts: problem reported by Peter Eisentraut.
Added tests to check the types are respected in a complete Py -> PG ->
Py roundtrip without context.
Don't rely on Postgres casting the literal according to the context:
this doesn't work e.g. passing the object as function argument where a
function with the same name but taking a text exists. It doesn't work
either when the object is in an ARRAY construct.
Added test to check the type is respected in a complete Py -> PG -> Py
roundtrip without context.
Bug and solution reported by Peter Eisentraut.
With the current implementation, at best they would silently block. They
actually hang everything.
Implementation posponed after some refactoring of the polling system,
because it will be probably possible to provide an implementation for
'poll()' during COPY which is good for both async and green modes.
If the connection is sync, notices will be processed by pq_fetch()
downstream.
If the connection is async, here we have only sent the query: no result
is ready yet, and neither notices have had a chance to arrive: they will
be retrieved later by pq_is_busy().
Added tests to check the above statement don't break.
Instead, the code should be using the fileno() and poll() methods of
the cursor's connection. Handle the case when poll() is called on an
already built connection as a request to poll the asynchronous query
(if there is one) and get NOTIFY events.
Update the tests to reflect that change, add a test for NOTIFY.
Do it by keeping the reference to the last PGresult in the cursor and
calling pq_fetch() before ending the asynchronous execution. This
takes care of handling the possible error state of the PGresult and
also allows the removal of the needsfetch flag, since now after
execution ends the results are already fetched and parsed.
This hides from the user the libpq's implementation detail of
requiring the first select() to wait for the connection socket to
become writable and makes it possible to have a uniform select loop
for both cursors and connections, in which you always start by polling
the object and then acting according to the result from poll().
Idea and implementation by Daniele Varrazzo.
If there is an asynchronous query, polling a cursor that did not
initiate it will raise an exception. Polling while there is no
asynchronous query underway still works, because the user needs to
have a way to get asynchronous NOTIFYs.
When a large query is sent to the backend (and probably in high
concurrency situations), writing the query could block. In
this case PQflush() should be called until it returns 0. The test checks
this is done correctly.
Some methods were forbidden in asynchronous mode, the isolation level
of an asynchronous connection is not always 0 and these changes
influenced expected test results.
The lobject.truncate(len=0) method will be available if psycopg2 has
been built against libpq from 8.3 or later (which is when the lobject
truncating support has been introduced).
coverage for datetime and time strings with and without time zone
information.
* psycopg/typecast_datetime.c (typecast_PYDATETIME_cast): adjust
to handle the changes in typecast_parse_time.
(typecast_PYTIME_cast): add support for time zone aware time
values.
* psycopg/typecast_mxdatetime.c (typecast_MXDATE_cast): make sure
that values with time zones are correctly processed (even though
that means ignoring the time zone value).
(typecast_MXTIME_cast): same here.
* psycopg/typecast.c (typecast_parse_time): Update method to parse
second resolution timezone offsets.
negative timezone offsets with a non-zero minutes field.
* tests/test_dates.py (DatetimeTests): Add tests for time zone
parsing. The test for HH:MM:SS time zones is disabled because we
don't currently support it.
Currently the second fails for negative offsets due to bugs in the
parser, and the third fails because it doesn't even try to parse second
offset values (as Python doesn't either).
including behaviour on closed lobjects and stale lobjects.
* psycopg/lobject_type.c (psyco_lobj_close): don't mark the
connection closed here because it is done by
lobject_close_locked().
* psycopg/lobject_int.c (lobject_open): mark objects as not closed
if we successfully open them.
(lobject_close_locked): mark the lobject closed here.
(lobject_export): ensure we are in a transaction, since
lo_export() issues multiple queries.
* psycopg/lobject_type.c (lobject_setup): make lobjects start closed.
* tests/*.py: use the DSN constructed in tests/__init__.py.
* tests/__init__.py: allow setting the host, port and user for the
DSN used by the tests through the environment.
return value for partially parsed time values.
* psycopg/typecast_mxdatetime.c (typecast_MXDATE_cast): return
NULL after setting DataError. Also, don't treat it as an error if
typecast_parse_time() returns 0 (as might happen if the remainder
of the string is " BC").
* psycopg/typecast_datetime.c (typecast_PYDATE_cast): return NULL
after setting DataError.
(typecast_PYDATETIME_cast): same here.
(typecast_PYTIME_cast): same here.
* tests/test_dates.py
(CommonDatetimeTestsMixin.test_parse_incomplete_date): test that
parsing incomplete date values results in DataError.
(CommonDatetimeTestsMixin.test_parse_incomplete_time): same for
times.
(CommonDatetimeTestsMixin.test_parse_incomplete_time): same for
datetimes.
the Connection and Cursor "closed" attributes.
* psycopg/cursor_type.c (psyco_curs_get_closed): add a "closed"
attribute to cursors. It will be True if either the cursor or its
associated connection are closed. This fixes bug #164.