Skip to content

Commit f1d32bb

Browse files
committed
1.0.0rc2
* added engine.repr() * changed PendingDeprecationWarning to DeprecationWarning * PyPI auto release with GitHub action
1 parent ccf003e commit f1d32bb

8 files changed

Lines changed: 253 additions & 87 deletions

File tree

‎.github/workflows/test.yml‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ on:
55
branches:
66
- master
77
- v*.*.x
8+
tags:
9+
- 'v*.*.*'
810
pull_request:
911
branches:
1012
- master
@@ -61,3 +63,35 @@ jobs:
6163
run: |
6264
pip install codacy-coverage
6365
python-codacy-coverage -r coverage.xml
66+
release:
67+
runs-on: ubuntu-latest
68+
needs: test
69+
strategy:
70+
matrix:
71+
python-version: [ '3.8' ]
72+
steps:
73+
- name: Checkout source code
74+
if: startsWith(github.ref, 'refs/tags/')
75+
uses: actions/checkout@v1
76+
- name: Set up Python
77+
if: startsWith(github.ref, 'refs/tags/')
78+
uses: actions/setup-python@v1
79+
with:
80+
python-version: ${{ matrix.python-version }}
81+
- name: virtualenv cache
82+
if: startsWith(github.ref, 'refs/tags/')
83+
uses: actions/cache@preview
84+
with:
85+
path: ~/.cache/pypoetry/virtualenvs
86+
key: ${{ runner.os }}-${{ matrix.python-version }}-poetry-${{ hashFiles(format('{0}{1}', github.workspace, '/poetry.lock')) }}
87+
restore-keys: |
88+
${{ runner.os }}-${{ matrix.python-version }}-poetry-
89+
- name: Release to PyPI
90+
if: startsWith(github.ref, 'refs/tags/')
91+
env:
92+
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
93+
run: |
94+
curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python
95+
$HOME/.poetry/bin/poetry install
96+
$HOME/.poetry/bin/poetry build
97+
$HOME/.poetry/bin/poetry publish --username __token__ --password ${{ secrets.PYPI_TOKEN }}

‎poetry.lock‎

Lines changed: 91 additions & 84 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎pyproject.toml‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "gino"
3-
version = "1.0.0-rc.1"
3+
version = "1.0.0-rc.2"
44
description = "GINO Is Not ORM - a Python asyncio ORM on SQLAlchemy core."
55
license = "BSD-3-Clause"
66
authors = ["Fantix King <fantix.king@gmail.com>"]
@@ -26,12 +26,29 @@ classifiers = [
2626
python = "^3.5"
2727
asyncpg = ">=0.18,<1.0"
2828
SQLAlchemy = "^1.2"
29+
30+
# compatibility
2931
contextvars = { version = "^2.4", python = "<3.7" }
3032
importlib_metadata = { version = "^1.3.0", python = "<3.8" }
3133

34+
# extensions
35+
#gino-starlette = { version = "^0.1.0", optional = true }
36+
#gino-aiohttp = { version = "^0.1.0", optional = true }
37+
#gino-tornado = { version = "^0.1.0", optional = true }
38+
#gino-sanic = { version = "^0.1.0", optional = true }
39+
#gino-quart = { version = "^0.1.0", optional = true }
40+
#
41+
#[tool.poetry.extras]
42+
#starlette = ["gino-starlette"]
43+
#aiohttp = ["gino-aiohttp"]
44+
#tornado = ["gino-tornado"]
45+
#sanic = ["gino-sanic"]
46+
#quart = ["gino-quart"]
47+
3248
[tool.poetry.dev-dependencies]
3349
psycopg2-binary = "^2.8.4"
3450
async_generator = "^1.10"
51+
click = "^7.0"
3552

3653
# tests
3754
pytest = "^5.3.2"

‎src/gino/dialects/asyncpg.py‎

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import inspect
22
import itertools
33
import time
4+
import warnings
45

56
import asyncpg
67
from sqlalchemy import util, exc, sql
@@ -22,6 +23,10 @@
2223

2324
from . import base
2425

26+
try:
27+
import click
28+
except ImportError:
29+
click = None
2530
JSON_COLTYPE = 114
2631
JSONB_COLTYPE = 3802
2732

@@ -229,6 +234,56 @@ async def release(self, conn):
229234
async def close(self):
230235
await self._pool.close()
231236

237+
def repr(self, color):
238+
if color and not click:
239+
warnings.warn("Install click to get colorful repr.", ImportWarning)
240+
241+
if color and click:
242+
# noinspection PyProtectedMember
243+
return "<{classname} max={max} min={min} cur={cur} use={use}>".format(
244+
classname=click.style(
245+
self._pool.__class__.__module__
246+
+ "."
247+
+ self._pool.__class__.__name__,
248+
fg="green",
249+
),
250+
max=click.style(repr(self._pool._maxsize), fg="cyan"),
251+
min=click.style(repr(self._pool._minsize), fg="cyan"),
252+
cur=click.style(
253+
repr(
254+
len(
255+
[
256+
0
257+
for con in self._pool._holders
258+
if con._con and not con._con.is_closed()
259+
]
260+
)
261+
),
262+
fg="cyan",
263+
),
264+
use=click.style(
265+
repr(len([0 for con in self._pool._holders if con._in_use])),
266+
fg="cyan",
267+
),
268+
)
269+
else:
270+
# noinspection PyProtectedMember
271+
return "<{classname} max={max} min={min} cur={cur} use={use}>".format(
272+
classname=self._pool.__class__.__module__
273+
+ "."
274+
+ self._pool.__class__.__name__,
275+
max=self._pool._maxsize,
276+
min=self._pool._minsize,
277+
cur=len(
278+
[
279+
0
280+
for con in self._pool._holders
281+
if con._con and not con._con.is_closed()
282+
]
283+
),
284+
use=len([0 for con in self._pool._holders if con._in_use]),
285+
)
286+
232287

233288
class NullPool(base.Pool):
234289
# TODO: generic NullPool, abstracting connection part
@@ -247,6 +302,7 @@ def __init__(self, url, loop, **kwargs):
247302
password=url.password,
248303
)
249304
)
305+
self._count = 0
250306

251307
def __await__(self):
252308
async def return_self():
@@ -262,14 +318,33 @@ async def acquire(self, *, timeout=None):
262318
args = self._kwargs.copy()
263319
if timeout is not None:
264320
args.update(timeout=timeout)
265-
return await asyncpg.connect(loop=self._loop, **args)
321+
rv = await asyncpg.connect(loop=self._loop, **args)
322+
self._count += 1
323+
return rv
266324

267325
async def release(self, conn):
326+
self._count -= 1
268327
await conn.close()
269328

270329
async def close(self):
271330
pass
272331

332+
def repr(self, color):
333+
if color and not click:
334+
warnings.warn("Install click to get colorful repr.", ImportWarning)
335+
336+
if color and click:
337+
return "<{classname} max={max} min={min} cur={cur} use={cur}>".format(
338+
classname=click.style("NullPool", fg="green"),
339+
max=click.style("inf", fg="cyan"),
340+
min=click.style("0", fg="cyan"),
341+
cur=click.style(repr(self._count), fg="cyan"),
342+
)
343+
else:
344+
return "<NullPool max=inf min=0 cur={cur} use={cur}>".format(
345+
cur=self._count
346+
)
347+
273348

274349
class Transaction(base.Transaction):
275350
def __init__(self, tx):

‎src/gino/dialects/base.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ async def release(self, conn):
5555
async def close(self):
5656
raise NotImplementedError
5757

58+
def repr(self, color):
59+
return repr(self)
60+
5861

5962
class Transaction:
6063
@property

‎src/gino/engine.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,3 +857,9 @@ def update_execution_options(self, **opt):
857857
async def _run_visitor(self, *args, **kwargs):
858858
async with self.acquire(reuse=True) as conn:
859859
await getattr(conn, "_run_visitor")(*args, **kwargs)
860+
861+
def repr(self, color=False):
862+
return self._pool.repr(color)
863+
864+
def __repr__(self):
865+
return self.repr()

‎src/gino/loader.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ def distinct(self, *columns):
155155
def none_as_none(self, enabled=True):
156156
if not enabled:
157157
warnings.warn(
158-
"Disabling none_as_none is not supported.", PendingDeprecationWarning,
158+
"Disabling none_as_none is not supported.", DeprecationWarning,
159159
)
160160
return self
161161

‎tests/test_engine.py‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,3 +405,27 @@ async def test_null_pool():
405405
# noinspection PyProtectedMember
406406
raw_conn = conn.raw_connection._con
407407
assert not raw_conn.is_closed()
408+
409+
410+
async def test_repr():
411+
from gino.dialects.asyncpg import NullPool
412+
413+
e = await create_engine(PG_URL, pool_class=NullPool)
414+
assert 'cur=0' in repr(e)
415+
async with e.acquire():
416+
assert 'cur=1' in repr(e)
417+
async with e.acquire():
418+
assert 'cur=2' in repr(e)
419+
assert 'cur=1' in repr(e)
420+
assert 'cur=0' in repr(e)
421+
assert 'NullPool' in e.repr(color=True)
422+
423+
e = await create_engine(PG_URL)
424+
assert 'cur=10 use=0' in repr(e)
425+
async with e.acquire():
426+
assert 'cur=10 use=1' in repr(e)
427+
async with e.acquire():
428+
assert 'cur=10 use=2' in repr(e)
429+
assert 'cur=10 use=1' in repr(e)
430+
assert 'cur=10 use=0' in repr(e)
431+
assert 'asyncpg.pool.Pool' in e.repr(color=True)

0 commit comments

Comments
 (0)