diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fdb21d2..1041b0a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -98,7 +98,7 @@ jobs: echo "MOD_DPATH = $MOD_DPATH" python -m pytest --verbose --cov=line_profiler $MOD_DPATH ../tests cd .. - - uses: actions/upload-artifact@v4.3.1 + - uses: actions/upload-artifact@v4.4.0 name: Upload sdist artifact with: name: sdist_wheels @@ -123,8 +123,8 @@ jobs: - ubuntu-latest - macOS-latest - windows-latest - cibw_skip: - - '*-win32' + #cibw_skip: + #- '*-win32' arch: - auto steps: @@ -132,7 +132,8 @@ jobs: uses: actions/checkout@v4.1.1 - name: Enable MSVC 64bit uses: ilammy/msvc-dev-cmd@v1 - if: matrix.os == 'windows-latest' && ${{ contains(matrix.cibw_skip, '*-win32') }} + #if: matrix.os == 'windows-latest' && ${{ contains(matrix.cibw_skip, '*-win32') }} + if: matrix.os == 'windows-latest' - name: Set up QEMU uses: docker/setup-qemu-action@v3.0.0 if: runner.os == 'Linux' && matrix.arch != 'auto' @@ -144,7 +145,7 @@ jobs: output-dir: wheelhouse config-file: pyproject.toml env: - CIBW_SKIP: ${{ matrix.cibw_skip }} + #CIBW_SKIP: ${{ matrix.cibw_skip }} CIBW_ARCHS_LINUX: ${{ matrix.arch }} - name: Show built files shell: bash @@ -182,7 +183,7 @@ jobs: with: file: ./coverage.xml token: ${{ secrets.CODECOV_TOKEN }} - - uses: actions/upload-artifact@v4.3.1 + - uses: actions/upload-artifact@v4.4.0 name: Upload wheels artifact with: name: wheels-${{ matrix.os }}-${{ matrix.arch }} @@ -216,23 +217,23 @@ jobs: install-extras: tests-strict,runtime-strict os: windows-latest arch: auto - - python-version: '3.12' + - python-version: 3.13.0-rc.2 install-extras: tests-strict,runtime-strict,optional-strict os: ubuntu-latest arch: auto - - python-version: '3.12' + - python-version: 3.13.0-rc.2 install-extras: tests-strict,runtime-strict,optional-strict os: macOS-latest arch: auto - - python-version: '3.12' + - python-version: 3.13.0-rc.2 install-extras: tests-strict,runtime-strict,optional-strict os: windows-latest arch: auto - - python-version: '3.12' + - python-version: 3.13.0-rc.2 install-extras: tests os: macOS-latest arch: auto - - python-version: '3.12' + - python-version: 3.13.0-rc.2 install-extras: tests os: windows-latest arch: auto @@ -256,6 +257,10 @@ jobs: install-extras: tests,optional os: ubuntu-latest arch: auto + - python-version: 3.13.0-rc.2 + install-extras: tests,optional + os: ubuntu-latest + arch: auto - python-version: '3.8' install-extras: tests,optional os: macOS-latest @@ -276,6 +281,10 @@ jobs: install-extras: tests,optional os: macOS-latest arch: auto + - python-version: 3.13.0-rc.2 + install-extras: tests,optional + os: macOS-latest + arch: auto - python-version: '3.8' install-extras: tests,optional os: windows-latest @@ -296,6 +305,10 @@ jobs: install-extras: tests,optional os: windows-latest arch: auto + - python-version: 3.13.0-rc.2 + install-extras: tests,optional + os: windows-latest + arch: auto steps: - name: Checkout source uses: actions/checkout@v4.1.1 @@ -311,7 +324,7 @@ jobs: uses: actions/setup-python@v5.1.1 with: python-version: ${{ matrix.python-version }} - - uses: actions/download-artifact@v4.1.2 + - uses: actions/download-artifact@v4.1.8 name: Download wheels with: pattern: wheels-* @@ -407,13 +420,13 @@ jobs: steps: - name: Checkout source uses: actions/checkout@v4.1.1 - - uses: actions/download-artifact@v4.1.2 + - uses: actions/download-artifact@v4.1.8 name: Download wheels with: pattern: wheels-* merge-multiple: true path: wheelhouse - - uses: actions/download-artifact@v4.1.2 + - uses: actions/download-artifact@v4.1.8 name: Download sdist with: name: sdist_wheels @@ -462,7 +475,7 @@ jobs: ots stamp wheelhouse/*.whl wheelhouse/*.tar.gz wheelhouse/*.asc ls -la wheelhouse twine upload --username __token__ --password "$TWINE_PASSWORD" --repository-url "$TWINE_REPOSITORY_URL" wheelhouse/*.whl wheelhouse/*.tar.gz --skip-existing --verbose || { echo "failed to twine upload" ; exit 1; } - - uses: actions/upload-artifact@v4.3.1 + - uses: actions/upload-artifact@v4.4.0 name: Upload deploy artifacts with: name: deploy_artifacts @@ -482,13 +495,13 @@ jobs: steps: - name: Checkout source uses: actions/checkout@v4.1.1 - - uses: actions/download-artifact@v4.1.2 + - uses: actions/download-artifact@v4.1.8 name: Download wheels with: pattern: wheels-* merge-multiple: true path: wheelhouse - - uses: actions/download-artifact@v4.1.2 + - uses: actions/download-artifact@v4.1.8 name: Download sdist with: name: sdist_wheels @@ -537,7 +550,7 @@ jobs: ots stamp wheelhouse/*.whl wheelhouse/*.tar.gz wheelhouse/*.asc ls -la wheelhouse twine upload --username __token__ --password "$TWINE_PASSWORD" --repository-url "$TWINE_REPOSITORY_URL" wheelhouse/*.whl wheelhouse/*.tar.gz --skip-existing --verbose || { echo "failed to twine upload" ; exit 1; } - - uses: actions/upload-artifact@v4.3.1 + - uses: actions/upload-artifact@v4.4.0 name: Upload deploy artifacts with: name: deploy_artifacts @@ -558,7 +571,7 @@ jobs: steps: - name: Checkout source uses: actions/checkout@v4.1.1 - - uses: actions/download-artifact@v4.1.2 + - uses: actions/download-artifact@v4.1.8 name: Download artifacts with: name: deploy_artifacts diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ba19a4f..50fb3e1 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,7 @@ Changes * FIX: Fix issue with auto-profile of editable installs #279 * FIX: Lookup OP-codes instead of hard coding them #284 * CHANGE: Drop support for Python 3.6 and Python 3.7 +* ENH: Add support for Python 3.13 4.1.3 ~~~~~ diff --git a/line_profiler/_line_profiler.pyx b/line_profiler/_line_profiler.pyx index acbae89..5438eb8 100644 --- a/line_profiler/_line_profiler.pyx +++ b/line_profiler/_line_profiler.pyx @@ -222,6 +222,8 @@ cdef class LineProfiler: self.code_hash_map = {} self.dupes_map = {} self.timer_unit = hpTimerUnit() + # Create a data store for thread-local objects + # https://docs.python.org/3/library/threading.html#thread-local-data self.threaddata = threading.local() for func in functions: diff --git a/line_profiler/autoprofile/autoprofile.py b/line_profiler/autoprofile/autoprofile.py index ef66b89..7331dcc 100644 --- a/line_profiler/autoprofile/autoprofile.py +++ b/line_profiler/autoprofile/autoprofile.py @@ -91,4 +91,5 @@ def run(script_file, ns, prof_mod, profile_imports=False): tree_profiled = AstTreeProfiler(script_file, prof_mod, profile_imports).profile() _extend_line_profiler_for_profiling_imports(ns[PROFILER_LOCALS_NAME]) - exec(compile(tree_profiled, script_file, 'exec'), ns, ns) + code_obj = compile(tree_profiled, script_file, 'exec') + exec(code_obj, ns, ns) diff --git a/line_profiler/line_profiler.py b/line_profiler/line_profiler.py index bb30198..2a71d03 100755 --- a/line_profiler/line_profiler.py +++ b/line_profiler/line_profiler.py @@ -432,9 +432,17 @@ def show_func(filename, start_lineno, func_name, timings, unit, else: for lineno, line in zip(linenos, sublines): nhits, time, per_hit, percent = display.get(lineno, empty) - txt = template % (lineno, nhits, time, per_hit, percent, - line.rstrip('\n').rstrip('\r')) - stream.write(txt) + line_ = line.rstrip('\n').rstrip('\r') + txt = template % (lineno, nhits, time, per_hit, percent, line_) + try: + stream.write(txt) + except UnicodeEncodeError: + # todo: better handling of windows encoding issue + # for now just work around it + line_ = 'UnicodeEncodeError - help wanted for a fix' + txt = template % (lineno, nhits, time, per_hit, percent, line_) + stream.write(txt) + stream.write('\n') stream.write('\n') diff --git a/pyproject.toml b/pyproject.toml index 235d1a0..08a4ea0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,8 @@ omit =[ ] [tool.cibuildwheel] -build = "cp38-* cp39-* cp310-* cp311-* cp312-*" +build = "cp38-* cp39-* cp310-* cp311-* cp312-* cp313-*" +skip = ["*-win32", "cp313-musllinux_i686"] build-frontend = "build" build-verbosity = 1 #test-requires = [ "-r requirements/tests-strict.txt",] diff --git a/run_tests.py b/run_tests.py index 627c46f..ae053a0 100755 --- a/run_tests.py +++ b/run_tests.py @@ -141,17 +141,26 @@ def main(): else: print(f'[run_tests] No installed version of {package_name} found') + # disable coverage in cibuildwheel for now + use_coverage = not is_cibuildwheel() + try: import pytest - pytest_args = [ - '--cov-config', os.fspath(pyproject_fpath), - '--cov-report', 'html', - '--cov-report', 'term', - '--cov-report', 'xml', - '--cov=' + package_name, + pytest_args = [] + + if use_coverage: + pytest_args += [ + '--cov-config', os.fspath(pyproject_fpath), + '--cov-report', 'html', + '--cov-report', 'term', + '--cov-report', 'xml', + '--cov=' + package_name, + ] + + pytest_args += [ os.fspath(modpath), os.fspath(test_dir) ] - if is_cibuildwheel(): + if is_cibuildwheel() and use_coverage: pytest_args.append('--cov-append') pytest_args = pytest_args + sys.argv[1:] @@ -163,7 +172,7 @@ def main(): retcode = 1 finally: os.chdir(orig_cwd) - if is_cibuildwheel(): + if is_cibuildwheel() and use_coverage: # for CIBW under linux copy_coverage_cibuildwheel_docker(f'/home/runner/work/{package_name}/{package_name}') print('[run_tests] Restoring cwd = {!r}'.format(orig_cwd)) diff --git a/setup.py b/setup.py index 4cb9490..deaf58f 100755 --- a/setup.py +++ b/setup.py @@ -294,6 +294,7 @@ def run_cythonize(force=False): 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', 'Programming Language :: Python :: Implementation :: CPython', 'Topic :: Software Development', ] diff --git a/tests/test_assumptions.py b/tests/test_assumptions.py deleted file mode 100644 index 34bb7df..0000000 --- a/tests/test_assumptions.py +++ /dev/null @@ -1,9 +0,0 @@ - -def test_assumed_noop(): - """ - We are assuming the NOP code is 9. - Double check that it is. - """ - import opcode - NOP_VALUE: int = opcode.opmap['NOP'] - assert NOP_VALUE == 9 diff --git a/tests/test_autoprofile.py b/tests/test_autoprofile.py index b5c661e..6b3bc48 100644 --- a/tests/test_autoprofile.py +++ b/tests/test_autoprofile.py @@ -313,15 +313,22 @@ def test_autoprofile_script_with_prof_imports(): # pytest.skip('Failing due to the noop bug') args = [sys.executable, '-m', 'kernprof', '--prof-imports', '-p', 'script.py', '-l', os.fspath(script_fpath)] - proc = ub.cmd(args, cwd=temp_dpath, verbose=2) + proc = ub.cmd(args, cwd=temp_dpath, verbose=0) + print('Kernprof Stdout:') print(proc.stdout) + print('Kernprof Stderr:') print(proc.stderr) + print('About to check kernprof return code') proc.check_returncode() args = [sys.executable, '-m', 'line_profiler', os.fspath(script_fpath) + '.lprof'] - proc = ub.cmd(args, cwd=temp_dpath) + proc = ub.cmd(args, cwd=temp_dpath, verbose=0) raw_output = proc.stdout + print('Line_profile Stdout:') print(raw_output) + print('Line_profile Stderr:') + print(proc.stderr) + print('About to check line_profiler return code') proc.check_returncode() assert 'Function: add_one' in raw_output diff --git a/tests/test_explicit_profile.py b/tests/test_explicit_profile.py index 4570005..b76c03b 100644 --- a/tests/test_explicit_profile.py +++ b/tests/test_explicit_profile.py @@ -34,9 +34,9 @@ def _demo_explicit_profile_script(): @profile def fib(n): a, b = 0, 1 - while a < n: + for _ in range(n): a, b = b, a + b - + return a fib(10) ''')