Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-rpyc for openSUSE:Factory checked in at 2024-11-15 15:44:03 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-rpyc (Old) and /work/SRC/openSUSE:Factory/.python-rpyc.new.2017 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-rpyc" Fri Nov 15 15:44:03 2024 rev:15 rq:1224272 version:6.0.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-rpyc/python-rpyc.changes 2024-03-13 22:22:15.200402899 +0100 +++ /work/SRC/openSUSE:Factory/.python-rpyc.new.2017/python-rpyc.changes 2024-11-15 15:44:17.773070288 +0100 @@ -1,0 +2,9 @@ +Thu Nov 14 11:29:43 UTC 2024 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- Update to 6.0.1 + * Minor fixes to class module id packs and related unittest assertions + * #559 closes #558 which reported issues with proxy cache referrant + race conditions, get_method errors, and stream issues + * #557 fix pytest issues reported in #544 + +------------------------------------------------------------------- Old: ---- 6.0.0.tar.gz New: ---- 6.0.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-rpyc.spec ++++++ --- /var/tmp/diff_new_pack.m0P3Gt/_old 2024-11-15 15:44:18.389096090 +0100 +++ /var/tmp/diff_new_pack.m0P3Gt/_new 2024-11-15 15:44:18.389096090 +0100 @@ -26,7 +26,7 @@ %endif %{?sle15_python_module_pythons} Name: python-rpyc%{psuffix} -Version: 6.0.0 +Version: 6.0.1 Release: 0 Summary: Remote Python Call (RPyC), a RPC library License: MIT ++++++ 6.0.0.tar.gz -> 6.0.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/.github/workflows/python-app.yml new/rpyc-6.0.1/.github/workflows/python-app.yml --- old/rpyc-6.0.0/.github/workflows/python-app.yml 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/.github/workflows/python-app.yml 2024-09-25 06:24:13.000000000 +0200 @@ -10,22 +10,24 @@ branches: [ master ] jobs: - python-unittest-all-versions: + unittest: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] + python_version: ["3", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13.0-rc.2", "3.14.0-alpha.0"] + RPYC_BIND_THREADS: ["true", "false"] + name: Unittest (${{ matrix.python_version }}, bind_threads=${{ matrix.RPYC_BIND_THREADS }}) steps: - uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ matrix.python_version }} uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} + python_version: ${{ matrix.python_version }} - name: Install dependencies run: | python -m pip install --upgrade pip setuptools flake8 @@ -46,9 +48,11 @@ ssh-keygen -q -f ~/.ssh/id_rsa -N '' cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys uname -a - - name: Bind threads tests with unittest - run: | - RPYC_BIND_THREADS="true" python -m unittest discover -v - - name: Default tests with unittest + - name: Run unittest with default settings + if: ${{ matrix.RPYC_BIND_THREADS == 'false' }} run: | python -m unittest discover -v + - name: Run unittest with RPYC_BIND_THREADS enabled + if: ${{ matrix.RPYC_BIND_THREADS == 'true' }} + run: | + RPYC_BIND_THREADS="${{ matrix.RPYC_BIND_THREADS }}" python -m unittest discover -v diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/CHANGELOG.rst new/rpyc-6.0.1/CHANGELOG.rst --- old/rpyc-6.0.0/CHANGELOG.rst 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/CHANGELOG.rst 2024-09-25 06:24:13.000000000 +0200 @@ -1,3 +1,17 @@ +6.0.1 +===== +Date: 2024-09-24 + +- Minor fixes to class module id packs and related unittest assertions +- `#559`_ closes `#558`_ which reported issues with proxy cache referrant race conditions, get_method errors, and stream issues +- `#557`_ fix pytest issues reported in `#544`_ + +.. _#559: https://github.com/tomerfiliba-org/rpyc/pull/559 +.. _#558: https://github.com/tomerfiliba-org/rpyc/issues/558 +.. _#557: https://github.com/tomerfiliba-org/rpyc/pull/557 +.. _#544: https://github.com/tomerfiliba-org/rpyc/issues/544 + + 6.0.0 ===== Date: 2024-02-23 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/docs/docs/advanced-debugging.rst new/rpyc-6.0.1/docs/docs/advanced-debugging.rst --- old/rpyc-6.0.0/docs/docs/advanced-debugging.rst 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/docs/docs/advanced-debugging.rst 2024-09-25 06:24:13.000000000 +0200 @@ -11,7 +11,7 @@ .. code-block:: bash - versions=( 3.7 3.8 3.9 3.10 3.11 3.12) + versions=( 3.8 3.9 3.10 3.11 3.12 3.13.0rc2 3.14-dev) for ver in ${versions[@]}; do pyenv install --force ${ver} pyenv global ${ver} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/docs/docs/rpyc-release-process.rst new/rpyc-6.0.1/docs/docs/rpyc-release-process.rst --- old/rpyc-6.0.0/docs/docs/rpyc-release-process.rst 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/docs/docs/rpyc-release-process.rst 2024-09-25 06:24:13.000000000 +0200 @@ -33,8 +33,8 @@ owner="tomerfiliba-org" repo="rpyc" #url="https://github.com/${owner}/${repo}" - revisions="$(git rev-list $(hatch version)..HEAD | sed -z 's/\(.*\)\n/\1/;s/\n/|/g')" - numbers=( $(git log $(hatch version)..HEAD --no-merges --oneline | sed -nE 's/^.*#([0-9]+).*/\1/p' | sort -nu) ) + revisions="$(git rev-list $(pyenv exec hatch version)..HEAD | sed -z 's/\(.*\)\n/\1/;s/\n/|/g')" + numbers=( $(git log $(pyenv exec hatch version)..HEAD --no-merges --oneline | sed -nE 's/^.*#([0-9]+).*/\1/p' | sort -nu) ) issue_numbers="$(echo "${numbers[@]}" | sed 's/ /|/g')" # api_filter() { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/pyproject.toml new/rpyc-6.0.1/pyproject.toml --- old/rpyc-6.0.0/pyproject.toml 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/pyproject.toml 2024-09-25 06:24:13.000000000 +0200 @@ -9,7 +9,7 @@ description = "Remote Python Call (RPyC) is a transparent and symmetric distributed computing library" readme = "README.rst" license = {text = "MIT License"} -requires-python = ">=3.7" +requires-python = ">=3.8" authors = [ { name = "Tomer Filiba", email = "tomerfil...@gmail.com" }, { name = "James Stronz", email = "comrum...@archstrike.org" }, @@ -21,12 +21,13 @@ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Internet", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Object Brokering", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/rpyc/core/protocol.py new/rpyc-6.0.1/rpyc/core/protocol.py --- old/rpyc-6.0.0/rpyc/core/protocol.py 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/rpyc/core/protocol.py 2024-09-25 06:24:13.000000000 +0200 @@ -336,8 +336,8 @@ return self._local_objects[value] if label == consts.LABEL_REMOTE_REF: id_pack = (str(value[0]), value[1], value[2]) # so value is a id_pack - if id_pack in self._proxy_cache: - proxy = self._proxy_cache[id_pack] + proxy = self._proxy_cache.get(id_pack) # Ensure referents exist until we increment refcount issue #558 + if proxy is not None: proxy.____refcount__ += 1 # if cached then remote incremented refcount, so sync refcount else: proxy = self._netref_factory(id_pack) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/rpyc/core/stream.py new/rpyc-6.0.1/rpyc/core/stream.py --- old/rpyc-6.0.0/rpyc/core/stream.py 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/rpyc/core/stream.py 2024-09-25 06:24:13.000000000 +0200 @@ -326,7 +326,10 @@ :returns: a :class:`PipeStream` instance """ - return cls(sys.stdin, sys.stdout) + pipestream = cls(sys.stdin, sys.stdout) + sys.stdin = os.open(os.devnull, os.O_RDWR) + sys.stdout = sys.stdin + return pipestream @classmethod def create_pair(cls): @@ -405,7 +408,10 @@ @classmethod def from_std(cls): - return cls(sys.stdin, sys.stdout) + pipestream = cls(sys.stdin, sys.stdout) + sys.stdin = os.open(os.devnull, os.O_RDWR) + sys.stdout = sys.stdin + return pipestream @classmethod def create_pair(cls): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/rpyc/lib/__init__.py new/rpyc-6.0.1/rpyc/lib/__init__.py --- old/rpyc-6.0.0/rpyc/lib/__init__.py 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/rpyc/lib/__init__.py 2024-09-25 06:24:13.000000000 +0200 @@ -170,44 +170,50 @@ def get_id_pack(obj): - """introspects the given "local" object, returns id_pack as expected by BaseNetref + """introspects the given "local" object, returns id_pack as expected by + BaseNetref - The given object is "local" in the sense that it is from the local cache. Any object in the local cache exists - in the current address space or is a netref. A netref in the local cache could be from a chained-connection. - To handle type related behavior properly, the attribute `__class__` is a descriptor for netrefs. + The given object is "local" in the sense that it is from the local + cache. Any object in the local cache exists in the current address + space or is a netref. A netref in the local cache could be from a + chained-connection. To handle type related behavior properly, the + attribute `__class__` is a descriptor for netrefs. - So, check thy assumptions regarding the given object when creating `id_pack`. + So, check thy assumptions regarding the given object when creating + `id_pack`. """ - if hasattr(obj, '____id_pack__'): - # netrefs are handled first since __class__ is a descriptor - return obj.____id_pack__ - elif inspect.ismodule(obj) or getattr(obj, '__name__', None) == 'module': - # TODO: not sure about this, need to enumerate cases in units - if isinstance(obj, type): # module - obj_cls = type(obj) - name_pack = '{0}.{1}'.format(obj_cls.__module__, obj_cls.__name__) - return (name_pack, id(type(obj)), id(obj)) + undef = object() + name_pack = getattr(obj, '____id_pack__', undef) + if name_pack is not undef: + return name_pack + + obj_name = getattr(obj, '__name__', None) + if inspect.ismodule(obj): + # Handle instances of the module class. Since inspect.ismodule(obj) is False, + # the module class id pack must have zero for the instance object id. + if inspect.ismodule(obj) and obj_name != 'module': + if obj_name in sys.modules: + name_pack = obj_name + else: + obj_cls = getattr(obj, '__class__', type(obj)) + name_pack = f'{obj_cls.__module__}.{obj_name}' + elif inspect.ismodule(obj): + name_pack = '{obj.__module__}.{obj_name}' else: - if inspect.ismodule(obj) and obj.__name__ != 'module': - if obj.__name__ in sys.modules: - name_pack = obj.__name__ - else: - name_pack = '{0}.{1}'.format(obj.__class__.__module__, obj.__name__) - elif inspect.ismodule(obj): - name_pack = '{0}.{1}'.format(obj.__module__, obj.__name__) - print(name_pack) - elif hasattr(obj, '__module__'): - name_pack = '{0}.{1}'.format(obj.__module__, obj.__name__) + obj_module = getattr(obj, '__module__', undef) + if obj_module is not undef: + name_pack = f'{obj.__module__}.{obj_name}' else: - obj_cls = type(obj) - name_pack = '{0}'.format(obj.__name__) - return (name_pack, id(type(obj)), id(obj)) - elif not inspect.isclass(obj): - name_pack = '{0}.{1}'.format(obj.__class__.__module__, obj.__class__.__name__) + name_pack = obj_name return (name_pack, id(type(obj)), id(obj)) - else: - name_pack = '{0}.{1}'.format(obj.__module__, obj.__name__) - return (name_pack, id(obj), 0) + + if not inspect.isclass(obj): + obj_cls = getattr(obj, '__class__', type(obj)) + name_pack = f'{obj_cls.__module__}.{obj_cls.__name__}' + return (name_pack, id(type(obj)), id(obj)) + + name_pack = f'{obj.__module__}.{obj_name}' + return (name_pack, id(obj), 0) def get_methods(obj_attrs, obj): @@ -229,6 +235,6 @@ for basecls in mros: attrs.update(basecls.__dict__) for name, attr in attrs.items(): - if name not in obj_attrs and hasattr(attr, "__call__"): + if name not in obj_attrs and inspect.isroutine(attr): methods[name] = inspect.getdoc(attr) return methods.items() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/rpyc/version.py new/rpyc-6.0.1/rpyc/version.py --- old/rpyc-6.0.0/rpyc/version.py 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/rpyc/version.py 2024-09-25 06:24:13.000000000 +0200 @@ -1,3 +1,3 @@ -__version__ = '6.0.0' +__version__ = '6.0.1' version = tuple(__version__.split('.')) -release_date = "2024-02-23" +release_date = "2024-09-24" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/tests/test_affinity.py new/rpyc-6.0.1/tests/test_affinity.py --- old/rpyc-6.0.0/tests/test_affinity.py 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/tests/test_affinity.py 2024-09-25 06:24:13.000000000 +0200 @@ -1,7 +1,7 @@ import sys import time import unittest -import support +from tests import support import rpyc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/tests/test_attributes.py new/rpyc-6.0.1/tests/test_attributes.py --- old/rpyc-6.0.0/tests/test_attributes.py 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/tests/test_attributes.py 2024-09-25 06:24:13.000000000 +0200 @@ -26,7 +26,7 @@ self.conn.close() def test_properties(self): - p = self.conn.modules["test_attributes"].Properties() + p = self.conn.modules["tests.test_attributes"].Properties() print(p.counter) # 1 print(p.counter) # 2 print(p.counter) # 3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/tests/test_classic.py new/rpyc-6.0.1/tests/test_classic.py --- old/rpyc-6.0.0/tests/test_classic.py 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/tests/test_classic.py 2024-09-25 06:24:13.000000000 +0200 @@ -52,7 +52,7 @@ self.assertEqual(conn.eval("2+3"), 5) def test_modules(self): - self.assertIn('test_magic', self.conn.modules) + self.assertIn('tests.test_magic', self.conn.modules) self.assertNotIn('test_badmagic', self.conn.modules) self.assertIsNone(self.conn.builtins.locals()['self']._last_traceback) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/tests/test_magic.py new/rpyc-6.0.1/tests/test_magic.py --- old/rpyc-6.0.0/tests/test_magic.py 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/tests/test_magic.py 2024-09-25 06:24:13.000000000 +0200 @@ -37,7 +37,7 @@ def test_hash_class(self): hesh = self.conn.builtins.hash - mod = self.conn.modules.test_magic + mod = self.conn.modules.tests.test_magic self.assertEqual(hash(mod.Base), 4321) self.assertEqual(hash(mod.Foo), 4321) self.assertEqual(hash(mod.Bar), 4321) @@ -53,7 +53,7 @@ def test_hash_obj(self): hesh = self.conn.builtins.hash - mod = self.conn.modules.test_magic + mod = self.conn.modules.tests.test_magic obj = mod.Base() self.assertNotEqual(hash(obj), 1234) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/tests/test_netref_hierachy.py new/rpyc-6.0.1/tests/test_netref_hierachy.py --- old/rpyc-6.0.0/tests/test_netref_hierachy.py 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/tests/test_netref_hierachy.py 2024-09-25 06:24:13.000000000 +0200 @@ -108,15 +108,15 @@ def test_instancecheck_across_connections(self): self.conn2 = rpyc.classic.connect('localhost', port=18878) - self.conn.execute('import test_magic') - self.conn2.execute('import test_magic') - foo = self.conn.modules.test_magic.Foo() - bar = self.conn.modules.test_magic.Bar() - self.assertTrue(isinstance(foo, self.conn.modules.test_magic.Foo)) - self.assertTrue(isinstance(bar, self.conn2.modules.test_magic.Bar)) - self.assertFalse(isinstance(bar, self.conn.modules.test_magic.Foo)) + self.conn.execute('import tests.test_magic') + self.conn2.execute('import tests.test_magic') + foo = self.conn.modules.tests.test_magic.Foo() + bar = self.conn.modules.tests.test_magic.Bar() + self.assertTrue(isinstance(foo, self.conn.modules.tests.test_magic.Foo)) + self.assertTrue(isinstance(bar, self.conn2.modules.tests.test_magic.Bar)) + self.assertFalse(isinstance(bar, self.conn.modules.tests.test_magic.Foo)) with self.assertRaises(TypeError): - isinstance(self.conn.modules.test_magic.Foo, bar) + isinstance(self.conn.modules.tests.test_magic.Foo, bar) def test_classic(self): x = self.conn.builtin.list((1, 2, 3, 4)) @@ -177,10 +177,17 @@ >>> type(conn.modules.unittest.__class__) <class 'type'> # matches base case """ + # instance module assertions self.assertEqual(repr(self.conn.modules.unittest), repr(unittest)) self.assertEqual(repr(type(self.conn.modules.unittest)), "<netref class 'rpyc.core.netref.unittest'>") self.assertIs(self.conn.modules.unittest.__class__, type(unittest)) self.assertIs(type(self.conn.modules.unittest.__class__), type) + # class module assertions + remote_module_cls = self.conn.modules.builtins.type(self.conn.modules.sys) + remote_module_cls_id = self.conn.modules.builtins.id(remote_module_cls) + self.assertEqual(repr(remote_module_cls), "<class 'module'>") + self.assertEqual(remote_module_cls.____id_pack__, ('builtins.module', remote_module_cls_id, 0)) + def test_proxy_instancecheck(self): self.assertIsInstance(self.conn.modules.builtins.RuntimeError(), Exception) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rpyc-6.0.0/tests/test_service_pickle.py new/rpyc-6.0.1/tests/test_service_pickle.py --- old/rpyc-6.0.0/tests/test_service_pickle.py 2024-02-24 00:30:15.000000000 +0100 +++ new/rpyc-6.0.1/tests/test_service_pickle.py 2024-09-25 06:24:13.000000000 +0200 @@ -4,7 +4,7 @@ import timeit import rpyc import unittest -import cfg_tests +from tests import cfg_tests try: import pandas as pd import numpy as np