[gentoo-portage-dev] [PATCH gentoolkit] equery: Remove 'changes' subcommand

2021-01-04 Thread Matt Turner
ChangeLogs have been gone from gentoo.git since the beginning, and
Council agreed in 2016 to allow Infra to decide whether to distribute
them through rsync, which they have decided not to do [1].

[1] https://projects.gentoo.org/council/meeting-logs/20160410-summary.txt

Signed-off-by: Matt Turner 
---
 pym/gentoolkit/equery/__init__.py   |   1 -
 pym/gentoolkit/equery/changes.py| 184 
 pym/gentoolkit/helpers.py   | 173 --
 pym/gentoolkit/test/equery/test_init.py |   1 -
 pym/gentoolkit/test/test_helpers.py |  47 --
 5 files changed, 406 deletions(-)
 delete mode 100644 pym/gentoolkit/equery/changes.py

diff --git a/pym/gentoolkit/equery/__init__.py 
b/pym/gentoolkit/equery/__init__.py
index 4640086..677f534 100644
--- a/pym/gentoolkit/equery/__init__.py
+++ b/pym/gentoolkit/equery/__init__.py
@@ -42,7 +42,6 @@ __authors__ = (
 
 NAME_MAP = {
'b': 'belongs',
-   'c': 'changes',
'k': 'check',
'd': 'depends',
'g': 'depgraph',
diff --git a/pym/gentoolkit/equery/changes.py b/pym/gentoolkit/equery/changes.py
deleted file mode 100644
index f234ecb..000
--- a/pym/gentoolkit/equery/changes.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# Copyright(c) 2009, Gentoo Foundation
-#
-# Licensed under the GNU General Public License, v2 or higher
-
-"""Displays the ChangeLog entry for the latest installable version of an 
atom"""
-
-__docformat__ = 'epytext'
-
-# ===
-# Imports
-# ===
-
-import sys
-import os
-from getopt import gnu_getopt, GetoptError
-
-import gentoolkit.pprinter as pp
-from gentoolkit.atom import Atom
-from gentoolkit.equery import format_options, mod_usage
-from gentoolkit.helpers import ChangeLog
-from gentoolkit.query import Query
-
-# ===
-# Globals
-# ===
-
-QUERY_OPTS = {
-   'only_latest': False,
-   'show_full_log': False,
-   'limit': None,
-   'from': None,
-   'to': None
-}
-
-# =
-# Functions
-# =
-
-def print_help(with_description=True):
-   """Print description, usage and a detailed help message.
-
-   @type with_description: bool
-   @param with_description: if true, print module's __doc__ string
-   """
-
-   if with_description:
-   print(__doc__.strip())
-   print()
-   print(mod_usage(mod_name="changes"))
-   print()
-   print(pp.emph("examples"))
-   print (" c portage# show latest visible 
"
-  "version's entry")
-   print(" c portage --full --limit=3   # show 3 latest 
entries")
-   print(" c '=sys-apps/portage-2.1.6*' # use atom syntax")
-   print(" c portage --from=2.2_rc60 --to=2.2_rc70  # use version ranges")
-   print()
-   print(pp.command("options"))
-   print(format_options((
-   (" -h, --help", "display this help message"),
-   (" -l, --latest", "display only the latest ChangeLog entry"),
-   (" -f, --full", "display the full ChangeLog"),
-   (" --limit=NUM",
-   "limit the number of entries displayed (with --full)"),
-   (" --from=VER", "set which version to display from"),
-   (" --to=VER", "set which version to display to"),
-   )))
-
-
-def parse_module_options(module_opts):
-   """Parse module options and update QUERY_OPTS"""
-
-   opts = (x[0] for x in module_opts)
-   posargs = (x[1] for x in module_opts)
-   for opt, posarg in zip(opts, posargs):
-   if opt in ('-h', '--help'):
-   print_help()
-   sys.exit(0)
-   elif opt in ('-f', '--full'):
-   QUERY_OPTS['show_full_log'] = True
-   elif opt in ('-l', '--latest'):
-   QUERY_OPTS['only_latest'] = True
-   elif opt in ('--limit',):
-   set_limit(posarg)
-   elif opt in ('--from',):
-   QUERY_OPTS['from'] = posarg
-   elif opt in ('--to',):
-   QUERY_OPTS['to'] = posarg
-
-
-def print_entries(entries):
-   """Print entries and strip trailing whitespace from the last entry."""
-
-   len_entries = len(entries)
-   for i, entry in enumerate(entries, start=1):
-   if i < len_entries:
-   pp.uprint(entry)
-   else:
-   pp.uprint(entry.strip())
-
-
-def set_limit(posarg):
-   """Set a limit in QUERY_OPTS on how many ChangeLog entries to display.
-
-   Die if posarg is not an integer.
-   """
-
-   if posarg.isdigit():
-   QUERY_OPTS['limit'] = int(posarg)
-   else:
-   err = "Module option --limit requires integer (got '%s')"
-   sys.stderr.write(pp.error(err % posarg))
-   print()
-   print_help(with_description=False)
- 

[gentoo-portage-dev] [PATCH gentoolkit] gentoolkit: Remove gentoolkit.test.cmp

2021-01-04 Thread Matt Turner
Signed-off-by: Matt Turner 
---
Seems to only be used by duplicated unit tests? I guess this might have
been useful when Python 2 was still supported?

 pym/gentoolkit/test/__init__.py  | 23 ---
 pym/gentoolkit/test/test_atom.py | 15 ---
 pym/gentoolkit/test/test_cpv.py  | 15 ---
 3 files changed, 53 deletions(-)

diff --git a/pym/gentoolkit/test/__init__.py b/pym/gentoolkit/test/__init__.py
index 9e41686..e69de29 100644
--- a/pym/gentoolkit/test/__init__.py
+++ b/pym/gentoolkit/test/__init__.py
@@ -1,23 +0,0 @@
-#!/usr/bin/python
-# Copyright 2009 Gentoo Foundation
-#
-# Distributed under the terms of the GNU General Public License v2
-
-__all__ = ['cmp']
-
-# py3k doesn't have cmp emulate it in order to keep testing cmp
-# in python-2.x
-#XXX: not sure if this is the best place for this
-try:
-   cmp = cmp
-except NameError:
-   def cmp(a, b):
-   if a == b:
-   return 0
-   elif a < b:
-   return -1
-   elif a > b:
-   return 1
-   # just to be safe, __lt__/ __gt__ above should have thrown
-   # something like this already
-   raise TypeError("Comparison between unorderable types")
diff --git a/pym/gentoolkit/test/test_atom.py b/pym/gentoolkit/test/test_atom.py
index 664bf40..6df52a9 100644
--- a/pym/gentoolkit/test/test_atom.py
+++ b/pym/gentoolkit/test/test_atom.py
@@ -7,7 +7,6 @@ import unittest
 
 from gentoolkit.atom import Atom
 from gentoolkit.cpv import CPV
-from gentoolkit.test import cmp
 
 """Atom test suite (verbatim) from pkgcore."""
 
@@ -17,26 +16,12 @@ class TestGentoolkitAtom(unittest.TestCase):
# logic bugs hidden behind short circuiting comparisons for 
metadata
# is why we test the comparison *both* ways.
self.assertEqual(o1, o2)
-   c = cmp(o1, o2)
-   self.assertEqual(c, 0,
-   msg="checking cmp for %r, %r, aren't equal: got %i" % 
(o1, o2, c))
self.assertEqual(o2, o1)
-   c = cmp(o2, o1)
-   self.assertEqual(c, 0,
-   msg="checking cmp for %r, %r,aren't equal: got %i" % 
(o2, o1, c))
 
def assertNotEqual2(self, o1, o2):
# is why we test the comparison *both* ways.
self.assertNotEqual(o1, o2)
-   c = cmp(o1, o2)
-   self.assertNotEqual(c, 0,
-   msg="checking cmp for %r, %r, not supposed to be equal, 
got %i"
-   % (o1, o2, c))
self.assertNotEqual(o2, o1)
-   c = cmp(o2, o1)
-   self.assertNotEqual(c, 0,
-   msg="checking cmp for %r, %r, not supposed to be equal, 
got %i"
-   % (o2, o1, c))
 
def test_comparison(self):
self.assertEqual2(Atom('cat/pkg'), Atom('cat/pkg'))
diff --git a/pym/gentoolkit/test/test_cpv.py b/pym/gentoolkit/test/test_cpv.py
index 3817e9f..92ffba5 100644
--- a/pym/gentoolkit/test/test_cpv.py
+++ b/pym/gentoolkit/test/test_cpv.py
@@ -7,7 +7,6 @@
 import unittest
 
 from gentoolkit.cpv import CPV, compare_strs
-from gentoolkit.test import cmp
 
 class TestGentoolkitCPV(unittest.TestCase):
 
@@ -15,26 +14,12 @@ class TestGentoolkitCPV(unittest.TestCase):
# logic bugs hidden behind short circuiting comparisons for 
metadata
# is why we test the comparison *both* ways.
self.assertEqual(o1, o2)
-   c = cmp(o1, o2)
-   self.assertEqual(c, 0,
-   msg="checking cmp for %r, %r, aren't equal: got %i" % 
(o1, o2, c))
self.assertEqual(o2, o1)
-   c = cmp(o2, o1)
-   self.assertEqual(c, 0,
-   msg="checking cmp for %r, %r,aren't equal: got %i" % 
(o2, o1, c))
 
def assertNotEqual2(self, o1, o2):
# is why we test the comparison *both* ways.
self.assertNotEqual(o1, o2)
-   c = cmp(o1, o2)
-   self.assertNotEqual(c, 0,
-   msg="checking cmp for %r, %r, not supposed to be equal, 
got %i"
-   % (o1, o2, c))
self.assertNotEqual(o2, o1)
-   c = cmp(o2, o1)
-   self.assertNotEqual(c, 0,
-   msg="checking cmp for %r, %r, not supposed to be equal, 
got %i"
-   % (o2, o1, c))
 
def test_comparison(self):
self.assertEqual2(CPV('pkg'), CPV('pkg'))
-- 
2.26.2




[gentoo-portage-dev] Re: [PATCH] global_event_loop: return running loop for current thread

2021-01-04 Thread Zac Medico
On 1/4/21 1:06 AM, Zac Medico wrote:
> Like asyncio.get_event_loop(), return the running loop for the
> current thread if there is one, and otherwise construct a new
> one if needed. This allows the _safe_loop function to become
> synonymous with the global_event_loop function.
> 
> Bug: https://bugs.gentoo.org/763339
> Signed-off-by: Zac Medico 
> ---
>  .../util/_eventloop/global_event_loop.py  | 28 ++-
>  lib/portage/util/futures/_asyncio/__init__.py | 22 ++-
>  2 files changed, 17 insertions(+), 33 deletions(-)

For the case of "loop running in non-main thread" of API consumer, this
change makes portage compatible with PEP 492 coroutines with async and
await syntax. Portage internals can safely begin using async / await
syntax instead of compat_coroutine.
-- 
Thanks,
Zac



signature.asc
Description: OpenPGP digital signature


[gentoo-portage-dev] [PATCH] global_event_loop: return running loop for current thread

2021-01-04 Thread Zac Medico
Like asyncio.get_event_loop(), return the running loop for the
current thread if there is one, and otherwise construct a new
one if needed. This allows the _safe_loop function to become
synonymous with the global_event_loop function.

Bug: https://bugs.gentoo.org/763339
Signed-off-by: Zac Medico 
---
 .../util/_eventloop/global_event_loop.py  | 28 ++-
 lib/portage/util/futures/_asyncio/__init__.py | 22 ++-
 2 files changed, 17 insertions(+), 33 deletions(-)

diff --git a/lib/portage/util/_eventloop/global_event_loop.py 
b/lib/portage/util/_eventloop/global_event_loop.py
index 413011178..bf314dc34 100644
--- a/lib/portage/util/_eventloop/global_event_loop.py
+++ b/lib/portage/util/_eventloop/global_event_loop.py
@@ -1,28 +1,4 @@
-# Copyright 2012-2020 Gentoo Authors
+# Copyright 2012-2021 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
-import portage
-from portage.util._eventloop.asyncio_event_loop import AsyncioEventLoop
-
-_instances = {}
-
-
-def global_event_loop():
-   """
-   Get a global EventLoop (or compatible object) instance which
-   belongs exclusively to the current process.
-   """
-
-   pid = portage.getpid()
-   instance = _instances.get(pid)
-   if instance is not None:
-   return instance
-
-   constructor = AsyncioEventLoop
-
-   # Use the _asyncio_wrapper attribute, so that unit tests can compare
-   # the reference to one retured from _wrap_loop(), since they should
-   # not close the loop if it refers to a global event loop.
-   instance = constructor()._asyncio_wrapper
-   _instances[pid] = instance
-   return instance
+from portage.util.futures._asyncio import _safe_loop as global_event_loop
diff --git a/lib/portage/util/futures/_asyncio/__init__.py 
b/lib/portage/util/futures/_asyncio/__init__.py
index d39f31786..ab1468d43 100644
--- a/lib/portage/util/futures/_asyncio/__init__.py
+++ b/lib/portage/util/futures/_asyncio/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2018-2020 Gentoo Authors
+# Copyright 2018-2021 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
 __all__ = (
@@ -37,9 +37,6 @@ portage.proxy.lazyimport.lazyimport(globals(),
'portage.util.futures:compat_coroutine@_compat_coroutine',
 )
 from portage.util._eventloop.asyncio_event_loop import AsyncioEventLoop as 
_AsyncioEventLoop
-from portage.util._eventloop.global_event_loop import (
-   global_event_loop as _global_event_loop,
-)
 # pylint: disable=redefined-builtin
 from portage.util.futures.futures import (
CancelledError,
@@ -238,7 +235,7 @@ def _wrap_loop(loop=None):
# The default loop returned by _wrap_loop should be consistent
# with global_event_loop, in order to avoid accidental registration
# of callbacks with a loop that is not intended to run.
-   loop = loop or _global_event_loop()
+   loop = loop or _safe_loop()
return (loop if hasattr(loop, '_asyncio_wrapper')
else _AsyncioEventLoop(loop=loop))
 
@@ -267,8 +264,9 @@ def _safe_loop():
@rtype: asyncio.AbstractEventLoop (or compatible)
@return: event loop instance
"""
-   if portage._internal_caller or threading.current_thread() is 
threading.main_thread():
-   return _global_event_loop()
+   loop = _get_running_loop()
+   if loop is not None:
+   return loop
 
thread_key = threading.get_ident()
with _thread_weakrefs.lock:
@@ -286,6 +284,16 @@ def _safe_loop():
return loop
 
 
+def _get_running_loop():
+   with _thread_weakrefs.lock:
+   if _thread_weakrefs.pid == portage.getpid():
+   try:
+   loop = 
_thread_weakrefs.loops[threading.get_ident()]
+   except KeyError:
+   return None
+   return loop if loop.is_running() else None
+
+
 def _thread_weakrefs_atexit():
with _thread_weakrefs.lock:
if _thread_weakrefs.pid == portage.getpid():
-- 
2.26.2