├── MANIFEST.in ├── python ├── ujson.h ├── version_template.h ├── ujson.c └── JSONtoObj.c ├── deps └── double-conversion │ ├── double-conversion │ ├── .gitignore │ ├── SConscript │ ├── double-conversion.h │ ├── fixed-dtoa.h │ ├── cached-powers.h │ ├── strtod.h │ ├── fast-dtoa.h │ ├── bignum-dtoa.h │ ├── diy-fp.h │ ├── bignum.h │ ├── cached-powers.cc │ └── string-to-double.h │ ├── test │ ├── CMakeLists.txt │ └── cctest │ │ ├── SConscript │ │ ├── CMakeLists.txt │ │ ├── gay-shortest.h │ │ ├── gay-shortest-single.h │ │ ├── gay-fixed.h │ │ ├── gay-precision.h │ │ ├── test-diy-fp.cc │ │ ├── cctest.cc │ │ ├── cctest.h │ │ └── checks.h │ ├── WORKSPACE │ ├── cmake │ └── Config.cmake.in │ ├── msvc │ ├── testrunner.cmd │ ├── double-conversion.sln │ ├── double-conversion.vcxproj.filters │ ├── run_tests │ │ ├── run_tests.vcxproj.filters │ │ └── run_tests.vcxproj │ └── double-conversion.vcxproj │ ├── .gitignore │ ├── AUTHORS │ ├── COPYING │ ├── LICENSE │ ├── README.md │ ├── SConstruct │ ├── BUILD │ ├── CMakeLists.txt │ └── Changelog ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── zizmor.yml ├── workflows │ ├── lint.yml │ ├── labels.yml │ ├── fuzz.yml │ ├── require-pr-label.yml │ ├── release-drafter.yml │ ├── benchmark.yml │ ├── test.yml │ └── deploy.yml ├── renovate.json ├── ISSUE_TEMPLATE.md ├── release-drafter.yml └── labels.yml ├── pyproject.toml ├── scripts └── coverage.sh ├── RELEASING.md ├── setup.cfg ├── tests ├── memory.py └── fuzz.py ├── .pre-commit-config.yaml ├── setup.py ├── .gitignore ├── LICENSE.txt └── README.md /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include python/version.h 2 | -------------------------------------------------------------------------------- /python/ujson.h: -------------------------------------------------------------------------------- 1 | extern PyObject* JSONDecodeError; 2 | -------------------------------------------------------------------------------- /deps/double-conversion/double-conversion/.gitignore: -------------------------------------------------------------------------------- 1 | *.os 2 | -------------------------------------------------------------------------------- /deps/double-conversion/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(cctest) 2 | -------------------------------------------------------------------------------- /deps/double-conversion/WORKSPACE: -------------------------------------------------------------------------------- 1 | # Bazel (http://bazel.io/) WORKSPACE file for double-conversion. 2 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Fixes # 2 | 3 | Changes proposed in this pull request: 4 | 5 | * 6 | * 7 | * 8 | -------------------------------------------------------------------------------- /deps/double-conversion/cmake/Config.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake") 4 | check_required_components("@PROJECT_NAME@") 5 | -------------------------------------------------------------------------------- /.github/zizmor.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | artipacked: 3 | ignore: 4 | - benchmark.yml 5 | - deploy.yml 6 | - fuzz.yml 7 | - labels.yml 8 | - lint.yml 9 | - test.yml 10 | -------------------------------------------------------------------------------- /deps/double-conversion/msvc/testrunner.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal enabledelayedexpansion 3 | setlocal enableextensions 4 | 5 | for /f useback %%f in (`Release\x64\run_tests.exe --list`) do ( 6 | set var=%%f 7 | if "x!var:~-1!" == "x<" ( 8 | set var=!var:~0,-1! 9 | ) 10 | Release\x64\run_tests !var! 11 | ) 12 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = [ 3 | "setuptools>=42", 4 | 'setuptools<72.2; implementation_name == "pypy"', # https://github.com/pypa/distutils/issues/283 5 | "setuptools_scm[toml]>=3.4", 6 | ] 7 | 8 | [tool.black] 9 | target_version = ["py39"] 10 | 11 | [tool.isort] 12 | profile = "black" 13 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | jobs: 6 | lint: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: actions/setup-python@v5 12 | with: 13 | python-version: "3.x" 14 | - uses: pre-commit/action@v3.0.1 15 | -------------------------------------------------------------------------------- /deps/double-conversion/double-conversion/SConscript: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | double_conversion_sources = [ 3 | 'bignum.cc', 4 | 'bignum-dtoa.cc', 5 | 'cached-powers.cc', 6 | 'double-to-string.cc', 7 | 'fast-dtoa.cc', 8 | 'fixed-dtoa.cc', 9 | 'string-to-double.cc', 10 | 'strtod.cc' 11 | ] 12 | Return('double_conversion_sources') 13 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base" 5 | ], 6 | "labels": [ 7 | "changelog: skip", 8 | "dependencies" 9 | ], 10 | "packageRules": [ 11 | { 12 | "groupName": "github-actions", 13 | "matchManagers": ["github-actions"], 14 | "separateMajorMinor": "false" 15 | } 16 | ], 17 | "schedule": ["on the first day of the month"] 18 | } 19 | -------------------------------------------------------------------------------- /.github/workflows/labels.yml: -------------------------------------------------------------------------------- 1 | name: Sync labels 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - .github/labels.yml 9 | workflow_dispatch: 10 | 11 | jobs: 12 | sync: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: micnncim/action-label-syncer@v1 17 | with: 18 | prune: false 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | -------------------------------------------------------------------------------- /deps/double-conversion/.gitignore: -------------------------------------------------------------------------------- 1 | .sconsign.dblite 2 | *~ 3 | *.o 4 | *.obj 5 | msvc/Release/ 6 | msvc/Debug/ 7 | *.suo 8 | *.opensdf 9 | *.sdf 10 | *.user 11 | *.a 12 | *.so 13 | *.so.* 14 | *.dylib 15 | /run_tests 16 | Makefile 17 | CMakeLists.txt.user 18 | CMakeCache.txt 19 | CMakeFiles 20 | CMakeScripts 21 | Testing 22 | cmake_install.cmake 23 | install_manifest.txt 24 | compile_commands.json 25 | CTestTestfile.cmake 26 | _deps 27 | *.cmake 28 | *.kdev4 29 | DartConfiguration.tcl 30 | bazel-* 31 | .cache 32 | -------------------------------------------------------------------------------- /deps/double-conversion/test/cctest/SConscript: -------------------------------------------------------------------------------- 1 | double_conversion_test_sources = [ 2 | 'cctest.cc', 3 | 'gay-fixed.cc', 4 | 'gay-precision.cc', 5 | 'gay-shortest.cc', 6 | 'gay-shortest-single.cc', 7 | 'test-bignum.cc', 8 | 'test-bignum-dtoa.cc', 9 | 'test-conversions.cc', 10 | 'test-diy-fp.cc', 11 | 'test-dtoa.cc', 12 | 'test-fast-dtoa.cc', 13 | 'test-fixed-dtoa.cc', 14 | 'test-ieee.cc', 15 | 'test-strtod.cc', 16 | ] 17 | Return('double_conversion_test_sources') 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### What did you do? 2 | 3 | ### What did you expect to happen? 4 | 5 | ### What actually happened? 6 | 7 | ### What versions are you using? 8 | 9 | * OS: 10 | * Python: 11 | * UltraJSON: 12 | 13 | Please include **code** that reproduces the issue. 14 | 15 | The [best reproductions](https://stackoverflow.com/help/minimal-reproducible-example) are [self-contained scripts](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) with minimal dependencies. 16 | 17 | ```python 18 | code goes here 19 | ``` 20 | -------------------------------------------------------------------------------- /.github/workflows/fuzz.yml: -------------------------------------------------------------------------------- 1 | name: Fuzz 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | - uses: actions/setup-python@v5 11 | with: 12 | python-version: 3.x 13 | 14 | - name: Install 15 | run: | 16 | python -m pip install -U pip 17 | python -m pip install . 18 | env: 19 | CFLAGS: '-DDEBUG' 20 | 21 | - name: Fuzz 22 | run: python tests/fuzz.py --seed=0:1000 23 | -------------------------------------------------------------------------------- /.github/workflows/require-pr-label.yml: -------------------------------------------------------------------------------- 1 | name: Require PR label 2 | 3 | on: 4 | pull_request: 5 | types: [opened, reopened, labeled, unlabeled, synchronize] 6 | 7 | jobs: 8 | label: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: mheap/github-action-required-labels@v5 13 | with: 14 | mode: minimum 15 | count: 1 16 | labels: 17 | "changelog: Added, changelog: Changed, changelog: Deprecated, changelog: 18 | Fixed, changelog: Removed, changelog: Security, changelog: skip" 19 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release drafter 2 | 3 | on: 4 | push: 5 | # branches to consider in the event; optional, defaults to all 6 | branches: 7 | - main 8 | workflow_dispatch: 9 | 10 | jobs: 11 | update_release_draft: 12 | if: github.repository_owner == 'ultrajson' 13 | runs-on: ubuntu-latest 14 | steps: 15 | # Drafts your next release notes as pull requests are merged into "main" 16 | - uses: release-drafter/release-drafter@v6 17 | env: 18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 19 | -------------------------------------------------------------------------------- /deps/double-conversion/AUTHORS: -------------------------------------------------------------------------------- 1 | # Below is a list of people and organizations that have contributed 2 | # to the double-conversion project. Names should be added to the 3 | # list like so: 4 | # 5 | # Name/Organization 6 | 7 | Google Inc. 8 | Mozilla Foundation 9 | 10 | Jeff Muizelaar 11 | Mike Hommey 12 | Martin Olsson 13 | Kent Williams 14 | Elan Ruusamäe 15 | Colin Hirsch 16 | Zhenyi Peng 17 | -------------------------------------------------------------------------------- /scripts/coverage.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Coverage for ultrajson's C code. 4 | # Usage: 5 | # CFLAGS="--coverage -O0" python setup.py -q build_ext --inplace -f 6 | # pytest 7 | # ./scripts/coverage.sh 8 | # Then inspect the files in the `cov` folder. 9 | 10 | # The exact arguments depend on whether we're using LLVM's gcov or GNU's. 11 | unameOut="$(uname -s)" 12 | case "${unameOut}" in 13 | Linux*) gcov_options=(--relative-only);; 14 | Darwin*) gcov_options=(--color);; 15 | *) echo "Unsupported OS ${unameOut}"; exit 1;; 16 | esac 17 | 18 | # The actual gcov instructions: 19 | gcov "${gcov_options[@]}" python/**.c -o build/temp.*/python 20 | gcov "${gcov_options[@]}" lib/**.c -o build/temp.*/lib 21 | 22 | # gcov dumps everything in the cwd without any option to change this. 23 | # Manually move the .gcov files to a `cov` folder. 24 | mkdir -p cov 25 | rm -rf cov/* 26 | mv ./**.gcov cov || exit 1 27 | 28 | echo Written gcov files to ./cov 29 | -------------------------------------------------------------------------------- /RELEASING.md: -------------------------------------------------------------------------------- 1 | # Release Checklist 2 | 3 | - [ ] Get `main` to the appropriate code release state. 4 | [GitHub Actions](https://github.com/ultrajson/ultrajson/actions) should be running 5 | cleanly for all merges to `main`. 6 | [![GitHub Actions status](https://github.com/ultrajson/ultrajson/workflows/Test/badge.svg)](https://github.com/ultrajson/ultrajson/actions) 7 | 8 | - [ ] Edit release draft, adjust text if needed: https://github.com/ultrajson/ultrajson/releases 9 | 10 | - [ ] Check next tag is correct, amend if needed 11 | 12 | - [ ] Publish release 13 | 14 | - [ ] Check the tagged GitHub Actions builds have deployed 15 | [source and wheels](https://github.com/ultrajson/ultrajson/actions?query=workflow%3ADeploy) 16 | to 17 | [PyPI](https://pypi.org/project/ujson/#history) 18 | 19 | - [ ] Check installation: 20 | 21 | ```bash 22 | pip3 uninstall -y ujson && pip3 install -U ujson 23 | python3 -c "import ujson; print(ujson.__version__)" 24 | ``` 25 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: "$RESOLVED_VERSION" 2 | tag-template: "$RESOLVED_VERSION" 3 | 4 | categories: 5 | - title: "Added" 6 | labels: 7 | - "changelog: Added" 8 | - "enhancement" 9 | - title: "Changed" 10 | label: "changelog: Changed" 11 | - title: "Deprecated" 12 | label: "changelog: Deprecated" 13 | - title: "Removed" 14 | label: "changelog: Removed" 15 | - title: "Fixed" 16 | labels: 17 | - "changelog: Fixed" 18 | - "bug" 19 | - title: "Security" 20 | label: "changelog: Security" 21 | 22 | exclude-labels: 23 | - "changelog: skip" 24 | 25 | template: | 26 | $CHANGES 27 | 28 | version-resolver: 29 | major: 30 | labels: 31 | - "changelog: Removed" 32 | minor: 33 | labels: 34 | - "changelog: Added" 35 | - "changelog: Changed" 36 | - "changelog: Deprecated" 37 | - "enhancement" 38 | 39 | patch: 40 | labels: 41 | - "changelog: Fixed" 42 | - "bug" 43 | default: minor 44 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = ujson 3 | description = Ultra fast JSON encoder and decoder for Python 4 | long_description = file: README.md 5 | long_description_content_type = text/markdown 6 | url = https://github.com/ultrajson/ultrajson 7 | author = Jonas Tarnstrom 8 | license_files = LICENSE.txt 9 | platforms = any 10 | classifiers = 11 | Development Status :: 5 - Production/Stable 12 | Intended Audience :: Developers 13 | License :: OSI Approved :: BSD License 14 | Programming Language :: C 15 | Programming Language :: Python :: 3 16 | Programming Language :: Python :: 3 :: Only 17 | Programming Language :: Python :: 3.9 18 | Programming Language :: Python :: 3.10 19 | Programming Language :: Python :: 3.11 20 | Programming Language :: Python :: 3.12 21 | Programming Language :: Python :: 3.13 22 | download_url = https://github.com/ultrajson/ultrajson 23 | project_urls = 24 | Source=https://github.com/ultrajson/ultrajson 25 | 26 | [options] 27 | python_requires = >=3.9 28 | setup_requires = 29 | setuptools-scm 30 | 31 | [flake8] 32 | max_line_length = 88 33 | -------------------------------------------------------------------------------- /.github/workflows/benchmark.yml: -------------------------------------------------------------------------------- 1 | name: Benchmark 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | paths: 9 | - ".github/workflows/benchmark.yml" 10 | - "tests/benchmark.py" 11 | workflow_dispatch: 12 | 13 | jobs: 14 | build: 15 | runs-on: ${{ matrix.os }} 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | python-version: ["3.11"] 20 | os: [ubuntu-22.04] 21 | 22 | steps: 23 | - uses: actions/checkout@v4 24 | - run: git fetch --prune --unshallow 25 | 26 | - name: Set up Python ${{ matrix.python-version }} 27 | uses: actions/setup-python@v5 28 | with: 29 | python-version: ${{ matrix.python-version }} 30 | cache: pip 31 | cache-dependency-path: "setup.py" 32 | 33 | - name: Install dependencies 34 | run: | 35 | python -m pip install --upgrade pip 36 | python -m pip install --upgrade orjson simplejson 37 | python -m pip install . 38 | 39 | - name: Tests 40 | shell: bash 41 | run: | 42 | python tests/benchmark.py 43 | -------------------------------------------------------------------------------- /tests/memory.py: -------------------------------------------------------------------------------- 1 | import gc 2 | import sys 3 | import tracemalloc 4 | 5 | # exec the first argument to get func() and n 6 | exec_globals = {} 7 | exec(sys.argv[1], exec_globals) 8 | func = exec_globals["func"] 9 | n = int(sys.argv[2]) if sys.argv[2:] else 1 10 | 11 | # Pre-run once 12 | try: 13 | func() 14 | except Exception: 15 | pass 16 | 17 | # Create filter to only report leaks on the 'tracemalloc: measure' line below 18 | filters = [] 19 | with open(__file__) as fp: 20 | for i, line in enumerate(fp, start=1): 21 | if "tracemalloc: measure" in line: 22 | filters.append(tracemalloc.Filter(True, __file__, i)) 23 | 24 | # Clean up and take a snapshot 25 | tracemalloc.start() 26 | gc.collect() 27 | before = tracemalloc.take_snapshot().filter_traces(filters) 28 | 29 | # Run 30 | for i in range(n): 31 | try: 32 | func() # tracemalloc: measure 33 | except Exception: 34 | pass 35 | 36 | # Clean up and second snapshot 37 | gc.collect() 38 | after = tracemalloc.take_snapshot().filter_traces(filters) 39 | 40 | # Check that nothing got leaked 41 | diff = after.compare_to(before, "lineno") 42 | if diff: 43 | for stat in diff: 44 | print(stat) 45 | sys.exit(1) 46 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/asottile/pyupgrade 3 | rev: v3.19.0 4 | hooks: 5 | - id: pyupgrade 6 | args: [--py39-plus] 7 | 8 | - repo: https://github.com/psf/black-pre-commit-mirror 9 | rev: 24.10.0 10 | hooks: 11 | - id: black 12 | args: [--target-version=py39] 13 | 14 | - repo: https://github.com/PyCQA/isort 15 | rev: 5.13.2 16 | hooks: 17 | - id: isort 18 | 19 | - repo: https://github.com/PyCQA/flake8 20 | rev: 7.1.1 21 | hooks: 22 | - id: flake8 23 | additional_dependencies: [flake8-2020, flake8-implicit-str-concat] 24 | 25 | - repo: https://github.com/pre-commit/pygrep-hooks 26 | rev: v1.10.0 27 | hooks: 28 | - id: python-check-blanket-noqa 29 | - id: rst-backticks 30 | 31 | - repo: https://github.com/pre-commit/pre-commit-hooks 32 | rev: v5.0.0 33 | hooks: 34 | - id: check-json 35 | - id: check-merge-conflict 36 | - id: check-toml 37 | - id: check-yaml 38 | - id: end-of-file-fixer 39 | - id: trailing-whitespace 40 | exclude: "^.github/.*_TEMPLATE.md" 41 | 42 | - repo: https://github.com/woodruffw/zizmor-pre-commit 43 | rev: v0.9.1 44 | hooks: 45 | - id: zizmor 46 | 47 | - repo: https://github.com/asottile/setup-cfg-fmt 48 | rev: v2.7.0 49 | hooks: 50 | - id: setup-cfg-fmt 51 | args: [--include-version-classifiers, --max-py-version=3.13] 52 | ci: 53 | autoupdate_schedule: quarterly 54 | -------------------------------------------------------------------------------- /deps/double-conversion/COPYING: -------------------------------------------------------------------------------- 1 | Copyright 2006-2011, the V8 project authors. All rights reserved. 2 | Redistribution and use in source and binary forms, with or without 3 | modification, are permitted provided that the following conditions are 4 | met: 5 | 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above 9 | copyright notice, this list of conditions and the following 10 | disclaimer in the documentation and/or other materials provided 11 | with the distribution. 12 | * Neither the name of Google Inc. nor the names of its 13 | contributors may be used to endorse or promote products derived 14 | from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /deps/double-conversion/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2006-2011, the V8 project authors. All rights reserved. 2 | Redistribution and use in source and binary forms, with or without 3 | modification, are permitted provided that the following conditions are 4 | met: 5 | 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above 9 | copyright notice, this list of conditions and the following 10 | disclaimer in the documentation and/or other materials provided 11 | with the distribution. 12 | * Neither the name of Google Inc. nor the names of its 13 | contributors may be used to endorse or promote products derived 14 | from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /deps/double-conversion/README.md: -------------------------------------------------------------------------------- 1 | https://github.com/google/double-conversion 2 | 3 | This project (double-conversion) provides binary-decimal and decimal-binary 4 | routines for IEEE doubles. 5 | 6 | The library consists of efficient conversion routines that have been extracted 7 | from the V8 JavaScript engine. The code has been refactored and improved so that 8 | it can be used more easily in other projects. 9 | 10 | There is extensive documentation in `double-conversion/string-to-double.h` and 11 | `double-conversion/double-to-string.h`. Other examples can be found in 12 | `test/cctest/test-conversions.cc`. 13 | 14 | 15 | Building 16 | ======== 17 | 18 | This library can be built with [scons][0] or [cmake][1]. 19 | The checked-in Makefile simply forwards to scons, and provides a 20 | shortcut to run all tests: 21 | 22 | make 23 | make test 24 | 25 | Scons 26 | ----- 27 | 28 | The easiest way to install this library is to use `scons`. It builds 29 | the static and shared library, and is set up to install those at the 30 | correct locations: 31 | 32 | scons install 33 | 34 | Use the `DESTDIR` option to change the target directory: 35 | 36 | scons DESTDIR=alternative_directory install 37 | 38 | Cmake 39 | ----- 40 | 41 | To use cmake run `cmake .` in the root directory. This overwrites the 42 | existing Makefile. 43 | 44 | Use `-DBUILD_SHARED_LIBS=ON` to enable the compilation of shared libraries. 45 | Note that this disables static libraries. There is currently no way to 46 | build both libraries at the same time with cmake. 47 | 48 | Use `-DBUILD_TESTING=ON` to build the test executable. 49 | 50 | cmake . -DBUILD_TESTING=ON 51 | make 52 | test/cctest/cctest 53 | 54 | [0]: http://www.scons.org/ 55 | [1]: https://cmake.org/ 56 | -------------------------------------------------------------------------------- /deps/double-conversion/test/cctest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(CCTEST_SRC 3 | cctest.cc 4 | gay-fixed.cc 5 | gay-precision.cc 6 | gay-shortest.cc 7 | gay-shortest-single.cc 8 | test-bignum.cc 9 | test-bignum-dtoa.cc 10 | test-conversions.cc 11 | test-diy-fp.cc 12 | test-dtoa.cc 13 | test-fast-dtoa.cc 14 | test-fixed-dtoa.cc 15 | test-ieee.cc 16 | test-strtod.cc 17 | ) 18 | 19 | add_executable(cctest ${CCTEST_SRC}) 20 | target_link_libraries(cctest double-conversion) 21 | if(MSVC) 22 | target_compile_options(cctest PRIVATE /bigobj) 23 | endif() 24 | 25 | add_test(NAME test_bignum 26 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 27 | COMMAND $ test-bignum) 28 | 29 | add_test(NAME test_bignum_dtoa 30 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 31 | COMMAND $ test-bignum-dtoa) 32 | 33 | add_test(NAME test_conversions 34 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 35 | COMMAND $ test-conversions) 36 | add_test(NAME test_diy_fp 37 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 38 | COMMAND $ test-diy-fp) 39 | add_test(NAME test_dtoa 40 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 41 | COMMAND $ test-dtoa) 42 | add_test(NAME test_fast_dtoa 43 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 44 | COMMAND $ test-fast-dtoa) 45 | add_test(NAME test_fixed_dtoa 46 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 47 | COMMAND $ test-fixed-dtoa) 48 | add_test(NAME test_ieee 49 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 50 | COMMAND $ test-ieee) 51 | add_test(NAME test_strtod 52 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 53 | COMMAND $ test-strtod) 54 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import platform 2 | import shlex 3 | from glob import glob 4 | from os import environ, pathsep 5 | 6 | from setuptools import Extension, setup 7 | 8 | dconv_includes = [ 9 | dir 10 | for dir in environ.get( 11 | "UJSON_BUILD_DC_INCLUDES", 12 | "./deps/double-conversion/double-conversion", 13 | ).split(pathsep) 14 | if dir 15 | ] 16 | dconv_libs = shlex.split(environ.get("UJSON_BUILD_DC_LIBS", "")) 17 | dconv_source_files = [] 18 | if not dconv_libs: 19 | dconv_source_files.extend(glob("./deps/double-conversion/double-conversion/*.cc")) 20 | dconv_source_files.append("./lib/dconv_wrapper.cc") 21 | 22 | if platform.system() == "Linux" and environ.get("UJSON_BUILD_NO_STRIP", "0") not in ( 23 | "1", 24 | "True", 25 | ): 26 | strip_flags = ["-Wl,--strip-all"] 27 | else: 28 | strip_flags = [] 29 | 30 | module1 = Extension( 31 | "ujson", 32 | sources=dconv_source_files 33 | + [ 34 | "./python/ujson.c", 35 | "./python/objToJSON.c", 36 | "./python/JSONtoObj.c", 37 | "./lib/ultrajsonenc.c", 38 | "./lib/ultrajsondec.c", 39 | ], 40 | include_dirs=["./python", "./lib"] + dconv_includes, 41 | extra_compile_args=["-D_GNU_SOURCE"], 42 | extra_link_args=["-lstdc++", "-lm"] + dconv_libs + strip_flags, 43 | ) 44 | 45 | with open("python/version_template.h") as f: 46 | version_template = f.read() 47 | 48 | 49 | def local_scheme(version): 50 | """Skip the local version (eg. +xyz of 0.6.1.dev4+gdf99fe2) 51 | to be able to upload to Test PyPI""" 52 | return "" 53 | 54 | 55 | setup( 56 | ext_modules=[module1], 57 | use_scm_version={ 58 | "local_scheme": local_scheme, 59 | "write_to": "python/version.h", 60 | "write_to_template": version_template, 61 | }, 62 | ) 63 | -------------------------------------------------------------------------------- /deps/double-conversion/SConstruct: -------------------------------------------------------------------------------- 1 | # vim:ft=python 2 | import os 3 | 4 | double_conversion_sources = ['double-conversion/' + x for x in SConscript('double-conversion/SConscript')] 5 | double_conversion_test_sources = ['test/cctest/' + x for x in SConscript('test/cctest/SConscript')] 6 | 7 | DESTDIR = ARGUMENTS.get('DESTDIR', '') 8 | prefix = ARGUMENTS.get('prefix', '/usr/local') 9 | lib = ARGUMENTS.get('libsuffix', 'lib') 10 | libdir = os.path.join(DESTDIR + prefix, lib) 11 | 12 | env = Environment(CPPPATH='#', LIBS=['m', 'stdc++'], 13 | CXXFLAGS=ARGUMENTS.get('CXXFLAGS', '')) 14 | debug = ARGUMENTS.get('debug', 0) 15 | optimize = ARGUMENTS.get('optimize', 0) 16 | env.Replace(CXX = ARGUMENTS.get('CXX', 'g++')) 17 | 18 | # for shared lib, requires scons 2.3.0 19 | env['SHLIBVERSION'] = '3.0.0' 20 | 21 | CCFLAGS = [] 22 | if int(debug): 23 | CCFLAGS.append(ARGUMENTS.get('CXXFLAGS', '-g -Wall -Wshadow -Werror -UNDEBUG')) 24 | if int(optimize): 25 | CCFLAGS.append(ARGUMENTS.get('CXXFLAGS', '-O3 -DNDEBUG=1')) 26 | 27 | env.Append(CCFLAGS = " ".join(CCFLAGS)) 28 | 29 | double_conversion_shared_objects = [ 30 | env.SharedObject(src) for src in double_conversion_sources] 31 | double_conversion_static_objects = [ 32 | env.StaticObject(src) for src in double_conversion_sources] 33 | 34 | library_name = 'double-conversion' 35 | 36 | static_lib = env.StaticLibrary(library_name, double_conversion_static_objects) 37 | static_lib_pic = env.StaticLibrary(library_name + '_pic', double_conversion_shared_objects) 38 | shared_lib = env.SharedLibrary(library_name, double_conversion_shared_objects) 39 | 40 | env.Program('run_tests', double_conversion_test_sources, LIBS=[static_lib]) 41 | 42 | env.InstallVersionedLib(libdir, shared_lib) 43 | env.Install(libdir, static_lib) 44 | env.Install(libdir, static_lib_pic) 45 | 46 | env.Alias('install', libdir) 47 | -------------------------------------------------------------------------------- /deps/double-conversion/double-conversion/double-conversion.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ 29 | #define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ 30 | 31 | #include "string-to-double.h" 32 | #include "double-to-string.h" 33 | 34 | #endif // DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ 35 | -------------------------------------------------------------------------------- /deps/double-conversion/test/cctest/gay-shortest.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006-2008 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef GAY_SHORTEST_H_ 29 | #define GAY_SHORTEST_H_ 30 | 31 | namespace double_conversion { 32 | 33 | struct PrecomputedShortest { 34 | double v; 35 | const char* representation; 36 | int decimal_point; 37 | }; 38 | 39 | Vector PrecomputedShortestRepresentations(); 40 | 41 | } // namespace double_conversion 42 | 43 | #endif // GAY_SHORTEST_H_ 44 | -------------------------------------------------------------------------------- /python/version_template.h: -------------------------------------------------------------------------------- 1 | /* 2 | Developed by ESN, an Electronic Arts Inc. studio. 3 | Copyright (c) 2014, Electronic Arts Inc. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of ESN, Electronic Arts Inc. nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | 29 | Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc) 30 | http://code.google.com/p/stringencoders/ 31 | Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved. 32 | 33 | Numeric decoder derived from from TCL library 34 | http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms 35 | * Copyright (c) 1988-1993 The Regents of the University of California. 36 | * Copyright (c) 1994 Sun Microsystems, Inc. 37 | */ 38 | 39 | #define UJSON_VERSION "{version}" 40 | -------------------------------------------------------------------------------- /deps/double-conversion/test/cctest/gay-shortest-single.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011, the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef GAY_SHORTEST_SINGLE_H_ 29 | #define GAY_SHORTEST_SINGLE_H_ 30 | 31 | namespace double_conversion { 32 | 33 | struct PrecomputedShortestSingle { 34 | float v; 35 | const char* representation; 36 | int decimal_point; 37 | }; 38 | 39 | Vector 40 | PrecomputedShortestSingleRepresentations(); 41 | 42 | } // namespace double_conversion 43 | 44 | #endif // GAY_SHORTEST_SINGLE_H_ 45 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | # Default GitHub labels 2 | - color: d73a4a 3 | description: "Something isn't working" 4 | name: bug 5 | - color: cfd3d7 6 | description: "This issue or pull request already exists" 7 | name: duplicate 8 | - color: a2eeef 9 | description: "New feature or request" 10 | name: enhancement 11 | - color: 7057ff 12 | description: "Good for newcomers" 13 | name: good first issue 14 | - color: 008672 15 | description: "Extra attention is needed" 16 | name: help wanted 17 | - color: e4e669 18 | description: "This doesn't seem right" 19 | name: invalid 20 | - color: d876e3 21 | description: "Further information is requested" 22 | name: question 23 | - color: ffffff 24 | description: "This will not be worked on" 25 | name: wontfix 26 | 27 | # Keep a Changelog labels 28 | # https://keepachangelog.com/en/1.0.0/ 29 | - color: 0e8a16 30 | description: "For new features" 31 | name: "changelog: Added" 32 | - color: af99e5 33 | description: "For changes in existing functionality" 34 | name: "changelog: Changed" 35 | - color: FFA500 36 | description: "For soon-to-be removed features" 37 | name: "changelog: Deprecated" 38 | - color: 00A800 39 | description: "For any bug fixes" 40 | name: "changelog: Fixed" 41 | - color: ff0000 42 | description: "For now removed features" 43 | name: "changelog: Removed" 44 | - color: 045aa0 45 | description: "In case of vulnerabilities" 46 | name: "changelog: Security" 47 | - color: fbca04 48 | description: "Exclude PR from release draft" 49 | name: "changelog: skip" 50 | 51 | # Other labels 52 | - color: 0366d6 53 | description: "For dependencies" 54 | name: dependencies 55 | - color: e28acf 56 | description: "Documentation" 57 | name: documentation 58 | - color: f4660e 59 | description: "" 60 | name: Hacktoberfest 61 | - color: f4660e 62 | description: "To credit accepted Hacktoberfest PRs" 63 | name: hacktoberfest-accepted 64 | - color: caffaf 65 | description: "Deploy and release" 66 | name: release 67 | - color: fbca04 68 | description: "Unit tests, linting, CI, etc." 69 | name: testing 70 | - color: FFD43B 71 | description: "" 72 | name: Python 2 73 | - color: F25022 74 | description: "" 75 | name: Windows 76 | -------------------------------------------------------------------------------- /deps/double-conversion/msvc/double-conversion.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30723.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "double-conversion", "double-conversion.vcxproj", "{6863544A-0CE8-4CA9-A132-74116FD9D9BB}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "run_tests", "run_tests\run_tests.vcxproj", "{5619CA2B-6D39-4984-BE37-7580BBBD2139}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Win32 = Debug|Win32 13 | Debug|x64 = Debug|x64 14 | Release|Win32 = Release|Win32 15 | Release|x64 = Release|x64 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {6863544A-0CE8-4CA9-A132-74116FD9D9BB}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {6863544A-0CE8-4CA9-A132-74116FD9D9BB}.Debug|Win32.Build.0 = Debug|Win32 20 | {6863544A-0CE8-4CA9-A132-74116FD9D9BB}.Debug|x64.ActiveCfg = Debug|x64 21 | {6863544A-0CE8-4CA9-A132-74116FD9D9BB}.Debug|x64.Build.0 = Debug|x64 22 | {6863544A-0CE8-4CA9-A132-74116FD9D9BB}.Release|Win32.ActiveCfg = Release|Win32 23 | {6863544A-0CE8-4CA9-A132-74116FD9D9BB}.Release|Win32.Build.0 = Release|Win32 24 | {6863544A-0CE8-4CA9-A132-74116FD9D9BB}.Release|x64.ActiveCfg = Release|x64 25 | {6863544A-0CE8-4CA9-A132-74116FD9D9BB}.Release|x64.Build.0 = Release|x64 26 | {5619CA2B-6D39-4984-BE37-7580BBBD2139}.Debug|Win32.ActiveCfg = Debug|Win32 27 | {5619CA2B-6D39-4984-BE37-7580BBBD2139}.Debug|Win32.Build.0 = Debug|Win32 28 | {5619CA2B-6D39-4984-BE37-7580BBBD2139}.Debug|x64.ActiveCfg = Debug|x64 29 | {5619CA2B-6D39-4984-BE37-7580BBBD2139}.Debug|x64.Build.0 = Debug|x64 30 | {5619CA2B-6D39-4984-BE37-7580BBBD2139}.Release|Win32.ActiveCfg = Release|Win32 31 | {5619CA2B-6D39-4984-BE37-7580BBBD2139}.Release|Win32.Build.0 = Release|Win32 32 | {5619CA2B-6D39-4984-BE37-7580BBBD2139}.Release|x64.ActiveCfg = Release|x64 33 | {5619CA2B-6D39-4984-BE37-7580BBBD2139}.Release|x64.Build.0 = Release|x64 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /deps/double-conversion/test/cctest/gay-fixed.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006-2008 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef GAY_FIXED_H_ 29 | #define GAY_FIXED_H_ 30 | 31 | namespace double_conversion { 32 | 33 | struct PrecomputedFixed { 34 | double v; 35 | int number_digits; 36 | const char* representation; 37 | int decimal_point; 38 | }; 39 | 40 | // Returns precomputed values of dtoa. The strings have been generated using 41 | // Gay's dtoa in mode "fixed". 42 | Vector PrecomputedFixedRepresentations(); 43 | 44 | } // namespace double_conversion 45 | 46 | #endif // GAY_FIXED_H_ 47 | -------------------------------------------------------------------------------- /deps/double-conversion/test/cctest/gay-precision.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006-2008 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef GAY_PRECISION_H_ 29 | #define GAY_PRECISION_H_ 30 | 31 | namespace double_conversion { 32 | 33 | struct PrecomputedPrecision { 34 | double v; 35 | int number_digits; 36 | const char* representation; 37 | int decimal_point; 38 | }; 39 | 40 | // Returns precomputed values of dtoa. The strings have been generated using 41 | // Gay's dtoa in mode "precision". 42 | Vector PrecomputedPrecisionRepresentations(); 43 | 44 | } // namespace double_conversion 45 | 46 | #endif // GAY_PRECISION_H_ 47 | -------------------------------------------------------------------------------- /deps/double-conversion/BUILD: -------------------------------------------------------------------------------- 1 | # Bazel(http://bazel.io) BUILD file 2 | 3 | load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") 4 | 5 | licenses(["notice"]) 6 | 7 | exports_files(["LICENSE"]) 8 | 9 | cc_library( 10 | name = "double-conversion", 11 | srcs = [ 12 | "double-conversion/bignum.cc", 13 | "double-conversion/bignum-dtoa.cc", 14 | "double-conversion/cached-powers.cc", 15 | "double-conversion/double-to-string.cc", 16 | "double-conversion/fast-dtoa.cc", 17 | "double-conversion/fixed-dtoa.cc", 18 | "double-conversion/string-to-double.cc", 19 | "double-conversion/strtod.cc", 20 | ], 21 | hdrs = [ 22 | "double-conversion/bignum.h", 23 | "double-conversion/bignum-dtoa.h", 24 | "double-conversion/cached-powers.h", 25 | "double-conversion/diy-fp.h", 26 | "double-conversion/double-conversion.h", 27 | "double-conversion/double-to-string.h", 28 | "double-conversion/fast-dtoa.h", 29 | "double-conversion/fixed-dtoa.h", 30 | "double-conversion/ieee.h", 31 | "double-conversion/string-to-double.h", 32 | "double-conversion/strtod.h", 33 | "double-conversion/utils.h", 34 | ], 35 | linkopts = [ 36 | "-lm", 37 | ], 38 | visibility = ["//visibility:public"], 39 | ) 40 | 41 | cc_test( 42 | name = "cctest", 43 | srcs = [ 44 | "test/cctest/cctest.cc", 45 | "test/cctest/cctest.h", 46 | "test/cctest/checks.h", 47 | "test/cctest/gay-fixed.cc", 48 | "test/cctest/gay-fixed.h", 49 | "test/cctest/gay-precision.cc", 50 | "test/cctest/gay-precision.h", 51 | "test/cctest/gay-shortest.cc", 52 | "test/cctest/gay-shortest.h", 53 | "test/cctest/gay-shortest-single.cc", 54 | "test/cctest/gay-shortest-single.h", 55 | "test/cctest/test-bignum.cc", 56 | "test/cctest/test-bignum-dtoa.cc", 57 | "test/cctest/test-conversions.cc", 58 | "test/cctest/test-diy-fp.cc", 59 | "test/cctest/test-dtoa.cc", 60 | "test/cctest/test-fast-dtoa.cc", 61 | "test/cctest/test-fixed-dtoa.cc", 62 | "test/cctest/test-ieee.cc", 63 | "test/cctest/test-strtod.cc", 64 | ], 65 | args = [ 66 | "test-bignum", 67 | "test-bignum-dtoa", 68 | "test-conversions", 69 | "test-diy-fp", 70 | "test-dtoa", 71 | "test-fast-dtoa", 72 | "test-fixed-dtoa", 73 | "test-ieee", 74 | "test-strtod", 75 | ], 76 | visibility = ["//visibility:public"], 77 | deps = [":double-conversion"], 78 | ) 79 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | *.cover 42 | *.py,cover 43 | .cache 44 | .coverage 45 | .coverage.* 46 | .hypothesis/ 47 | .nox/ 48 | .pytest_cache/ 49 | .testmondata 50 | .tox/ 51 | cover/ 52 | coverage.xml 53 | htmlcov/ 54 | nosetests.xml 55 | 56 | # Translations 57 | *.mo 58 | *.pot 59 | 60 | # Django stuff: 61 | *.log 62 | local_settings.py 63 | db.sqlite3 64 | db.sqlite3-journal 65 | 66 | # Flask stuff: 67 | instance/ 68 | .webassets-cache 69 | 70 | # Scrapy stuff: 71 | .scrapy 72 | 73 | # Sphinx documentation 74 | docs/_build/ 75 | 76 | # PyBuilder 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | # For a library or package, you might want to ignore these files since the code is 88 | # intended to run in multiple environments; otherwise, check them in: 89 | # .python-version 90 | 91 | # pipenv 92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 95 | # install all needed dependencies. 96 | #Pipfile.lock 97 | 98 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 99 | __pypackages__/ 100 | 101 | # Celery stuff 102 | celerybeat-schedule 103 | celerybeat.pid 104 | 105 | # SageMath parsed files 106 | *.sage.py 107 | 108 | # Environments 109 | .env 110 | .venv 111 | env/ 112 | venv/ 113 | ENV/ 114 | env.bak/ 115 | venv.bak/ 116 | 117 | # Spyder project settings 118 | .spyderproject 119 | .spyproject 120 | 121 | # Rope project settings 122 | .ropeproject 123 | 124 | # mkdocs documentation 125 | /site 126 | 127 | # mypy 128 | .mypy_cache/ 129 | .dmypy.json 130 | dmypy.json 131 | 132 | # Pyre type checker 133 | .pyre/ 134 | 135 | # pytype static type analyzer 136 | .pytype/ 137 | 138 | # Generated by setuptools_scm 139 | python/version.h 140 | 141 | # Docker wheel build 142 | pip-cache/ 143 | temp-wheels/ 144 | 145 | # gcov coverage files 146 | cov 147 | *.gcov 148 | *.gcda 149 | *.gcno 150 | -------------------------------------------------------------------------------- /deps/double-conversion/double-conversion/fixed-dtoa.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef DOUBLE_CONVERSION_FIXED_DTOA_H_ 29 | #define DOUBLE_CONVERSION_FIXED_DTOA_H_ 30 | 31 | #include "utils.h" 32 | 33 | namespace double_conversion { 34 | 35 | // Produces digits necessary to print a given number with 36 | // 'fractional_count' digits after the decimal point. 37 | // The buffer must be big enough to hold the result plus one terminating null 38 | // character. 39 | // 40 | // The produced digits might be too short in which case the caller has to fill 41 | // the gaps with '0's. 42 | // Example: FastFixedDtoa(0.001, 5, ...) is allowed to return buffer = "1", and 43 | // decimal_point = -2. 44 | // Halfway cases are rounded towards +/-Infinity (away from 0). The call 45 | // FastFixedDtoa(0.15, 2, ...) thus returns buffer = "2", decimal_point = 0. 46 | // The returned buffer may contain digits that would be truncated from the 47 | // shortest representation of the input. 48 | // 49 | // This method only works for some parameters. If it can't handle the input it 50 | // returns false. The output is null-terminated when the function succeeds. 51 | bool FastFixedDtoa(double v, int fractional_count, 52 | Vector buffer, int* length, int* decimal_point); 53 | 54 | } // namespace double_conversion 55 | 56 | #endif // DOUBLE_CONVERSION_FIXED_DTOA_H_ 57 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | env: 6 | FORCE_COLOR: 1 7 | 8 | jobs: 9 | test: 10 | runs-on: ${{ matrix.os }} 11 | strategy: 12 | fail-fast: false 13 | matrix: 14 | python-version: ["pypy-3.10", "3.9", "3.10", "3.11", "3.12", "3.13"] 15 | os: [ubuntu-latest] 16 | include: 17 | - { python-version: "pypy-3.10", os: windows-latest } 18 | - { python-version: "pypy-3.10", os: macos-latest } 19 | - { python-version: "3.12", os: windows-latest } 20 | - { python-version: "3.12", os: macos-latest } 21 | - { python-version: "3.13", os: windows-latest } 22 | - { python-version: "3.13", os: macos-latest } 23 | 24 | steps: 25 | - uses: actions/checkout@v4 26 | 27 | - name: Set up Python ${{ matrix.python-version }} 28 | uses: actions/setup-python@v5 29 | with: 30 | python-version: ${{ matrix.python-version }} 31 | allow-prereleases: true 32 | cache: pip 33 | cache-dependency-path: "setup.py" 34 | 35 | - name: Install dependencies 36 | run: | 37 | python -m pip install -U pip 38 | python -m pip install -U pytest 39 | python -m pip install . 40 | env: 41 | CFLAGS: '-DDEBUG' 42 | 43 | - name: Tests 44 | run: | 45 | python -m pytest --capture=no 46 | 47 | - name: Test without debug mode 48 | run: | 49 | git clean -Xfd 50 | python -m pip install --force-reinstall . 51 | python -m pytest 52 | 53 | - name: Test with coverage 54 | if: ${{ startsWith(matrix.os, 'ubuntu') && matrix.python-version == '3.10' }} 55 | env: 56 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 57 | run: | 58 | pip install -e . 59 | pip install coverage 60 | CFLAGS="--coverage -O0" python setup.py -q build_ext --inplace -f 61 | coverage run -m pytest 62 | ./scripts/coverage.sh 63 | bash <(curl -s https://codecov.io/bash) -X gcov 64 | 65 | cross-arch: 66 | runs-on: ubuntu-latest 67 | strategy: 68 | fail-fast: false 69 | matrix: 70 | architecture: [ppc64le, s390x, aarch64, arm/v6, 386] 71 | steps: 72 | - uses: actions/checkout@v4 73 | - run: git fetch --prune --unshallow 74 | 75 | # https://github.com/docker/setup-qemu-action 76 | - name: Set up QEMU 77 | uses: docker/setup-qemu-action@v3 78 | 79 | - name: Test 80 | run: | 81 | docker run -v "$PWD:/io" --platform=linux/${{ matrix.architecture }} python:alpine ash -e -c ' 82 | apk add gcc g++ musl-dev git 83 | cd /io 84 | git config --global --add safe.directory /io 85 | pip install . pytest 86 | FORCE_COLOR=1 pytest 87 | ' 88 | 89 | success: 90 | needs: [test, cross-arch] 91 | runs-on: ubuntu-latest 92 | name: test successful 93 | steps: 94 | - name: Success 95 | run: echo Test successful 96 | -------------------------------------------------------------------------------- /deps/double-conversion/double-conversion/cached-powers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef DOUBLE_CONVERSION_CACHED_POWERS_H_ 29 | #define DOUBLE_CONVERSION_CACHED_POWERS_H_ 30 | 31 | #include "diy-fp.h" 32 | 33 | namespace double_conversion { 34 | 35 | namespace PowersOfTenCache { 36 | 37 | // Not all powers of ten are cached. The decimal exponent of two neighboring 38 | // cached numbers will differ by kDecimalExponentDistance. 39 | static const int kDecimalExponentDistance = 8; 40 | 41 | static const int kMinDecimalExponent = -348; 42 | static const int kMaxDecimalExponent = 340; 43 | 44 | // Returns a cached power-of-ten with a binary exponent in the range 45 | // [min_exponent; max_exponent] (boundaries included). 46 | void GetCachedPowerForBinaryExponentRange(int min_exponent, 47 | int max_exponent, 48 | DiyFp* power, 49 | int* decimal_exponent); 50 | 51 | // Returns a cached power of ten x ~= 10^k such that 52 | // k <= decimal_exponent < k + kCachedPowersDecimalDistance. 53 | // The given decimal_exponent must satisfy 54 | // kMinDecimalExponent <= requested_exponent, and 55 | // requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance. 56 | void GetCachedPowerForDecimalExponent(int requested_exponent, 57 | DiyFp* power, 58 | int* found_exponent); 59 | 60 | } // namespace PowersOfTenCache 61 | 62 | } // namespace double_conversion 63 | 64 | #endif // DOUBLE_CONVERSION_CACHED_POWERS_H_ 65 | -------------------------------------------------------------------------------- /deps/double-conversion/double-conversion/strtod.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef DOUBLE_CONVERSION_STRTOD_H_ 29 | #define DOUBLE_CONVERSION_STRTOD_H_ 30 | 31 | #include "utils.h" 32 | 33 | namespace double_conversion { 34 | 35 | // The buffer must only contain digits in the range [0-9]. It must not 36 | // contain a dot or a sign. It must not start with '0', and must not be empty. 37 | double Strtod(Vector buffer, int exponent); 38 | 39 | // The buffer must only contain digits in the range [0-9]. It must not 40 | // contain a dot or a sign. It must not start with '0', and must not be empty. 41 | float Strtof(Vector buffer, int exponent); 42 | 43 | // Same as Strtod, but assumes that 'trimmed' is already trimmed, as if run 44 | // through TrimAndCut. That is, 'trimmed' must have no leading or trailing 45 | // zeros, must not be a lone zero, and must not have 'too many' digits. 46 | double StrtodTrimmed(Vector trimmed, int exponent); 47 | 48 | // Same as Strtof, but assumes that 'trimmed' is already trimmed, as if run 49 | // through TrimAndCut. That is, 'trimmed' must have no leading or trailing 50 | // zeros, must not be a lone zero, and must not have 'too many' digits. 51 | float StrtofTrimmed(Vector trimmed, int exponent); 52 | 53 | inline Vector TrimTrailingZeros(Vector buffer) { 54 | for (int i = buffer.length() - 1; i >= 0; --i) { 55 | if (buffer[i] != '0') { 56 | return buffer.SubVector(0, i + 1); 57 | } 58 | } 59 | return Vector(buffer.start(), 0); 60 | } 61 | 62 | } // namespace double_conversion 63 | 64 | #endif // DOUBLE_CONVERSION_STRTOD_H_ 65 | -------------------------------------------------------------------------------- /deps/double-conversion/msvc/double-conversion.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | 44 | 45 | Header Files 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | Header Files 70 | 71 | 72 | Header Files 73 | 74 | 75 | Header Files 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /deps/double-conversion/msvc/run_tests/run_tests.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | Source Files 56 | 57 | 58 | Source Files 59 | 60 | 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | Header Files 70 | 71 | 72 | Header Files 73 | 74 | 75 | Header Files 76 | 77 | 78 | Header Files 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /deps/double-conversion/test/cctest/test-diy-fp.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006-2008 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #include 29 | 30 | #include "cctest.h" 31 | #include "double-conversion/diy-fp.h" 32 | #include "double-conversion/utils.h" 33 | 34 | 35 | using namespace double_conversion; 36 | 37 | 38 | TEST(Subtract) { 39 | DiyFp diy_fp1 = DiyFp(3, 0); 40 | DiyFp diy_fp2 = DiyFp(1, 0); 41 | DiyFp diff = DiyFp::Minus(diy_fp1, diy_fp2); 42 | 43 | CHECK(2 == diff.f()); // NOLINT 44 | CHECK_EQ(0, diff.e()); 45 | diy_fp1.Subtract(diy_fp2); 46 | CHECK(2 == diy_fp1.f()); // NOLINT 47 | CHECK_EQ(0, diy_fp1.e()); 48 | } 49 | 50 | 51 | TEST(Multiply) { 52 | DiyFp diy_fp1 = DiyFp(3, 0); 53 | DiyFp diy_fp2 = DiyFp(2, 0); 54 | DiyFp product = DiyFp::Times(diy_fp1, diy_fp2); 55 | 56 | CHECK(0 == product.f()); // NOLINT 57 | CHECK_EQ(64, product.e()); 58 | diy_fp1.Multiply(diy_fp2); 59 | CHECK(0 == diy_fp1.f()); // NOLINT 60 | CHECK_EQ(64, diy_fp1.e()); 61 | 62 | diy_fp1 = DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0x80000000, 00000000), 11); 63 | diy_fp2 = DiyFp(2, 13); 64 | product = DiyFp::Times(diy_fp1, diy_fp2); 65 | CHECK(1 == product.f()); // NOLINT 66 | CHECK_EQ(11 + 13 + 64, product.e()); 67 | 68 | // Test rounding. 69 | diy_fp1 = DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0x80000000, 00000001), 11); 70 | diy_fp2 = DiyFp(1, 13); 71 | product = DiyFp::Times(diy_fp1, diy_fp2); 72 | CHECK(1 == product.f()); // NOLINT 73 | CHECK_EQ(11 + 13 + 64, product.e()); 74 | 75 | diy_fp1 = DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0x7fffffff, ffffffff), 11); 76 | diy_fp2 = DiyFp(1, 13); 77 | product = DiyFp::Times(diy_fp1, diy_fp2); 78 | CHECK(0 == product.f()); // NOLINT 79 | CHECK_EQ(11 + 13 + 64, product.e()); 80 | 81 | // Halfway cases are allowed to round either way. So don't check for it. 82 | 83 | // Big numbers. 84 | diy_fp1 = DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF), 11); 85 | diy_fp2 = DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF), 13); 86 | // 128bit result: 0xfffffffffffffffe0000000000000001 87 | product = DiyFp::Times(diy_fp1, diy_fp2); 88 | CHECK(DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, FFFFFFFe) == product.f()); 89 | CHECK_EQ(11 + 13 + 64, product.e()); 90 | } 91 | -------------------------------------------------------------------------------- /deps/double-conversion/double-conversion/fast-dtoa.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef DOUBLE_CONVERSION_FAST_DTOA_H_ 29 | #define DOUBLE_CONVERSION_FAST_DTOA_H_ 30 | 31 | #include "utils.h" 32 | 33 | namespace double_conversion { 34 | 35 | enum FastDtoaMode { 36 | // Computes the shortest representation of the given input. The returned 37 | // result will be the most accurate number of this length. Longer 38 | // representations might be more accurate. 39 | FAST_DTOA_SHORTEST, 40 | // Same as FAST_DTOA_SHORTEST but for single-precision floats. 41 | FAST_DTOA_SHORTEST_SINGLE, 42 | // Computes a representation where the precision (number of digits) is 43 | // given as input. The precision is independent of the decimal point. 44 | FAST_DTOA_PRECISION 45 | }; 46 | 47 | // FastDtoa will produce at most kFastDtoaMaximalLength digits. This does not 48 | // include the terminating '\0' character. 49 | static const int kFastDtoaMaximalLength = 17; 50 | // Same for single-precision numbers. 51 | static const int kFastDtoaMaximalSingleLength = 9; 52 | 53 | // Provides a decimal representation of v. 54 | // The result should be interpreted as buffer * 10^(point - length). 55 | // 56 | // Precondition: 57 | // * v must be a strictly positive finite double. 58 | // 59 | // Returns true if it succeeds, otherwise the result can not be trusted. 60 | // There will be *length digits inside the buffer followed by a null terminator. 61 | // If the function returns true and mode equals 62 | // - FAST_DTOA_SHORTEST, then 63 | // the parameter requested_digits is ignored. 64 | // The result satisfies 65 | // v == (double) (buffer * 10^(point - length)). 66 | // The digits in the buffer are the shortest representation possible. E.g. 67 | // if 0.099999999999 and 0.1 represent the same double then "1" is returned 68 | // with point = 0. 69 | // The last digit will be closest to the actual v. That is, even if several 70 | // digits might correctly yield 'v' when read again, the buffer will contain 71 | // the one closest to v. 72 | // - FAST_DTOA_PRECISION, then 73 | // the buffer contains requested_digits digits. 74 | // the difference v - (buffer * 10^(point-length)) is closest to zero for 75 | // all possible representations of requested_digits digits. 76 | // If there are two values that are equally close, then FastDtoa returns 77 | // false. 78 | // For both modes the buffer must be large enough to hold the result. 79 | bool FastDtoa(double d, 80 | FastDtoaMode mode, 81 | int requested_digits, 82 | Vector buffer, 83 | int* length, 84 | int* decimal_point); 85 | 86 | } // namespace double_conversion 87 | 88 | #endif // DOUBLE_CONVERSION_FAST_DTOA_H_ 89 | -------------------------------------------------------------------------------- /deps/double-conversion/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | project(double-conversion VERSION 3.2.0) 3 | 4 | option(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" OFF) 5 | 6 | if(BUILD_SHARED_LIBS AND MSVC) 7 | set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) 8 | endif() 9 | 10 | set(headers 11 | double-conversion/bignum.h 12 | double-conversion/cached-powers.h 13 | double-conversion/diy-fp.h 14 | double-conversion/double-conversion.h 15 | double-conversion/double-to-string.h 16 | double-conversion/fast-dtoa.h 17 | double-conversion/fixed-dtoa.h 18 | double-conversion/ieee.h 19 | double-conversion/string-to-double.h 20 | double-conversion/strtod.h 21 | double-conversion/utils.h) 22 | 23 | add_library(double-conversion 24 | double-conversion/bignum.cc 25 | double-conversion/bignum-dtoa.cc 26 | double-conversion/cached-powers.cc 27 | double-conversion/double-to-string.cc 28 | double-conversion/fast-dtoa.cc 29 | double-conversion/fixed-dtoa.cc 30 | double-conversion/string-to-double.cc 31 | double-conversion/strtod.cc 32 | ${headers}) 33 | target_include_directories( 34 | double-conversion PUBLIC 35 | $) 36 | 37 | # pick a version # 38 | set_target_properties(double-conversion PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION 3) 39 | 40 | # set up testing if requested 41 | option(BUILD_TESTING "Build test programs" OFF) 42 | if(BUILD_TESTING) 43 | enable_testing() 44 | include(CTest) 45 | add_subdirectory(test) 46 | endif() 47 | 48 | #### 49 | # Installation (https://github.com/forexample/package-example) 50 | 51 | include(GNUInstallDirs) 52 | 53 | # Layout. This works for all platforms: 54 | # * /lib/cmake/ 55 | # * /lib/ 56 | # * /include/ 57 | set(config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") 58 | 59 | set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated") 60 | 61 | # Configuration 62 | set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake") 63 | set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake") 64 | set(targets_export_name "${PROJECT_NAME}Targets") 65 | set(namespace "${PROJECT_NAME}::") 66 | 67 | # Include module with function 'write_basic_package_version_file' 68 | include(CMakePackageConfigHelpers) 69 | 70 | # Configure 'ConfigVersion.cmake' 71 | # Note: PROJECT_VERSION is used as a VERSION 72 | write_basic_package_version_file( 73 | "${version_config}" COMPATIBILITY SameMajorVersion 74 | ) 75 | 76 | # Configure 'Config.cmake' 77 | # Use variables: 78 | # * targets_export_name 79 | # * PROJECT_NAME 80 | configure_package_config_file( 81 | "cmake/Config.cmake.in" 82 | "${project_config}" 83 | INSTALL_DESTINATION "${config_install_dir}" 84 | ) 85 | 86 | # Targets: 87 | # * /lib/libdouble-conversion.a 88 | # * header location after install: /include/double-conversion/*.h 89 | # * headers can be included by C++ code `#include ` 90 | install( 91 | TARGETS double-conversion 92 | EXPORT "${targets_export_name}" 93 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 94 | ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 95 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 96 | INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" 97 | ) 98 | 99 | # Headers: 100 | # * double-conversion/*.h -> /include/double-conversion/*.h 101 | install( 102 | FILES ${headers} 103 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/double-conversion" 104 | ) 105 | 106 | # Config 107 | # * /lib/cmake/double-conversion/double-conversionConfig.cmake 108 | # * /lib/cmake/double-conversion/double-conversionConfigVersion.cmake 109 | install( 110 | FILES "${project_config}" "${version_config}" 111 | DESTINATION "${config_install_dir}" 112 | ) 113 | 114 | # Config 115 | # * /lib/cmake/double-conversion/double-conversionTargets.cmake 116 | install( 117 | EXPORT "${targets_export_name}" 118 | NAMESPACE "${namespace}" 119 | DESTINATION "${config_install_dir}" 120 | ) 121 | 122 | if (MSVC AND BUILD_SHARED_LIBS) 123 | # Install companion PDB for Visual Studio 124 | install( 125 | FILES $ 126 | TYPE BIN 127 | OPTIONAL 128 | ) 129 | endif() 130 | -------------------------------------------------------------------------------- /deps/double-conversion/double-conversion/bignum-dtoa.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef DOUBLE_CONVERSION_BIGNUM_DTOA_H_ 29 | #define DOUBLE_CONVERSION_BIGNUM_DTOA_H_ 30 | 31 | #include "utils.h" 32 | 33 | namespace double_conversion { 34 | 35 | enum BignumDtoaMode { 36 | // Return the shortest correct representation. 37 | // For example the output of 0.299999999999999988897 is (the less accurate but 38 | // correct) 0.3. 39 | BIGNUM_DTOA_SHORTEST, 40 | // Same as BIGNUM_DTOA_SHORTEST but for single-precision floats. 41 | BIGNUM_DTOA_SHORTEST_SINGLE, 42 | // Return a fixed number of digits after the decimal point. 43 | // For instance fixed(0.1, 4) becomes 0.1000 44 | // If the input number is big, the output will be big. 45 | BIGNUM_DTOA_FIXED, 46 | // Return a fixed number of digits, no matter what the exponent is. 47 | BIGNUM_DTOA_PRECISION 48 | }; 49 | 50 | // Converts the given double 'v' to ascii. 51 | // The result should be interpreted as buffer * 10^(point-length). 52 | // The buffer will be null-terminated. 53 | // 54 | // The input v must be > 0 and different from NaN, and Infinity. 55 | // 56 | // The output depends on the given mode: 57 | // - SHORTEST: produce the least amount of digits for which the internal 58 | // identity requirement is still satisfied. If the digits are printed 59 | // (together with the correct exponent) then reading this number will give 60 | // 'v' again. The buffer will choose the representation that is closest to 61 | // 'v'. If there are two at the same distance, than the number is round up. 62 | // In this mode the 'requested_digits' parameter is ignored. 63 | // - FIXED: produces digits necessary to print a given number with 64 | // 'requested_digits' digits after the decimal point. The produced digits 65 | // might be too short in which case the caller has to fill the gaps with '0's. 66 | // Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2. 67 | // Halfway cases are rounded up. The call toFixed(0.15, 2) thus returns 68 | // buffer="2", point=0. 69 | // Note: the length of the returned buffer has no meaning wrt the significance 70 | // of its digits. That is, just because it contains '0's does not mean that 71 | // any other digit would not satisfy the internal identity requirement. 72 | // - PRECISION: produces 'requested_digits' where the first digit is not '0'. 73 | // Even though the length of produced digits usually equals 74 | // 'requested_digits', the function is allowed to return fewer digits, in 75 | // which case the caller has to fill the missing digits with '0's. 76 | // Halfway cases are again rounded up. 77 | // 'BignumDtoa' expects the given buffer to be big enough to hold all digits 78 | // and a terminating null-character. 79 | void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, 80 | Vector buffer, int* length, int* point); 81 | 82 | } // namespace double_conversion 83 | 84 | #endif // DOUBLE_CONVERSION_BIGNUM_DTOA_H_ 85 | -------------------------------------------------------------------------------- /deps/double-conversion/Changelog: -------------------------------------------------------------------------------- 1 | 2022-01-16: 2 | Install Visual Studio debugger (pdb) files. 3 | 4 | 2022-01-10: 5 | Fix quiet NANs on MIPS* and PA-RISC architectures. 6 | Update version number. 7 | 8 | 2021-12-22: 9 | Add support of Synopsys ARC64 architecture. 10 | Reintroduce macros, if DOUBLE_CONVERSION_NON_PREFIXED_MACROS is set. 11 | 12 | 2021-12-04: 13 | Update version number. 14 | 15 | 2021-10-04: 16 | Consistently use semicolons after DOUBLE_CONVERSION_ASSERT. 17 | 18 | 2021-07-16: 19 | Fix spelling. 20 | 21 | 2021-05-19: 22 | Loongarch is a RISC-style command system architecture. 23 | Add support for loongarch architecture. 24 | 25 | 2020-02-16: 26 | Add support for quiet and signaling NaNs to ieee header. 27 | 28 | 2019-10-31: 29 | Add support for xtensa architecture. 30 | Add support for nios2 architecture. 31 | 32 | 2019-10-12: 33 | Really add support for microblaze. A previous commit was lacking 34 | the necessary line. 35 | 36 | 2019-09-02: 37 | Add support for e2k architecture. Thanks to Michael Shigorin. 38 | 39 | 2019-08-01: 40 | Add min exponent width option in double-to-string conversion. 41 | 42 | 2019-06-22: 43 | Remove redundant parenthesis. 44 | 45 | 2019-06-11: 46 | Changed all macros to use DOUBLE_CONVERSION_ as prefix. 47 | Renamed ALLOW_CASE_INSENSIBILITY to ALLOW_CASE_INSENSITIVITY, 48 | the old name is still available but officially deprecated. 49 | Created and exposed new intermediate function StrtodTrimmed(). 50 | 51 | 2019-05-25: 52 | Fix `0x` for string->double conversion when Hex Floats are allowed. 53 | Avoid integer overflow when exponents for hex floats were too big. 54 | Update version number. 55 | 56 | 2019-04-22: 57 | Fixed warning in gcc4.9. Thanks to Scott McCaskill 58 | (https://github.com/usefulcat) for the patch. 59 | 60 | 2019-04-16: 61 | Merged changes to install libraries in the correct place when 62 | using 64-bit libraries. 63 | Contributed by Jason Zaman and (independently) 64 | Dan Church (https://github.com/h3xx) 65 | 66 | 2019-03-11: 67 | Use relative includes in the library. This shouldn't have any visible effect 68 | for consumers of the library. 69 | 70 | Update version number. 71 | 72 | 2019-03-06: 73 | Fix typo in test. 74 | Update version number. 75 | 76 | 2019-03-03: 77 | Fix separator characters when they they don't fit into 8 bits. 78 | Update version number. 79 | 80 | 2019-02-16: 81 | Check correctly for _MSC_VER. 82 | Patch by Ben Boeckel 83 | 84 | 2019-01-17: 85 | Allow the library to be compiled for Emscripten. 86 | Patch by Tim Paine. 87 | 88 | 2018-09-15: 89 | Update version numbers. This also updates the shared-library version number. 90 | 91 | 2018-09-09: 92 | Fix bug where large hex literals would lose their minus sign. 93 | Added support for separator characters (which adds a new optional 94 | argument). Thus increasing the version number to 3.1.0 95 | Added support for hexadecimal float literals. 96 | Support for more architectures. 97 | 98 | 2017-12-06: 99 | Renamed `DISALLOW_COPY_AND_ASSIGN` and `DISALLOW_IMPLICIT_CONSTRUCTORS` 100 | macros to `DC_DISALLOW_COPY_AND_ASSIGN` and 101 | `DC_DISALLOW_IMPLICIT_CONSTRUCTORS` to make it easier to integrate the 102 | library with other libraries that have similar macros. 103 | 104 | 2017-08-05: 105 | Tagged v3.0.0. 106 | Due to the directory rename switching to a new version number. 107 | The API for the library itself hasn't changed. 108 | 109 | 2017-03-04: 110 | Avoid negative shift. Fixes #41. 111 | 112 | 2016-11-17: 113 | Support RISC-V. 114 | 115 | 116 | 2016-09-10: 117 | Add fPIC flag on x86_64 if the compiler supports it. Fixes #34. 118 | 119 | 2015 and 2016: 120 | Lots of improvements to the build system. 121 | 122 | 2015: 123 | Warning fixes. 124 | 125 | 2015-05-19: 126 | Rename 'src' directory to 'double-conversion'. 127 | 128 | 2014-03-08: 129 | Update version number for cmake. 130 | Support shared libraries with cmake. 131 | Add build instructions to the README. 132 | 133 | 2014-01-12: 134 | Tagged v2.0.1. 135 | Fix compilation for ARMv8 64bit (used wrong define). 136 | Improved SConstruct file. Thanks to Milan Bouchet-Valat and Elan Ruusamäe. 137 | Fixed lots of warnings (especially on Windows). Thanks to Greg Smith. 138 | 139 | 2013-11-09: 140 | Tagged v2.0.0. 141 | String-to-Double|Float: ALLOW_LEADING_SPACES and similar flags now include 142 | new-lines, tabs and all Unicode whitespace characters. 143 | 144 | 2013-11-09: 145 | Tagged v1.1.2. 146 | Add support for ARM 64 and OsX ppc. 147 | Rewrite tests so they pass under Visual Studio. 148 | Add CMake build system support. 149 | Fix warnings. 150 | 151 | 2012-06-10: 152 | Tagged v1.1.1. 153 | Null terminate exponent buffer (only an issue when asserts are enabled). 154 | Support more architectures. 155 | 156 | 2012-02-05: 157 | Merged in Single-branch with single-precision support. 158 | Tagged v1.1 (based on b28450f33e1db493948a535d8f84e88fa211bd10). 159 | 160 | 2012-02-05: 161 | Tagged v1.0 (based on eda0196e9ac8fcdf59e92cb62885ee0af5391969). 162 | -------------------------------------------------------------------------------- /deps/double-conversion/test/cctest/cctest.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #include "cctest.h" 29 | #include 30 | #include 31 | #include 32 | 33 | 34 | CcTest* CcTest::last_ = NULL; 35 | 36 | // The windows compiler doesn't like to use `strdup`, and claims it's a 37 | // deprecated name. 38 | // For simplicity just implement it ourselves. 39 | static char* Strdup(const char* str) { 40 | size_t len = strlen(str); 41 | char* result = reinterpret_cast(malloc(len + 1)); 42 | memcpy(result, str, len + 1); 43 | return result; 44 | } 45 | 46 | CcTest::CcTest(TestFunction* callback, const char* test_file, 47 | const char* test_name, const char* test_dependency, 48 | bool test_is_enabled) 49 | : callback_(callback), name_(test_name), dependency_(test_dependency), 50 | prev_(last_) { 51 | // Find the base name of this test (const_cast required on Windows). 52 | char *basename = strrchr(const_cast(test_file), '/'); 53 | if (!basename) { 54 | basename = strrchr(const_cast(test_file), '\\'); 55 | } 56 | if (!basename) { 57 | basename = Strdup(test_file); 58 | } else { 59 | basename = Strdup(basename + 1); 60 | } 61 | // Drop the extension, if there is one. 62 | char *extension = strrchr(basename, '.'); 63 | if (extension) *extension = 0; 64 | // Install this test in the list of tests 65 | file_ = basename; 66 | enabled_ = test_is_enabled; 67 | prev_ = last_; 68 | last_ = this; 69 | } 70 | 71 | 72 | static void PrintTestList(CcTest* current) { 73 | if (current == NULL) return; 74 | PrintTestList(current->prev()); 75 | if (current->dependency() != NULL) { 76 | printf("%s/%s<%s\n", 77 | current->file(), current->name(), current->dependency()); 78 | } else { 79 | printf("%s/%s<\n", current->file(), current->name()); 80 | } 81 | } 82 | 83 | 84 | int main(int argc, char* argv[]) { 85 | int tests_run = 0; 86 | bool print_run_count = true; 87 | if (argc == 1) { 88 | // Just run all the tests. 89 | CcTest* test = CcTest::last(); 90 | while (test != NULL) { 91 | if (test->enabled()) { 92 | test->Run(); 93 | tests_run++; 94 | } 95 | test = test->prev(); 96 | } 97 | } 98 | for (int i = 1; i < argc; i++) { 99 | char* arg = argv[i]; 100 | if (strcmp(arg, "--list") == 0) { 101 | PrintTestList(CcTest::last()); 102 | print_run_count = false; 103 | 104 | } else { 105 | char* arg_copy = Strdup(arg); 106 | char* testname = strchr(arg_copy, '/'); 107 | if (testname) { 108 | // Split the string in two by nulling the slash and then run 109 | // exact matches. 110 | *testname = 0; 111 | char* file = arg_copy; 112 | char* name = testname + 1; 113 | CcTest* test = CcTest::last(); 114 | while (test != NULL) { 115 | if (test->enabled() 116 | && strcmp(test->file(), file) == 0 117 | && strcmp(test->name(), name) == 0) { 118 | test->Run(); 119 | tests_run++; 120 | } 121 | test = test->prev(); 122 | } 123 | 124 | } else { 125 | // Run all tests with the specified file or test name. 126 | char* file_or_name = arg_copy; 127 | CcTest* test = CcTest::last(); 128 | while (test != NULL) { 129 | if (test->enabled() 130 | && (strcmp(test->file(), file_or_name) == 0 131 | || strcmp(test->name(), file_or_name) == 0)) { 132 | test->Run(); 133 | tests_run++; 134 | } 135 | test = test->prev(); 136 | } 137 | } 138 | free(arg_copy); 139 | } 140 | } 141 | if (print_run_count && tests_run != 1) 142 | printf("Ran %i tests.\n", tests_run); 143 | return 0; 144 | } 145 | -------------------------------------------------------------------------------- /deps/double-conversion/double-conversion/diy-fp.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef DOUBLE_CONVERSION_DIY_FP_H_ 29 | #define DOUBLE_CONVERSION_DIY_FP_H_ 30 | 31 | #include "utils.h" 32 | 33 | namespace double_conversion { 34 | 35 | // This "Do It Yourself Floating Point" class implements a floating-point number 36 | // with a uint64 significand and an int exponent. Normalized DiyFp numbers will 37 | // have the most significant bit of the significand set. 38 | // Multiplication and Subtraction do not normalize their results. 39 | // DiyFp store only non-negative numbers and are not designed to contain special 40 | // doubles (NaN and Infinity). 41 | class DiyFp { 42 | public: 43 | static const int kSignificandSize = 64; 44 | 45 | DiyFp() : f_(0), e_(0) {} 46 | DiyFp(const uint64_t significand, const int32_t exponent) : f_(significand), e_(exponent) {} 47 | 48 | // this -= other. 49 | // The exponents of both numbers must be the same and the significand of this 50 | // must be greater or equal than the significand of other. 51 | // The result will not be normalized. 52 | void Subtract(const DiyFp& other) { 53 | DOUBLE_CONVERSION_ASSERT(e_ == other.e_); 54 | DOUBLE_CONVERSION_ASSERT(f_ >= other.f_); 55 | f_ -= other.f_; 56 | } 57 | 58 | // Returns a - b. 59 | // The exponents of both numbers must be the same and a must be greater 60 | // or equal than b. The result will not be normalized. 61 | static DiyFp Minus(const DiyFp& a, const DiyFp& b) { 62 | DiyFp result = a; 63 | result.Subtract(b); 64 | return result; 65 | } 66 | 67 | // this *= other. 68 | void Multiply(const DiyFp& other) { 69 | // Simply "emulates" a 128 bit multiplication. 70 | // However: the resulting number only contains 64 bits. The least 71 | // significant 64 bits are only used for rounding the most significant 64 72 | // bits. 73 | const uint64_t kM32 = 0xFFFFFFFFU; 74 | const uint64_t a = f_ >> 32; 75 | const uint64_t b = f_ & kM32; 76 | const uint64_t c = other.f_ >> 32; 77 | const uint64_t d = other.f_ & kM32; 78 | const uint64_t ac = a * c; 79 | const uint64_t bc = b * c; 80 | const uint64_t ad = a * d; 81 | const uint64_t bd = b * d; 82 | // By adding 1U << 31 to tmp we round the final result. 83 | // Halfway cases will be rounded up. 84 | const uint64_t tmp = (bd >> 32) + (ad & kM32) + (bc & kM32) + (1U << 31); 85 | e_ += other.e_ + 64; 86 | f_ = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); 87 | } 88 | 89 | // returns a * b; 90 | static DiyFp Times(const DiyFp& a, const DiyFp& b) { 91 | DiyFp result = a; 92 | result.Multiply(b); 93 | return result; 94 | } 95 | 96 | void Normalize() { 97 | DOUBLE_CONVERSION_ASSERT(f_ != 0); 98 | uint64_t significand = f_; 99 | int32_t exponent = e_; 100 | 101 | // This method is mainly called for normalizing boundaries. In general, 102 | // boundaries need to be shifted by 10 bits, and we optimize for this case. 103 | const uint64_t k10MSBits = DOUBLE_CONVERSION_UINT64_2PART_C(0xFFC00000, 00000000); 104 | while ((significand & k10MSBits) == 0) { 105 | significand <<= 10; 106 | exponent -= 10; 107 | } 108 | while ((significand & kUint64MSB) == 0) { 109 | significand <<= 1; 110 | exponent--; 111 | } 112 | f_ = significand; 113 | e_ = exponent; 114 | } 115 | 116 | static DiyFp Normalize(const DiyFp& a) { 117 | DiyFp result = a; 118 | result.Normalize(); 119 | return result; 120 | } 121 | 122 | uint64_t f() const { return f_; } 123 | int32_t e() const { return e_; } 124 | 125 | void set_f(uint64_t new_value) { f_ = new_value; } 126 | void set_e(int32_t new_value) { e_ = new_value; } 127 | 128 | private: 129 | static const uint64_t kUint64MSB = DOUBLE_CONVERSION_UINT64_2PART_C(0x80000000, 00000000); 130 | 131 | uint64_t f_; 132 | int32_t e_; 133 | }; 134 | 135 | } // namespace double_conversion 136 | 137 | #endif // DOUBLE_CONVERSION_DIY_FP_H_ 138 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Deploy 3 | 4 | on: 5 | push: 6 | branches: 7 | - main 8 | pull_request: 9 | paths: 10 | - ".github/workflows/deploy.yml" 11 | release: 12 | types: 13 | - published 14 | workflow_dispatch: 15 | 16 | env: 17 | FORCE_COLOR: 1 18 | 19 | jobs: 20 | build-native-wheels: 21 | runs-on: ${{ matrix.os }} 22 | strategy: 23 | fail-fast: false 24 | matrix: 25 | os: [windows-latest, macOS-latest, ubuntu-latest] 26 | 27 | steps: 28 | - uses: actions/checkout@v4 29 | - run: git fetch --prune --unshallow 30 | 31 | - name: Set up Python 32 | uses: actions/setup-python@v5 33 | with: 34 | python-version: "3.x" 35 | cache: pip 36 | cache-dependency-path: ".github/workflows/deploy.yml" 37 | 38 | # https://github.com/pypa/cibuildwheel 39 | - name: Build wheels 40 | uses: pypa/cibuildwheel@v2.22.0 41 | with: 42 | output-dir: dist 43 | # Options are supplied via environment variables: 44 | env: 45 | # Build separate wheels for macOS's different architectures. 46 | CIBW_ARCHS_MACOS: "x86_64 arm64" 47 | # Build only on Linux architectures that don't need qemu emulation. 48 | CIBW_ARCHS_LINUX: "x86_64 i686" 49 | # Include latest Python beta. 50 | CIBW_ENABLE: cpython-prerelease 51 | # Skip EOL Python versions. 52 | CIBW_SKIP: "pp39*" 53 | # Run the test suite after each build. 54 | CIBW_TEST_REQUIRES: "pytest" 55 | CIBW_TEST_COMMAND: pytest {package}/tests 56 | 57 | - name: Upload as build artifacts 58 | uses: actions/upload-artifact@v4 59 | with: 60 | name: wheels-${{ matrix.os }} 61 | path: dist/*.whl 62 | 63 | build-QEMU-emulated-wheels: 64 | runs-on: ubuntu-latest 65 | strategy: 66 | fail-fast: false 67 | matrix: 68 | python-version: 69 | - pp310 70 | - cp39 71 | - cp310 72 | - cp311 73 | - cp312 74 | - cp313 75 | 76 | steps: 77 | - uses: actions/checkout@v4 78 | - run: git fetch --prune --unshallow 79 | 80 | - name: Set up Python 81 | uses: actions/setup-python@v5 82 | with: 83 | python-version: "3.x" 84 | cache: pip 85 | cache-dependency-path: ".github/workflows/deploy.yml" 86 | 87 | # https://github.com/docker/setup-qemu-action 88 | - name: Set up QEMU 89 | uses: docker/setup-qemu-action@v3 90 | 91 | # https://github.com/pypa/cibuildwheel 92 | - name: Build wheels 93 | uses: pypa/cibuildwheel@v2.22.0 94 | with: 95 | output-dir: dist 96 | # Options are supplied via environment variables: 97 | env: 98 | # Build only the currently selected Linux architecture (so we can 99 | # parallelise for speed). 100 | CIBW_ARCHS_LINUX: "aarch64" 101 | # Likewise, select only one Python version per job to speed this up. 102 | CIBW_BUILD: "${{ matrix.python-version }}-*" 103 | # Include latest Python beta. 104 | CIBW_ENABLE: cpython-prerelease 105 | # Run the test suite after each build. 106 | CIBW_TEST_REQUIRES: "pytest" 107 | CIBW_TEST_COMMAND: pytest {package}/tests 108 | 109 | - name: Upload as build artifacts 110 | uses: actions/upload-artifact@v4 111 | with: 112 | name: wheels-qemu-${{ matrix.python-version }} 113 | path: dist/*.whl 114 | 115 | build-sdist-and-upload: 116 | runs-on: ubuntu-latest 117 | needs: ['build-native-wheels', 'build-QEMU-emulated-wheels'] 118 | permissions: 119 | # IMPORTANT: this permission is mandatory for trusted publishing 120 | id-token: write 121 | 122 | steps: 123 | - uses: actions/checkout@v4 124 | - run: | 125 | git fetch --prune --unshallow 126 | 127 | - name: Set up Python 128 | uses: actions/setup-python@v5 129 | with: 130 | python-version: "3.x" 131 | cache: pip 132 | cache-dependency-path: "setup.py" 133 | 134 | - name: Install dependencies 135 | run: | 136 | python -m pip install -U pip 137 | python -m pip install -U build twine 138 | 139 | - name: Download wheels from build artifacts 140 | uses: actions/download-artifact@v4 141 | with: 142 | pattern: wheels-* 143 | merge-multiple: true 144 | path: dist-wheels/ 145 | 146 | - name: Build package 147 | run: | 148 | git tag 149 | python -m build --sdist 150 | twine check --strict dist/* 151 | twine check --strict dist-wheels/* 152 | 153 | - name: Publish wheels to PyPI 154 | if: github.event.action == 'published' 155 | uses: pypa/gh-action-pypi-publish@release/v1 156 | with: 157 | packages-dir: dist-wheels/ 158 | 159 | - name: Publish sdist to PyPI 160 | if: github.event.action == 'published' 161 | uses: pypa/gh-action-pypi-publish@release/v1 162 | 163 | - name: Publish wheels to TestPyPI 164 | if: | 165 | github.repository == 'ultrajson/ultrajson' && 166 | github.ref == 'refs/heads/main' 167 | uses: pypa/gh-action-pypi-publish@release/v1 168 | with: 169 | repository-url: https://test.pypi.org/legacy/ 170 | packages-dir: dist-wheels/ 171 | 172 | - name: Publish sdist to TestPyPI 173 | if: | 174 | github.repository == 'ultrajson/ultrajson' && 175 | github.ref == 'refs/heads/main' 176 | uses: pypa/gh-action-pypi-publish@release/v1 177 | with: 178 | repository-url: https://test.pypi.org/legacy/ 179 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Developed by ESN, an Electronic Arts Inc. studio. 2 | Copyright (c) 2014, Electronic Arts Inc. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of ESN, Electronic Arts Inc. nor the 13 | names of its contributors may be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | ---- 28 | 29 | Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc) 30 | https://github.com/client9/stringencoders 31 | 32 | Copyright 2005, 2006, 2007 33 | Nick Galbreath -- nickg [at] modp [dot] com 34 | All rights reserved. 35 | 36 | Redistribution and use in source and binary forms, with or without 37 | modification, are permitted provided that the following conditions are 38 | met: 39 | 40 | Redistributions of source code must retain the above copyright 41 | notice, this list of conditions and the following disclaimer. 42 | 43 | Redistributions in binary form must reproduce the above copyright 44 | notice, this list of conditions and the following disclaimer in the 45 | documentation and/or other materials provided with the distribution. 46 | 47 | Neither the name of the modp.com nor the names of its 48 | contributors may be used to endorse or promote products derived from 49 | this software without specific prior written permission. 50 | 51 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 52 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 53 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 54 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 55 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 56 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 57 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 58 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 59 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 60 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 61 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 | 63 | This is the standard "new" BSD license: 64 | http://www.opensource.org/licenses/bsd-license.php 65 | 66 | https://github.com/client9/stringencoders/blob/cfd5c1507325ae497ea9bacdacba12c0ffd79d30/COPYING 67 | 68 | ---- 69 | 70 | Numeric decoder derived from from TCL library 71 | https://opensource.apple.com/source/tcl/tcl-14/tcl/license.terms 72 | * Copyright (c) 1988-1993 The Regents of the University of California. 73 | * Copyright (c) 1994 Sun Microsystems, Inc. 74 | 75 | This software is copyrighted by the Regents of the University of 76 | California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState 77 | Corporation and other parties. The following terms apply to all files 78 | associated with the software unless explicitly disclaimed in 79 | individual files. 80 | 81 | The authors hereby grant permission to use, copy, modify, distribute, 82 | and license this software and its documentation for any purpose, provided 83 | that existing copyright notices are retained in all copies and that this 84 | notice is included verbatim in any distributions. No written agreement, 85 | license, or royalty fee is required for any of the authorized uses. 86 | Modifications to this software may be copyrighted by their authors 87 | and need not follow the licensing terms described here, provided that 88 | the new terms are clearly indicated on the first page of each file where 89 | they apply. 90 | 91 | IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY 92 | FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 93 | ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY 94 | DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE 95 | POSSIBILITY OF SUCH DAMAGE. 96 | 97 | THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, 98 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, 99 | FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE 100 | IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE 101 | NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 102 | MODIFICATIONS. 103 | 104 | GOVERNMENT USE: If you are acquiring this software on behalf of the 105 | U.S. government, the Government shall have only "Restricted Rights" 106 | in the software and related documentation as defined in the Federal 107 | Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you 108 | are acquiring the software on behalf of the Department of Defense, the 109 | software shall be classified as "Commercial Computer Software" and the 110 | Government shall have only "Restricted Rights" as defined in Clause 111 | 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the 112 | authors grant the U.S. Government and others acting in its behalf 113 | permission to use and distribute the software in accordance with the 114 | terms specified in this license. 115 | -------------------------------------------------------------------------------- /deps/double-conversion/double-conversion/bignum.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef DOUBLE_CONVERSION_BIGNUM_H_ 29 | #define DOUBLE_CONVERSION_BIGNUM_H_ 30 | 31 | #include "utils.h" 32 | 33 | namespace double_conversion { 34 | 35 | class Bignum { 36 | public: 37 | // 3584 = 128 * 28. We can represent 2^3584 > 10^1000 accurately. 38 | // This bignum can encode much bigger numbers, since it contains an 39 | // exponent. 40 | static const int kMaxSignificantBits = 3584; 41 | 42 | Bignum() : used_bigits_(0), exponent_(0) {} 43 | 44 | void AssignUInt16(const uint16_t value); 45 | void AssignUInt64(uint64_t value); 46 | void AssignBignum(const Bignum& other); 47 | 48 | void AssignDecimalString(const Vector value); 49 | void AssignHexString(const Vector value); 50 | 51 | void AssignPowerUInt16(uint16_t base, const int exponent); 52 | 53 | void AddUInt64(const uint64_t operand); 54 | void AddBignum(const Bignum& other); 55 | // Precondition: this >= other. 56 | void SubtractBignum(const Bignum& other); 57 | 58 | void Square(); 59 | void ShiftLeft(const int shift_amount); 60 | void MultiplyByUInt32(const uint32_t factor); 61 | void MultiplyByUInt64(const uint64_t factor); 62 | void MultiplyByPowerOfTen(const int exponent); 63 | void Times10() { return MultiplyByUInt32(10); } 64 | // Pseudocode: 65 | // int result = this / other; 66 | // this = this % other; 67 | // In the worst case this function is in O(this/other). 68 | uint16_t DivideModuloIntBignum(const Bignum& other); 69 | 70 | bool ToHexString(char* buffer, const int buffer_size) const; 71 | 72 | // Returns 73 | // -1 if a < b, 74 | // 0 if a == b, and 75 | // +1 if a > b. 76 | static int Compare(const Bignum& a, const Bignum& b); 77 | static bool Equal(const Bignum& a, const Bignum& b) { 78 | return Compare(a, b) == 0; 79 | } 80 | static bool LessEqual(const Bignum& a, const Bignum& b) { 81 | return Compare(a, b) <= 0; 82 | } 83 | static bool Less(const Bignum& a, const Bignum& b) { 84 | return Compare(a, b) < 0; 85 | } 86 | // Returns Compare(a + b, c); 87 | static int PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c); 88 | // Returns a + b == c 89 | static bool PlusEqual(const Bignum& a, const Bignum& b, const Bignum& c) { 90 | return PlusCompare(a, b, c) == 0; 91 | } 92 | // Returns a + b <= c 93 | static bool PlusLessEqual(const Bignum& a, const Bignum& b, const Bignum& c) { 94 | return PlusCompare(a, b, c) <= 0; 95 | } 96 | // Returns a + b < c 97 | static bool PlusLess(const Bignum& a, const Bignum& b, const Bignum& c) { 98 | return PlusCompare(a, b, c) < 0; 99 | } 100 | private: 101 | typedef uint32_t Chunk; 102 | typedef uint64_t DoubleChunk; 103 | 104 | static const int kChunkSize = sizeof(Chunk) * 8; 105 | static const int kDoubleChunkSize = sizeof(DoubleChunk) * 8; 106 | // With bigit size of 28 we loose some bits, but a double still fits easily 107 | // into two chunks, and more importantly we can use the Comba multiplication. 108 | static const int kBigitSize = 28; 109 | static const Chunk kBigitMask = (1 << kBigitSize) - 1; 110 | // Every instance allocates kBigitLength chunks on the stack. Bignums cannot 111 | // grow. There are no checks if the stack-allocated space is sufficient. 112 | static const int kBigitCapacity = kMaxSignificantBits / kBigitSize; 113 | 114 | static void EnsureCapacity(const int size) { 115 | if (size > kBigitCapacity) { 116 | DOUBLE_CONVERSION_UNREACHABLE(); 117 | } 118 | } 119 | void Align(const Bignum& other); 120 | void Clamp(); 121 | bool IsClamped() const { 122 | return used_bigits_ == 0 || RawBigit(used_bigits_ - 1) != 0; 123 | } 124 | void Zero() { 125 | used_bigits_ = 0; 126 | exponent_ = 0; 127 | } 128 | // Requires this to have enough capacity (no tests done). 129 | // Updates used_bigits_ if necessary. 130 | // shift_amount must be < kBigitSize. 131 | void BigitsShiftLeft(const int shift_amount); 132 | // BigitLength includes the "hidden" bigits encoded in the exponent. 133 | int BigitLength() const { return used_bigits_ + exponent_; } 134 | Chunk& RawBigit(const int index); 135 | const Chunk& RawBigit(const int index) const; 136 | Chunk BigitOrZero(const int index) const; 137 | void SubtractTimes(const Bignum& other, const int factor); 138 | 139 | // The Bignum's value is value(bigits_buffer_) * 2^(exponent_ * kBigitSize), 140 | // where the value of the buffer consists of the lower kBigitSize bits of 141 | // the first used_bigits_ Chunks in bigits_buffer_, first chunk has lowest 142 | // significant bits. 143 | int16_t used_bigits_; 144 | int16_t exponent_; 145 | Chunk bigits_buffer_[kBigitCapacity]; 146 | 147 | DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(Bignum); 148 | }; 149 | 150 | } // namespace double_conversion 151 | 152 | #endif // DOUBLE_CONVERSION_BIGNUM_H_ 153 | -------------------------------------------------------------------------------- /deps/double-conversion/test/cctest/cctest.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef CCTEST_H_ 29 | #define CCTEST_H_ 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include "double-conversion/utils.h" 36 | 37 | #ifndef TEST 38 | #define TEST(Name) \ 39 | static void Test##Name(); \ 40 | CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, true); \ 41 | static void Test##Name() 42 | #endif 43 | 44 | #ifndef DEPENDENT_TEST 45 | #define DEPENDENT_TEST(Name, Dep) \ 46 | static void Test##Name(); \ 47 | CcTest register_test_##Name(Test##Name, __FILE__, #Name, #Dep, true); \ 48 | static void Test##Name() 49 | #endif 50 | 51 | #ifndef DISABLED_TEST 52 | #define DISABLED_TEST(Name) \ 53 | static void Test##Name(); \ 54 | CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, false); \ 55 | static void Test##Name() 56 | #endif 57 | 58 | #define CHECK(condition) CheckHelper(__FILE__, __LINE__, #condition, condition) 59 | #define CHECK_GE(a, b) CHECK((a) >= (b)) 60 | 61 | static inline void CheckHelper(const char* file, 62 | int line, 63 | const char* source, 64 | bool condition) { 65 | if (!condition) { 66 | printf("%s:%d:\n CHECK(%s) failed\n", file, line, source); 67 | abort(); 68 | } 69 | } 70 | 71 | #define CHECK_EQ(a, b) CheckEqualsHelper(__FILE__, __LINE__, #a, a, #b, b) 72 | 73 | template inline void PrintfValue(T x); 74 | template<> inline void PrintfValue(int x) { printf("%d", x); } 75 | template<> inline void PrintfValue(unsigned int x) { printf("%u", x); } 76 | template<> inline void PrintfValue(short x) { printf("%hd", x); } 77 | template<> inline void PrintfValue(unsigned short x) { printf("%hu", x); } 78 | template<> inline void PrintfValue(int64_t x) { printf("%" PRId64, x); } 79 | template<> inline void PrintfValue(uint64_t x) { printf("%" PRIu64, x); } 80 | template<> inline void PrintfValue(float x) { printf("%.30e", static_cast(x)); } 81 | template<> inline void PrintfValue(double x) { printf("%.30e", x); } 82 | template<> inline void PrintfValue(bool x) { printf("%s", x ? "true" : "false"); } 83 | 84 | template 85 | inline void CheckEqualsHelper(const char* file, int line, 86 | const char* expected_source, 87 | T1 expected, 88 | const char* value_source, 89 | T2 value) { 90 | // If expected and value are NaNs then expected != value. 91 | if (expected != value && (expected == expected || value == value)) { 92 | printf("%s:%d:\n CHECK_EQ(%s, %s) failed\n", 93 | file, line, expected_source, value_source); 94 | printf("# Expected: "); 95 | PrintfValue(expected); 96 | printf("\n"); 97 | printf("# Found: "); 98 | PrintfValue(value); 99 | printf("\n"); 100 | abort(); 101 | } 102 | } 103 | 104 | template<> 105 | inline void CheckEqualsHelper(const char* file, int line, 106 | const char* expected_source, 107 | const char* expected, 108 | const char* value_source, 109 | const char* value) { 110 | if ((expected == NULL && value != NULL) || 111 | (expected != NULL && value == NULL)) { 112 | abort(); 113 | } 114 | 115 | if ((expected != NULL && value != NULL && strcmp(expected, value) != 0)) { 116 | printf("%s:%d:\n CHECK_EQ(%s, %s) failed\n" 117 | "# Expected: %s\n" 118 | "# Found: %s\n", 119 | file, line, expected_source, value_source, expected, value); 120 | abort(); 121 | } 122 | } 123 | 124 | template<> 125 | inline void CheckEqualsHelper(const char* file, int line, 126 | const char* expected_source, 127 | const char* expected, 128 | const char* value_source, 129 | char* value) { 130 | CheckEqualsHelper(file, line, expected_source, expected, value_source, static_cast(value)); 131 | } 132 | 133 | class CcTest { 134 | public: 135 | typedef void (TestFunction)(); 136 | CcTest(TestFunction* callback, const char* file, const char* name, 137 | const char* dependency, bool enabled); 138 | void Run() { callback_(); } 139 | static int test_count(); 140 | static CcTest* last() { return last_; } 141 | CcTest* prev() { return prev_; } 142 | const char* file() const { return file_; } 143 | const char* name() const { return name_; } 144 | const char* dependency() const { return dependency_; } 145 | bool enabled() const { return enabled_; } 146 | private: 147 | TestFunction* callback_; 148 | const char* file_; 149 | const char* name_; 150 | const char* dependency_; 151 | bool enabled_; 152 | static CcTest* last_; 153 | CcTest* prev_; 154 | }; 155 | 156 | #endif // ifndef CCTEST_H_ 157 | -------------------------------------------------------------------------------- /tests/fuzz.py: -------------------------------------------------------------------------------- 1 | """ 2 | A brute force fuzzer for detecting memory issues in ujson.dumps(). To use, first 3 | compile ujson in debug mode: 4 | 5 | CFLAGS='-DDEBUG' python setup.py -q build_ext --inplace -f 6 | 7 | Then run without arguments: 8 | 9 | python tests/fuzz.py 10 | 11 | If it crashes, the last line of output is the arguments to reproduce the 12 | failure. 13 | 14 | python tests/fuzz.py {{ last line of output before crash }} 15 | 16 | Adding --dump-python or --dump-json will print the object it intends to 17 | serialise as either a Python literal or in JSON. 18 | 19 | """ 20 | 21 | import argparse 22 | import gc 23 | import itertools 24 | import json 25 | import math 26 | import random 27 | import re 28 | import sys 29 | from pprint import pprint 30 | 31 | import ujson 32 | 33 | 34 | class FuzzGenerator: 35 | """A random JSON serialisable object generator.""" 36 | 37 | def __init__(self, seed=None): 38 | self._randomizer = random.Random(seed) 39 | self._shrink = 1 40 | 41 | def key(self): 42 | key_types = [self.int, self.float, self.string, self.null, self.bool] 43 | return self._randomizer.choice(key_types)() 44 | 45 | def item(self): 46 | if self._randomizer.random() > 0.8: 47 | return self.key() 48 | return self._randomizer.choice([self.list, self.dict])() 49 | 50 | def int(self): 51 | return int(self.float()) 52 | 53 | def float(self): 54 | sign = self._randomizer.choice([-1, 1, 0]) 55 | return sign * math.exp(self._randomizer.uniform(-40, 40)) 56 | 57 | def string(self): 58 | characters = ["\x00", "\t", "a", "\U0001f680", "<>", "\u1234"] 59 | return self._randomizer.choice(characters) * self.length() 60 | 61 | def bool(self): 62 | return self._randomizer.random() < 0.5 63 | 64 | def null(self): 65 | return None 66 | 67 | def list(self): 68 | return [self.item() for i in range(self.length())] 69 | 70 | def dict(self): 71 | return {self.key(): self.item() for i in range(self.length())} 72 | 73 | def length(self): 74 | self._shrink *= 0.99 75 | return int(math.exp(self._randomizer.uniform(-0.5, 5)) * self._shrink) 76 | 77 | 78 | def random_object(seed=None): 79 | return FuzzGenerator(seed).item() 80 | 81 | 82 | class RangeOption(argparse.Action): 83 | def __call__(self, parser, namespace, values, option_string=None): 84 | values = re.findall("[^: ]+", values) 85 | if len(values) == 1: 86 | values = (int(values[0]),) 87 | else: 88 | values = range(*map(int, values)) 89 | setattr(namespace, self.dest, values) 90 | 91 | 92 | class ListOption(argparse.Action): 93 | def __call__(self, parser, namespace, values, option_string=None): 94 | values = tuple(map(int, re.findall("[^, ]+", values))) 95 | setattr(namespace, self.dest, values) 96 | 97 | 98 | parser = argparse.ArgumentParser( 99 | epilog=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter 100 | ) 101 | parser.add_argument( 102 | "--seed", 103 | default=range(100), 104 | action=RangeOption, 105 | dest="seeds", 106 | help="A seed or range of seeds (in the form start:end[:step]) " 107 | "to initialise the randomizer.", 108 | ) 109 | parser.add_argument( 110 | "--indent", 111 | default=(0, 1, 2, 3, 4, 5, 12, 100, 1000), 112 | action=ListOption, 113 | help="A comma separated sequence of indentation lengths to test.", 114 | ) 115 | parser.add_argument( 116 | "--ensure_ascii", 117 | default=(0, 1), 118 | action=ListOption, 119 | help="Sets the ensure_ascii option to ujson.dumps(). " 120 | "May be 0 or 1 or 0,1 to testboth.", 121 | ) 122 | parser.add_argument( 123 | "--encode_html_chars", 124 | default=(0, 1), 125 | action=ListOption, 126 | help="Sets the encode_html_chars option to ujson.dumps(). " 127 | "May be 0 or 1 or 0,1 to test both.", 128 | ) 129 | parser.add_argument( 130 | "--escape_forward_slashes", 131 | default=(0, 1), 132 | action=ListOption, 133 | help="Sets the escape_forward_slashes option to ujson.dumps(). " 134 | "May be 0 or 1 or 0,1 to test both.", 135 | ) 136 | parser.add_argument( 137 | "--dump-python", 138 | action="store_true", 139 | help="Print the randomly generated object as a Python literal and exit.", 140 | ) 141 | parser.add_argument( 142 | "--dump-json", 143 | action="store_true", 144 | help="Print the randomly generated object in JSON format and exit.", 145 | ) 146 | 147 | 148 | def cli(args=None): 149 | options = dict(parser.parse_args(args)._get_kwargs()) 150 | if options.pop("dump_json"): 151 | print(json.dumps(random_object(options["seeds"][0]), indent=2)) 152 | elif options.pop("dump_python"): 153 | pprint(random_object(options["seeds"][0])) 154 | else: 155 | fuzz(**options) 156 | 157 | 158 | def fuzz(seeds, **options): 159 | try: 160 | for seed in seeds: 161 | data = random_object(seed) 162 | for permutation in itertools.product(*options.values()): 163 | _options = dict(zip(options.keys(), permutation)) 164 | print(f"--seed {seed}", *(f"--{k} {v}" for (k, v) in _options.items())) 165 | 166 | data_objects = collect_all_objects(data) 167 | # Exclude ints because they get referenced by the lists below. 168 | data_objects = [o for o in data_objects if not isinstance(o, int)] 169 | gc.collect() 170 | data_ref_counts_before = [sys.getrefcount(o) for o in data_objects] 171 | ujson.dumps(data, **_options) 172 | gc.collect() 173 | data_ref_counts_after = [sys.getrefcount(o) for o in data_objects] 174 | if data_ref_counts_before != data_ref_counts_after: 175 | for o, before, after in zip( 176 | data_objects, data_ref_counts_before, data_ref_counts_after 177 | ): 178 | if before != after: 179 | print(f"Ref count of {o!r} went from {before} to {after}") 180 | raise ValueError("ref counts changed") 181 | except KeyboardInterrupt: 182 | pass 183 | 184 | 185 | def collect_all_objects(obj): 186 | """Given an object, return a list of all objects referenced by it.""" 187 | 188 | if hasattr(sys, "pypy_version_info"): 189 | # PyPy's GC works differently (no ref counting), so this wouldn't be useful. 190 | # Simply returning an empty list effectively disables the refcount test. 191 | return [] 192 | 193 | def _inner(o): 194 | yield o 195 | if isinstance(o, list): 196 | for v in o: 197 | yield from _inner(v) 198 | elif isinstance(o, dict): 199 | for k, v in o.items(): 200 | yield from _inner(k) 201 | yield from _inner(v) 202 | 203 | out = [] 204 | seen = set() 205 | for o in _inner(obj): 206 | if id(o) not in seen: 207 | seen.add(id(o)) 208 | out.append(o) 209 | return out 210 | 211 | 212 | if __name__ == "__main__": 213 | cli() 214 | -------------------------------------------------------------------------------- /python/ujson.c: -------------------------------------------------------------------------------- 1 | /* 2 | Developed by ESN, an Electronic Arts Inc. studio. 3 | Copyright (c) 2014, Electronic Arts Inc. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of ESN, Electronic Arts Inc. nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS INC. BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | 29 | Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc) 30 | http://code.google.com/p/stringencoders/ 31 | Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved. 32 | 33 | Numeric decoder derived from from TCL library 34 | http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms 35 | * Copyright (c) 1988-1993 The Regents of the University of California. 36 | * Copyright (c) 1994 Sun Microsystems, Inc. 37 | */ 38 | 39 | #include 40 | #include "version.h" 41 | #include "ujson.h" 42 | 43 | /* objToJSON */ 44 | PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs); 45 | 46 | /* JSONToObj */ 47 | PyObject* JSONToObj(PyObject* self, PyObject *args, PyObject *kwargs); 48 | 49 | /* objToJSONFile */ 50 | PyObject* objToJSONFile(PyObject* self, PyObject *args, PyObject *kwargs); 51 | 52 | /* JSONFileToObj */ 53 | PyObject* JSONFileToObj(PyObject* self, PyObject *args, PyObject *kwargs); 54 | 55 | PyObject* JSONDecodeError; 56 | 57 | 58 | #define ENCODER_HELP_TEXT "Use ensure_ascii=false to output UTF-8. " \ 59 | "Set encode_html_chars=True to encode < > & as unicode escape sequences. "\ 60 | "Set escape_forward_slashes=False to prevent escaping / characters." \ 61 | "Set allow_nan=False to raise an exception when NaN or Infinity would be serialized." \ 62 | "Set reject_bytes=True to raise TypeError on bytes." 63 | 64 | static PyMethodDef ujsonMethods[] = { 65 | {"encode", (PyCFunction) objToJSON, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursively into JSON. " ENCODER_HELP_TEXT}, 66 | {"decode", (PyCFunction) JSONToObj, METH_VARARGS | METH_KEYWORDS, "Converts JSON as string to dict object structure."}, 67 | {"dumps", (PyCFunction) objToJSON, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursively into JSON. " ENCODER_HELP_TEXT}, 68 | {"loads", (PyCFunction) JSONToObj, METH_VARARGS | METH_KEYWORDS, "Converts JSON as string to dict object structure."}, 69 | {"dump", (PyCFunction) objToJSONFile, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursively into JSON file. " ENCODER_HELP_TEXT}, 70 | {"load", (PyCFunction) JSONFileToObj, METH_VARARGS | METH_KEYWORDS, "Converts JSON as file to dict object structure."}, 71 | {NULL, NULL, 0, NULL} /* Sentinel */ 72 | }; 73 | 74 | typedef struct { 75 | PyObject *type_decimal; 76 | } modulestate; 77 | 78 | static int module_traverse(PyObject *m, visitproc visit, void *arg); 79 | static int module_clear(PyObject *m); 80 | static void module_free(void *m); 81 | 82 | static struct PyModuleDef moduledef = { 83 | PyModuleDef_HEAD_INIT, 84 | "ujson", 85 | 0, /* m_doc */ 86 | sizeof(modulestate), /* m_size */ 87 | ujsonMethods, /* m_methods */ 88 | NULL, /* m_slots */ 89 | module_traverse, /* m_traverse */ 90 | module_clear, /* m_clear */ 91 | module_free /* m_free */ 92 | }; 93 | 94 | #define modulestate(o) ((modulestate *)PyModule_GetState(o)) 95 | #define modulestate_global modulestate(PyState_FindModule(&moduledef)) 96 | 97 | #ifndef PYPY_VERSION 98 | /* Used in objToJSON.c */ 99 | int object_is_decimal_type(PyObject *obj) 100 | { 101 | PyObject *module = PyState_FindModule(&moduledef); 102 | if (module == NULL) return 0; 103 | modulestate *state = modulestate(module); 104 | if (state == NULL) return 0; 105 | PyObject *type_decimal = state->type_decimal; 106 | if (type_decimal == NULL) { 107 | PyErr_Clear(); 108 | return 0; 109 | } 110 | int result = PyObject_IsInstance(obj, type_decimal); 111 | if (result == -1) { 112 | PyErr_Clear(); 113 | return 0; 114 | } 115 | return result; 116 | } 117 | #else 118 | /* Used in objToJSON.c */ 119 | int object_is_decimal_type(PyObject *obj) 120 | { 121 | PyObject *module = PyImport_ImportModule("decimal"); 122 | if (module == NULL) { 123 | PyErr_Clear(); 124 | return 0; 125 | } 126 | PyObject *type_decimal = PyObject_GetAttrString(module, "Decimal"); 127 | if (type_decimal == NULL) { 128 | Py_DECREF(module); 129 | PyErr_Clear(); 130 | return 0; 131 | } 132 | int result = PyObject_IsInstance(obj, type_decimal); 133 | if (result == -1) { 134 | Py_DECREF(module); 135 | Py_DECREF(type_decimal); 136 | PyErr_Clear(); 137 | return 0; 138 | } 139 | return result; 140 | } 141 | #endif 142 | 143 | static int module_traverse(PyObject *m, visitproc visit, void *arg) 144 | { 145 | Py_VISIT(modulestate(m)->type_decimal); 146 | return 0; 147 | } 148 | 149 | static int module_clear(PyObject *m) 150 | { 151 | Py_CLEAR(modulestate(m)->type_decimal); 152 | return 0; 153 | } 154 | 155 | static void module_free(void *m) 156 | { 157 | module_clear((PyObject *)m); 158 | } 159 | 160 | PyMODINIT_FUNC PyInit_ujson(void) 161 | { 162 | PyObject* module; 163 | 164 | #ifndef PYPY_VERSION 165 | // This function is not supported in PyPy. 166 | if ((module = PyState_FindModule(&moduledef)) != NULL) 167 | { 168 | Py_INCREF(module); 169 | return module; 170 | } 171 | #endif 172 | 173 | module = PyModule_Create(&moduledef); 174 | if (module == NULL) 175 | { 176 | return NULL; 177 | } 178 | 179 | PyModule_AddStringConstant(module, "__version__", UJSON_VERSION); 180 | 181 | #ifndef PYPY_VERSION 182 | PyObject *mod_decimal = PyImport_ImportModule("decimal"); 183 | if (mod_decimal) 184 | { 185 | PyObject* type_decimal = PyObject_GetAttrString(mod_decimal, "Decimal"); 186 | assert(type_decimal != NULL); 187 | modulestate(module)->type_decimal = type_decimal; 188 | Py_DECREF(mod_decimal); 189 | } 190 | else 191 | PyErr_Clear(); 192 | #endif 193 | 194 | JSONDecodeError = PyErr_NewException("ujson.JSONDecodeError", PyExc_ValueError, NULL); 195 | Py_XINCREF(JSONDecodeError); 196 | if (PyModule_AddObject(module, "JSONDecodeError", JSONDecodeError) < 0) 197 | { 198 | Py_XDECREF(JSONDecodeError); 199 | Py_CLEAR(JSONDecodeError); 200 | Py_DECREF(module); 201 | return NULL; 202 | } 203 | 204 | return module; 205 | } 206 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UltraJSON 2 | 3 | [![PyPI version](https://img.shields.io/pypi/v/ujson.svg?logo=pypi&logoColor=FFE873)](https://pypi.org/project/ujson) 4 | [![Supported Python versions](https://img.shields.io/pypi/pyversions/ujson.svg?logo=python&logoColor=FFE873)](https://pypi.org/project/ujson) 5 | [![PyPI downloads](https://img.shields.io/pypi/dm/ujson.svg)](https://pypistats.org/packages/ujson) 6 | [![GitHub Actions status](https://github.com/ultrajson/ultrajson/workflows/Test/badge.svg)](https://github.com/ultrajson/ultrajson/actions) 7 | [![codecov](https://codecov.io/gh/ultrajson/ultrajson/branch/main/graph/badge.svg)](https://codecov.io/gh/ultrajson/ultrajson) 8 | [![DOI](https://zenodo.org/badge/1418941.svg)](https://zenodo.org/badge/latestdoi/1418941) 9 | [![Code style: Black](https://img.shields.io/badge/code%20style-Black-000000.svg)](https://github.com/psf/black) 10 | 11 | UltraJSON is an ultra fast JSON encoder and decoder written in pure C with bindings for 12 | Python 3.9+. 13 | 14 | Install with pip: 15 | 16 | ```sh 17 | python -m pip install ujson 18 | ``` 19 | 20 | ## Project status 21 | 22 | > [!WARNING] 23 | > UltraJSON's architecture is fundamentally ill-suited to making changes without 24 | > risk of introducing new security vulnerabilities. As a result, this library 25 | > has been put into a *maintenance-only* mode. Support for new Python versions 26 | > will be added and critical bugs and security issues will still be 27 | > fixed but all other changes will be rejected. Users are encouraged to migrate 28 | > to [orjson](https://pypi.org/project/orjson/) which is both much faster and 29 | > less likely to introduce a surprise buffer overflow vulnerability in the 30 | > future. 31 | 32 | ## Usage 33 | 34 | May be used as a drop in replacement for most other JSON parsers for Python: 35 | 36 | ```pycon 37 | >>> import ujson 38 | >>> ujson.dumps([{"key": "value"}, 81, True]) 39 | '[{"key":"value"},81,true]' 40 | >>> ujson.loads("""[{"key": "value"}, 81, true]""") 41 | [{'key': 'value'}, 81, True] 42 | ``` 43 | 44 | ### Encoder options 45 | 46 | #### encode_html_chars 47 | 48 | Used to enable special encoding of "unsafe" HTML characters into safer Unicode 49 | sequences. Default is `False`: 50 | 51 | ```pycon 52 | >>> ujson.dumps("