import initial package (rhbz#1772578)

epel8
Ken Dreyer 5 years ago
parent 0649302b51
commit e1dad4d3a6

1
.gitignore vendored

@ -0,0 +1 @@
/importlib_resources-1.0.2.tar.gz

@ -0,0 +1,302 @@
From a6a3a716c97b438ed64d5368e3462c6787ba0b85 Mon Sep 17 00:00:00 2001
From: Ken Dreyer <kdreyer@redhat.com>
Date: Fri, 8 Nov 2019 09:13:38 -0700
Subject: [PATCH] raise NotImplementedError on Python 2
---
importlib_resources/__init__.py | 4 +-
importlib_resources/_py2.py | 270 ----------------------------------------
2 files changed, 1 insertion(+), 273 deletions(-)
delete mode 100644 importlib_resources/_py2.py
diff --git a/importlib_resources/__init__.py b/importlib_resources/__init__.py
index fab437a..b012e5c 100644
--- a/importlib_resources/__init__.py
+++ b/importlib_resources/__init__.py
@@ -28,9 +28,7 @@ elif sys.version_info >= (3,):
from importlib_resources.abc import ResourceReader
__all__.extend(['Package', 'Resource', 'ResourceReader'])
else:
- from importlib_resources._py2 import (
- contents, is_resource, open_binary, open_text, path, read_binary,
- read_text)
+ raise NotImplementedError('Fedora package does not support Python 2')
__version__ = read_text('importlib_resources', 'version.txt').strip()
diff --git a/importlib_resources/_py2.py b/importlib_resources/_py2.py
deleted file mode 100644
index 376f0e3..0000000
--- a/importlib_resources/_py2.py
+++ /dev/null
@@ -1,270 +0,0 @@
-import os
-import errno
-import tempfile
-
-from ._compat import FileNotFoundError
-from contextlib import contextmanager
-from importlib import import_module
-from io import BytesIO, TextIOWrapper, open as io_open
-from pathlib2 import Path
-from zipfile import ZipFile
-
-
-def _get_package(package):
- """Normalize a path by ensuring it is a string.
-
- If the resulting string contains path separators, an exception is raised.
- """
- if isinstance(package, basestring): # noqa: F821
- module = import_module(package)
- else:
- module = package
- if not hasattr(module, '__path__'):
- raise TypeError("{!r} is not a package".format(package))
- return module
-
-
-def _normalize_path(path):
- """Normalize a path by ensuring it is a string.
-
- If the resulting string contains path separators, an exception is raised.
- """
- str_path = str(path)
- parent, file_name = os.path.split(str_path)
- if parent:
- raise ValueError("{!r} must be only a file name".format(path))
- else:
- return file_name
-
-
-def open_binary(package, resource):
- """Return a file-like object opened for binary reading of the resource."""
- resource = _normalize_path(resource)
- package = _get_package(package)
- # Using pathlib doesn't work well here due to the lack of 'strict' argument
- # for pathlib.Path.resolve() prior to Python 3.6.
- package_path = os.path.dirname(package.__file__)
- relative_path = os.path.join(package_path, resource)
- full_path = os.path.abspath(relative_path)
- try:
- return io_open(full_path, 'rb')
- except IOError:
- # This might be a package in a zip file. zipimport provides a loader
- # with a functioning get_data() method, however we have to strip the
- # archive (i.e. the .zip file's name) off the front of the path. This
- # is because the zipimport loader in Python 2 doesn't actually follow
- # PEP 302. It should allow the full path, but actually requires that
- # the path be relative to the zip file.
- try:
- loader = package.__loader__
- full_path = relative_path[len(loader.archive)+1:]
- data = loader.get_data(full_path)
- except (IOError, AttributeError):
- package_name = package.__name__
- message = '{!r} resource not found in {!r}'.format(
- resource, package_name)
- raise FileNotFoundError(message)
- else:
- return BytesIO(data)
-
-
-def open_text(package, resource, encoding='utf-8', errors='strict'):
- """Return a file-like object opened for text reading of the resource."""
- resource = _normalize_path(resource)
- package = _get_package(package)
- # Using pathlib doesn't work well here due to the lack of 'strict' argument
- # for pathlib.Path.resolve() prior to Python 3.6.
- package_path = os.path.dirname(package.__file__)
- relative_path = os.path.join(package_path, resource)
- full_path = os.path.abspath(relative_path)
- try:
- return io_open(full_path, mode='r', encoding=encoding, errors=errors)
- except IOError:
- # This might be a package in a zip file. zipimport provides a loader
- # with a functioning get_data() method, however we have to strip the
- # archive (i.e. the .zip file's name) off the front of the path. This
- # is because the zipimport loader in Python 2 doesn't actually follow
- # PEP 302. It should allow the full path, but actually requires that
- # the path be relative to the zip file.
- try:
- loader = package.__loader__
- full_path = relative_path[len(loader.archive)+1:]
- data = loader.get_data(full_path)
- except (IOError, AttributeError):
- package_name = package.__name__
- message = '{!r} resource not found in {!r}'.format(
- resource, package_name)
- raise FileNotFoundError(message)
- else:
- return TextIOWrapper(BytesIO(data), encoding, errors)
-
-
-def read_binary(package, resource):
- """Return the binary contents of the resource."""
- resource = _normalize_path(resource)
- package = _get_package(package)
- with open_binary(package, resource) as fp:
- return fp.read()
-
-
-def read_text(package, resource, encoding='utf-8', errors='strict'):
- """Return the decoded string of the resource.
-
- The decoding-related arguments have the same semantics as those of
- bytes.decode().
- """
- resource = _normalize_path(resource)
- package = _get_package(package)
- with open_text(package, resource, encoding, errors) as fp:
- return fp.read()
-
-
-@contextmanager
-def path(package, resource):
- """A context manager providing a file path object to the resource.
-
- If the resource does not already exist on its own on the file system,
- a temporary file will be created. If the file was created, the file
- will be deleted upon exiting the context manager (no exception is
- raised if the file was deleted prior to the context manager
- exiting).
- """
- resource = _normalize_path(resource)
- package = _get_package(package)
- package_directory = Path(package.__file__).parent
- file_path = package_directory / resource
- # If the file actually exists on the file system, just return it.
- # Otherwise, it's probably in a zip file, so we need to create a temporary
- # file and copy the contents into that file, hence the contextmanager to
- # clean up the temp file resource.
- if file_path.exists():
- yield file_path
- else:
- with open_binary(package, resource) as fp:
- data = fp.read()
- # Not using tempfile.NamedTemporaryFile as it leads to deeper 'try'
- # blocks due to the need to close the temporary file to work on Windows
- # properly.
- fd, raw_path = tempfile.mkstemp()
- try:
- os.write(fd, data)
- os.close(fd)
- yield Path(raw_path)
- finally:
- try:
- os.remove(raw_path)
- except FileNotFoundError:
- pass
-
-
-def is_resource(package, name):
- """True if name is a resource inside package.
-
- Directories are *not* resources.
- """
- package = _get_package(package)
- _normalize_path(name)
- try:
- package_contents = set(contents(package))
- except OSError as error:
- if error.errno not in (errno.ENOENT, errno.ENOTDIR):
- # We won't hit this in the Python 2 tests, so it'll appear
- # uncovered. We could mock os.listdir() to return a non-ENOENT or
- # ENOTDIR, but then we'd have to depend on another external
- # library since Python 2 doesn't have unittest.mock. It's not
- # worth it.
- raise # pragma: nocover
- return False
- if name not in package_contents:
- return False
- # Just because the given file_name lives as an entry in the package's
- # contents doesn't necessarily mean it's a resource. Directories are not
- # resources, so let's try to find out if it's a directory or not.
- path = Path(package.__file__).parent / name
- if path.is_file():
- return True
- if path.is_dir():
- return False
- # If it's not a file and it's not a directory, what is it? Well, this
- # means the file doesn't exist on the file system, so it probably lives
- # inside a zip file. We have to crack open the zip, look at its table of
- # contents, and make sure that this entry doesn't have sub-entries.
- archive_path = package.__loader__.archive # type: ignore
- package_directory = Path(package.__file__).parent
- with ZipFile(archive_path) as zf:
- toc = zf.namelist()
- relpath = package_directory.relative_to(archive_path)
- candidate_path = relpath / name
- for entry in toc: # pragma: nobranch
- try:
- relative_to_candidate = Path(entry).relative_to(candidate_path)
- except ValueError:
- # The two paths aren't relative to each other so we can ignore it.
- continue
- # Since directories aren't explicitly listed in the zip file, we must
- # infer their 'directory-ness' by looking at the number of path
- # components in the path relative to the package resource we're
- # looking up. If there are zero additional parts, it's a file, i.e. a
- # resource. If there are more than zero it's a directory, i.e. not a
- # resource. It has to be one of these two cases.
- return len(relative_to_candidate.parts) == 0
- # I think it's impossible to get here. It would mean that we are looking
- # for a resource in a zip file, there's an entry matching it in the return
- # value of contents(), but we never actually found it in the zip's table of
- # contents.
- raise AssertionError('Impossible situation')
-
-
-def contents(package):
- """Return an iterable of entries in `package`.
-
- Note that not all entries are resources. Specifically, directories are
- not considered resources. Use `is_resource()` on each entry returned here
- to check if it is a resource or not.
- """
- package = _get_package(package)
- package_directory = Path(package.__file__).parent
- try:
- return os.listdir(str(package_directory))
- except OSError as error:
- if error.errno not in (errno.ENOENT, errno.ENOTDIR):
- # We won't hit this in the Python 2 tests, so it'll appear
- # uncovered. We could mock os.listdir() to return a non-ENOENT or
- # ENOTDIR, but then we'd have to depend on another external
- # library since Python 2 doesn't have unittest.mock. It's not
- # worth it.
- raise # pragma: nocover
- # The package is probably in a zip file.
- archive_path = getattr(package.__loader__, 'archive', None)
- if archive_path is None:
- raise
- relpath = package_directory.relative_to(archive_path)
- with ZipFile(archive_path) as zf:
- toc = zf.namelist()
- subdirs_seen = set() # type: Set
- subdirs_returned = []
- for filename in toc:
- path = Path(filename)
- # Strip off any path component parts that are in common with the
- # package directory, relative to the zip archive's file system
- # path. This gives us all the parts that live under the named
- # package inside the zip file. If the length of these subparts is
- # exactly 1, then it is situated inside the package. The resulting
- # length will be 0 if it's above the package, and it will be
- # greater than 1 if it lives in a subdirectory of the package
- # directory.
- #
- # However, since directories themselves don't appear in the zip
- # archive as a separate entry, we need to return the first path
- # component for any case that has > 1 subparts -- but only once!
- if path.parts[:len(relpath.parts)] != relpath.parts:
- continue
- subparts = path.parts[len(relpath.parts):]
- if len(subparts) == 1:
- subdirs_returned.append(subparts[0])
- elif len(subparts) > 1: # pragma: nobranch
- subdir = subparts[0]
- if subdir not in subdirs_seen:
- subdirs_seen.add(subdir)
- subdirs_returned.append(subdir)
- return subdirs_returned

@ -1,2 +0,0 @@
[koji]
targets = epel8 epel8-playground

@ -0,0 +1,72 @@
%global pypi_name importlib_resources
%global desc \
importlib_resources is a backport of Python 3.7's standard library\
importlib.resources module for 3.4 through 3.6. Users of Python 3.7 and\
beyond should use the standard library module, since for these\
versions, importlib_resources just delegates to that module.
Name: python-importlib-resources
Version: 1.0.2
Release: 1%{?dist}
Summary: Read resources from Python packages
License: ASL 2.0
URL: https://importlib-resources.readthedocs.io/
Source0: %pypi_source
Patch0001: 0001-raise-NotImplementedError-on-Python-2.patch
BuildArch: noarch
BuildRequires: python3-devel
BuildRequires: python3dist(sphinx)
BuildRequires: python3dist(wheel)
%description %{desc}
%package -n python3-importlib-resources
Summary: %{summary}
%{?python_provide:%python_provide python3-%{pypi_name}}
%description -n python3-importlib-resources %{desc}
%package doc
Summary: importlib_resources documentation
%description doc
Documentation for importlib_resources
%prep
%autosetup -p1 -n %{pypi_name}-%{version}
# Remove bundled egg-info
rm -rf %{pypi_name}.egg-info
%build
%py3_build
# generate html docs
PYTHONPATH=${PWD} sphinx-build-3 importlib_resources/docs html
# remove the sphinx-build leftovers
rm -rf html/.{doctrees,buildinfo}
%install
%py3_install
# Don't ship docs sources or tests
rm -r %{buildroot}/%{python3_sitelib}/%{pypi_name}/{docs,tests}/
%check
%{__python3} setup.py test
%files -n python3-importlib-resources
%license LICENSE
%doc README.rst
%{python3_sitelib}/%{pypi_name}
%{python3_sitelib}/%{pypi_name}-%{version}-py?.?.egg-info
%files doc
%license LICENSE
%doc html
%changelog
* Thu Nov 07 2019 Ken Dreyer <kdreyer@redhat.com> - 1.0.2-1
- Initial package.

@ -0,0 +1 @@
SHA512 (importlib_resources-1.0.2.tar.gz) = 50bfc5130a2c9c9354efef1cd7132e805ed0f13467ba67172f83e11d907212bef3957aeef51fd904b73996c8280008d99c918637956a470448dfd67ef4807f82
Loading…
Cancel
Save