Skip to content

Commit

Permalink
build: modernize build process
Browse files Browse the repository at this point in the history
- Move to `pyproject.toml`
- Update support to 3.8+
  • Loading branch information
scanny committed Aug 3, 2024
1 parent af6a8f7 commit 1e1005c
Show file tree
Hide file tree
Showing 14 changed files with 89 additions and 152 deletions.
42 changes: 24 additions & 18 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,49 +1,55 @@
BEHAVE = behave
MAKE = make
PYTHON = python
SETUP = $(PYTHON) ./setup.py
TWINE = $(PYTHON) -m twine

.PHONY: accept build clean cleandocs coverage docs opendocs

.PHONY: help
help:
@echo "Please use \`make <target>' where <target> is one or more of"
@echo " accept run acceptance tests using behave"
@echo " clean delete intermediate work product and start fresh"
@echo " cleandocs delete cached HTML documentation and start fresh"
@echo " coverage run nosetests with coverage"
@echo " docs build HTML documentation using Sphinx (incremental)"
@echo " opendocs open local HTML documentation in browser"
@echo " readme update README.html from README.rst"
@echo " sdist generate a source distribution into dist/"
@echo " upload upload distribution tarball to PyPI"

@echo " accept run acceptance tests using behave"
@echo " build generate both sdist and wheel suitable for upload to PyPI"
@echo " clean delete intermediate work product and start fresh"
@echo " cleandocs delete cached HTML documentation and start fresh"
@echo " coverage run nosetests with coverage"
@echo " docs build HTML documentation using Sphinx (incremental)"
@echo " opendocs open local HTML documentation in browser"
@echo " test-upload upload distribution to TestPyPI"
@echo " upload upload distribution tarball to PyPI"

.PHONY: accept
accept:
$(BEHAVE) --stop

.PHONY: build
build:
rm -rf dist
$(SETUP) bdist_wheel sdist
python -m build
twine check dist/*

.PHONY: clean
clean:
find . -type f -name \*.pyc -exec rm {} \;
find . -type f -name .DS_Store -exec rm {} \;
rm -rf dist .coverage

.PHONY: cleandocs
cleandocs:
$(MAKE) -C docs clean

.PHONY: coverage
coverage:
py.test --cov-report term-missing --cov=pptx --cov=tests

.PHONY: docs
docs:
$(MAKE) -C docs html

.PHONY: opendocs
opendocs:
open docs/.build/html/index.html

.PHONY: test-upload
test-upload: build
$(TWINE) upload --repository testpypi dist/*
twine upload --repository testpypi dist/*

.PHONY: upload
upload: clean build
$(TWINE) upload dist/*
twine upload dist/*
45 changes: 45 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
[build-system]
requires = ["setuptools>=61.0.0"]
build-backend = "setuptools.build_meta"

[project]
name = "python-pptx"
authors = [{name = "Steve Canny", email = "[email protected]"}]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"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",
"Topic :: Office/Business :: Office Suites",
"Topic :: Software Development :: Libraries",
]
dependencies = [
"Pillow>=3.3.2",
"XlsxWriter>=0.5.7",
"lxml>=3.1.0",
"typing_extensions>=4.9.0",
]
description = "Create, read, and update PowerPoint 2007+ (.pptx) files."
dynamic = ["version"]
keywords = ["powerpoint", "ppt", "pptx", "openxml", "office"]
license = { text = "MIT" }
readme = "README.rst"
requires-python = ">=3.8"

[project.urls]
Changelog = "https://github.com/scanny/python-pptx/blob/master/HISTORY.rst"
Documentation = "https://python-pptx.readthedocs.io/en/latest/"
Homepage = "https://github.com/scanny/python-pptx"
Repository = "https://github.com/scanny/python-pptx"

[tool.black]
line-length = 100

Expand Down Expand Up @@ -98,3 +140,6 @@ ignore = [

[tool.ruff.lint.isort]
known-first-party = ["pptx"]

[tool.setuptools.dynamic]
version = {attr = "pptx.__version__"}
5 changes: 5 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-r requirements-test.txt
build
ruff
setuptools>=61.0.0
twine
5 changes: 5 additions & 0 deletions requirements-docs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Sphinx==1.8.6
Jinja2==2.11.3
MarkupSafe==0.23
alabaster<0.7.14
-e .
1 change: 1 addition & 0 deletions requirements-test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ pytest>=2.5
pytest-coverage
pytest-xdist
ruff
tox
Empty file removed setup.cfg
Empty file.
89 changes: 0 additions & 89 deletions setup.py

This file was deleted.

5 changes: 2 additions & 3 deletions src/pptx/opc/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
from __future__ import annotations

import collections
from collections.abc import Mapping
from typing import IO, TYPE_CHECKING, DefaultDict, Iterator, Set, cast
from typing import IO, TYPE_CHECKING, DefaultDict, Iterator, Mapping, Set, cast

from pptx.opc.constants import RELATIONSHIP_TARGET_MODE as RTM
from pptx.opc.constants import RELATIONSHIP_TYPE as RT
Expand Down Expand Up @@ -428,7 +427,7 @@ def part(self):

def _rel_ref_count(self, rId: str) -> int:
"""Return int count of references in this part's XML to `rId`."""
return len([r for r in cast(list[str], self._element.xpath("//@r:id")) if r == rId])
return len([r for r in cast("list[str]", self._element.xpath("//@r:id")) if r == rId])


class PartFactory:
Expand Down
3 changes: 1 addition & 2 deletions src/pptx/opc/serialized.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
import os
import posixpath
import zipfile
from collections.abc import Container
from typing import IO, TYPE_CHECKING, Any, Sequence
from typing import IO, TYPE_CHECKING, Any, Container, Sequence

from pptx.exc import PackageNotFoundError
from pptx.opc.constants import CONTENT_TYPE as CT
Expand Down
2 changes: 1 addition & 1 deletion src/pptx/oxml/presentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def _next_id(self) -> int:
MIN_SLIDE_ID = 256
MAX_SLIDE_ID = 2147483647

used_ids = [int(s) for s in cast(list[str], self.xpath("./p:sldId/@id"))]
used_ids = [int(s) for s in cast("list[str]", self.xpath("./p:sldId/@id"))]
simple_next = max([MIN_SLIDE_ID - 1] + used_ids) + 1
if simple_next <= MAX_SLIDE_ID:
return simple_next
Expand Down
2 changes: 1 addition & 1 deletion src/pptx/oxml/shapes/graphfrm.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def _oleObj(self) -> CT_OleObject | None:
choices. The last one should suit best for reading purposes because it contains the lowest
common denominator.
"""
oleObjs = cast(list[CT_OleObject], self.xpath(".//p:oleObj"))
oleObjs = cast("list[CT_OleObject]", self.xpath(".//p:oleObj"))
return oleObjs[-1] if oleObjs else None


Expand Down
3 changes: 1 addition & 2 deletions src/pptx/shapes/freeform.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

from __future__ import annotations

from collections.abc import Sequence
from typing import TYPE_CHECKING, Iterable, Iterator
from typing import TYPE_CHECKING, Iterable, Iterator, Sequence

from pptx.util import Emu, lazyproperty

Expand Down
2 changes: 1 addition & 1 deletion src/pptx/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
if TYPE_CHECKING:
from typing_extensions import TypeAlias

AdjustmentValue: TypeAlias = tuple[str, int]
AdjustmentValue: TypeAlias = "tuple[str, int]"


class ShapeSpec(TypedDict):
Expand Down
37 changes: 2 additions & 35 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,42 +1,9 @@
#
# Configuration for tox and pytest

[flake8]
exclude = dist,docs,*.egg-info,.git,lab,ref,_scratch,spec,.tox
ignore =
# -- E203 - whitespace before ':'. Black disagrees for slice expressions.
E203,

# -- W503 - line break before binary operator. Black has a different opinion about
# -- this, that binary operators should appear at the beginning of new-line
# -- expression segments. I agree because right is ragged and left lines up.
W503
max-line-length = 88

[tox]
envlist = py27, py38, py311
requires = virtualenv<20.22.0
skip_missing_interpreters = false
envlist = py38, py39, py310, py311, py312

[testenv]
deps =
behave==1.2.5
lxml>=3.1.0
Pillow>=3.3.2
pyparsing>=2.0.1
pytest
XlsxWriter>=0.5.7
deps = -rrequirements-test.txt

commands =
py.test -qx
behave --format progress --stop --tags=-wip

[testenv:py27]
deps =
behave==1.2.5
lxml>=3.1.0
mock
Pillow>=3.3.2
pyparsing>=2.0.1
pytest
XlsxWriter>=0.5.7

0 comments on commit 1e1005c

Please sign in to comment.