mirror of
https://github.com/kennethreitz/tablib.git
synced 2026-06-05 06:56:13 +00:00
Add support for Python 3.9, drop EOL 3.5 (#477)
This commit is contained in:
committed by
GitHub
parent
5fa4496f9d
commit
8c5404591b
@@ -2,23 +2,39 @@ name: Docs and lint
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.8]
|
||||
env:
|
||||
- TOXENV: docs
|
||||
- TOXENV: lint
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v1
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
python-version: 3.9
|
||||
|
||||
- name: Get pip cache dir
|
||||
id: pip-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(pip cache dir)"
|
||||
|
||||
- name: Cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.pip-cache.outputs.dir }}
|
||||
key:
|
||||
${{ matrix.os }}-${{ matrix.python-version }}-v1-${{ hashFiles('**/setup.py') }}
|
||||
restore-keys: |
|
||||
${{ matrix.os }}-${{ matrix.python-version }}-v1-
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
|
||||
@@ -2,24 +2,40 @@ name: Test
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: [3.5, 3.6, 3.7, 3.8]
|
||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
||||
|
||||
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: Get pip cache dir
|
||||
id: pip-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(pip cache dir)"
|
||||
|
||||
- name: Cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.pip-cache.outputs.dir }}
|
||||
key:
|
||||
${{ matrix.os }}-${{ matrix.python-version }}-v1-${{ hashFiles('**/setup.py') }}
|
||||
restore-keys: |
|
||||
${{ matrix.os }}-${{ matrix.python-version }}-v1-
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
repos:
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v1.26.2
|
||||
rev: v2.7.3
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: ["--py3-plus"]
|
||||
args: ["--py36-plus"]
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-isort
|
||||
rev: v4.3.21
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.6.4
|
||||
hooks:
|
||||
- id: isort
|
||||
additional_dependencies: [toml]
|
||||
|
||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||
rev: v1.4.4
|
||||
rev: v1.7.0
|
||||
hooks:
|
||||
- id: python-check-blanket-noqa
|
||||
- id: rst-backticks
|
||||
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v2.4.0
|
||||
rev: v3.3.0
|
||||
hooks:
|
||||
- id: check-merge-conflict
|
||||
- id: check-toml
|
||||
|
||||
@@ -11,6 +11,7 @@ matrix:
|
||||
env: TOXENV=docs
|
||||
- python: 3.8
|
||||
env: TOXENV=lint
|
||||
- python: 3.9
|
||||
- python: 3.8
|
||||
- python: 3.7
|
||||
- python: 3.6
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- Dropped Python 3.5 support
|
||||
|
||||
### Improvements
|
||||
|
||||
- Added Python 3.9 support
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- Prevented crash in rst export with only-space strings (#469).
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ THE SOFTWARE.
|
||||
Pythons Supported
|
||||
-----------------
|
||||
|
||||
Python 3.5+ is officially supported.
|
||||
Python 3.6+ is officially supported.
|
||||
|
||||
Now, go :ref:`install Tablib <install>`.
|
||||
|
||||
|
||||
+1
-6
@@ -1,7 +1,2 @@
|
||||
[tool.isort]
|
||||
force_grid_wrap = 0
|
||||
include_trailing_comma = true
|
||||
known_third_party = ["MarkupPy", "odf", "openpyxl", "setuptools", "tablib", "xlrd", "xlwt", "yaml"]
|
||||
line_length = 88
|
||||
multi_line_output = 3
|
||||
use_parentheses = true
|
||||
profile = "black"
|
||||
|
||||
@@ -33,12 +33,12 @@ setup(
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 3 :: Only',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
],
|
||||
python_requires='>=3.5',
|
||||
python_requires='>=3.6',
|
||||
extras_require={
|
||||
'all': ['markuppy', 'odfpy', 'openpyxl>=2.6.0', 'pandas', 'pyyaml', 'tabulate', 'xlrd', 'xlwt'],
|
||||
'cli': ['tabulate'],
|
||||
|
||||
+5
-5
@@ -414,10 +414,10 @@ class Dataset:
|
||||
|
||||
fmt = registry.get_format(format)
|
||||
if not hasattr(fmt, 'import_set'):
|
||||
raise UnsupportedFormat('Format {} cannot be imported.'.format(format))
|
||||
raise UnsupportedFormat(f'Format {format} cannot be imported.')
|
||||
|
||||
if not import_set:
|
||||
raise UnsupportedFormat('Format {} cannot be imported.'.format(format))
|
||||
raise UnsupportedFormat(f'Format {format} cannot be imported.')
|
||||
|
||||
fmt.import_set(self, stream, **kwargs)
|
||||
return self
|
||||
@@ -430,7 +430,7 @@ class Dataset:
|
||||
"""
|
||||
fmt = registry.get_format(format)
|
||||
if not hasattr(fmt, 'export_set'):
|
||||
raise UnsupportedFormat('Format {} cannot be exported.'.format(format))
|
||||
raise UnsupportedFormat(f'Format {format} cannot be exported.')
|
||||
|
||||
return fmt.export_set(self, **kwargs)
|
||||
|
||||
@@ -875,7 +875,7 @@ class Databook:
|
||||
|
||||
fmt = registry.get_format(format)
|
||||
if not hasattr(fmt, 'import_book'):
|
||||
raise UnsupportedFormat('Format {} cannot be loaded.'.format(format))
|
||||
raise UnsupportedFormat(f'Format {format} cannot be loaded.')
|
||||
|
||||
fmt.import_book(self, stream, **kwargs)
|
||||
return self
|
||||
@@ -888,7 +888,7 @@ class Databook:
|
||||
"""
|
||||
fmt = registry.get_format(format)
|
||||
if not hasattr(fmt, 'export_book'):
|
||||
raise UnsupportedFormat('Format {} cannot be exported.'.format(format))
|
||||
raise UnsupportedFormat(f'Format {format} cannot be exported.')
|
||||
|
||||
return fmt.export_book(self, **kwargs)
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ def load_format_class(dotted_path):
|
||||
module_path, class_name = dotted_path.rsplit('.', 1)
|
||||
return getattr(import_module(module_path), class_name)
|
||||
except (ValueError, AttributeError) as err:
|
||||
raise ImportError("Unable to load format class '{}' ({})".format(dotted_path, err))
|
||||
raise ImportError(f"Unable to load format class '{dotted_path}' ({err})")
|
||||
|
||||
|
||||
class FormatDescriptorBase:
|
||||
|
||||
@@ -55,7 +55,7 @@ class HTMLFormat:
|
||||
|
||||
for i, dset in enumerate(databook._datasets):
|
||||
title = (dset.title if dset.title else 'Set %s' % (i))
|
||||
wrapper.write('<{}>{}</{}>\n'.format(cls.BOOK_ENDINGS, title, cls.BOOK_ENDINGS))
|
||||
wrapper.write(f'<{cls.BOOK_ENDINGS}>{title}</{cls.BOOK_ENDINGS}>\n')
|
||||
wrapper.write(dset.html)
|
||||
wrapper.write('\n')
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ class JIRAFormat:
|
||||
|
||||
header = cls._get_header(dataset.headers) if dataset.headers else ''
|
||||
body = cls._get_body(dataset)
|
||||
return '{}\n{}'.format(header, body) if header else body
|
||||
return f'{header}\n{body}' if header else body
|
||||
|
||||
@classmethod
|
||||
def _get_body(cls, dataset):
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
import tablib
|
||||
import xlrd
|
||||
import xlwt
|
||||
from xlrd.xldate import xldate_as_datetime
|
||||
|
||||
import tablib
|
||||
|
||||
# special styles
|
||||
wrap = xlwt.easyxf("alignment: wrap on")
|
||||
bold = xlwt.easyxf("font: bold on")
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
import tablib
|
||||
from openpyxl.reader.excel import ExcelReader, load_workbook
|
||||
from openpyxl.styles import Alignment, Font
|
||||
from openpyxl.utils import get_column_letter
|
||||
from openpyxl.workbook import Workbook
|
||||
from openpyxl.writer.excel import ExcelWriter
|
||||
|
||||
import tablib
|
||||
|
||||
|
||||
class XLSXFormat:
|
||||
title = 'xlsx'
|
||||
@@ -114,7 +115,7 @@ class XLSXFormat:
|
||||
row_number = i + 1
|
||||
for j, col in enumerate(row):
|
||||
col_idx = get_column_letter(j + 1)
|
||||
cell = ws['{}{}'.format(col_idx, row_number)]
|
||||
cell = ws[f'{col_idx}{row_number}']
|
||||
|
||||
# bold headers
|
||||
if (row_number == 1) and dataset.headers:
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
""" Tablib - YAML Support.
|
||||
"""
|
||||
|
||||
import tablib
|
||||
import yaml
|
||||
|
||||
import tablib
|
||||
|
||||
|
||||
class YAMLFormat:
|
||||
title = 'yaml'
|
||||
|
||||
@@ -315,7 +315,7 @@ class DbfLogicalFieldDef(DbfFieldDef):
|
||||
return False
|
||||
if value in "YyTt":
|
||||
return True
|
||||
raise ValueError("[{}] Invalid logical value {!r}".format(self.name, value))
|
||||
raise ValueError(f"[{self.name}] Invalid logical value {value!r}")
|
||||
|
||||
def encodeValue(self, value):
|
||||
"""Return a character from the "TF?" set.
|
||||
|
||||
@@ -11,8 +11,9 @@ from io import BytesIO, StringIO
|
||||
from pathlib import Path
|
||||
from uuid import uuid4
|
||||
|
||||
import tablib
|
||||
from MarkupPy import markup
|
||||
|
||||
import tablib
|
||||
from tablib.core import Row, detect_format
|
||||
from tablib.exceptions import UnsupportedFormat
|
||||
from tablib.formats import registry
|
||||
|
||||
@@ -4,12 +4,14 @@ minversion = 2.4
|
||||
envlist =
|
||||
docs
|
||||
lint
|
||||
py{35,36,37,38}
|
||||
py{36,37,38,39}
|
||||
|
||||
[testenv]
|
||||
deps =
|
||||
-rtests/requirements.txt
|
||||
extras = pandas
|
||||
passenv =
|
||||
FORCE_COLOR
|
||||
commands =
|
||||
pytest {posargs:tests}
|
||||
|
||||
@@ -35,4 +37,3 @@ skip_install = true
|
||||
[flake8]
|
||||
exclude =
|
||||
.tox
|
||||
ignore=E501,E127,E128,E124
|
||||
|
||||
Reference in New Issue
Block a user