forked from pool/python-smart-open
Accepting request 1231284 from devel:languages:python
- Remove upper pin on urllib3. - Drop moto_server set up and teardown, it is for one testcase. - Drop patch skip-gzip-tests-python312.patch, not required. - Add patch support-python-313.patch: * Support Python 3.13 changes. OBS-URL: https://build.opensuse.org/request/show/1231284 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-smart-open?expand=0&rev=9
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Dec 16 03:17:47 UTC 2024 - Steve Kowalik <steven.kowalik@suse.com>
|
||||
|
||||
- Remove upper pin on urllib3.
|
||||
- Drop moto_server set up and teardown, it is for one testcase.
|
||||
- Drop patch skip-gzip-tests-python312.patch, not required.
|
||||
- Add patch support-python-313.patch:
|
||||
* Support Python 3.13 changes.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Oct 30 19:30:36 UTC 2024 - Dirk Müller <dmueller@suse.com>
|
||||
|
||||
|
@@ -23,7 +23,8 @@ Summary: Python utils for streaming large files
|
||||
License: MIT
|
||||
URL: https://github.com/piskvorky/smart_open
|
||||
Source: https://github.com/piskvorky/smart_open/archive/refs/tags/v%{version}.tar.gz#/smart_open-%{version}.tar.gz
|
||||
Patch0: skip-gzip-tests-python312.patch
|
||||
# PATCH-FIX-UPSTREAM gh#piskvorky/smart_open#847
|
||||
Patch0: support-python-313.patch
|
||||
BuildRequires: %{python_module pip}
|
||||
BuildRequires: %{python_module setuptools}
|
||||
BuildRequires: %{python_module wheel}
|
||||
@@ -39,9 +40,6 @@ Requires: python-wrapt
|
||||
Requires: python-zstandard
|
||||
Suggests: python-paramiko
|
||||
BuildArch: noarch
|
||||
# see https://github.com/piskvorky/smart_open/issues/784
|
||||
BuildRequires: %{python_module urllib3 < 2}
|
||||
Requires: python-urllib3 < 2
|
||||
# SECTION test requirements
|
||||
BuildRequires: %{python_module azure-common}
|
||||
BuildRequires: %{python_module azure-core}
|
||||
@@ -74,12 +72,7 @@ Includes support for S3, HDFS, gzip, bz2, etc.
|
||||
%python_expand %fdupes %{buildroot}%{$python_sitelib}
|
||||
|
||||
%check
|
||||
moto_server -p5000 2>/dev/null &
|
||||
server_pid=$!
|
||||
export SO_ENABLE_MOTO_SERVER=1
|
||||
# Requires network
|
||||
%pytest -rs -k 'not (test_http_gz or test_s3_gzip_compress_sanity)' smart_open/
|
||||
kill $server_pid
|
||||
%pytest
|
||||
|
||||
%files %{python_files}
|
||||
%doc README.rst
|
||||
|
@@ -1,48 +0,0 @@
|
||||
Index: smart_open-7.0.1/smart_open/tests/test_smart_open.py
|
||||
===================================================================
|
||||
--- smart_open-7.0.1.orig/smart_open/tests/test_smart_open.py
|
||||
+++ smart_open-7.0.1/smart_open/tests/test_smart_open.py
|
||||
@@ -20,6 +20,7 @@ import tempfile
|
||||
import unittest
|
||||
from unittest import mock
|
||||
import warnings
|
||||
+import sys
|
||||
|
||||
import boto3
|
||||
import pytest
|
||||
@@ -1795,6 +1796,8 @@ def test_s3_gzip_compress_sanity():
|
||||
)
|
||||
def test_s3_read_explicit(url, _compression):
|
||||
"""Can we read using the explicitly specified compression?"""
|
||||
+ if sys.version_info.minor == 12 and _compression == ".gz":
|
||||
+ raise unittest.SkipTest
|
||||
initialize_bucket()
|
||||
with smart_open.open(url, 'rb', compression=_compression) as fin:
|
||||
assert fin.read() == _DECOMPRESSED_DATA
|
||||
@@ -1811,6 +1814,8 @@ def test_s3_read_explicit(url, _compress
|
||||
)
|
||||
def test_s3_write_explicit(_compression, expected):
|
||||
"""Can we write using the explicitly specified compression?"""
|
||||
+ if sys.version_info.minor == 12 and _compression == ".gz":
|
||||
+ raise unittest.SkipTest
|
||||
initialize_bucket()
|
||||
|
||||
with smart_open.open("s3://bucket/key", "wb", compression=_compression) as fout:
|
||||
@@ -1831,6 +1836,8 @@ def test_s3_write_explicit(_compression,
|
||||
)
|
||||
def test_s3_write_implicit(url, _compression, expected):
|
||||
"""Can we determine the compression from the file extension?"""
|
||||
+ if sys.version_info.minor == 12 and _compression == ".gz":
|
||||
+ raise unittest.SkipTest
|
||||
initialize_bucket()
|
||||
|
||||
with smart_open.open(url, "wb", compression=INFER_FROM_EXTENSION) as fout:
|
||||
@@ -1851,6 +1858,8 @@ def test_s3_write_implicit(url, _compres
|
||||
)
|
||||
def test_s3_disable_compression(url, _compression, expected):
|
||||
"""Can we handle the compression parameter when reading/writing?"""
|
||||
+ if sys.version_info.minor == 12 and _compression == ".gz":
|
||||
+ raise unittest.SkipTest
|
||||
initialize_bucket()
|
||||
|
||||
with smart_open.open(url, "wb") as fout:
|
322
support-python-313.patch
Normal file
322
support-python-313.patch
Normal file
@@ -0,0 +1,322 @@
|
||||
From 1266ddb5d671d08ba1da45db963d0102de00cae4 Mon Sep 17 00:00:00 2001
|
||||
From: ddelange <14880945+ddelange@users.noreply.github.com>
|
||||
Date: Sun, 15 Dec 2024 09:28:01 +0100
|
||||
Subject: [PATCH 1/2] Add cp313 to CI
|
||||
|
||||
---
|
||||
.github/workflows/python-package.yml | 4 ++++
|
||||
setup.py | 2 ++
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml
|
||||
index 58302d60..be6a7228 100644
|
||||
--- a/.github/workflows/python-package.yml
|
||||
+++ b/.github/workflows/python-package.yml
|
||||
@@ -31,6 +31,7 @@ jobs:
|
||||
- {python-version: '3.10', os: ubuntu-20.04}
|
||||
- {python-version: '3.11', os: ubuntu-20.04}
|
||||
- {python-version: '3.12', os: ubuntu-20.04}
|
||||
+ - {python-version: '3.13', os: ubuntu-20.04}
|
||||
|
||||
- {python-version: '3.8', os: windows-2019}
|
||||
- {python-version: '3.9', os: windows-2019}
|
||||
@@ -67,6 +68,7 @@ jobs:
|
||||
- {python-version: '3.10', os: ubuntu-20.04}
|
||||
- {python-version: '3.11', os: ubuntu-20.04}
|
||||
- {python-version: '3.12', os: ubuntu-20.04}
|
||||
+ - {python-version: '3.13', os: ubuntu-20.04}
|
||||
|
||||
#
|
||||
# Some of the doctests don't pass on Windows because of Windows-specific
|
||||
@@ -104,6 +106,7 @@ jobs:
|
||||
- {python-version: '3.10', os: ubuntu-20.04}
|
||||
- {python-version: '3.11', os: ubuntu-20.04}
|
||||
- {python-version: '3.12', os: ubuntu-20.04}
|
||||
+ - {python-version: '3.13', os: ubuntu-20.04}
|
||||
|
||||
# Not sure why we exclude these, perhaps for historical reasons?
|
||||
#
|
||||
@@ -153,6 +156,7 @@ jobs:
|
||||
- {python-version: '3.10', os: ubuntu-20.04}
|
||||
- {python-version: '3.11', os: ubuntu-20.04}
|
||||
- {python-version: '3.12', os: ubuntu-20.04}
|
||||
+ - {python-version: '3.13', os: ubuntu-20.04}
|
||||
|
||||
# - {python-version: '3.7', os: windows-2019}
|
||||
# - {python-version: '3.8', os: windows-2019}
|
||||
diff --git a/setup.py b/setup.py
|
||||
index 9e738bea..d099c283 100644
|
||||
--- a/setup.py
|
||||
+++ b/setup.py
|
||||
@@ -102,6 +102,8 @@ def read(fname):
|
||||
'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',
|
||||
'Topic :: System :: Distributed Computing',
|
||||
'Topic :: Database :: Front-Ends',
|
||||
],
|
||||
|
||||
From c3105cc3d326cdfc50b6d0cb3d1544ca8522be29 Mon Sep 17 00:00:00 2001
|
||||
From: ddelange <14880945+ddelange@users.noreply.github.com>
|
||||
Date: Sun, 15 Dec 2024 23:42:55 +0100
|
||||
Subject: [PATCH 2/2] Fix tests
|
||||
|
||||
---
|
||||
.github/workflows/python-package.yml | 10 ++++++
|
||||
smart_open/azure.py | 52 +++++++++++++++++-----------
|
||||
smart_open/hdfs.py | 22 +++++++++---
|
||||
smart_open/tests/test_azure.py | 10 ++++++
|
||||
4 files changed, 69 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml
|
||||
index be6a7228..abd387cf 100644
|
||||
--- a/.github/workflows/python-package.yml
|
||||
+++ b/.github/workflows/python-package.yml
|
||||
@@ -38,6 +38,7 @@ jobs:
|
||||
- {python-version: '3.10', os: windows-2019}
|
||||
- {python-version: '3.11', os: windows-2019}
|
||||
- {python-version: '3.12', os: windows-2019}
|
||||
+ - {python-version: '3.13', os: windows-2019}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@@ -78,6 +79,9 @@ jobs:
|
||||
# - {python-version: '3.8', os: windows-2019}
|
||||
# - {python-version: '3.9', os: windows-2019}
|
||||
# - {python-version: '3.10', os: windows-2019}
|
||||
+ # - {python-version: '3.11', os: windows-2019}
|
||||
+ # - {python-version: '3.12', os: windows-2019}
|
||||
+ # - {python-version: '3.13', os: windows-2019}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@@ -114,6 +118,9 @@ jobs:
|
||||
# - {python-version: '3.8', os: windows-2019}
|
||||
# - {python-version: '3.9', os: windows-2019}
|
||||
# - {python-version: '3.10', os: windows-2019}
|
||||
+ # - {python-version: '3.11', os: windows-2019}
|
||||
+ # - {python-version: '3.12', os: windows-2019}
|
||||
+ # - {python-version: '3.13', os: windows-2019}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@@ -162,6 +169,9 @@ jobs:
|
||||
# - {python-version: '3.8', os: windows-2019}
|
||||
# - {python-version: '3.9', os: windows-2019}
|
||||
# - {python-version: '3.10', os: windows-2019}
|
||||
+ # - {python-version: '3.11', os: windows-2019}
|
||||
+ # - {python-version: '3.12', os: windows-2019}
|
||||
+ # - {python-version: '3.13', os: windows-2019}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
diff --git a/smart_open/azure.py b/smart_open/azure.py
|
||||
index 1c991f05..f467992c 100644
|
||||
--- a/smart_open/azure.py
|
||||
+++ b/smart_open/azure.py
|
||||
@@ -195,8 +195,9 @@ class Reader(io.BufferedIOBase):
|
||||
Implements the io.BufferedIOBase interface of the standard library.
|
||||
|
||||
:raises azure.core.exceptions.ResourceNotFoundError: Raised when the blob to read from does not exist.
|
||||
-
|
||||
"""
|
||||
+ _blob = None # always initialized so closed property is functional in case _get_blob_client fails
|
||||
+
|
||||
def __init__(
|
||||
self,
|
||||
container,
|
||||
@@ -207,9 +208,10 @@ def __init__(
|
||||
max_concurrency=DEFAULT_MAX_CONCURRENCY,
|
||||
):
|
||||
self._container_name = container
|
||||
+ self._blob_name = blob
|
||||
|
||||
- self._blob = _get_blob_client(client, container, blob)
|
||||
# type: azure.storage.blob.BlobClient
|
||||
+ self._blob = _get_blob_client(client, container, blob)
|
||||
|
||||
if self._blob is None:
|
||||
raise azure.core.exceptions.ResourceNotFoundError(
|
||||
@@ -236,8 +238,13 @@ def __init__(
|
||||
def close(self):
|
||||
"""Flush and close this stream."""
|
||||
logger.debug("close: called")
|
||||
- self._blob = None
|
||||
- self._raw_reader = None
|
||||
+ if not self.closed:
|
||||
+ self._blob = None
|
||||
+ self._raw_reader = None
|
||||
+
|
||||
+ @property
|
||||
+ def closed(self):
|
||||
+ return self._blob is None
|
||||
|
||||
def readable(self):
|
||||
"""Return True if the stream can be read from."""
|
||||
@@ -369,20 +376,26 @@ def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.close()
|
||||
|
||||
def __str__(self):
|
||||
- return "(%s, %r, %r)" % (self.__class__.__name__,
|
||||
- self._container_name,
|
||||
- self._blob.blob_name)
|
||||
+ return "(%s, %r, %r)" % (
|
||||
+ self.__class__.__name__,
|
||||
+ self._container_name,
|
||||
+ self._blob_name
|
||||
+ )
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(container=%r, blob=%r)" % (
|
||||
- self.__class__.__name__, self._container_name, self._blob.blob_name,
|
||||
+ self.__class__.__name__,
|
||||
+ self._container_name,
|
||||
+ self._blob_name,
|
||||
)
|
||||
|
||||
|
||||
class Writer(io.BufferedIOBase):
|
||||
"""Writes bytes to Azure Blob Storage.
|
||||
|
||||
- Implements the io.BufferedIOBase interface of the standard library."""
|
||||
+ Implements the io.BufferedIOBase interface of the standard library.
|
||||
+ """
|
||||
+ _blob = None # always initialized so closed property is functional in case _get_blob_client fails
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -392,21 +405,19 @@ def __init__(
|
||||
blob_kwargs=None,
|
||||
min_part_size=_DEFAULT_MIN_PART_SIZE,
|
||||
):
|
||||
- self._is_closed = False
|
||||
self._container_name = container
|
||||
-
|
||||
- self._blob = _get_blob_client(client, container, blob)
|
||||
+ self._blob_name = blob
|
||||
self._blob_kwargs = blob_kwargs or {}
|
||||
- # type: azure.storage.blob.BlobClient
|
||||
-
|
||||
self._min_part_size = min_part_size
|
||||
-
|
||||
self._total_size = 0
|
||||
self._total_parts = 0
|
||||
self._bytes_uploaded = 0
|
||||
self._current_part = io.BytesIO()
|
||||
self._block_list = []
|
||||
|
||||
+ # type: azure.storage.blob.BlobClient
|
||||
+ self._blob = _get_blob_client(client, container, blob)
|
||||
+
|
||||
#
|
||||
# This member is part of the io.BufferedIOBase interface.
|
||||
#
|
||||
@@ -424,25 +435,26 @@ def terminate(self):
|
||||
logger.debug('%s: terminating multipart upload', self)
|
||||
if not self.closed:
|
||||
self._block_list = []
|
||||
- self._is_closed = True
|
||||
+ self._blob = None
|
||||
logger.debug('%s: terminated multipart upload', self)
|
||||
|
||||
#
|
||||
# Override some methods from io.IOBase.
|
||||
#
|
||||
def close(self):
|
||||
+ logger.debug("close: called")
|
||||
if not self.closed:
|
||||
logger.debug('%s: completing multipart upload', self)
|
||||
if self._current_part.tell() > 0:
|
||||
self._upload_part()
|
||||
self._blob.commit_block_list(self._block_list, **self._blob_kwargs)
|
||||
self._block_list = []
|
||||
- self._is_closed = True
|
||||
+ self._blob = None
|
||||
logger.debug('%s: completed multipart upload', self)
|
||||
|
||||
@property
|
||||
def closed(self):
|
||||
- return self._is_closed
|
||||
+ return self._blob is None
|
||||
|
||||
def writable(self):
|
||||
"""Return True if the stream supports writing."""
|
||||
@@ -528,13 +540,13 @@ def __str__(self):
|
||||
return "(%s, %r, %r)" % (
|
||||
self.__class__.__name__,
|
||||
self._container_name,
|
||||
- self._blob.blob_name
|
||||
+ self._blob_name
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(container=%r, blob=%r, min_part_size=%r)" % (
|
||||
self.__class__.__name__,
|
||||
self._container_name,
|
||||
- self._blob.blob_name,
|
||||
+ self._blob_name,
|
||||
self._min_part_size
|
||||
)
|
||||
diff --git a/smart_open/hdfs.py b/smart_open/hdfs.py
|
||||
index a247d3e3..772d7591 100644
|
||||
--- a/smart_open/hdfs.py
|
||||
+++ b/smart_open/hdfs.py
|
||||
@@ -84,8 +84,13 @@ def __init__(self, uri):
|
||||
def close(self):
|
||||
"""Flush and close this stream."""
|
||||
logger.debug("close: called")
|
||||
- self._sub.terminate()
|
||||
- self._sub = None
|
||||
+ if not self.closed:
|
||||
+ self._sub.terminate()
|
||||
+ self._sub = None
|
||||
+
|
||||
+ @property
|
||||
+ def closed(self):
|
||||
+ return self._sub is None
|
||||
|
||||
def readable(self):
|
||||
"""Return True if the stream can be read from."""
|
||||
@@ -136,9 +141,16 @@ def __init__(self, uri):
|
||||
self.raw = None
|
||||
|
||||
def close(self):
|
||||
- self.flush()
|
||||
- self._sub.stdin.close()
|
||||
- self._sub.wait()
|
||||
+ logger.debug("close: called")
|
||||
+ if not self.closed:
|
||||
+ self.flush()
|
||||
+ self._sub.stdin.close()
|
||||
+ self._sub.wait()
|
||||
+ self._sub = None
|
||||
+
|
||||
+ @property
|
||||
+ def closed(self):
|
||||
+ return self._sub is None
|
||||
|
||||
def flush(self):
|
||||
self._sub.stdin.flush()
|
||||
diff --git a/smart_open/tests/test_azure.py b/smart_open/tests/test_azure.py
|
||||
index a82dbf17..2eb23a0e 100644
|
||||
--- a/smart_open/tests/test_azure.py
|
||||
+++ b/smart_open/tests/test_azure.py
|
||||
@@ -554,6 +554,16 @@ def test_read_blob_client(self):
|
||||
|
||||
assert data == content
|
||||
|
||||
+ def test_nonexisting_container(self):
|
||||
+ with self.assertRaises(azure.core.exceptions.ResourceNotFoundError):
|
||||
+ with smart_open.azure.open(
|
||||
+ 'thiscontainerdoesntexist',
|
||||
+ 'mykey',
|
||||
+ 'rb',
|
||||
+ CLIENT
|
||||
+ ) as fin:
|
||||
+ fin.read()
|
||||
+
|
||||
|
||||
class WriterTest(unittest.TestCase):
|
||||
"""Test writing into Azure Blob files."""
|
Reference in New Issue
Block a user