Add pairwise_longest tools

This commit is contained in:
Cédric Krier
2023-10-18 23:11:07 +02:00
parent 7e2c1f8cbd
commit 420e0a48d6
10 changed files with 43 additions and 50 deletions
+2 -8
View File
@@ -1,6 +1,5 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from itertools import tee, zip_longest
from dateutil.relativedelta import relativedelta
@@ -18,15 +17,10 @@ from trytond.modules.currency.fields import Monetary
from trytond.modules.product import price_digits
from trytond.pool import Pool
from trytond.pyson import Eval, If
from trytond.tools import pairwise_longest
from trytond.transaction import Transaction
def pairwise(iterable):
a, b = tee(iterable)
next(b, None)
return zip_longest(a, b)
class Agent(ModelView, ModelSQL):
"Commission Reporting per Agent"
__name__ = 'commission.reporting.agent'
@@ -121,7 +115,7 @@ class Agent(ModelView, ModelSQL):
@property
def time_series_all(self):
delta = self._period_delta()
for ts, next_ts in pairwise(self.time_series or []):
for ts, next_ts in pairwise_longest(self.time_series or []):
yield ts
if delta and next_ts:
date = ts.date + delta
+2 -8
View File
@@ -1,6 +1,5 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from itertools import tee, zip_longest
try:
import pygal
@@ -17,15 +16,10 @@ from trytond.model import ModelSQL, ModelView, fields
from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool
from trytond.pyson import Eval, If
from trytond.tools import pairwise_longest
from trytond.transaction import Transaction
def pairwise(iterable):
a, b = tee(iterable)
next(b, None)
return zip_longest(a, b)
class Abstract(ModelSQL):
company = fields.Many2One(
@@ -122,7 +116,7 @@ class Abstract(ModelSQL):
@property
def time_series_all(self):
delta = self._period_delta()
for ts, next_ts in pairwise(self.time_series or []):
for ts, next_ts in pairwise_longest(self.time_series or []):
yield ts
if delta and next_ts:
date = ts.date + delta
+2 -9
View File
@@ -2,7 +2,6 @@
# this repository contains the full copyright notices and license terms.
from collections import defaultdict
from decimal import Decimal
from itertools import tee, zip_longest
try:
import pygal
@@ -20,17 +19,11 @@ from trytond.model import ModelSQL, ModelView, UnionMixin, fields, sum_tree
from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool
from trytond.pyson import Eval, If
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice, pairwise_longest, reduce_ids
from trytond.transaction import Transaction
from trytond.wizard import StateAction, StateTransition, Wizard
def pairwise(iterable):
a, b = tee(iterable)
next(b, None)
return zip_longest(a, b)
class Abstract(ModelSQL):
company = fields.Many2One(
@@ -190,7 +183,7 @@ class Abstract(ModelSQL):
@property
def time_series_all(self):
delta = self._period_delta()
for ts, next_ts in pairwise(self.time_series or []):
for ts, next_ts in pairwise_longest(self.time_series or []):
yield ts
if delta and next_ts:
date = ts.date + delta
@@ -1,8 +1,6 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from itertools import tee, zip_longest
from dateutil.relativedelta import relativedelta
from sql import Literal, Null, With
from sql.aggregate import Count, Min, Sum
@@ -19,15 +17,10 @@ from trytond.model import ModelSQL, ModelView, fields
from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool
from trytond.pyson import Eval, If
from trytond.tools import pairwise_longest
from trytond.transaction import Transaction
def pairwise(iterable):
a, b = tee(iterable)
next(b, None)
return zip_longest(a, b)
class Abstract(ModelSQL):
company = fields.Many2One(
@@ -201,7 +194,7 @@ class Abstract(ModelSQL):
@property
def time_series_all(self):
delta = self._period_delta()
for ts, next_ts in pairwise(self.time_series or []):
for ts, next_ts in pairwise_longest(self.time_series or []):
yield ts
if delta and next_ts:
date = ts.date + delta
+2 -9
View File
@@ -3,7 +3,6 @@
from collections import defaultdict
from decimal import Decimal
from itertools import tee, zip_longest
from sql import Literal, Null, With
from sql.aggregate import Max, Min, Sum
@@ -21,16 +20,10 @@ from trytond.model import ModelSQL, ModelView, fields, sum_tree
from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool
from trytond.pyson import Eval, If
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice, pairwise_longest, reduce_ids
from trytond.transaction import Transaction
def pairwise(iterable):
a, b = tee(iterable)
next(b, None)
return zip_longest(a, b)
class Abstract(ModelSQL, ModelView):
company = fields.Many2One(
@@ -211,7 +204,7 @@ class Abstract(ModelSQL, ModelView):
@property
def time_series_all(self):
delta = self._period_delta()
for ts, next_ts in pairwise(self.time_series or []):
for ts, next_ts in pairwise_longest(self.time_series or []):
yield ts
if delta and next_ts:
date = ts.date + delta
+1
View File
@@ -1,3 +1,4 @@
* Add pairwise_longest tools
* Add support for Python 3.12
* Support default values for autocomplete
* Support default value from context
+8
View File
@@ -16,6 +16,14 @@ Miscellaneous
Return the path of the named directory in subdir from root directory.
.. function:: pairwise_longest(iterable)
Return successive overlapping pairs taken from the input iterable.
The number of 2-tuples in the output iterator will be the number of inputs
and ends with the ``None``.
It will be empty if the input iterable has fewer than two values.
.. function:: resolve(name)
Resolve a dotted name to a global object.
+13 -3
View File
@@ -13,9 +13,10 @@ import sql.operators
from trytond.tools import (
decimal_, escape_wildcard, file_open, firstline, grouped_slice,
is_full_text, is_instance_method, likify, lstrip_wildcard, reduce_domain,
reduce_ids, remove_forbidden_chars, rstrip_wildcard, slugify,
sortable_values, strip_wildcard, timezone, unescape_wildcard)
is_full_text, is_instance_method, likify, lstrip_wildcard,
pairwise_longest, reduce_domain, reduce_ids, remove_forbidden_chars,
rstrip_wildcard, slugify, sortable_values, strip_wildcard, timezone,
unescape_wildcard)
from trytond.tools.domain_inversion import (
canonicalize, concat, domain_inversion, eval_domain,
extract_reference_models, localize_domain, merge, parse,
@@ -128,6 +129,15 @@ class ToolsTestCase(unittest.TestCase):
list(map(list, grouped_slice((x for x in range(10)), 5))),
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])
def test_pairwise_longest(self):
"Test pairwise_longest"
self.assertEqual(
list(pairwise_longest(range(3))), [(0, 1), (1, 2), (2, None)])
def test_pairwise_longest_empty(self):
"Test pairwise_longest empty"
self.assertEqual(list(pairwise_longest([])), [])
def test_is_instance_method(self):
'Test is_instance_method'
+4 -3
View File
@@ -16,9 +16,9 @@ from .decimal_ import decistmt
from .misc import (
escape_wildcard, file_open, find_dir, find_path, firstline,
get_smtp_server, grouped_slice, is_full_text, is_instance_method, likify,
lstrip_wildcard, reduce_domain, reduce_ids, remove_forbidden_chars,
resolve, rstrip_wildcard, slugify, sortable_values, sql_pairing,
strip_wildcard, unescape_wildcard)
lstrip_wildcard, pairwise_longest, reduce_domain, reduce_ids,
remove_forbidden_chars, resolve, rstrip_wildcard, slugify, sortable_values,
sql_pairing, strip_wildcard, unescape_wildcard)
class ClassProperty(property):
@@ -52,6 +52,7 @@ __all__ = [
is_instance_method,
likify,
lstrip_wildcard,
pairwise_longest,
reduce_domain,
reduce_ids,
remove_forbidden_chars,
+7 -1
View File
@@ -14,7 +14,7 @@ import warnings
from array import array
from collections.abc import Sized
from functools import wraps
from itertools import islice
from itertools import islice, tee, zip_longest
from sql import Literal
from sql.conditionals import Case
@@ -174,6 +174,12 @@ def grouped_slice(records, count=None):
yield islice(records, i, i + count)
def pairwise_longest(iterable):
a, b = tee(iterable)
next(b, None)
return zip_longest(a, b)
def is_instance_method(cls, method):
for klass in cls.__mro__:
type_ = klass.__dict__.get(method)