Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,6 @@ TODO text svneol=native#text/plain
*.tpp text svneol=native#text/plain
*.jam text svneol=native#text/plain
*.java text svneol=native#text/plain

# UTF-16 test fixtures must not have line endings converted
*_ucs16le.c binary
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-24.04
strategy:
matrix:
python-version: ['3.x', 'pypy3.11']
python-version: ['3.x', '3.15', 'pypy3.11']

steps:
- uses: actions/checkout@v5
Expand All @@ -33,7 +33,7 @@ jobs:
runs-on: ubuntu-24.04
strategy:
matrix:
python-version: ['3.x', 'pypy3.11']
python-version: ['3.x', '3.15', 'pypy3.11']

steps:
- uses: actions/checkout@v5
Expand All @@ -56,7 +56,7 @@ jobs:
runs-on: ubuntu-24.04
strategy:
matrix:
python-version: ['3.x', 'pypy3.11']
python-version: ['3.x', '3.15', 'pypy3.11']

steps:
- uses: actions/checkout@v5
Expand All @@ -79,7 +79,7 @@ jobs:
runs-on: ubuntu-24.04
strategy:
matrix:
python-version: ['3.x', 'pypy3.11']
python-version: ['3.x', '3.15', 'pypy3.11']

steps:
- uses: actions/checkout@v5
Expand Down Expand Up @@ -109,7 +109,7 @@ jobs:
runs-on: ubuntu-24.04
strategy:
matrix:
python-version: ['3.x', 'pypy3.11']
python-version: ['3.x', '3.15', 'pypy3.11']

steps:
- uses: actions/checkout@v5
Expand Down
17 changes: 14 additions & 3 deletions pcpp/pcmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@

__all__ = []

# argparse.FileType is deprecated from Python 3.14, so this replicates it
def FileType(mode):
def opener(path):
if path == '-':
return sys.stdin if 'r' in mode else sys.stdout
try:
return open(path, mode)
except OSError as e:
raise argparse.ArgumentTypeError("can't open '%s': %s" % (path, e))
return opener

class FileAction(argparse.Action):
def __init__(self, option_strings, dest, **kwargs):
super(FileAction, self).__init__(option_strings, dest, **kwargs)
Expand All @@ -21,7 +32,7 @@ def __call__(self, parser, namespace, values, option_string=None):
items = []
else:
items = copy.copy(getattr(namespace, self.dest))
items += [argparse.FileType('rt')(value) for value in values]
items += [FileType('rt')(value) for value in values]
setattr(namespace, self.dest, items)

class CmdPreprocessor(Preprocessor):
Expand All @@ -37,7 +48,7 @@ def __init__(self, argv):
'''Note that so pcpp can stand in for other preprocessor tooling, it
ignores any arguments it does not understand.''')
argp.add_argument('inputs', metavar = 'input', default = [sys.stdin], nargs = '*', action = FileAction, help = 'Files to preprocess (use \'-\' for stdin)')
argp.add_argument('-o', dest = 'output', metavar = 'path', type = argparse.FileType('wt'), default=sys.stdout, nargs = '?', help = 'Output to a file instead of stdout')
argp.add_argument('-o', dest = 'output', metavar = 'path', type = FileType('wt'), default=sys.stdout, nargs = '?', help = 'Output to a file instead of stdout')
argp.add_argument('-D', dest = 'defines', metavar = 'macro[=val]', nargs = 1, action = 'append', help = 'Predefine name as a macro [with value]')
argp.add_argument('-U', dest = 'undefines', metavar = 'macro', nargs = 1, action = 'append', help = 'Pre-undefine name as a macro')
argp.add_argument('-N', dest = 'nevers', metavar = 'macro', nargs = 1, action = 'append', help = 'Never define name as a macro, even if defined during the preprocessing.')
Expand All @@ -55,7 +66,7 @@ def __init__(self, argv):
argp.add_argument('--line-directive', dest = 'line_directive', metavar = 'form', default = '#line', nargs = '?', help = "Form of line directive to use, defaults to #line, specify nothing to disable output of line directives")
argp.add_argument('--debug', dest = 'debug', action = 'store_true', help = 'Generate a pcpp_debug.log file logging execution')
argp.add_argument('--time', dest = 'time', action = 'store_true', help = 'Print the time it took to #include each file')
argp.add_argument('--filetimes', dest = 'filetimes', metavar = 'path', type = argparse.FileType('wt'), default=None, nargs = '?', help = 'Write CSV file with time spent inside each included file, inclusive and exclusive')
argp.add_argument('--filetimes', dest = 'filetimes', metavar = 'path', type = FileType('wt'), default=None, nargs = '?', help = 'Write CSV file with time spent inside each included file, inclusive and exclusive')
argp.add_argument('--compress', dest = 'compress', action = 'store_true', help = 'Make output as small as possible')
argp.add_argument('--assume-input-encoding', dest = 'assume_input_encoding', metavar = '<encoding>', default = None, nargs = 1, help = 'The text encoding to assume inputs are in')
argp.add_argument('--output-encoding', dest = 'output_encoding', metavar = '<encoding>', default = None, nargs = 1, help = 'The text encoding to use when writing files')
Expand Down
14 changes: 13 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,22 @@ classifiers = [
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12"
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3.15"
]
requires-python = ">=3.6"

[project.optional-dependencies]
dev = [
"build>=0.9.0",
"pytest>=7.0.1",
"setuptools>=59.6.0",
"twine>=3.8.0",
"wheel>=0.37.1",
]

[project.scripts]
pcpp = "pcpp:main"

Expand Down
17 changes: 12 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
#!/usr/bin/env python

from setuptools import setup
from setuptools.command.test import test as TestCommand
from setuptools import setup, Command
import os
import re
import sys


class PyTest(TestCommand):
# setuptools.command.test was removed in setuptools 72, so implement the
# test command directly on top of Command
class PyTest(Command):
"""Custom test command that uses pytest"""
user_options = [('pytest-args=', 'a', "Arguments to pass to pytest")]

def initialize_options(self):
TestCommand.initialize_options(self)
self.pytest_args = []

def run_tests(self):
def finalize_options(self):
if isinstance(self.pytest_args, str):
self.pytest_args = self.pytest_args.split()

def run(self):
import subprocess
import sys

Expand Down Expand Up @@ -73,6 +77,9 @@ def run_tests(self):
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3.13',
'Programming Language :: Python :: 3.14',
'Programming Language :: Python :: 3.15',
],
cmdclass={'test': PyTest},
)