pglib 5.9.1__tar.gz → 5.11.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. {pglib-5.9.1 → pglib-5.11.0}/MANIFEST.in +0 -2
  2. pglib-5.11.0/PKG-INFO +34 -0
  3. {pglib-5.9.1 → pglib-5.11.0}/README.rst +2 -2
  4. pglib-5.11.0/pglib.egg-info/PKG-INFO +34 -0
  5. {pglib-5.9.1 → pglib-5.11.0}/pglib.egg-info/SOURCES.txt +2 -18
  6. pglib-5.11.0/pglib.egg-info/requires.txt +3 -0
  7. pglib-5.11.0/pyproject.toml +40 -0
  8. pglib-5.11.0/setup.cfg +4 -0
  9. {pglib-5.9.1 → pglib-5.11.0}/setup.py +11 -63
  10. {pglib-5.9.1 → pglib-5.11.0}/src/getdata.cpp +3 -0
  11. {pglib-5.9.1 → pglib-5.11.0}/src/pgarrays.cpp +111 -1
  12. {pglib-5.9.1 → pglib-5.11.0}/src/pgarrays.h +1 -0
  13. {pglib-5.9.1 → pglib-5.11.0}/src/pglib.h +1 -0
  14. {pglib-5.9.1 → pglib-5.11.0}/test/test_async.py +10 -15
  15. {pglib-5.9.1 → pglib-5.11.0}/test/test_sync.py +9 -1
  16. {pglib-5.9.1 → pglib-5.11.0}/test/testutils.py +18 -16
  17. pglib-5.9.1/PKG-INFO +0 -25
  18. pglib-5.9.1/pglib.egg-info/PKG-INFO +0 -25
  19. pglib-5.9.1/setup.cfg +0 -10
  20. {pglib-5.9.1 → pglib-5.11.0}/LICENSE +0 -0
  21. {pglib-5.9.1 → pglib-5.11.0}/pglib/__init__.py +0 -0
  22. {pglib-5.9.1 → pglib-5.11.0}/pglib/asyncpglib.py +0 -0
  23. {pglib-5.9.1 → pglib-5.11.0}/pglib.egg-info/dependency_links.txt +0 -0
  24. {pglib-5.9.1 → pglib-5.11.0}/pglib.egg-info/top_level.txt +0 -0
  25. {pglib-5.9.1 → pglib-5.11.0}/src/byteswap.h +0 -0
  26. {pglib-5.9.1 → pglib-5.11.0}/src/connection.cpp +0 -0
  27. {pglib-5.9.1 → pglib-5.11.0}/src/connection.h +0 -0
  28. {pglib-5.9.1 → pglib-5.11.0}/src/conninfoopt.cpp +0 -0
  29. {pglib-5.9.1 → pglib-5.11.0}/src/conninfoopt.h +0 -0
  30. {pglib-5.9.1 → pglib-5.11.0}/src/datatypes.cpp +0 -0
  31. {pglib-5.9.1 → pglib-5.11.0}/src/datatypes.h +0 -0
  32. {pglib-5.9.1 → pglib-5.11.0}/src/debug.cpp +0 -0
  33. {pglib-5.9.1 → pglib-5.11.0}/src/debug.h +0 -0
  34. {pglib-5.9.1 → pglib-5.11.0}/src/enums.cpp +0 -0
  35. {pglib-5.9.1 → pglib-5.11.0}/src/enums.h +0 -0
  36. {pglib-5.9.1 → pglib-5.11.0}/src/errors.cpp +0 -0
  37. {pglib-5.9.1 → pglib-5.11.0}/src/errors.h +0 -0
  38. {pglib-5.9.1 → pglib-5.11.0}/src/getdata.h +0 -0
  39. {pglib-5.9.1 → pglib-5.11.0}/src/juliandate.cpp +0 -0
  40. {pglib-5.9.1 → pglib-5.11.0}/src/juliandate.h +0 -0
  41. {pglib-5.9.1 → pglib-5.11.0}/src/params.cpp +0 -0
  42. {pglib-5.9.1 → pglib-5.11.0}/src/params.h +0 -0
  43. {pglib-5.9.1 → pglib-5.11.0}/src/pglib.cpp +0 -0
  44. {pglib-5.9.1 → pglib-5.11.0}/src/pgtypes.h +0 -0
  45. {pglib-5.9.1 → pglib-5.11.0}/src/resultset.cpp +0 -0
  46. {pglib-5.9.1 → pglib-5.11.0}/src/resultset.h +0 -0
  47. {pglib-5.9.1 → pglib-5.11.0}/src/row.cpp +0 -0
  48. {pglib-5.9.1 → pglib-5.11.0}/src/row.h +0 -0
  49. {pglib-5.9.1 → pglib-5.11.0}/src/runtime.cpp +0 -0
  50. {pglib-5.9.1 → pglib-5.11.0}/src/runtime.h +0 -0
  51. {pglib-5.9.1 → pglib-5.11.0}/src/type_hstore.cpp +0 -0
  52. {pglib-5.9.1 → pglib-5.11.0}/src/type_hstore.h +0 -0
  53. {pglib-5.9.1 → pglib-5.11.0}/src/type_json.cpp +0 -0
  54. {pglib-5.9.1 → pglib-5.11.0}/src/type_json.h +0 -0
  55. {pglib-5.9.1 → pglib-5.11.0}/src/type_ltree.cpp +0 -0
  56. {pglib-5.9.1 → pglib-5.11.0}/src/type_ltree.h +0 -0
@@ -1,5 +1,3 @@
1
1
  include README.rst
2
2
  include src/*.h
3
3
  include src/*.cpp
4
- include versioneer.py
5
- include pglib/_version.py
pglib-5.11.0/PKG-INFO ADDED
@@ -0,0 +1,34 @@
1
+ Metadata-Version: 2.4
2
+ Name: pglib
3
+ Version: 5.11.0
4
+ Summary: A PostgreSQL interface
5
+ Author-email: Michael Kleehammer <michael@kleehammer.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://gitlab.com/mkleehammer/pglib
8
+ Project-URL: Repository, https://gitlab.com/mkleehammer/pglib
9
+ Keywords: postgresql,postgres
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Topic :: Database
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/x-rst
20
+ License-File: LICENSE
21
+ Provides-Extra: test
22
+ Requires-Dist: pytest; extra == "test"
23
+ Dynamic: license-file
24
+
25
+
26
+ pglib is a Python 3.10+ module for working with PostgreSQL databases. It is a C extension that
27
+ exposes the `libpq <http://www.postgresql.org/docs/current/static/libpq.html>`_ API. It is
28
+ designed to be small, fast, and as convenient as possible. It provides both synchronous and
29
+ asynchronous APIs.
30
+
31
+ Unlike some libraries, it never modifies the SQL you pass. Parameters are passed using the
32
+ official libpq protocol for parameters.
33
+
34
+ Documentation is available in /docs and online at http://pglib.readthedocs.org
@@ -1,6 +1,6 @@
1
1
 
2
- pglib is a Python 3.6+ module for working with PostgreSQL databases. It is a C extension that
3
- exposes the `libpq <http://www.postgresql.org/docs/9.3/static/libpq.html>`_ API. It is
2
+ pglib is a Python 3.10+ module for working with PostgreSQL databases. It is a C extension that
3
+ exposes the `libpq <http://www.postgresql.org/docs/current/static/libpq.html>`_ API. It is
4
4
  designed to be small, fast, and as convenient as possible. It provides both synchronous and
5
5
  asynchronous APIs.
6
6
 
@@ -0,0 +1,34 @@
1
+ Metadata-Version: 2.4
2
+ Name: pglib
3
+ Version: 5.11.0
4
+ Summary: A PostgreSQL interface
5
+ Author-email: Michael Kleehammer <michael@kleehammer.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://gitlab.com/mkleehammer/pglib
8
+ Project-URL: Repository, https://gitlab.com/mkleehammer/pglib
9
+ Keywords: postgresql,postgres
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Topic :: Database
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/x-rst
20
+ License-File: LICENSE
21
+ Provides-Extra: test
22
+ Requires-Dist: pytest; extra == "test"
23
+ Dynamic: license-file
24
+
25
+
26
+ pglib is a Python 3.10+ module for working with PostgreSQL databases. It is a C extension that
27
+ exposes the `libpq <http://www.postgresql.org/docs/current/static/libpq.html>`_ API. It is
28
+ designed to be small, fast, and as convenient as possible. It provides both synchronous and
29
+ asynchronous APIs.
30
+
31
+ Unlike some libraries, it never modifies the SQL you pass. Parameters are passed using the
32
+ official libpq protocol for parameters.
33
+
34
+ Documentation is available in /docs and online at http://pglib.readthedocs.org
@@ -1,30 +1,14 @@
1
1
  LICENSE
2
2
  MANIFEST.in
3
3
  README.rst
4
- setup.cfg
4
+ pyproject.toml
5
5
  setup.py
6
- /home/mkleehammer/dev/pglib/src/connection.cpp
7
- /home/mkleehammer/dev/pglib/src/conninfoopt.cpp
8
- /home/mkleehammer/dev/pglib/src/datatypes.cpp
9
- /home/mkleehammer/dev/pglib/src/debug.cpp
10
- /home/mkleehammer/dev/pglib/src/enums.cpp
11
- /home/mkleehammer/dev/pglib/src/errors.cpp
12
- /home/mkleehammer/dev/pglib/src/getdata.cpp
13
- /home/mkleehammer/dev/pglib/src/juliandate.cpp
14
- /home/mkleehammer/dev/pglib/src/params.cpp
15
- /home/mkleehammer/dev/pglib/src/pgarrays.cpp
16
- /home/mkleehammer/dev/pglib/src/pglib.cpp
17
- /home/mkleehammer/dev/pglib/src/resultset.cpp
18
- /home/mkleehammer/dev/pglib/src/row.cpp
19
- /home/mkleehammer/dev/pglib/src/runtime.cpp
20
- /home/mkleehammer/dev/pglib/src/type_hstore.cpp
21
- /home/mkleehammer/dev/pglib/src/type_json.cpp
22
- /home/mkleehammer/dev/pglib/src/type_ltree.cpp
23
6
  pglib/__init__.py
24
7
  pglib/asyncpglib.py
25
8
  pglib.egg-info/PKG-INFO
26
9
  pglib.egg-info/SOURCES.txt
27
10
  pglib.egg-info/dependency_links.txt
11
+ pglib.egg-info/requires.txt
28
12
  pglib.egg-info/top_level.txt
29
13
  src/byteswap.h
30
14
  src/connection.cpp
@@ -0,0 +1,3 @@
1
+
2
+ [test]
3
+ pytest
@@ -0,0 +1,40 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pglib"
7
+ version = "5.11.0"
8
+ description = "A PostgreSQL interface"
9
+ readme = "README.rst"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.10"
13
+ authors = [
14
+ {name = "Michael Kleehammer", email = "michael@kleehammer.com"}
15
+ ]
16
+ keywords = ["postgresql", "postgres"]
17
+ classifiers = [
18
+ "Development Status :: 5 - Production/Stable",
19
+ "Intended Audience :: Developers",
20
+ "Topic :: Database",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3 :: Only",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.14",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://gitlab.com/mkleehammer/pglib"
30
+ Repository = "https://gitlab.com/mkleehammer/pglib"
31
+
32
+ [project.optional-dependencies]
33
+ test = ["pytest"]
34
+
35
+ [tool.setuptools.packages.find]
36
+ where = ["."]
37
+ include = ["pglib*"]
38
+
39
+ [tool.pytest.ini_options]
40
+ testpaths = ["test"]
pglib-5.11.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -1,36 +1,24 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
- import sys, os, re
4
- import subprocess, sysconfig
3
+ import sys
4
+ import os
5
+ import re
6
+ import subprocess
7
+ import sysconfig
5
8
  from os.path import join, abspath, dirname
6
9
 
7
- try:
8
- from setuptools import setup, Extension
9
- except:
10
- from distutils.core import setup, Extension
11
-
12
- long_description = """\
13
- A PostgreSQL interface for Python.
14
-
15
- This provides an interface to the libpq library. It is not an DB API
16
- library, but is instead designed to match the interface PostgreSQL
17
- offers.
18
- """
10
+ from setuptools import setup, Extension
19
11
 
20
12
 
21
13
  def _get_osx_sdkpath():
22
14
  """
23
15
  Use xcodebuild to find the latest installed OS X SDK and return the path to it.
24
16
  """
25
- # The output is in blank line separated sections. Find the section for the latest OS/X SDK
26
- # and get the Path entry.
27
-
28
17
  output = subprocess.check_output(['xcodebuild', '-version', '-sdk']).strip().decode('utf-8')
29
18
 
30
19
  highest = (0, 0)
31
- path = None
20
+ path = None
32
21
 
33
- # MacOSX10.8.sdk - OS X 10.8 (macosx10.8)
34
22
  resection = re.compile(r'^.*- (?:OS X|macOS) (\d+)\.(\d+)')
35
23
  repath = re.compile('^Path: ([^\n]+)', re.MULTILINE)
36
24
 
@@ -50,27 +38,14 @@ def _get_osx_sdkpath():
50
38
  return path
51
39
 
52
40
 
53
- def getoutput(cmd):
54
- pipe = os.popen(cmd, 'r')
55
- text = pipe.read().rstrip('\n')
56
- status = pipe.close() or 0
57
- return status, text
58
-
59
-
60
41
  def _get_files():
61
- return [abspath(join('src', f)) for f in os.listdir('src') if f.endswith('.cpp')]
42
+ return [join('src', f) for f in os.listdir('src') if f.endswith('.cpp')]
62
43
 
63
44
 
64
45
  def _get_settings():
65
-
66
- # version = get_version()
67
- #
68
- # settings = { 'define_macros' : [ ('PGLIB_VERSION', version) ] }
69
-
70
46
  settings = {'define_macros': []}
71
47
 
72
- # This isn't the best or right way to do this, but I don't see how someone is supposed to sanely subclass the build
73
- # command.
48
+ # Custom build options
74
49
  for option in ['assert', 'trace', 'leak-check']:
75
50
  try:
76
51
  sys.argv.remove('--%s' % option)
@@ -90,17 +65,12 @@ def _get_settings():
90
65
  ]
91
66
 
92
67
  if '--debug' in sys.argv:
93
- # TODO: The build command already has debug. Pass it in.
94
68
  sys.argv.remove('--debug')
95
69
  settings['extra_compile_args'].extend('/Od /Ge /GS /GZ /RTC1 /Wp64 /Yd'.split())
96
70
 
97
71
  settings['libraries'] = ['libpq', 'Ws2_32']
98
72
 
99
73
  elif sys.platform == 'darwin':
100
- # Apple is not making it easy for non-Xcode builds. We'll always build with the latest
101
- # SDK we can find but we'll set the version we are targeting to the same one that
102
- # Python was built with.
103
-
104
74
  sdkpath = _get_osx_sdkpath()
105
75
 
106
76
  settings['include_dirs'] = [
@@ -109,7 +79,7 @@ def _get_settings():
109
79
  subprocess.check_output(['pg_config', '--includedir']).strip().decode('utf-8')
110
80
  ]
111
81
  settings['library_dirs'] = [subprocess.check_output(['pg_config', '--libdir']).strip().decode('utf-8')]
112
- settings['libraries'] = ['pq']
82
+ settings['libraries'] = ['pq']
113
83
 
114
84
  settings['define_macros'].append(('MAC_OS_X_VERSION_10_7',))
115
85
 
@@ -117,37 +87,15 @@ def _get_settings():
117
87
 
118
88
  else:
119
89
  # Other posix-like: Linux, Solaris, etc.
120
-
121
90
  settings['include_dirs'] = [subprocess.check_output(['pg_config', '--includedir']).strip().decode('utf-8')]
122
91
  settings['library_dirs'] = [subprocess.check_output(['pg_config', '--libdir']).strip().decode('utf-8')]
123
- settings['libraries'] = ['pq']
92
+ settings['libraries'] = ['pq']
124
93
 
125
- # Python functions take a lot of 'char *' that really should be const. gcc complains about this *a lot*
126
94
  settings['extra_compile_args'] = ['-Wno-write-strings']
127
95
 
128
96
  return settings
129
97
 
130
98
 
131
99
  setup(
132
- name='pglib',
133
- version='5.9.1',
134
- description='A PostgreSQL interface',
135
- long_description=long_description,
136
- maintainer='Michael Kleehammer',
137
- maintainer_email='michael@kleehammer.com',
138
- packages=['pglib'],
139
100
  ext_modules=[Extension('_pglib', _get_files(), **_get_settings())],
140
- keywords='postgresql postgres',
141
- tests_require=['pytest'],
142
- url='https://gitlab.com/mkleehammer/pglib',
143
- license='MIT',
144
- classifiers=[
145
- # https://pypi.python.org/pypi?%3Aaction=list_classifiers
146
- 'Development Status :: 5 - Production/Stable',
147
- 'Intended Audience :: Developers',
148
- 'Topic :: Database',
149
- 'License :: OSI Approved :: MIT License',
150
- 'Programming Language :: Python :: 3',
151
- 'Programming Language :: Python :: 3 :: Only'
152
- ]
153
101
  )
@@ -398,6 +398,9 @@ PyObject* ConvertValue(PGresult* result, int iRow, int iCol, bool integer_dateti
398
398
  case INT8ARRAYOID:
399
399
  return GetInt8Array(p);
400
400
 
401
+ case FLOAT8ARRAYOID:
402
+ return GetFloat8Array(p);
403
+
401
404
  case TEXTARRAYOID:
402
405
  return GetTextArray(p);
403
406
 
@@ -91,6 +91,11 @@ inline uint32_t ReadU32(const char ** pp) {
91
91
  return htonl(n);
92
92
  }
93
93
 
94
+ inline double ReadDouble(const char ** pp) {
95
+ double n = **(double**)pp;
96
+ *pp += sizeof(double);
97
+ return swapdouble(n);
98
+ }
94
99
 
95
100
 
96
101
  static PyObject* FindFirstParam(Object& seq)
@@ -375,6 +380,69 @@ bool BindLongArray(Params& params, Object& seq, Py_ssize_t cItems)
375
380
  }
376
381
 
377
382
 
383
+ static bool BindFloatArray(Params& params, Object& seq, Py_ssize_t cItems)
384
+ {
385
+ // Loop through the array and make sure each entry is a float (or None).
386
+
387
+ int cNonNull = 0; // count of non-null items
388
+
389
+ for (Py_ssize_t iItem = 0; iItem < cItems; iItem++)
390
+ {
391
+ PyObject* item = PySequence_Fast_GET_ITEM(seq.Get(), iItem);
392
+ if (item != Py_None)
393
+ {
394
+ if (!PyFloat_Check(item))
395
+ {
396
+ SetStringError(Error, "array parameters must all be the same type");
397
+ return false;
398
+ }
399
+
400
+ cNonNull += 1;
401
+ }
402
+ }
403
+
404
+ int cbItem = sizeof(double);
405
+
406
+ Py_ssize_t cb = sizeof(ArrayHeader) +
407
+ (4 * cItems) + // length indicators
408
+ (cbItem * cNonNull); // values
409
+
410
+
411
+ WriteBuffer buf = params.Allocate(cb);
412
+ if (!buf)
413
+ return false;
414
+
415
+ ArrayHeader* phdr = (ArrayHeader*)buf.pbStart;
416
+ phdr->ndim = htonl(1);
417
+ phdr->flags = htonl(1);
418
+ phdr->oid = htonl(FLOAT8OID);
419
+ phdr->dim = htonl(cItems);
420
+ phdr->lbound = htonl(1);
421
+
422
+ char* pT = &phdr->buffer[0];
423
+
424
+ for (Py_ssize_t iItem = 0; iItem < cItems; iItem++)
425
+ {
426
+ PyObject* item = PySequence_Fast_GET_ITEM(seq.Get(), iItem);
427
+ if (item != Py_None)
428
+ {
429
+ (*(uint32_t*)pT) = htonl(cbItem); // could be swapped and cached
430
+ pT += 4;
431
+
432
+ (*(double*)pT) = swapdouble(PyFloat_AS_DOUBLE(item));
433
+ pT += cbItem;
434
+ }
435
+ else
436
+ {
437
+ (*(uint32_t*)pT) = htonl(-1);
438
+ pT += 4;
439
+ }
440
+ }
441
+
442
+ return params.Bind(FLOAT8ARRAYOID, buf, FORMAT_BINARY);
443
+ }
444
+
445
+
378
446
  bool BindArray(Params& params, PyObject* param)
379
447
  {
380
448
  // Binds a list or tuple as an array. All elements must be of the same type, though None
@@ -399,7 +467,10 @@ bool BindArray(Params& params, PyObject* param)
399
467
  if (PyDate_Check(first))
400
468
  return BindDateArray(params, seq, cItems);
401
469
 
402
- SetStringError(Error, "Unhandled type in parameter array");
470
+ if (PyFloat_Check(first))
471
+ return BindFloatArray(params, seq, cItems);
472
+
473
+ SetStringError(Error, "Unhandled type in array parameter");
403
474
 
404
475
  return false;
405
476
  }
@@ -527,6 +598,45 @@ PyObject* GetInt8Array(const char* p)
527
598
  }
528
599
 
529
600
 
601
+ PyObject* GetFloat8Array(const char* p)
602
+ {
603
+ // Reads an FLOAT8ARRAYOID array result and returns a list of floats.
604
+
605
+ ArrayInfo info;
606
+ if (!ReadArrayInfo(p, info, FLOAT8OID)) {
607
+ return 0;
608
+ }
609
+
610
+ Object list(PyList_New(info.len));
611
+ if (!list)
612
+ return 0;
613
+
614
+ if (info.len) {
615
+ const char* data = info.data;
616
+
617
+ for (uint32_t i = 0; i < info.len; i++)
618
+ {
619
+ int32_t len = Read32(&data);
620
+
621
+ if (len == -1)
622
+ {
623
+ Py_INCREF(Py_None);
624
+ PyList_SET_ITEM(list.Get(), i, Py_None);
625
+ }
626
+ else
627
+ {
628
+ double val = ReadDouble(&data);
629
+ PyObject* o = PyFloat_FromDouble(val);
630
+ if (!o)
631
+ return 0;
632
+
633
+ PyList_SET_ITEM(list.Get(), i, o);
634
+ }
635
+ }
636
+ }
637
+
638
+ return list.Detach();
639
+ }
530
640
 
531
641
  PyObject* GetTextArray(const char* p)
532
642
  {
@@ -15,5 +15,6 @@ PyObject* GetInt8Array(const char* p);
15
15
  PyObject* GetTextArray(const char* p);
16
16
  PyObject* GetDateArray(const char* p);
17
17
  PyObject* GetJSONBArray(const char* p);
18
+ PyObject* GetFloat8Array(const char* p);
18
19
 
19
20
  #endif
@@ -69,6 +69,7 @@ extern PyObject* Error;
69
69
  #define DATEARRAYOID 1182
70
70
  #define FLOAT4OID 700
71
71
  #define FLOAT8OID 701
72
+ #define FLOAT8ARRAYOID 1022
72
73
  #define INT2ARRAYOID 1005
73
74
  #define INT2OID 21
74
75
  #define INT4ARRAYOID 1007
@@ -44,8 +44,7 @@ def test_async():
44
44
  assert row.b == 3
45
45
  assert row[1] == 3
46
46
 
47
- loop = asyncio.get_event_loop()
48
- loop.run_until_complete(_t())
47
+ asyncio.run(_t())
49
48
 
50
49
 
51
50
  def test_async_params():
@@ -60,8 +59,7 @@ def test_async_params():
60
59
  assert row.b == 2
61
60
  assert row[1] == 2
62
61
 
63
- loop = asyncio.get_event_loop()
64
- loop.run_until_complete(_t())
62
+ asyncio.run(_t())
65
63
 
66
64
 
67
65
  def test_async_notify():
@@ -84,8 +82,7 @@ def test_async_notify():
84
82
  assert item == sent[0]
85
83
  sent.pop(0)
86
84
 
87
- loop = asyncio.get_event_loop()
88
- loop.run_until_complete(_t())
85
+ asyncio.run(_t())
89
86
 
90
87
 
91
88
  def test_notify_and_command():
@@ -112,8 +109,7 @@ def test_notify_and_command():
112
109
  item = ns[0]
113
110
  assert item == ('test', 'both')
114
111
 
115
- loop = asyncio.get_event_loop()
116
- loop.run_until_complete(_t())
112
+ asyncio.run(_t())
117
113
 
118
114
 
119
115
  def test_notification_wait():
@@ -132,9 +128,10 @@ def test_notification_wait():
132
128
  cnxn = await pglib.connect_async(CONNINFO)
133
129
  await cnxn.notify('test')
134
130
 
135
- both = asyncio.gather(_listener(), _notifier())
136
- loop = asyncio.get_event_loop()
137
- loop.run_until_complete(both)
131
+ async def _run_both():
132
+ await asyncio.gather(_listener(), _notifier())
133
+
134
+ asyncio.run(_run_both())
138
135
 
139
136
 
140
137
  def test_notification_timeout():
@@ -144,8 +141,7 @@ def test_notification_timeout():
144
141
  ns = await cnxn.notifications(timeout=0.25)
145
142
  assert ns == []
146
143
 
147
- loop = asyncio.get_event_loop()
148
- loop.run_until_complete(_t())
144
+ asyncio.run(_t())
149
145
 
150
146
 
151
147
  def test_close():
@@ -156,5 +152,4 @@ def test_close():
156
152
  cnxn.close()
157
153
  cnxn = None
158
154
 
159
- loop = asyncio.get_event_loop()
160
- loop.run_until_complete(_t())
155
+ asyncio.run(_t())
@@ -1,4 +1,3 @@
1
-
2
1
  # Run with pytest.
3
2
 
4
3
  # pylint: disable=missing-function-docstring,redefined-outer-name,unidiomatic-typecheck
@@ -711,6 +710,15 @@ def test_array_bigint(cnxn):
711
710
  assert result == value
712
711
 
713
712
 
713
+ def test_array_float(cnxn):
714
+ cnxn.execute("create table t1(id int, v float[])")
715
+ value = [None, -100000.0, -32768.0, -123.45, -1.0, 0.0,
716
+ 1.0, 123.45, 32767.0, 2147483647.0, 10101010.8989]
717
+ cnxn.execute("insert into t1 values (1, $1)", value)
718
+ result = cnxn.fetchval("select v from t1")
719
+ assert result == value
720
+
721
+
714
722
  def test_array_text(cnxn):
715
723
  cnxn.execute("create table t1(id int, v text[])")
716
724
  value = ['one', None, 'two']
@@ -10,21 +10,22 @@ def add_to_path():
10
10
  it to be tested without installing it.
11
11
  """
12
12
  # Put the root directory into the path first so we pick up the Python code from the source
13
- # directories. It will also be in the build directory, so make sure build is 2nd!
13
+ # directories and any extension built via editable install.
14
14
 
15
15
  root = dirname(dirname(abspath(__file__)))
16
16
  sys.path.insert(0, root)
17
17
 
18
- # Put the build directory into the Python path so we pick up the version we just built.
19
- #
20
- # To make this cross platform, we'll search the directories until we find the .pyd file.
18
+ # Check if the extension is already importable (installed via pip or editable install)
19
+ try:
20
+ import _pglib
21
+ return
22
+ except ImportError:
23
+ pass
21
24
 
25
+ # Fall back to searching the build directory for legacy `python setup.py build` workflow.
22
26
  prefix = '_pglib'
23
-
24
27
  library_names = [prefix + ext for ext in EXTENSION_SUFFIXES]
25
28
 
26
- # Only go into directories that match the current Python's version number.
27
-
28
29
  dir_suffix = (
29
30
  '-%s.%s' % (sys.version_info[0], sys.version_info[1]),
30
31
  '-%s%s' % (sys.version_info[0], sys.version_info[1]),
@@ -33,17 +34,18 @@ def add_to_path():
33
34
 
34
35
  build = join(dirname(dirname(abspath(__file__))), 'build')
35
36
 
36
- for root, dirs, files in os.walk(build):
37
- for d in dirs[:]:
38
- if not d.endswith(dir_suffix):
39
- dirs.remove(d)
37
+ if os.path.isdir(build):
38
+ for root, dirs, files in os.walk(build):
39
+ for d in dirs[:]:
40
+ if not d.endswith(dir_suffix):
41
+ dirs.remove(d)
40
42
 
41
- for name in library_names:
42
- if name in files:
43
- sys.path.insert(1, root)
44
- return
43
+ for name in library_names:
44
+ if name in files:
45
+ sys.path.insert(1, root)
46
+ return
45
47
 
46
- sys.exit('Did not find the build directory')
48
+ sys.exit('Did not find _pglib extension. Run: pip install -e .')
47
49
 
48
50
 
49
51
  _TESTSTR = '0123456789-abcdefghijklmnopqrstuvwxyz-'
pglib-5.9.1/PKG-INFO DELETED
@@ -1,25 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: pglib
3
- Version: 5.9.1
4
- Summary: A PostgreSQL interface
5
- Home-page: https://gitlab.com/mkleehammer/pglib
6
- Maintainer: Michael Kleehammer
7
- Maintainer-email: michael@kleehammer.com
8
- License: MIT
9
- Keywords: postgresql postgres
10
- Platform: UNKNOWN
11
- Classifier: Development Status :: 5 - Production/Stable
12
- Classifier: Intended Audience :: Developers
13
- Classifier: Topic :: Database
14
- Classifier: License :: OSI Approved :: MIT License
15
- Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3 :: Only
17
- License-File: LICENSE
18
-
19
- A PostgreSQL interface for Python.
20
-
21
- This provides an interface to the libpq library. It is not an DB API
22
- library, but is instead designed to match the interface PostgreSQL
23
- offers.
24
-
25
-
@@ -1,25 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: pglib
3
- Version: 5.9.1
4
- Summary: A PostgreSQL interface
5
- Home-page: https://gitlab.com/mkleehammer/pglib
6
- Maintainer: Michael Kleehammer
7
- Maintainer-email: michael@kleehammer.com
8
- License: MIT
9
- Keywords: postgresql postgres
10
- Platform: UNKNOWN
11
- Classifier: Development Status :: 5 - Production/Stable
12
- Classifier: Intended Audience :: Developers
13
- Classifier: Topic :: Database
14
- Classifier: License :: OSI Approved :: MIT License
15
- Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3 :: Only
17
- License-File: LICENSE
18
-
19
- A PostgreSQL interface for Python.
20
-
21
- This provides an interface to the libpq library. It is not an DB API
22
- library, but is instead designed to match the interface PostgreSQL
23
- offers.
24
-
25
-
pglib-5.9.1/setup.cfg DELETED
@@ -1,10 +0,0 @@
1
- [tool:pytest]
2
- testpaths = test
3
-
4
- [aliases]
5
- test = pytest
6
-
7
- [egg_info]
8
- tag_build =
9
- tag_date = 0
10
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes