Skip to content

Commit b22c92c

Browse files
committed
Property on the Client to enable/disable logging
1 parent c36b287 commit b22c92c

File tree

5 files changed

+71
-13
lines changed

5 files changed

+71
-13
lines changed

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ Changelog
2929
* Add private method :meth:`Record._invalidate_cache` to implement
3030
:meth:`Record.refresh`.
3131

32+
* Property :attr:`Client.verbose` to enable/disable logging.
33+
3234

3335
2.4.7 (2025-11-07)
3436
~~~~~~~~~~~~~~~~~~

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ This is a sample session::
117117

118118
It's also possible to set verbosity from the interactive prompt::
119119

120-
>>> client._printer.cols = 180
120+
>>> client.verbose = 180 # Width in columns
121121

122122
.. note::
123123

odooly.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -414,15 +414,13 @@ class ServerError(Exception):
414414

415415

416416
class Printer:
417-
def __init__(self, cols):
418-
self.cols = MAXCOL[min(3, cols) - 1] if (cols or 9) < 9 else cols or None
417+
cols = None
419418

420419
def _print_(self, message, _prefix):
421-
cols = max(36, self.cols)
422420
xch = str(message)
423-
if len(xch) > cols:
421+
if len(xch) > self.cols:
424422
suffix = f"... L={len(xch)}"
425-
xch = xch[:cols - len(suffix)] + suffix
423+
xch = xch[:self.cols - len(suffix)] + suffix
426424
print(f"{_prefix} {xch}")
427425

428426
print_sent = functools.partialmethod(_print_, _prefix='-->')
@@ -1174,19 +1172,29 @@ class Client:
11741172
def __init__(self, server, db=None, user=None, password=None,
11751173
api_key=None, transport=None, verbose=False):
11761174
self._http = HTTPSession()
1175+
self._printer = Printer()
11771176
self._session_uid = None
1178-
self._set_services(server, db, transport, verbose)
1177+
self.verbose = verbose
1178+
self._set_services(server, db, transport)
11791179
self.env = Env(self)
11801180
if user: # Try to login
11811181
self.login(user, password=password, api_key=api_key, database=db)
11821182

1183-
def _set_services(self, server, db, transport, cols):
1183+
@property
1184+
def verbose(self):
1185+
return self._printer.cols
1186+
1187+
@verbose.setter
1188+
def verbose(self, cols):
1189+
cols = MAXCOL[min(3, cols) - 1] if (cols or 9) < 9 else cols
1190+
self._printer.cols = cols and max(36, cols) or None
1191+
1192+
def _set_services(self, server, db, transport):
11841193
if isinstance(server, list):
11851194
appname = Path(__file__).name.rstrip('co')
11861195
server = start_odoo_services(server, appname=appname)
11871196
elif isinstance(server, str) and server[-1:] == '/':
11881197
server = server.rstrip('/')
1189-
self._printer = Printer(cols)
11901198
self._server = server
11911199
self._connections = []
11921200

@@ -1329,7 +1337,7 @@ def from_config(cls, environment, user=None, verbose=False):
13291337
password = None
13301338
try:
13311339
client = Env._cache[Env, db, server].client
1332-
client._printer.__init__(verbose)
1340+
client.verbose = verbose
13331341
client.login(user or conf_user, password=password, api_key=api_key)
13341342
except KeyError:
13351343
client = cls(server, db, user or conf_user, password=password, api_key=api_key, verbose=verbose)
@@ -1469,11 +1477,11 @@ def connect(self, env_name=None, *, server=None, user=None):
14691477
"""Connect to another environment and replace the globals()."""
14701478
assert self._is_interactive(), 'Not available'
14711479
if env_name:
1472-
self.from_config(env_name, user=user, verbose=self._printer.cols)
1480+
self.from_config(env_name, user=user, verbose=self.verbose)
14731481
elif server:
14741482
if not user and self.env.uid:
14751483
user = self.env.user.login
1476-
self.__class__(server, user=user, verbose=self._printer.cols)
1484+
self.__class__(server, user=user, verbose=self.verbose)
14771485
else:
14781486
assert not user, "Use client.login(...) instead"
14791487
self._globals['client'] = self.env.client

tests/test_client.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,25 @@ def test_module_upgrade(self):
365365
)
366366
self.assertOutput(ANY)
367367

368+
def test_client_verbose(self):
369+
client = self.client
370+
371+
self.assertIsNone(client.verbose)
372+
373+
client.verbose = 1
374+
self.assertEqual(client.verbose, 79)
375+
376+
client.verbose = 3
377+
self.assertEqual(client.verbose, 9999)
378+
379+
client.verbose = 140
380+
self.assertEqual(client.verbose, 140)
381+
self.assertEqual(client._printer.cols, 140)
382+
383+
client.verbose = 0
384+
self.assertIsNone(client.verbose)
385+
self.assertIsNone(client._printer.cols)
386+
368387

369388
class TestClientApi(XmlRpcTestCase):
370389
"""Test the Client API."""

tests/test_util.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from functools import partial
22
from unittest import TestCase
33

4-
from odooly import issearchdomain, searchargs, Model
4+
from odooly import issearchdomain, searchargs, Model, Client, Printer
55

66

77
class TestUtils(TestCase):
@@ -141,3 +141,32 @@ def test_readfmt(self):
141141

142142
(fields, fmt) = readfmt('a {color} elephant enters {location[1]}.\n\n{firstname!r} has left')
143143
self.assertEqual(fields, ['color', 'location', 'firstname'])
144+
145+
def test_printer(self):
146+
# Verbosity None or 0 --> disable logging
147+
# Verbosity 1 to 8 --> mapped 1 -> 79 / 2 -> 179 / 3+ -> 9999
148+
# Verbosity >= 36 --> width to print in columns
149+
client = object.__new__(Client)
150+
client._printer = Printer()
151+
client.verbose = 2
152+
self.assertEqual(client._printer.cols, 179)
153+
self.assertEqual(client.verbose, 179)
154+
client.verbose = 3
155+
self.assertEqual(client._printer.cols, 9999)
156+
client.verbose = 250
157+
self.assertEqual(client._printer.cols, 250)
158+
client.verbose = None
159+
self.assertIsNone(client._printer.cols)
160+
client.verbose = 64
161+
self.assertEqual(client._printer.cols, 64)
162+
self.assertEqual(client.verbose, 64)
163+
client.verbose = True
164+
self.assertEqual(client._printer.cols, 79)
165+
client.verbose = 8
166+
self.assertEqual(client._printer.cols, 9999)
167+
self.assertEqual(client.verbose, 9999)
168+
client.verbose = 0
169+
self.assertIsNone(client._printer.cols)
170+
171+
self.assertRaises(TypeError, setattr, client, 'verbose', 'a')
172+
self.assertRaises(IndexError, setattr, client, 'verbose', -4)

0 commit comments

Comments
 (0)