updated pg8000 imports
This commit is contained in:
@@ -38,7 +38,7 @@ for fmt in (
|
||||
|
||||
import datetime
|
||||
import time
|
||||
from pg8000.six import binary_type, integer_types, PY2
|
||||
from .six import binary_type, integer_types, PY2
|
||||
|
||||
min_int2, max_int2 = -2 ** 15, 2 ** 15
|
||||
min_int4, max_int4 = -2 ** 31, 2 ** 31
|
||||
@@ -274,7 +274,7 @@ class Interval(object):
|
||||
def __neq__(self, other):
|
||||
return not self.__eq__(other)
|
||||
|
||||
import pg8000.core
|
||||
from .core import Connection
|
||||
|
||||
|
||||
def connect(
|
||||
@@ -291,6 +291,10 @@ def connect(
|
||||
provided, pg8000 looks first for the PGUSER then the USER environment
|
||||
variables.
|
||||
|
||||
If your server character encoding is not ``ascii`` or ``utf8``, then
|
||||
you need to provide ``user`` as bytes, eg.
|
||||
``"my_name".encode('EUC-JP')``.
|
||||
|
||||
:keyword host:
|
||||
The hostname of the PostgreSQL server to connect with. Providing this
|
||||
parameter is necessary for TCP/IP connections. One of either ``host``
|
||||
@@ -311,6 +315,10 @@ def connect(
|
||||
optional; if omitted, the PostgreSQL server will assume the database
|
||||
name is the same as the username.
|
||||
|
||||
If your server character encoding is not ``ascii`` or ``utf8``, then
|
||||
you need to provide ``database`` as bytes, eg.
|
||||
``"my_db".encode('EUC-JP')``.
|
||||
|
||||
:keyword password:
|
||||
The user password to connect to the server with. This parameter is
|
||||
optional; if omitted and the database server requests password-based
|
||||
@@ -324,7 +332,7 @@ def connect(
|
||||
:rtype:
|
||||
A :class:`Connection` object.
|
||||
"""
|
||||
return pg8000.core.Connection(
|
||||
return Connection(
|
||||
user, host, unix_sock, port, database, password, ssl)
|
||||
|
||||
apilevel = "2.0"
|
||||
@@ -472,7 +480,7 @@ def Binary(value):
|
||||
return value
|
||||
|
||||
|
||||
from pg8000.core import utc, Connection, Cursor
|
||||
from .core import utc, Cursor
|
||||
|
||||
__all__ = [
|
||||
Warning, Bytea, DataError, DatabaseError, connect, InterfaceError,
|
||||
@@ -481,10 +489,11 @@ __all__ = [
|
||||
ArrayDimensionsNotConsistentError, ArrayContentNotSupportedError, utc,
|
||||
Connection, Cursor]
|
||||
|
||||
from ._version import get_versions
|
||||
__version__ = get_versions()['version']
|
||||
"""Version string for pg8000.
|
||||
|
||||
.. versionadded:: 1.9.11
|
||||
"""
|
||||
|
||||
from ._version import get_versions
|
||||
__version__ = get_versions()['version']
|
||||
del get_versions
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
|
||||
# This file helps to compute a version number in source trees obtained from
|
||||
# git-archive tarball (such as those provided by githubs download-from-tag
|
||||
# feature). Distribution tarballs (build by setup.py sdist) and build
|
||||
# feature). Distribution tarballs (built by setup.py sdist) and build
|
||||
# directories (produced by setup.py build) will contain a much shorter file
|
||||
# that just contains the computed version number.
|
||||
|
||||
# This file is released into the public domain. Generated by
|
||||
# versioneer-0.10 (https://github.com/warner/python-versioneer)
|
||||
# versioneer-0.12 (https://github.com/warner/python-versioneer)
|
||||
|
||||
# these strings will be replaced by git during git-archive
|
||||
git_refnames = "$Format:%d$"
|
||||
git_full = "$Format:%H$"
|
||||
|
||||
# these strings are filled in when 'setup.py versioneer' creates _version.py
|
||||
tag_prefix = ""
|
||||
parentdir_prefix = "pg8000-"
|
||||
versionfile_source = "pg8000/_version.py"
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import subprocess
|
||||
import errno
|
||||
|
||||
|
||||
@@ -50,38 +56,49 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False):
|
||||
return stdout
|
||||
|
||||
|
||||
import re
|
||||
import os.path
|
||||
def versions_from_parentdir(parentdir_prefix, root, verbose=False):
|
||||
# Source tarballs conventionally unpack into a directory that includes
|
||||
# both the project name and a version string.
|
||||
dirname = os.path.basename(root)
|
||||
if not dirname.startswith(parentdir_prefix):
|
||||
if verbose:
|
||||
print(
|
||||
"guessing rootdir is '%s', but '%s' doesn't start with "
|
||||
"prefix '%s'" % (root, dirname, parentdir_prefix))
|
||||
return None
|
||||
return {"version": dirname[len(parentdir_prefix):], "full": ""}
|
||||
|
||||
|
||||
def get_expanded_variables(versionfile_abs):
|
||||
def git_get_keywords(versionfile_abs):
|
||||
# the code embedded in _version.py can just fetch the value of these
|
||||
# variables. When used from setup.py, we don't want to import
|
||||
# _version.py, so we do it with a regexp instead. This function is not
|
||||
# used from _version.py.
|
||||
variables = {}
|
||||
# keywords. When used from setup.py, we don't want to import _version.py,
|
||||
# so we do it with a regexp instead. This function is not used from
|
||||
# _version.py.
|
||||
keywords = {}
|
||||
try:
|
||||
f = open(versionfile_abs, "r")
|
||||
for line in f.readlines():
|
||||
if line.strip().startswith("git_refnames ="):
|
||||
mo = re.search(r'=\s*"(.*)"', line)
|
||||
if mo:
|
||||
variables["refnames"] = mo.group(1)
|
||||
keywords["refnames"] = mo.group(1)
|
||||
if line.strip().startswith("git_full ="):
|
||||
mo = re.search(r'=\s*"(.*)"', line)
|
||||
if mo:
|
||||
variables["full"] = mo.group(1)
|
||||
keywords["full"] = mo.group(1)
|
||||
f.close()
|
||||
except EnvironmentError:
|
||||
pass
|
||||
return variables
|
||||
return keywords
|
||||
|
||||
|
||||
def versions_from_expanded_variables(variables, tag_prefix, verbose=False):
|
||||
refnames = variables["refnames"].strip()
|
||||
def git_versions_from_keywords(keywords, tag_prefix, verbose=False):
|
||||
if not keywords:
|
||||
return {} # keyword-finding function failed to find keywords
|
||||
refnames = keywords["refnames"].strip()
|
||||
if refnames.startswith("$Format"):
|
||||
if verbose:
|
||||
print("variables are unexpanded, not using")
|
||||
print("keywords are unexpanded, not using")
|
||||
return {} # unexpanded, so not in an unpacked git-archive tarball
|
||||
refs = set([r.strip() for r in refnames.strip("()").split(",")])
|
||||
# starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
|
||||
@@ -107,18 +124,20 @@ def versions_from_expanded_variables(variables, tag_prefix, verbose=False):
|
||||
r = ref[len(tag_prefix):]
|
||||
if verbose:
|
||||
print("picking %s" % r)
|
||||
return {"version": r, "full": variables["full"].strip()}
|
||||
return {
|
||||
"version": r,
|
||||
"full": keywords["full"].strip()}
|
||||
# no suitable tags, so we use the full revision id
|
||||
if verbose:
|
||||
print("no suitable tags, using full revision id")
|
||||
return {
|
||||
"version": variables["full"].strip(),
|
||||
"full": variables["full"].strip()}
|
||||
"version": keywords["full"].strip(),
|
||||
"full": keywords["full"].strip()}
|
||||
|
||||
|
||||
def versions_from_vcs(tag_prefix, root, verbose=False):
|
||||
def git_versions_from_vcs(tag_prefix, root, verbose=False):
|
||||
# this runs 'git' from the root of the source tree. This only gets called
|
||||
# if the git-archive 'subst' variables were *not* expanded, and
|
||||
# if the git-archive 'subst' keywords were *not* expanded, and
|
||||
# _version.py hasn't already been rewritten with a short version string,
|
||||
# meaning we're inside a checked out source tree.
|
||||
|
||||
@@ -150,31 +169,14 @@ def versions_from_vcs(tag_prefix, root, verbose=False):
|
||||
return {"version": tag, "full": full}
|
||||
|
||||
|
||||
def versions_from_parentdir(parentdir_prefix, root, verbose=False):
|
||||
# Source tarballs conventionally unpack into a directory that includes
|
||||
# both the project name and a version string.
|
||||
dirname = os.path.basename(root)
|
||||
if not dirname.startswith(parentdir_prefix):
|
||||
if verbose:
|
||||
print(
|
||||
"guessing rootdir is '%s', but '%s' doesn't start with prefix "
|
||||
"'%s'" % (root, dirname, parentdir_prefix))
|
||||
return None
|
||||
return {"version": dirname[len(parentdir_prefix):], "full": ""}
|
||||
|
||||
tag_prefix = ""
|
||||
parentdir_prefix = "pg8000-"
|
||||
versionfile_source = "pg8000/_version.py"
|
||||
|
||||
|
||||
def get_versions(default={"version": "unknown", "full": ""}, verbose=False):
|
||||
# I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
|
||||
# __file__, we can work backwards from there to the root. Some
|
||||
# py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
|
||||
# case we can only use expanded variables.
|
||||
# case we can only use expanded keywords.
|
||||
|
||||
variables = {"refnames": git_refnames, "full": git_full}
|
||||
ver = versions_from_expanded_variables(variables, tag_prefix, verbose)
|
||||
keywords = {"refnames": git_refnames, "full": git_full}
|
||||
ver = git_versions_from_keywords(keywords, tag_prefix, verbose)
|
||||
if ver:
|
||||
return ver
|
||||
|
||||
@@ -183,11 +185,11 @@ def get_versions(default={"version": "unknown", "full": ""}, verbose=False):
|
||||
# versionfile_source is the relative path from the top of the source
|
||||
# tree (where the .git directory might live) to this file. Invert
|
||||
# this to find the root from __file__.
|
||||
for i in range(len(versionfile_source.split("/"))):
|
||||
for i in range(len(versionfile_source.split(os.sep))):
|
||||
root = os.path.dirname(root)
|
||||
except NameError:
|
||||
return default
|
||||
|
||||
return (versions_from_vcs(tag_prefix, root, verbose)
|
||||
return (git_versions_from_vcs(tag_prefix, root, verbose)
|
||||
or versions_from_parentdir(parentdir_prefix, root, verbose)
|
||||
or default)
|
||||
|
||||
@@ -29,7 +29,7 @@ __author__ = "Mathieu Fenniak"
|
||||
|
||||
import datetime
|
||||
from datetime import timedelta
|
||||
from pg8000 import (
|
||||
from . import (
|
||||
Interval, min_int2, max_int2, min_int4, max_int4, min_int8, max_int8,
|
||||
Bytea, NotSupportedError, ProgrammingError, InternalError, IntegrityError,
|
||||
OperationalError, DatabaseError, InterfaceError, Error,
|
||||
@@ -45,11 +45,10 @@ import threading
|
||||
from struct import pack
|
||||
from hashlib import md5
|
||||
from decimal import Decimal
|
||||
import pg8000
|
||||
from collections import deque, defaultdict
|
||||
from itertools import count, islice
|
||||
from pg8000.six.moves import map
|
||||
from pg8000.six import b, PY2, integer_types, next, PRE_26, text_type, u
|
||||
from .six.moves import map
|
||||
from .six import b, PY2, integer_types, next, PRE_26, text_type, u
|
||||
from sys import exc_info
|
||||
from uuid import UUID
|
||||
from copy import deepcopy
|
||||
@@ -57,6 +56,12 @@ from calendar import timegm
|
||||
import os
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
try:
|
||||
from json import loads
|
||||
except ImportError:
|
||||
pass # Can only use JSON with Python 2.6 and above
|
||||
|
||||
|
||||
ZERO = timedelta(0)
|
||||
|
||||
|
||||
@@ -891,7 +896,7 @@ class Connection(object):
|
||||
return error
|
||||
|
||||
def __init__(self, user, host, unix_sock, port, database, password, ssl):
|
||||
self._client_encoding = "ascii"
|
||||
self._client_encoding = "utf8"
|
||||
self._commands_with_count = (
|
||||
b("INSERT"), b("DELETE"), b("UPDATE"), b("MOVE"),
|
||||
b("FETCH"), b("COPY"), b("SELECT"))
|
||||
@@ -911,6 +916,9 @@ class Connection(object):
|
||||
else:
|
||||
self.user = user
|
||||
|
||||
if isinstance(self.user, text_type):
|
||||
self.user = self.user.encode('utf8')
|
||||
|
||||
self.password = password
|
||||
self.autocommit = False
|
||||
self._xid = None
|
||||
@@ -1085,6 +1093,10 @@ class Connection(object):
|
||||
def bool_recv(d, o, l):
|
||||
return d[o] == "\x01"
|
||||
|
||||
def json_in(data, offset, length):
|
||||
return loads(unicode( # noqa
|
||||
data[offset: offset + length], self._client_encoding))
|
||||
|
||||
else:
|
||||
def text_recv(data, offset, length):
|
||||
return str(
|
||||
@@ -1093,6 +1105,10 @@ class Connection(object):
|
||||
def bool_recv(data, offset, length):
|
||||
return data[offset] == 1
|
||||
|
||||
def json_in(data, offset, length):
|
||||
return loads(
|
||||
str(data[offset: offset + length], self._client_encoding))
|
||||
|
||||
def time_in(data, offset, length):
|
||||
hour = int(data[offset:offset + 2])
|
||||
minute = int(data[offset + 3:offset + 5])
|
||||
@@ -1131,6 +1147,7 @@ class Connection(object):
|
||||
25: (FC_BINARY, text_recv), # TEXT type
|
||||
26: (FC_TEXT, int_in), # oid
|
||||
28: (FC_TEXT, int_in), # xid
|
||||
114: (FC_TEXT, json_in), # json
|
||||
700: (FC_BINARY, float4_recv), # float4
|
||||
701: (FC_BINARY, float8_recv), # float8
|
||||
705: (FC_BINARY, text_recv), # unknown
|
||||
@@ -1157,6 +1174,7 @@ class Connection(object):
|
||||
1700: (FC_TEXT, numeric_in), # NUMERIC
|
||||
2275: (FC_BINARY, text_recv), # cstring
|
||||
2950: (FC_BINARY, uuid_recv), # uuid
|
||||
3802: (FC_TEXT, json_in), # jsonb
|
||||
})
|
||||
|
||||
self.py_types = {
|
||||
@@ -1183,7 +1201,7 @@ class Connection(object):
|
||||
}
|
||||
|
||||
if PY2:
|
||||
self.py_types[pg8000.Bytea] = (17, FC_BINARY, bytea_send) # bytea
|
||||
self.py_types[Bytea] = (17, FC_BINARY, bytea_send) # bytea
|
||||
self.py_types[text_type] = (705, FC_TEXT, text_out) # unknown
|
||||
|
||||
self.py_types[long] = (705, FC_TEXT, unknown_out) # noqa
|
||||
@@ -1242,11 +1260,12 @@ class Connection(object):
|
||||
# String - A parameter name (user, database, or options)
|
||||
# String - Parameter value
|
||||
protocol = 196608
|
||||
val = bytearray(i_pack(protocol) + b("user\x00"))
|
||||
val.extend(user.encode("ascii") + NULL_BYTE)
|
||||
val = bytearray(
|
||||
i_pack(protocol) + b("user\x00") + self.user + NULL_BYTE)
|
||||
if database is not None:
|
||||
val.extend(
|
||||
b("database\x00") + database.encode("ascii") + NULL_BYTE)
|
||||
if isinstance(database, text_type):
|
||||
database = database.encode('utf8')
|
||||
val.extend(b("database\x00") + database + NULL_BYTE)
|
||||
val.append(0)
|
||||
self._write(i_pack(len(val) + 4))
|
||||
self._write(val)
|
||||
@@ -1421,9 +1440,9 @@ class Connection(object):
|
||||
self._usock.close()
|
||||
self._sock = None
|
||||
except AttributeError:
|
||||
raise pg8000.InterfaceError("connection is closed")
|
||||
raise InterfaceError("connection is closed")
|
||||
except ValueError:
|
||||
raise pg8000.InterfaceError("connection is closed")
|
||||
raise InterfaceError("connection is closed")
|
||||
|
||||
def close(self):
|
||||
"""Closes the database connection.
|
||||
@@ -1478,10 +1497,8 @@ class Connection(object):
|
||||
"server requesting MD5 password authentication, but no "
|
||||
"password was provided")
|
||||
pwd = b("md5") + md5(
|
||||
md5(
|
||||
self.password.encode("ascii") +
|
||||
self.user.encode("ascii")).hexdigest().encode("ascii") +
|
||||
salt).hexdigest().encode("ascii")
|
||||
md5(self.password.encode("ascii") + self.user).
|
||||
hexdigest().encode("ascii") + salt).hexdigest().encode("ascii")
|
||||
# Byte1('p') - Identifies the message as a password message.
|
||||
# Int32 - Message length including self.
|
||||
# String - The password. Password may be encrypted.
|
||||
@@ -1529,26 +1546,22 @@ class Connection(object):
|
||||
count = h_unpack(data)[0]
|
||||
idx = 2
|
||||
for i in range(count):
|
||||
field = {'name': data[idx:data.find(NULL_BYTE, idx)]}
|
||||
idx += len(field['name']) + 1
|
||||
field.update(
|
||||
dict(zip((
|
||||
"table_oid", "column_attrnum", "type_oid",
|
||||
"type_size", "type_modifier", "format"),
|
||||
ihihih_unpack(data, idx))))
|
||||
name = data[idx:data.find(NULL_BYTE, idx)]
|
||||
idx += len(name) + 1
|
||||
field = dict(
|
||||
zip((
|
||||
"table_oid", "column_attrnum", "type_oid", "type_size",
|
||||
"type_modifier", "format"), ihihih_unpack(data, idx)))
|
||||
field['name'] = name
|
||||
idx += 18
|
||||
cursor.ps['row_desc'].append(field)
|
||||
try:
|
||||
field['pg8000_fc'], field['func'] = self.pg_types[
|
||||
field['type_oid']]
|
||||
except KeyError:
|
||||
raise NotSupportedError(
|
||||
"type oid " + exc_info()[1] + " not supported")
|
||||
field['pg8000_fc'], field['func'] = \
|
||||
self.pg_types[field['type_oid']]
|
||||
|
||||
def execute(self, cursor, operation, vals):
|
||||
if vals is None:
|
||||
vals = ()
|
||||
paramstyle = pg8000.paramstyle
|
||||
from . import paramstyle
|
||||
cache = self._caches[paramstyle]
|
||||
|
||||
try:
|
||||
@@ -1700,11 +1713,11 @@ class Connection(object):
|
||||
self._write(FLUSH_MSG)
|
||||
except ValueError:
|
||||
if str(exc_info()[1]) == "write to closed file":
|
||||
raise pg8000.InterfaceError("connection is closed")
|
||||
raise InterfaceError("connection is closed")
|
||||
else:
|
||||
raise exc_info()[1]
|
||||
except AttributeError:
|
||||
raise pg8000.InterfaceError("connection is closed")
|
||||
raise InterfaceError("connection is closed")
|
||||
|
||||
def send_EXECUTE(self, cursor):
|
||||
# Byte1('E') - Identifies the message as an execute message.
|
||||
|
||||
+3
-4
@@ -1,5 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from pydal import DAL as pyDAL
|
||||
from pydal import Field, SQLCustomType, geoPoint, geoLine, geoPolygon
|
||||
|
||||
@@ -128,9 +127,9 @@ from pydal.drivers import DRIVERS
|
||||
if not DRIVERS.get('pymysql'):
|
||||
from .contrib import pymysql
|
||||
DRIVERS['pymysql'] = pymysql
|
||||
#if not DRIVERS.get('pg8000'):
|
||||
# from .contrib import pg8000
|
||||
# DRIVERS['pg8000'] = pg8000
|
||||
if not DRIVERS.get('pg8000'):
|
||||
from .contrib import pg8000
|
||||
DRIVERS['pg8000'] = pg8000
|
||||
if not DRIVERS.get('pyodbc'):
|
||||
from .contrib import pypyodbc as pyodbc
|
||||
DRIVERS['pyodbc'] = pyodbc
|
||||
|
||||
Reference in New Issue
Block a user