From 1fc074a49e2552f661d682669c248347f43dd56c Mon Sep 17 00:00:00 2001 From: Xinyu Ma Date: Thu, 29 Apr 2021 19:24:07 -0700 Subject: [PATCH] Prepare release 0.3a1-2 Drop Python 3.6 support --- .github/workflows/pythonpackage.yml | 6 ++--- CHANGELOG.rst | 12 ++++++++-- README.rst | 2 +- docs/requirements.txt | 4 ++-- setup.py | 5 ++-- src/ndn/__init__.py | 2 +- src/ndn/app.py | 36 ++++++++++++++--------------- src/ndn/schema/schema_tree.py | 2 +- src/ndn/transport/stream_socket.py | 2 +- tests/integration/app_test.py | 8 +++++-- 10 files changed, 45 insertions(+), 34 deletions(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index d1c70fc..e8b03f0 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -9,12 +9,12 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ['3.6', '3.8', 'pypy3'] + python-version: ['3.7', '3.9', 'pypy-3.7'] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f47ed32..715a768 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,9 +1,17 @@ Changelog ========= -Master -- (latest) -++++++++++++++++++ +0.3a1-2 (2021-04-29) +++++++++++++++++++++ +* Handle ConnectionResetError. +* Drop Python 3.6 support. + +0.3a1-1 (2021-01-31) +++++++++++++++++++++ * Transfer the repo to ``named-data/python-ndn``. +* Fix cocoapy to make it work on MacOS 11 Big Sur. +* Add more supports to NDNLPv2 (CongestionMark). +* Add dispatcher and set_interest_filter. 0.3a1 (2020-09-24) ++++++++++++++++++ diff --git a/README.rst b/README.rst index 1c9f299..be4d5bf 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ python-ndn A Named Data Networking client library with AsyncIO support in Python 3. -It supports Python >=3.6 and PyPy3 >=7.1.1. +It supports Python >=3.7 and PyPy3 >=7.1.1. Please see our documentation_ if you have any issues. diff --git a/docs/requirements.txt b/docs/requirements.txt index 7a56970..57edd07 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ Sphinx>=3.2.1 sphinx-rtd-theme>=0.5.0 sphinx-autodoc-typehints>=1.11.0 -pycryptodomex>=3.8.2 -pygtrie>=2.3.2 +pycryptodomex>=3.10.1 +pygtrie>=2.4.2 diff --git a/setup.py b/setup.py index 845e55d..0c22706 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ version = re.search(r'__version__ = "(.*?)"', f.read()).group(1) -requirements = ['pycryptodomex >= 3.9.9', 'pygtrie >= 2.3.3', 'dataclasses >= 0.6'] +requirements = ['pycryptodomex >= 3.10.1', 'pygtrie >= 2.4.2'] setup( name='python-ndn', version=version, @@ -35,7 +35,6 @@ 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', @@ -47,7 +46,7 @@ package_dir={'': 'src'}, install_requires=requirements, - python_requires=">=3.6", + python_requires=">=3.7", extras_require={ "dev": ["pytest>=5.3.5", "pytest-cov>=2.8.1", "flake8>=3.7.9"], } diff --git a/src/ndn/__init__.py b/src/ndn/__init__.py index bf566f8..2dd9ba2 100644 --- a/src/ndn/__init__.py +++ b/src/ndn/__init__.py @@ -1 +1 @@ -__version__ = "0.3a1-1" +__version__ = "0.3a1-2" diff --git a/src/ndn/app.py b/src/ndn/app.py index fbbb4a3..9086dbe 100644 --- a/src/ndn/app.py +++ b/src/ndn/app.py @@ -213,7 +213,7 @@ def express_interest(self, kwargs['nonce'] = gen_nonce() interest_param = InterestParam.from_dict(kwargs) interest, final_name = make_interest(name, interest_param, app_param, signer=signer, need_final_name=True) - future = aio.get_event_loop().create_future() + future = aio.get_running_loop().create_future() node = self._int_tree.setdefault(final_name, InterestTreeNode()) node.append_interest(future, interest_param) self.face.send(interest) @@ -240,11 +240,13 @@ async def _wait_for_data(self, future: aio.Future, lifetime: int, name: FormalNa else: raise ValidationFailure(name, meta_info, content) - async def main_loop(self, after_start: Awaitable = None): + async def main_loop(self, after_start: Awaitable = None) -> bool: """ The main loop of NDNApp. :param after_start: the coroutine to start after connection to NFD is established. + :return: ``True`` if the connection is shutdown not by ``Ctrl+C``. + For example, manually or by the other side. """ async def starting_task(): for name, route, validator, need_raw_packet, need_sig_ptrs in self._autoreg_routes: @@ -265,12 +267,19 @@ async def starting_task(): elif isinstance(after_start, aio.Task) or isinstance(after_start, aio.Future): after_start.cancel() raise - task = aio.ensure_future(starting_task()) + task = aio.create_task(starting_task()) logging.debug('Connected to NFD node, start running...') - await self.face.run() - self.face.shutdown() + try: + await self.face.run() + ret = True + except aio.CancelledError: + logging.info('Shutting down') + ret = False + finally: + self.face.shutdown() self._clean_up() await task + return ret def _clean_up(self): for node in self._int_tree.itervalues(): @@ -285,13 +294,11 @@ def shutdown(self): logging.info('Manually shutdown') self.face.shutdown() - def run_forever(self, after_start: Awaitable = None) -> bool: + def run_forever(self, after_start: Awaitable = None): """ A non-async wrapper of :meth:`main_loop`. :param after_start: the coroutine to start after connection to NFD is established. - :return: ``True`` if the connection is shutdown not by ``Ctrl+C``. - For example, manually or by the other side. :examples: .. code-block:: python3 @@ -301,17 +308,10 @@ def run_forever(self, after_start: Awaitable = None) -> bool: if __name__ == '__main__': app.run_forever(after_start=main()) """ - task = self.main_loop(after_start) try: - aio.get_event_loop().run_until_complete(task) - ret = True + aio.run(self.main_loop(after_start)) except KeyboardInterrupt: - logging.info('Receiving Ctrl+C, shutdown') - ret = False - finally: - self.face.shutdown() - logging.debug('Face is down now') - return ret + logging.info('Receiving Ctrl+C, exit') def route(self, name: NonStrictName, validator: Optional[Validator] = None, need_raw_packet: bool = False, need_sig_ptrs: bool = False): @@ -355,7 +355,7 @@ def on_interest(name: FormalName, param: InterestParam, app_param): def decorator(func: Route): self._autoreg_routes.append((name, func, validator, need_raw_packet, need_sig_ptrs)) if self.face.running: - aio.ensure_future(self.register(name, func, validator, need_raw_packet, need_sig_ptrs)) + aio.create_task(self.register(name, func, validator, need_raw_packet, need_sig_ptrs)) return func return decorator diff --git a/src/ndn/schema/schema_tree.py b/src/ndn/schema/schema_tree.py index fc3440e..0d5af42 100644 --- a/src/ndn/schema/schema_tree.py +++ b/src/ndn/schema/schema_tree.py @@ -285,7 +285,7 @@ async def _int_validator(self, name: FormalName, sig_ptrs: SignaturePtrs) -> boo def _on_interest_root(self, name: FormalName, param: InterestParam, app_param: Optional[BinaryStr], raw_packet: BinaryStr): match = self.match(name) - aio.ensure_future(match.on_interest(param, app_param, raw_packet)) + aio.create_task(match.on_interest(param, app_param, raw_packet)) # ====== Functions on Interest & Data processing (For overriding) ====== diff --git a/src/ndn/transport/stream_socket.py b/src/ndn/transport/stream_socket.py index 97cdbed..e8cde09 100644 --- a/src/ndn/transport/stream_socket.py +++ b/src/ndn/transport/stream_socket.py @@ -64,7 +64,7 @@ async def run(self): siz = await read_tl_num_from_stream(self.reader, bio) bio.write(await self.reader.readexactly(siz)) buf = bio.getvalue() - aio.ensure_future(self.callback(typ, buf)) + aio.create_task(self.callback(typ, buf)) except (aio.IncompleteReadError, ConnectionResetError): self.shutdown() diff --git a/tests/integration/app_test.py b/tests/integration/app_test.py index 59b674b..c282cee 100644 --- a/tests/integration/app_test.py +++ b/tests/integration/app_test.py @@ -29,11 +29,15 @@ class NDNAppTestSuite: app = None def test_main(self): + aio.run(self.comain()) + + async def comain(self): face = DummyFace(self.face_proc) keychain = KeychainDigest() self.app = NDNApp(face, keychain) face.app = self.app - self.app.run_forever(after_start=self.app_main()) + await self.app.main_loop(self.app_main()) + # self.app.run_forever(after_start=self.app_main()) @abc.abstractmethod async def face_proc(self, face: DummyFace): @@ -118,7 +122,7 @@ async def face_proc(self, face: DummyFace): b'\x05\x0c\x07\x05\x08\x03not\x21\x00\x0c\x01\x05' b'\x05\x15\x07\x10\x08\x03not\x08\timportant\x0c\x01\x05') await face.input_packet(b'\x06\x1d\x07\x10\x08\x03not\x08\timportant\x14\x03\x18\x01\x00\x15\x04test') - await aio.sleep(0.007) + await aio.sleep(0.1) async def app_main(self): future1 = self.app.express_interest('/not', nonce=None, lifetime=5, can_be_prefix=False)