diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad4bc644..52414b12 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,18 +121,11 @@ jobs: libgoogle-glog-dev \ libeigen3-dev - # NOTE(aaron): Some packages do not have a version that supports py3.8..py3.12 - - name: Fix py3.12 versions - if: ${{ matrix.python == '3.12' }} - run: | - sed -i 's|numba==0.58.1|numba~=0.59.0|g' dev_requirements.txt - sed -i 's|llvmlite==0.41.1|llvmlite~=0.42.0|g' dev_requirements.txt - sed -i 's|numpy==1.24.4|numpy~=1.26.0|g' dev_requirements.txt - sed -i 's|scipy==1.10.1|scipy~=1.12.0|g' dev_requirements.txt - sed -i 's|pandas==2.0.3|pandas~=2.2.0|g' dev_requirements.txt - - name: Install python dependencies - run: pip install -r dev_requirements.txt + run: | + PY_MINOR_VERSION=$(python -c "import sys; print(sys.version_info.minor)") + python -m pip install pip==24.0 setuptools==69.5.1 + python -m pip install -r requirements_dev_py3${PY_MINOR_VERSION}.txt - name: Run cmake build run: | @@ -144,17 +137,11 @@ jobs: -D SYMFORCE_BUILD_BENCHMARKS=ON cmake --build build -j $(nproc) - # - lcmtypes need to be available for tests - # - Exact contents of dev_requirements.txt depend on python version. Need to update file to - # match current python version to avoid failure of corresponding gen test. symforce needs - # to be on the PYTHONPATH to run gen test in this manner. + # lcmtypes and symforce need to be available for tests - name: Run tests run: | pip install build/lcmtypes/python2.7 export PYTHONPATH=$PYTHONPATH:$(pwd) - python${{ matrix.python }} test/symforce_requirements_test.py --update - echo "Modifications made to requirements:" - git diff EXIT_CODE=0 ctest --test-dir build -j $(nproc) || EXIT_CODE=$? if [ $EXIT_CODE -ne 0 ]; then diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index e923ac23..48f4aa72 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -34,7 +34,9 @@ jobs: python-version: "3.8" - name: Install python dependencies - run: pip install -r dev_requirements.txt + run: | + PY_MINOR_VERSION=$(python -c "import sys; print(sys.version_info.minor)") + python -m pip install -r requirements_dev_py3${PY_MINOR_VERSION}.txt - name: Run cmake build run: | diff --git a/.github/workflows/test_editable_pip_install.yml b/.github/workflows/test_editable_pip_install.yml index 9b518e0f..31c3ddf8 100644 --- a/.github/workflows/test_editable_pip_install.yml +++ b/.github/workflows/test_editable_pip_install.yml @@ -34,18 +34,10 @@ jobs: pip==${{ matrix.pip_version }} \ setuptools==${{ matrix.setuptools_version }} - # NOTE(aaron): Some packages do not have a version that supports py3.8..py3.12 - - name: Fix py3.12 versions - if: ${{ matrix.os == 'ubuntu-24.04' }} + - name: install requirements run: | - sed -i 's|numba==0.58.1|numba~=0.59.0|g' dev_requirements.txt - sed -i 's|llvmlite==0.41.1|llvmlite~=0.42.0|g' dev_requirements.txt - sed -i 's|numpy==1.24.4|numpy~=1.26.0|g' dev_requirements.txt - sed -i 's|scipy==1.10.1|scipy~=1.12.0|g' dev_requirements.txt - sed -i 's|pandas==2.0.3|pandas~=2.2.0|g' dev_requirements.txt - - - name: install dev_requirements.txt - run: python -m pip install -r dev_requirements.txt + PY_MINOR_VERSION=$(python -c "import sys; print(sys.version_info.minor)") + python -m pip install -r requirements_dev_py3${PY_MINOR_VERSION}.txt - name: editable install run: python -m pip install -v -e . diff --git a/CMakeLists.txt b/CMakeLists.txt index cab37f36..3176f1e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ # NOTE(aaron): This is the minimum version for policy range support, not sure if we need newer; # certainly no newer than 3.15 required. This will use NEW policies up to CMake 3.25; this should -# be the maximum tested CMake version, matching dev_requirements.txt +# be the maximum tested CMake version, matching requirements_dev.txt cmake_minimum_required(VERSION 3.19...3.25) if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.27) diff --git a/README.md b/README.md index 47ea5e16..05b4d6c4 100644 --- a/README.md +++ b/README.md @@ -567,7 +567,7 @@ pip install -e . You should then [verify your installation](#verify-your-installation). -___Note:___ `pip install .` will not install pinned versions of SymForce's dependencies, it'll install any compatible versions. It also won't install all packages required to run all of the SymForce tests and build all of the targets (e.g. building the docs or running the linters). If you want all packages required for that, you should `pip install .[dev]` instead (or one of the other groups of extra requirements in our `setup.py`). If you additionally want pinned versions of our dependencies, which are the exact versions guaranteed by CI to pass all of our tests, you can install them from `pip install -r dev_requirements.txt`. +___Note:___ `pip install .` will not install pinned versions of SymForce's dependencies, it'll install any compatible versions. It also won't install all packages required to run all of the SymForce tests and build all of the targets (e.g. building the docs or running the linters). If you want all packages required for that, you should `pip install .[dev]` instead (or one of the other groups of extra requirements in our `setup.py`). If you additionally want pinned versions of our dependencies, which are the exact versions guaranteed by CI to pass all of our tests, you can install them from `pip install -r requirements_dev_py3.txt`. _Note: Editable installs as root with the system python on Ubuntu (and other Debian derivatives) are broken on `setuptools<64.0.0`. This is a [bug in Debian](https://ffy00.github.io/blog/02-python-debian-and-the-install-locations/), not something in SymForce that we can fix. If this is your situation, either use a virtual environment, upgrade setuptools to a version `>=64.0.0`, or use a different installation method._ @@ -576,11 +576,13 @@ _Note: Editable installs as root with the system python on Ubuntu (and other Deb If you'll be modifying the C++ parts of SymForce, you should build with CMake directly instead - this method will not install SymForce into your Python environment, so you'll need to add it to your PYTHONPATH separately. -Install python requirements: +Install dependencies required to build and run SymForce: ```bash -pip install -r dev_requirements.txt +pip install -r requirements_build.txt ``` +___Note:___ `requirements_build` contains only packages required to build and run symforce, but not everything recommended to develop symforce, like to run the SymForce tests and linters. For that, install the full pinned requirements using `pip install -r requirements_dev_py3.txt` for your Python version. + Build SymForce (requires C++14 or later): ```bash mkdir build diff --git a/pyproject.toml b/pyproject.toml index aebf6a38..4ca810d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -199,7 +199,6 @@ module = [ "argh.*", "clang_format", "graphviz.*", - "matplotlib.*", "mpl_toolkits.*", "numba.*", "ruff.*", @@ -215,3 +214,12 @@ ignore_missing_imports = true [[tool.mypy.overrides]] module = "lcmtypes" follow_imports = "silent" + +# matplotlib has some overly restrictive / wrong annotations, on animation.FuncAnimation. It also +# requires annotating Axes3d to get proper typing +[[tool.mypy.overrides]] +module = "matplotlib.*" +follow_imports = "skip" +follow_imports_for_stubs = true +# the py3.8 version of matplotlib has no type stubs, so we fully ignore it +ignore_missing_imports = true diff --git a/requirements_build.txt b/requirements_build.txt new file mode 100644 index 00000000..792973f9 --- /dev/null +++ b/requirements_build.txt @@ -0,0 +1,32 @@ +# This file was autogenerated by uv via the following command: +# python test/symforce_requirements_test.py --update +clang-format + # via symforce (pyproject.toml) +cmake + # via symforce (pyproject.toml) +cython + # via symforce (pyproject.toml) +graphviz + # via symforce (pyproject.toml) +jinja2 + # via symforce (pyproject.toml) +numpy + # via symforce (pyproject.toml) +pip + # via symforce (pyproject.toml) +ruff + # via symforce (pyproject.toml) +scipy + # via symforce (pyproject.toml) +setuptools + # via symforce (pyproject.toml) +setuptools-scm + # via symforce (pyproject.toml) +file:./third_party/skymarshal + # via symforce (pyproject.toml) +file:./gen/python + # via symforce (pyproject.toml) +sympy + # via symforce (pyproject.toml) +wheel + # via symforce (pyproject.toml) diff --git a/requirements_dev_py310.txt b/requirements_dev_py310.txt new file mode 100644 index 00000000..6af4518f --- /dev/null +++ b/requirements_dev_py310.txt @@ -0,0 +1,338 @@ +# This file was autogenerated by uv via the following command: +# python test/symforce_requirements_test.py --update +alabaster==0.7.16 + # via sphinx +argh==0.31.2 + # via + # symforce (pyproject.toml) + # skymarshal +asttokens==2.4.1 + # via stack-data +attrs==23.2.0 + # via + # jsonschema + # referencing +babel==2.15.0 + # via sphinx +beautifulsoup4==4.12.3 + # via + # furo + # nbconvert +bleach==6.1.0 + # via nbconvert +breathe==4.35.0 + # via symforce (pyproject.toml) +certifi==2024.2.2 + # via requests +charset-normalizer==3.3.2 + # via requests +clang-format==18.1.5 + # via symforce (pyproject.toml) +cmake==3.26.4 + # via symforce (pyproject.toml) +comm==0.2.2 + # via ipykernel +contourpy==1.2.1 + # via matplotlib +coverage==7.5.1 + # via symforce (pyproject.toml) +cycler==0.12.1 + # via matplotlib +cython==0.29.37 + # via symforce (pyproject.toml) +debugpy==1.8.1 + # via ipykernel +decorator==5.1.1 + # via ipython +defusedxml==0.7.1 + # via nbconvert +docutils==0.21.2 + # via + # breathe + # myst-parser + # nbsphinx + # sphinx +exceptiongroup==1.2.1 + # via ipython +executing==2.0.1 + # via stack-data +fastjsonschema==2.19.1 + # via nbformat +fonttools==4.51.0 + # via matplotlib +furo==2024.5.6 + # via symforce (pyproject.toml) +graphviz==0.20.3 + # via symforce (pyproject.toml) +idna==3.7 + # via requests +imagesize==1.4.1 + # via sphinx +ipykernel==6.29.4 + # via symforce (pyproject.toml) +ipython==8.24.0 + # via ipykernel +ipython-genutils==0.2.0 + # via symforce (pyproject.toml) +jedi==0.19.1 + # via ipython +jinja2==3.1.4 + # via + # symforce (pyproject.toml) + # myst-parser + # nbconvert + # nbsphinx + # skymarshal + # sphinx +jsonschema==4.22.0 + # via nbformat +jsonschema-specifications==2023.12.1 + # via jsonschema +jupyter-client==8.6.1 + # via + # ipykernel + # nbclient +jupyter-core==5.7.2 + # via + # ipykernel + # jupyter-client + # nbclient + # nbconvert + # nbformat +jupyterlab-pygments==0.3.0 + # via nbconvert +kiwisolver==1.4.5 + # via matplotlib +llvmlite==0.42.0 + # via numba +markdown-it-py==3.0.0 + # via + # mdit-py-plugins + # myst-parser +markupsafe==2.1.5 + # via + # jinja2 + # nbconvert +matplotlib==3.10.1 + # via symforce (pyproject.toml) +matplotlib-inline==0.1.7 + # via + # ipykernel + # ipython +mdit-py-plugins==0.4.1 + # via myst-parser +mdurl==0.1.2 + # via markdown-it-py +mistune==3.0.2 + # via nbconvert +mpmath==1.3.0 + # via sympy +mypy==1.11.2 + # via symforce (pyproject.toml) +mypy-extensions==1.0.0 + # via mypy +myst-parser==3.0.1 + # via symforce (pyproject.toml) +nbclient==0.10.0 + # via nbconvert +nbconvert==7.16.4 + # via nbsphinx +nbformat==5.10.4 + # via + # nbclient + # nbconvert + # nbsphinx + # nbstripout +nbsphinx==0.9.4 + # via symforce (pyproject.toml) +nbstripout==0.7.1 + # via symforce (pyproject.toml) +nest-asyncio==1.6.0 + # via ipykernel +numba==0.59.1 + # via symforce (pyproject.toml) +numpy==1.26.4 + # via + # symforce (pyproject.toml) + # contourpy + # matplotlib + # numba + # pandas + # scipy + # skymarshal + # symforce-sym +packaging==24.0 + # via + # ipykernel + # matplotlib + # nbconvert + # plotly + # setuptools-scm + # sphinx +pandas==2.2.2 + # via symforce (pyproject.toml) +pandocfilters==1.5.1 + # via nbconvert +parso==0.8.4 + # via jedi +pexpect==4.9.0 + # via ipython +pillow==10.3.0 + # via matplotlib +pip==24.0 + # via symforce (pyproject.toml) +platformdirs==4.2.2 + # via jupyter-core +plotly==5.22.0 + # via symforce (pyproject.toml) +ply==3.11 + # via skymarshal +prompt-toolkit==3.0.43 + # via ipython +psutil==5.9.8 + # via ipykernel +ptyprocess==0.7.0 + # via pexpect +pure-eval==0.2.2 + # via stack-data +pybind11-stubgen==2.5.3 + # via symforce (pyproject.toml) +pygments==2.18.0 + # via + # furo + # ipython + # nbconvert + # sphinx +pyparsing==3.1.2 + # via matplotlib +python-dateutil==2.9.0.post0 + # via + # jupyter-client + # matplotlib + # pandas +pytz==2024.1 + # via pandas +pyyaml==6.0.1 + # via myst-parser +pyzmq==26.0.3 + # via + # ipykernel + # jupyter-client +referencing==0.35.1 + # via + # jsonschema + # jsonschema-specifications +requests==2.31.0 + # via sphinx +rpds-py==0.18.1 + # via + # jsonschema + # referencing +ruff==0.9.10 + # via symforce (pyproject.toml) +scipy==1.13.0 + # via symforce (pyproject.toml) +setuptools==69.5.1 + # via + # symforce (pyproject.toml) + # setuptools-scm +setuptools-scm==8.2.0 + # via symforce (pyproject.toml) +six==1.16.0 + # via + # asttokens + # bleach + # python-dateutil +file:./third_party/skymarshal + # via symforce (pyproject.toml) +snowballstemmer==2.2.0 + # via sphinx +soupsieve==2.5 + # via beautifulsoup4 +sphinx==7.3.7 + # via + # symforce (pyproject.toml) + # breathe + # furo + # myst-parser + # nbsphinx + # sphinx-basic-ng + # sphinx-copybutton + # sphinxext-opengraph +sphinx-basic-ng==1.0.0b2 + # via furo +sphinx-copybutton==0.5.2 + # via symforce (pyproject.toml) +sphinxcontrib-applehelp==1.0.8 + # via sphinx +sphinxcontrib-devhelp==1.0.6 + # via sphinx +sphinxcontrib-htmlhelp==2.0.5 + # via sphinx +sphinxcontrib-jsmath==1.0.1 + # via sphinx +sphinxcontrib-qthelp==1.0.7 + # via sphinx +sphinxcontrib-serializinghtml==1.1.10 + # via sphinx +sphinxext-opengraph==0.9.1 + # via symforce (pyproject.toml) +stack-data==0.6.3 + # via ipython +file:./gen/python + # via symforce (pyproject.toml) +sympy==1.11.1 + # via symforce (pyproject.toml) +tenacity==8.3.0 + # via plotly +tinycss2==1.3.0 + # via nbconvert +tomli==2.0.1 + # via + # mypy + # setuptools-scm + # sphinx +tornado==6.4 + # via + # ipykernel + # jupyter-client +traitlets==5.14.3 + # via + # comm + # ipykernel + # ipython + # jupyter-client + # jupyter-core + # matplotlib-inline + # nbclient + # nbconvert + # nbformat + # nbsphinx +types-jinja2==2.11.9 + # via symforce (pyproject.toml) +types-markupsafe==1.1.10 + # via types-jinja2 +types-requests==2.31.0.20240406 + # via symforce (pyproject.toml) +types-setuptools==69.5.0.20240513 + # via symforce (pyproject.toml) +typing-extensions==4.11.0 + # via + # ipython + # mypy +tzdata==2024.1 + # via pandas +urllib3==2.2.1 + # via + # requests + # types-requests +uv==0.6.8 + # via symforce (pyproject.toml) +wcwidth==0.2.13 + # via prompt-toolkit +webencodings==0.5.1 + # via + # bleach + # tinycss2 +wheel==0.43.0 + # via symforce (pyproject.toml) diff --git a/requirements_dev_py311.txt b/requirements_dev_py311.txt new file mode 100644 index 00000000..e54c94ad --- /dev/null +++ b/requirements_dev_py311.txt @@ -0,0 +1,331 @@ +# This file was autogenerated by uv via the following command: +# python test/symforce_requirements_test.py --update +alabaster==0.7.16 + # via sphinx +argh==0.31.2 + # via + # symforce (pyproject.toml) + # skymarshal +asttokens==2.4.1 + # via stack-data +attrs==23.2.0 + # via + # jsonschema + # referencing +babel==2.15.0 + # via sphinx +beautifulsoup4==4.12.3 + # via + # furo + # nbconvert +bleach==6.1.0 + # via nbconvert +breathe==4.35.0 + # via symforce (pyproject.toml) +certifi==2024.2.2 + # via requests +charset-normalizer==3.3.2 + # via requests +clang-format==18.1.5 + # via symforce (pyproject.toml) +cmake==3.26.4 + # via symforce (pyproject.toml) +comm==0.2.2 + # via ipykernel +contourpy==1.2.1 + # via matplotlib +coverage==7.5.1 + # via symforce (pyproject.toml) +cycler==0.12.1 + # via matplotlib +cython==0.29.37 + # via symforce (pyproject.toml) +debugpy==1.8.1 + # via ipykernel +decorator==5.1.1 + # via ipython +defusedxml==0.7.1 + # via nbconvert +docutils==0.21.2 + # via + # breathe + # myst-parser + # nbsphinx + # sphinx +executing==2.0.1 + # via stack-data +fastjsonschema==2.19.1 + # via nbformat +fonttools==4.51.0 + # via matplotlib +furo==2024.5.6 + # via symforce (pyproject.toml) +graphviz==0.20.3 + # via symforce (pyproject.toml) +idna==3.7 + # via requests +imagesize==1.4.1 + # via sphinx +ipykernel==6.29.4 + # via symforce (pyproject.toml) +ipython==8.24.0 + # via ipykernel +ipython-genutils==0.2.0 + # via symforce (pyproject.toml) +jedi==0.19.1 + # via ipython +jinja2==3.1.4 + # via + # symforce (pyproject.toml) + # myst-parser + # nbconvert + # nbsphinx + # skymarshal + # sphinx +jsonschema==4.22.0 + # via nbformat +jsonschema-specifications==2023.12.1 + # via jsonschema +jupyter-client==8.6.1 + # via + # ipykernel + # nbclient +jupyter-core==5.7.2 + # via + # ipykernel + # jupyter-client + # nbclient + # nbconvert + # nbformat +jupyterlab-pygments==0.3.0 + # via nbconvert +kiwisolver==1.4.5 + # via matplotlib +llvmlite==0.42.0 + # via numba +markdown-it-py==3.0.0 + # via + # mdit-py-plugins + # myst-parser +markupsafe==2.1.5 + # via + # jinja2 + # nbconvert +matplotlib==3.10.1 + # via symforce (pyproject.toml) +matplotlib-inline==0.1.7 + # via + # ipykernel + # ipython +mdit-py-plugins==0.4.1 + # via myst-parser +mdurl==0.1.2 + # via markdown-it-py +mistune==3.0.2 + # via nbconvert +mpmath==1.3.0 + # via sympy +mypy==1.11.2 + # via symforce (pyproject.toml) +mypy-extensions==1.0.0 + # via mypy +myst-parser==3.0.1 + # via symforce (pyproject.toml) +nbclient==0.10.0 + # via nbconvert +nbconvert==7.16.4 + # via nbsphinx +nbformat==5.10.4 + # via + # nbclient + # nbconvert + # nbsphinx + # nbstripout +nbsphinx==0.9.4 + # via symforce (pyproject.toml) +nbstripout==0.7.1 + # via symforce (pyproject.toml) +nest-asyncio==1.6.0 + # via ipykernel +numba==0.59.1 + # via symforce (pyproject.toml) +numpy==1.26.4 + # via + # symforce (pyproject.toml) + # contourpy + # matplotlib + # numba + # pandas + # scipy + # skymarshal + # symforce-sym +packaging==24.0 + # via + # ipykernel + # matplotlib + # nbconvert + # plotly + # setuptools-scm + # sphinx +pandas==2.2.2 + # via symforce (pyproject.toml) +pandocfilters==1.5.1 + # via nbconvert +parso==0.8.4 + # via jedi +pexpect==4.9.0 + # via ipython +pillow==10.3.0 + # via matplotlib +pip==24.0 + # via symforce (pyproject.toml) +platformdirs==4.2.2 + # via jupyter-core +plotly==5.22.0 + # via symforce (pyproject.toml) +ply==3.11 + # via skymarshal +prompt-toolkit==3.0.43 + # via ipython +psutil==5.9.8 + # via ipykernel +ptyprocess==0.7.0 + # via pexpect +pure-eval==0.2.2 + # via stack-data +pybind11-stubgen==2.5.3 + # via symforce (pyproject.toml) +pygments==2.18.0 + # via + # furo + # ipython + # nbconvert + # sphinx +pyparsing==3.1.2 + # via matplotlib +python-dateutil==2.9.0.post0 + # via + # jupyter-client + # matplotlib + # pandas +pytz==2024.1 + # via pandas +pyyaml==6.0.1 + # via myst-parser +pyzmq==26.0.3 + # via + # ipykernel + # jupyter-client +referencing==0.35.1 + # via + # jsonschema + # jsonschema-specifications +requests==2.31.0 + # via sphinx +rpds-py==0.18.1 + # via + # jsonschema + # referencing +ruff==0.9.10 + # via symforce (pyproject.toml) +scipy==1.13.0 + # via symforce (pyproject.toml) +setuptools==69.5.1 + # via + # symforce (pyproject.toml) + # setuptools-scm +setuptools-scm==8.2.0 + # via symforce (pyproject.toml) +six==1.16.0 + # via + # asttokens + # bleach + # python-dateutil +file:./third_party/skymarshal + # via symforce (pyproject.toml) +snowballstemmer==2.2.0 + # via sphinx +soupsieve==2.5 + # via beautifulsoup4 +sphinx==7.3.7 + # via + # symforce (pyproject.toml) + # breathe + # furo + # myst-parser + # nbsphinx + # sphinx-basic-ng + # sphinx-copybutton + # sphinxext-opengraph +sphinx-basic-ng==1.0.0b2 + # via furo +sphinx-copybutton==0.5.2 + # via symforce (pyproject.toml) +sphinxcontrib-applehelp==1.0.8 + # via sphinx +sphinxcontrib-devhelp==1.0.6 + # via sphinx +sphinxcontrib-htmlhelp==2.0.5 + # via sphinx +sphinxcontrib-jsmath==1.0.1 + # via sphinx +sphinxcontrib-qthelp==1.0.7 + # via sphinx +sphinxcontrib-serializinghtml==1.1.10 + # via sphinx +sphinxext-opengraph==0.9.1 + # via symforce (pyproject.toml) +stack-data==0.6.3 + # via ipython +file:./gen/python + # via symforce (pyproject.toml) +sympy==1.11.1 + # via symforce (pyproject.toml) +tenacity==8.3.0 + # via plotly +tinycss2==1.3.0 + # via nbconvert +tornado==6.4 + # via + # ipykernel + # jupyter-client +traitlets==5.14.3 + # via + # comm + # ipykernel + # ipython + # jupyter-client + # jupyter-core + # matplotlib-inline + # nbclient + # nbconvert + # nbformat + # nbsphinx +types-jinja2==2.11.9 + # via symforce (pyproject.toml) +types-markupsafe==1.1.10 + # via types-jinja2 +types-requests==2.31.0.20240406 + # via symforce (pyproject.toml) +types-setuptools==69.5.0.20240513 + # via symforce (pyproject.toml) +typing-extensions==4.11.0 + # via + # ipython + # mypy +tzdata==2024.1 + # via pandas +urllib3==2.2.1 + # via + # requests + # types-requests +uv==0.6.8 + # via symforce (pyproject.toml) +wcwidth==0.2.13 + # via prompt-toolkit +webencodings==0.5.1 + # via + # bleach + # tinycss2 +wheel==0.43.0 + # via symforce (pyproject.toml) diff --git a/requirements_dev_py312.txt b/requirements_dev_py312.txt new file mode 100644 index 00000000..47b6dce8 --- /dev/null +++ b/requirements_dev_py312.txt @@ -0,0 +1,329 @@ +# This file was autogenerated by uv via the following command: +# python test/symforce_requirements_test.py --update +alabaster==0.7.16 + # via sphinx +argh==0.31.2 + # via + # symforce (pyproject.toml) + # skymarshal +asttokens==2.4.1 + # via stack-data +attrs==23.2.0 + # via + # jsonschema + # referencing +babel==2.15.0 + # via sphinx +beautifulsoup4==4.12.3 + # via + # furo + # nbconvert +bleach==6.1.0 + # via nbconvert +breathe==4.35.0 + # via symforce (pyproject.toml) +certifi==2024.2.2 + # via requests +charset-normalizer==3.3.2 + # via requests +clang-format==18.1.5 + # via symforce (pyproject.toml) +cmake==3.26.4 + # via symforce (pyproject.toml) +comm==0.2.2 + # via ipykernel +contourpy==1.2.1 + # via matplotlib +coverage==7.5.1 + # via symforce (pyproject.toml) +cycler==0.12.1 + # via matplotlib +cython==0.29.37 + # via symforce (pyproject.toml) +debugpy==1.8.1 + # via ipykernel +decorator==5.1.1 + # via ipython +defusedxml==0.7.1 + # via nbconvert +docutils==0.21.2 + # via + # breathe + # myst-parser + # nbsphinx + # sphinx +executing==2.0.1 + # via stack-data +fastjsonschema==2.19.1 + # via nbformat +fonttools==4.51.0 + # via matplotlib +furo==2024.5.6 + # via symforce (pyproject.toml) +graphviz==0.20.3 + # via symforce (pyproject.toml) +idna==3.7 + # via requests +imagesize==1.4.1 + # via sphinx +ipykernel==6.29.4 + # via symforce (pyproject.toml) +ipython==8.24.0 + # via ipykernel +ipython-genutils==0.2.0 + # via symforce (pyproject.toml) +jedi==0.19.1 + # via ipython +jinja2==3.1.4 + # via + # symforce (pyproject.toml) + # myst-parser + # nbconvert + # nbsphinx + # skymarshal + # sphinx +jsonschema==4.22.0 + # via nbformat +jsonschema-specifications==2023.12.1 + # via jsonschema +jupyter-client==8.6.1 + # via + # ipykernel + # nbclient +jupyter-core==5.7.2 + # via + # ipykernel + # jupyter-client + # nbclient + # nbconvert + # nbformat +jupyterlab-pygments==0.3.0 + # via nbconvert +kiwisolver==1.4.5 + # via matplotlib +llvmlite==0.42.0 + # via numba +markdown-it-py==3.0.0 + # via + # mdit-py-plugins + # myst-parser +markupsafe==2.1.5 + # via + # jinja2 + # nbconvert +matplotlib==3.10.1 + # via symforce (pyproject.toml) +matplotlib-inline==0.1.7 + # via + # ipykernel + # ipython +mdit-py-plugins==0.4.1 + # via myst-parser +mdurl==0.1.2 + # via markdown-it-py +mistune==3.0.2 + # via nbconvert +mpmath==1.3.0 + # via sympy +mypy==1.11.2 + # via symforce (pyproject.toml) +mypy-extensions==1.0.0 + # via mypy +myst-parser==3.0.1 + # via symforce (pyproject.toml) +nbclient==0.10.0 + # via nbconvert +nbconvert==7.16.4 + # via nbsphinx +nbformat==5.10.4 + # via + # nbclient + # nbconvert + # nbsphinx + # nbstripout +nbsphinx==0.9.4 + # via symforce (pyproject.toml) +nbstripout==0.7.1 + # via symforce (pyproject.toml) +nest-asyncio==1.6.0 + # via ipykernel +numba==0.59.1 + # via symforce (pyproject.toml) +numpy==1.26.4 + # via + # symforce (pyproject.toml) + # contourpy + # matplotlib + # numba + # pandas + # scipy + # skymarshal + # symforce-sym +packaging==24.0 + # via + # ipykernel + # matplotlib + # nbconvert + # plotly + # setuptools-scm + # sphinx +pandas==2.2.2 + # via symforce (pyproject.toml) +pandocfilters==1.5.1 + # via nbconvert +parso==0.8.4 + # via jedi +pexpect==4.9.0 + # via ipython +pillow==10.3.0 + # via matplotlib +pip==24.0 + # via symforce (pyproject.toml) +platformdirs==4.2.2 + # via jupyter-core +plotly==5.22.0 + # via symforce (pyproject.toml) +ply==3.11 + # via skymarshal +prompt-toolkit==3.0.43 + # via ipython +psutil==5.9.8 + # via ipykernel +ptyprocess==0.7.0 + # via pexpect +pure-eval==0.2.2 + # via stack-data +pybind11-stubgen==2.5.3 + # via symforce (pyproject.toml) +pygments==2.18.0 + # via + # furo + # ipython + # nbconvert + # sphinx +pyparsing==3.1.2 + # via matplotlib +python-dateutil==2.9.0.post0 + # via + # jupyter-client + # matplotlib + # pandas +pytz==2024.1 + # via pandas +pyyaml==6.0.1 + # via myst-parser +pyzmq==26.0.3 + # via + # ipykernel + # jupyter-client +referencing==0.35.1 + # via + # jsonschema + # jsonschema-specifications +requests==2.31.0 + # via sphinx +rpds-py==0.18.1 + # via + # jsonschema + # referencing +ruff==0.9.10 + # via symforce (pyproject.toml) +scipy==1.13.0 + # via symforce (pyproject.toml) +setuptools==69.5.1 + # via + # symforce (pyproject.toml) + # setuptools-scm +setuptools-scm==8.2.0 + # via symforce (pyproject.toml) +six==1.16.0 + # via + # asttokens + # bleach + # python-dateutil +file:./third_party/skymarshal + # via symforce (pyproject.toml) +snowballstemmer==2.2.0 + # via sphinx +soupsieve==2.5 + # via beautifulsoup4 +sphinx==7.3.7 + # via + # symforce (pyproject.toml) + # breathe + # furo + # myst-parser + # nbsphinx + # sphinx-basic-ng + # sphinx-copybutton + # sphinxext-opengraph +sphinx-basic-ng==1.0.0b2 + # via furo +sphinx-copybutton==0.5.2 + # via symforce (pyproject.toml) +sphinxcontrib-applehelp==1.0.8 + # via sphinx +sphinxcontrib-devhelp==1.0.6 + # via sphinx +sphinxcontrib-htmlhelp==2.0.5 + # via sphinx +sphinxcontrib-jsmath==1.0.1 + # via sphinx +sphinxcontrib-qthelp==1.0.7 + # via sphinx +sphinxcontrib-serializinghtml==1.1.10 + # via sphinx +sphinxext-opengraph==0.9.1 + # via symforce (pyproject.toml) +stack-data==0.6.3 + # via ipython +file:./gen/python + # via symforce (pyproject.toml) +sympy==1.11.1 + # via symforce (pyproject.toml) +tenacity==8.3.0 + # via plotly +tinycss2==1.3.0 + # via nbconvert +tornado==6.4 + # via + # ipykernel + # jupyter-client +traitlets==5.14.3 + # via + # comm + # ipykernel + # ipython + # jupyter-client + # jupyter-core + # matplotlib-inline + # nbclient + # nbconvert + # nbformat + # nbsphinx +types-jinja2==2.11.9 + # via symforce (pyproject.toml) +types-markupsafe==1.1.10 + # via types-jinja2 +types-requests==2.31.0.20240406 + # via symforce (pyproject.toml) +types-setuptools==69.5.0.20240513 + # via symforce (pyproject.toml) +typing-extensions==4.11.0 + # via mypy +tzdata==2024.1 + # via pandas +urllib3==2.2.1 + # via + # requests + # types-requests +uv==0.6.8 + # via symforce (pyproject.toml) +wcwidth==0.2.13 + # via prompt-toolkit +webencodings==0.5.1 + # via + # bleach + # tinycss2 +wheel==0.43.0 + # via symforce (pyproject.toml) diff --git a/dev_requirements.txt b/requirements_dev_py38.txt similarity index 76% rename from dev_requirements.txt rename to requirements_dev_py38.txt index c6eead8f..fbcdda6e 100644 --- a/dev_requirements.txt +++ b/requirements_dev_py38.txt @@ -1,20 +1,11 @@ -# -# This file is autogenerated by pip-compile with Python 3.8 -# by the following command: -# +# This file was autogenerated by uv via the following command: # python test/symforce_requirements_test.py --update -# ---index-url https://pypi.python.org/simple - -# Create a requirement incompatible with python < 3.8 -symforce_requires_python_38_or_higher___your_python_version_is_incompatible; python_version < '3.8' - alabaster==0.7.13 # via sphinx argh==0.31.2 # via + # symforce (pyproject.toml) # skymarshal - # symforce (setup.py) asttokens==2.4.1 # via stack-data attrs==23.2.0 @@ -32,29 +23,25 @@ beautifulsoup4==4.12.3 bleach==6.1.0 # via nbconvert breathe==4.35.0 - # via symforce (setup.py) -build==1.2.1 - # via pip-tools + # via symforce (pyproject.toml) certifi==2024.2.2 # via requests charset-normalizer==3.3.2 # via requests clang-format==18.1.5 - # via symforce (setup.py) -click==8.1.7 - # via pip-tools + # via symforce (pyproject.toml) cmake==3.26.4 - # via symforce (setup.py) + # via symforce (pyproject.toml) comm==0.2.2 # via ipykernel contourpy==1.1.1 # via matplotlib coverage==7.5.1 - # via symforce (setup.py) + # via symforce (pyproject.toml) cycler==0.12.1 # via matplotlib cython==0.29.37 - # via symforce (setup.py) + # via symforce (pyproject.toml) debugpy==1.8.1 # via ipykernel decorator==5.1.1 @@ -74,16 +61,15 @@ fastjsonschema==2.19.1 fonttools==4.51.0 # via matplotlib furo==2024.5.6 - # via symforce (setup.py) + # via symforce (pyproject.toml) graphviz==0.20.3 - # via symforce (setup.py) + # via symforce (pyproject.toml) idna==3.7 # via requests imagesize==1.4.1 # via sphinx importlib-metadata==7.1.0 # via - # build # jupyter-client # nbconvert # numba @@ -94,21 +80,21 @@ importlib-resources==6.4.0 # jsonschema-specifications # matplotlib ipykernel==6.29.4 - # via symforce (setup.py) + # via symforce (pyproject.toml) ipython==8.12.3 # via ipykernel ipython-genutils==0.2.0 - # via symforce (setup.py) + # via symforce (pyproject.toml) jedi==0.19.1 # via ipython jinja2==3.1.4 # via + # symforce (pyproject.toml) # myst-parser # nbconvert # nbsphinx # skymarshal # sphinx - # symforce (setup.py) jsonschema==4.22.0 # via nbformat jsonschema-specifications==2023.12.1 @@ -139,7 +125,7 @@ markupsafe==2.1.5 # jinja2 # nbconvert matplotlib==3.7.5 - # via symforce (setup.py) + # via symforce (pyproject.toml) matplotlib-inline==0.1.7 # via # ipykernel @@ -153,11 +139,11 @@ mistune==3.0.2 mpmath==1.3.0 # via sympy mypy==1.11.0 - # via symforce (setup.py) + # via symforce (pyproject.toml) mypy-extensions==1.0.0 # via mypy myst-parser==3.0.1 - # via symforce (setup.py) + # via symforce (pyproject.toml) nbclient==0.10.0 # via nbconvert nbconvert==7.16.4 @@ -169,26 +155,25 @@ nbformat==5.10.4 # nbsphinx # nbstripout nbsphinx==0.9.4 - # via symforce (setup.py) + # via symforce (pyproject.toml) nbstripout==0.7.1 - # via symforce (setup.py) + # via symforce (pyproject.toml) nest-asyncio==1.6.0 # via ipykernel numba==0.58.1 - # via symforce (setup.py) + # via symforce (pyproject.toml) numpy==1.24.4 # via + # symforce (pyproject.toml) # contourpy # matplotlib # numba # pandas # scipy # skymarshal - # symforce (setup.py) # symforce-sym packaging==24.0 # via - # build # ipykernel # matplotlib # nbconvert @@ -196,7 +181,7 @@ packaging==24.0 # setuptools-scm # sphinx pandas==2.0.3 - # via symforce (setup.py) + # via symforce (pyproject.toml) pandocfilters==1.5.1 # via nbconvert parso==0.8.4 @@ -207,14 +192,14 @@ pickleshare==0.7.5 # via ipython pillow==10.3.0 # via matplotlib -pip-tools==7.4.1 - # via symforce (setup.py) +pip==24.0 + # via symforce (pyproject.toml) pkgutil-resolve-name==1.3.10 # via jsonschema platformdirs==4.2.2 # via jupyter-core plotly==5.22.0 - # via symforce (setup.py) + # via symforce (pyproject.toml) ply==3.11 # via skymarshal prompt-toolkit==3.0.43 @@ -226,7 +211,7 @@ ptyprocess==0.7.0 pure-eval==0.2.2 # via stack-data pybind11-stubgen==2.5.3 - # via symforce (setup.py) + # via symforce (pyproject.toml) pygments==2.18.0 # via # furo @@ -235,10 +220,6 @@ pygments==2.18.0 # sphinx pyparsing==3.1.2 # via matplotlib -pyproject-hooks==1.1.0 - # via - # build - # pip-tools python-dateutil==2.9.0.post0 # via # jupyter-client @@ -265,24 +246,29 @@ rpds-py==0.18.1 # jsonschema # referencing ruff==0.9.7 - # via symforce (setup.py) + # via symforce (pyproject.toml) scipy==1.10.1 - # via symforce (setup.py) + # via symforce (pyproject.toml) +setuptools==69.5.1 + # via + # symforce (pyproject.toml) + # setuptools-scm setuptools-scm==8.1.0 - # via symforce (setup.py) + # via symforce (pyproject.toml) six==1.16.0 # via # asttokens # bleach # python-dateutil file:./third_party/skymarshal - # via symforce (setup.py) + # via symforce (pyproject.toml) snowballstemmer==2.2.0 # via sphinx soupsieve==2.5 # via beautifulsoup4 sphinx==7.1.2 # via + # symforce (pyproject.toml) # breathe # furo # myst-parser @@ -290,11 +276,10 @@ sphinx==7.1.2 # sphinx-basic-ng # sphinx-copybutton # sphinxext-opengraph - # symforce (setup.py) sphinx-basic-ng==1.0.0b2 # via furo sphinx-copybutton==0.5.2 - # via symforce (setup.py) + # via symforce (pyproject.toml) sphinxcontrib-applehelp==1.0.4 # via sphinx sphinxcontrib-devhelp==1.0.2 @@ -308,22 +293,20 @@ sphinxcontrib-qthelp==1.0.3 sphinxcontrib-serializinghtml==1.1.5 # via sphinx sphinxext-opengraph==0.9.1 - # via symforce (setup.py) + # via symforce (pyproject.toml) stack-data==0.6.3 # via ipython file:./gen/python - # via symforce (setup.py) + # via symforce (pyproject.toml) sympy==1.11.1 - # via symforce (setup.py) + # via symforce (pyproject.toml) tenacity==8.3.0 # via plotly tinycss2==1.3.0 # via nbconvert tomli==2.0.1 # via - # build # mypy - # pip-tools # setuptools-scm tornado==6.4 # via @@ -342,13 +325,13 @@ traitlets==5.14.3 # nbformat # nbsphinx types-jinja2==2.11.9 - # via symforce (setup.py) + # via symforce (pyproject.toml) types-markupsafe==1.1.10 # via types-jinja2 types-requests==2.31.0.20240406 - # via symforce (setup.py) + # via symforce (pyproject.toml) types-setuptools==69.5.0.20240513 - # via symforce (setup.py) + # via symforce (pyproject.toml) typing-extensions==4.11.0 # via # ipython @@ -360,6 +343,8 @@ urllib3==2.2.1 # via # requests # types-requests +uv==0.6.8 + # via symforce (pyproject.toml) wcwidth==0.2.13 # via prompt-toolkit webencodings==0.5.1 @@ -367,21 +352,8 @@ webencodings==0.5.1 # bleach # tinycss2 wheel==0.43.0 - # via - # pip-tools - # symforce (setup.py) + # via symforce (pyproject.toml) zipp==3.18.1 # via # importlib-metadata # importlib-resources - -# The following packages are considered to be unsafe in a requirements file: -pip==24.0 - # via - # pip-tools - # symforce (setup.py) -setuptools==69.5.1 - # via - # pip-tools - # setuptools-scm - # symforce (setup.py) diff --git a/requirements_dev_py39.txt b/requirements_dev_py39.txt new file mode 100644 index 00000000..87e45f09 --- /dev/null +++ b/requirements_dev_py39.txt @@ -0,0 +1,350 @@ +# This file was autogenerated by uv via the following command: +# python test/symforce_requirements_test.py --update +alabaster==0.7.16 + # via sphinx +argh==0.31.2 + # via + # symforce (pyproject.toml) + # skymarshal +asttokens==2.4.1 + # via stack-data +attrs==23.2.0 + # via + # jsonschema + # referencing +babel==2.15.0 + # via sphinx +beautifulsoup4==4.12.3 + # via + # furo + # nbconvert +bleach==6.1.0 + # via nbconvert +breathe==4.35.0 + # via symforce (pyproject.toml) +certifi==2024.2.2 + # via requests +charset-normalizer==3.3.2 + # via requests +clang-format==18.1.5 + # via symforce (pyproject.toml) +cmake==3.26.4 + # via symforce (pyproject.toml) +comm==0.2.2 + # via ipykernel +contourpy==1.2.1 + # via matplotlib +coverage==7.5.1 + # via symforce (pyproject.toml) +cycler==0.12.1 + # via matplotlib +cython==0.29.37 + # via symforce (pyproject.toml) +debugpy==1.8.1 + # via ipykernel +decorator==5.1.1 + # via ipython +defusedxml==0.7.1 + # via nbconvert +docutils==0.21.2 + # via + # breathe + # myst-parser + # nbsphinx + # sphinx +exceptiongroup==1.2.1 + # via ipython +executing==2.0.1 + # via stack-data +fastjsonschema==2.19.1 + # via nbformat +fonttools==4.51.0 + # via matplotlib +furo==2024.5.6 + # via symforce (pyproject.toml) +graphviz==0.20.3 + # via symforce (pyproject.toml) +idna==3.7 + # via requests +imagesize==1.4.1 + # via sphinx +importlib-metadata==7.1.0 + # via + # jupyter-client + # nbconvert + # sphinx +importlib-resources==6.4.0 + # via matplotlib +ipykernel==6.29.4 + # via symforce (pyproject.toml) +ipython==8.18.1 + # via ipykernel +ipython-genutils==0.2.0 + # via symforce (pyproject.toml) +jedi==0.19.1 + # via ipython +jinja2==3.1.4 + # via + # symforce (pyproject.toml) + # myst-parser + # nbconvert + # nbsphinx + # skymarshal + # sphinx +jsonschema==4.22.0 + # via nbformat +jsonschema-specifications==2023.12.1 + # via jsonschema +jupyter-client==8.6.1 + # via + # ipykernel + # nbclient +jupyter-core==5.7.2 + # via + # ipykernel + # jupyter-client + # nbclient + # nbconvert + # nbformat +jupyterlab-pygments==0.3.0 + # via nbconvert +kiwisolver==1.4.5 + # via matplotlib +llvmlite==0.42.0 + # via numba +markdown-it-py==3.0.0 + # via + # mdit-py-plugins + # myst-parser +markupsafe==2.1.5 + # via + # jinja2 + # nbconvert +matplotlib==3.9.4 + # via symforce (pyproject.toml) +matplotlib-inline==0.1.7 + # via + # ipykernel + # ipython +mdit-py-plugins==0.4.1 + # via myst-parser +mdurl==0.1.2 + # via markdown-it-py +mistune==3.0.2 + # via nbconvert +mpmath==1.3.0 + # via sympy +mypy==1.11.2 + # via symforce (pyproject.toml) +mypy-extensions==1.0.0 + # via mypy +myst-parser==3.0.1 + # via symforce (pyproject.toml) +nbclient==0.10.0 + # via nbconvert +nbconvert==7.16.4 + # via nbsphinx +nbformat==5.10.4 + # via + # nbclient + # nbconvert + # nbsphinx + # nbstripout +nbsphinx==0.9.4 + # via symforce (pyproject.toml) +nbstripout==0.7.1 + # via symforce (pyproject.toml) +nest-asyncio==1.6.0 + # via ipykernel +numba==0.59.1 + # via symforce (pyproject.toml) +numpy==1.26.4 + # via + # symforce (pyproject.toml) + # contourpy + # matplotlib + # numba + # pandas + # scipy + # skymarshal + # symforce-sym +packaging==24.0 + # via + # ipykernel + # matplotlib + # nbconvert + # plotly + # setuptools-scm + # sphinx +pandas==2.2.2 + # via symforce (pyproject.toml) +pandocfilters==1.5.1 + # via nbconvert +parso==0.8.4 + # via jedi +pexpect==4.9.0 + # via ipython +pillow==10.3.0 + # via matplotlib +pip==24.0 + # via symforce (pyproject.toml) +platformdirs==4.2.2 + # via jupyter-core +plotly==5.22.0 + # via symforce (pyproject.toml) +ply==3.11 + # via skymarshal +prompt-toolkit==3.0.43 + # via ipython +psutil==5.9.8 + # via ipykernel +ptyprocess==0.7.0 + # via pexpect +pure-eval==0.2.2 + # via stack-data +pybind11-stubgen==2.5.3 + # via symforce (pyproject.toml) +pygments==2.18.0 + # via + # furo + # ipython + # nbconvert + # sphinx +pyparsing==3.1.2 + # via matplotlib +python-dateutil==2.9.0.post0 + # via + # jupyter-client + # matplotlib + # pandas +pytz==2024.1 + # via pandas +pyyaml==6.0.1 + # via myst-parser +pyzmq==26.0.3 + # via + # ipykernel + # jupyter-client +referencing==0.35.1 + # via + # jsonschema + # jsonschema-specifications +requests==2.31.0 + # via sphinx +rpds-py==0.18.1 + # via + # jsonschema + # referencing +ruff==0.9.10 + # via symforce (pyproject.toml) +scipy==1.13.0 + # via symforce (pyproject.toml) +setuptools==69.5.1 + # via + # symforce (pyproject.toml) + # setuptools-scm +setuptools-scm==8.2.0 + # via symforce (pyproject.toml) +six==1.16.0 + # via + # asttokens + # bleach + # python-dateutil +file:./third_party/skymarshal + # via symforce (pyproject.toml) +snowballstemmer==2.2.0 + # via sphinx +soupsieve==2.5 + # via beautifulsoup4 +sphinx==7.3.7 + # via + # symforce (pyproject.toml) + # breathe + # furo + # myst-parser + # nbsphinx + # sphinx-basic-ng + # sphinx-copybutton + # sphinxext-opengraph +sphinx-basic-ng==1.0.0b2 + # via furo +sphinx-copybutton==0.5.2 + # via symforce (pyproject.toml) +sphinxcontrib-applehelp==1.0.8 + # via sphinx +sphinxcontrib-devhelp==1.0.6 + # via sphinx +sphinxcontrib-htmlhelp==2.0.5 + # via sphinx +sphinxcontrib-jsmath==1.0.1 + # via sphinx +sphinxcontrib-qthelp==1.0.7 + # via sphinx +sphinxcontrib-serializinghtml==1.1.10 + # via sphinx +sphinxext-opengraph==0.9.1 + # via symforce (pyproject.toml) +stack-data==0.6.3 + # via ipython +file:./gen/python + # via symforce (pyproject.toml) +sympy==1.11.1 + # via symforce (pyproject.toml) +tenacity==8.3.0 + # via plotly +tinycss2==1.3.0 + # via nbconvert +tomli==2.0.1 + # via + # mypy + # setuptools-scm + # sphinx +tornado==6.4 + # via + # ipykernel + # jupyter-client +traitlets==5.14.3 + # via + # comm + # ipykernel + # ipython + # jupyter-client + # jupyter-core + # matplotlib-inline + # nbclient + # nbconvert + # nbformat + # nbsphinx +types-jinja2==2.11.9 + # via symforce (pyproject.toml) +types-markupsafe==1.1.10 + # via types-jinja2 +types-requests==2.31.0.20240406 + # via symforce (pyproject.toml) +types-setuptools==69.5.0.20240513 + # via symforce (pyproject.toml) +typing-extensions==4.11.0 + # via + # ipython + # mypy + # setuptools-scm +tzdata==2024.1 + # via pandas +urllib3==2.2.1 + # via + # requests + # types-requests +uv==0.6.8 + # via symforce (pyproject.toml) +wcwidth==0.2.13 + # via prompt-toolkit +webencodings==0.5.1 + # via + # bleach + # tinycss2 +wheel==0.43.0 + # via symforce (pyproject.toml) +zipp==3.18.2 + # via + # importlib-metadata + # importlib-resources diff --git a/setup.py b/setup.py index 19304c10..d3786003 100644 --- a/setup.py +++ b/setup.py @@ -399,16 +399,16 @@ def fixed_readme() -> str: "jinja2~=3.0", "mypy~=1.11.0", "numba", - # 6.13 fixes pip >=23.1 support - "pip-tools>=6.13", # For https://github.com/sizmailov/pybind11-stubgen/pull/243 "pybind11-stubgen>=2.5.3", "ruff~=0.9.7", "types-jinja2", "types-requests", "types-setuptools", + # Oldest version that solves to the right requirements + "uv>=0.2.0", ] ), - "_setup": maybe_rewrite_local_dependencies(setup_requirements), + "setup": maybe_rewrite_local_dependencies(setup_requirements), }, ) diff --git a/symforce/codegen/format_util.py b/symforce/codegen/format_util.py index 6cf98653..30bc48f9 100644 --- a/symforce/codegen/format_util.py +++ b/symforce/codegen/format_util.py @@ -8,9 +8,8 @@ import subprocess from pathlib import Path -from ruff.__main__ import find_ruff_bin - from symforce import typing as T +from symforce.python_util import find_ruff_bin def format_cpp(file_contents: str, filename: str) -> str: @@ -48,35 +47,6 @@ def format_cpp(file_contents: str, filename: str) -> str: return result.stdout -_ruff_path: T.Optional[Path] = None - - -def _find_ruff() -> Path: - """ - Find the ruff binary - - `find_ruff_bin` does not work in all environments, for example it does not work on debian when - things are installed in `/usr/local/bin` and `sysconfig` only returns `/usr/bin`. Adding - `shutil.which` should cover most cases, but not all, the better solution would require `ruff` - putting the binary in `data` like `clang-format` does - """ - global _ruff_path # noqa: PLW0603 - - if _ruff_path is not None: - return _ruff_path - - try: - ruff = find_ruff_bin() - except FileNotFoundError as ex: - ruff = shutil.which("ruff") - if ruff is None: - raise FileNotFoundError("Could not find ruff") from ex - - _ruff_path = ruff - - return ruff - - def format_py(file_contents: str, filename: str) -> str: """ Autoformat a given Python file using ruff @@ -87,7 +57,7 @@ def format_py(file_contents: str, filename: str) -> str: location) """ result = subprocess.run( - [_find_ruff(), "format", f"--stdin-filename={filename}", "-"], + [find_ruff_bin(), "format", f"--stdin-filename={filename}", "-"], input=file_contents, stdout=subprocess.PIPE, check=True, @@ -99,7 +69,7 @@ def format_py(file_contents: str, filename: str) -> str: ) result = subprocess.run( [ - _find_ruff(), + find_ruff_bin(), "check", "--select=I", "--fix", @@ -124,7 +94,7 @@ def format_py_dir(dirname: T.Openable) -> None: Autoformat python files in a directory (recursively) in-place """ subprocess.run( - [_find_ruff(), "format", dirname], + [find_ruff_bin(), "format", dirname], check=True, # Disable the ruff cache. This is important for running in a hermetic context like a bazel # test, and shouldn't really hurt other use cases. If it does, we should work around this diff --git a/symforce/python_util.py b/symforce/python_util.py index 266087f3..f7a91fc5 100644 --- a/symforce/python_util.py +++ b/symforce/python_util.py @@ -319,3 +319,48 @@ def __getattr__(self, name: str) -> T.Any: def __setattr__(self, name: str, value: T.Any) -> None: pass + + +_astral_paths: T.Dict[str, str] = {} + + +def _find_astral_bin(name: str) -> str: + """ + Find the ruff or uv binary + + `find_ruff_bin`/`find_uv_bin` do not work in all environments, for example it does not work on + debian when things are installed in `/usr/local/bin` and `sysconfig` only returns `/usr/bin`. + Adding `shutil.which` should cover most cases, but not all, the better solution would require + `ruff`/`uv` putting the binary in `data` like `clang-format` does + """ + if name == "ruff": + from ruff.__main__ import find_ruff_bin + + finder = find_ruff_bin + elif name == "uv": + from uv import find_uv_bin + + finder = find_uv_bin + else: + raise ValueError(f"Unknown binary name {name}") + + try: + path = finder() + except FileNotFoundError as ex: + path = shutil.which(name) + if path is None: + raise FileNotFoundError(f"Could not find {name}") from ex + + return path + + +def find_ruff_bin() -> str: + if "ruff" not in _astral_paths: + _astral_paths["ruff"] = _find_astral_bin("ruff") + return _astral_paths["ruff"] + + +def find_uv_bin() -> str: + if "uv" not in _astral_paths: + _astral_paths["uv"] = _find_astral_bin("uv") + return _astral_paths["uv"] diff --git a/test/symforce_requirements_test.py b/test/symforce_requirements_test.py index 65098ff6..3530d510 100644 --- a/test/symforce_requirements_test.py +++ b/test/symforce_requirements_test.py @@ -7,48 +7,57 @@ import os import re import sys -import textwrap from symforce import path_util from symforce import python_util from symforce import typing as T from symforce.test_util import TestCase -from symforce.test_util import symengine_only +from symforce.test_util import sympy_only class SymforceRequirementsTest(TestCase): """ - Tests pip requirements + Generates pinned pip requirements for all python versions, and tests that solving for + requirements gives the same result as the checked-in requirements files. + + To re-solve for the requirements, pass --update. To also upgrade all packages to latest + (subject to given constraints), also pass --uv_arg=--upgrade. Or upgrade one package to + latest with --uv_arg=--upgrade-package=, etc. """ - # Pass the --upgrade flag to piptools? - _PIPTOOLS_UPGRADE = False + # Extra args for uv + _UV_ARGS: T.List[str] = [] @staticmethod def main(*args: T.Any, **kwargs: T.Any) -> None: """ Call this to run all tests in scope. """ - if "--piptools_upgrade" in sys.argv: - SymforceRequirementsTest._PIPTOOLS_UPGRADE = True - sys.argv.remove("--piptools_upgrade") + argv: T.List[str] = [] + for arg in sys.argv: + if arg.startswith("--uv_arg="): + SymforceRequirementsTest._UV_ARGS.append(arg[len("--uv_arg=") :]) + else: + argv.append(arg) + sys.argv = argv TestCase.main(*args, **kwargs) - @symengine_only - def test_requirements(self) -> None: - output_dir = self.make_output_dir("sf_requirements_test_") + def check_dev_requirements_for_version(self, version: int) -> None: + output_dir = self.make_output_dir("sf_requirements_test_dev_") - output_requirements_file = output_dir / "dev_requirements.txt" - symforce_requirements_file = path_util.symforce_root() / "dev_requirements.txt" + output_requirements_file = output_dir / f"requirements_dev_py3{version}.txt" + symforce_requirements_file = ( + path_util.symforce_root() / f"requirements_dev_py3{version}.txt" + ) local_requirements_map = { - "skymarshal @ file://localhost/{}/third_party/skymarshal": "file:./third_party/skymarshal", - "symforce-sym @ file://localhost/{}/gen/python": "file:./gen/python", + "skymarshal @ file://{}/third_party/skymarshal": "file:./third_party/skymarshal", + "symforce-sym @ file://{}/gen/python": "file:./gen/python", } # Copy the symforce requirements file into the temp directory - # This is necessary so piptools has current versions of the packages already in the list + # This is necessary so uv has current versions of the packages already in the list if symforce_requirements_file.exists(): requirements_contents = symforce_requirements_file.read_text() @@ -63,27 +72,30 @@ def test_requirements(self) -> None: output_requirements_file.write_text(requirements_contents) - maybe_piptools_upgrade = ["--upgrade"] if self._PIPTOOLS_UPGRADE else [] + # Do not use the cache if we have no custom args (for hermeticity) + extra_uv_args = self._UV_ARGS or ["--no-cache"] asyncio.run( python_util.execute_subprocess( [ - sys.executable, - "-m", - "piptools", + python_util.find_uv_bin(), + "pip", "compile", + "--all-extras", f"--output-file={output_requirements_file}", - "--index-url=https://pypi.python.org/simple", - "--allow-unsafe", - "--extra=dev", - "--extra=_setup", + f"--python-version=3.{version}", + "pyproject.toml", ] - + maybe_piptools_upgrade, + + extra_uv_args, cwd=path_util.symforce_root(), env=dict( os.environ, - # Compile command to put in the header of dev_requirements.txt - CUSTOM_COMPILE_COMMAND="python test/symforce_requirements_test.py --update", + # Compile command to put in the header of requirements.txt + UV_CUSTOM_COMPILE_COMMAND="python test/symforce_requirements_test.py --update", + # Don't actually deduce versions for these, we don't need them + SETUPTOOLS_SCM_PRETEND_VERSION_FOR_SYMFORCE="0.1.0", + SETUPTOOLS_SCM_PRETEND_VERSION_FOR_SYMFORCE_SYM="0.1.0", + SETUPTOOLS_SCM_PRETEND_VERSION_FOR_SKYMARSHAL="0.1.0", ), ) ) @@ -93,22 +105,86 @@ def test_requirements(self) -> None: for key, value in local_requirements_map.items(): requirements_contents = re.sub(key.format(".*"), value, requirements_contents) - # Inject the python version requirement - sentinel = "--index-url https://pypi.python.org/simple\n" - version_requirement = textwrap.dedent( - """ - # Create a requirement incompatible with python < 3.8 - symforce_requires_python_38_or_higher___your_python_version_is_incompatible; python_version < '3.8' - """ + output_requirements_file.write_text(requirements_contents) + + self.compare_or_update_file( + path_util.symforce_data_root() / f"requirements_dev_py3{version}.txt", + output_requirements_file, + ) + + @sympy_only + def test_dev_requirements_py38(self) -> None: + self.check_dev_requirements_for_version(8) + + @sympy_only + def test_dev_requirements_py39(self) -> None: + self.check_dev_requirements_for_version(9) + + @sympy_only + def test_dev_requirements_py310(self) -> None: + self.check_dev_requirements_for_version(10) + + @sympy_only + def test_dev_requirements_py311(self) -> None: + self.check_dev_requirements_for_version(11) + + @sympy_only + def test_dev_requirements_py312(self) -> None: + self.check_dev_requirements_for_version(12) + + @sympy_only + def test_build_requirements(self) -> None: + """ + Generate requirements_build.txt + """ + output_dir = self.make_output_dir("sf_requirements_test_build_") + output_requirements_file = output_dir / "requirements_build.txt" + + local_requirements_map = { + "skymarshal @ file://{}/third_party/skymarshal": "file:./third_party/skymarshal", + "symforce-sym @ file://{}/gen/python": "file:./gen/python", + } + + asyncio.run( + python_util.execute_subprocess( + [ + python_util.find_uv_bin(), + "pip", + "compile", + "--no-deps", + "--extra=setup", + "--no-cache", + f"--output-file={output_requirements_file}", + "pyproject.toml", + ], + cwd=path_util.symforce_root(), + env=dict( + os.environ, + # Compile command to put in the header of requirements.txt + UV_CUSTOM_COMPILE_COMMAND="python test/symforce_requirements_test.py --update", + # Don't actually deduce versions for these, we don't need them + SETUPTOOLS_SCM_PRETEND_VERSION_FOR_SYMFORCE="0.1.0", + SETUPTOOLS_SCM_PRETEND_VERSION_FOR_SYMFORCE_SYM="0.1.0", + SETUPTOOLS_SCM_PRETEND_VERSION_FOR_SKYMARSHAL="0.1.0", + ), + ) ) - requirements_contents = requirements_contents.replace( - sentinel, sentinel + version_requirement + + # Reverse path rewrite back to relative paths + requirements_contents = output_requirements_file.read_text() + for key, value in local_requirements_map.items(): + requirements_contents = re.sub(key.format(".*"), value, requirements_contents) + + # Strip version numbers + requirements_contents = re.sub( + r"==[+-\.a-zA-Z0-9]+$", "", requirements_contents, flags=re.MULTILINE ) output_requirements_file.write_text(requirements_contents) self.compare_or_update_file( - path_util.symforce_data_root() / "dev_requirements.txt", output_requirements_file + path_util.symforce_data_root() / "requirements_build.txt", + output_requirements_file, )